This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
coolmark1995's profile picture

SGCraft attempt to call nil

Started by coolmark1995, 21 September 2017 - 10:30 PM
coolmark1995 #1
Posted 22 September 2017 - 12:30 AM
So I am trying to get the program to work I have openperipherals. But the following code is showing a attempt to call nil on the dialer when my controller computer tries to ping it any ideas? here is the dialer code for that part.



while true do
	local id, msg, dis = rednet.receive()
  --  print("message received: "..msg)
	local msgArr = split(msg, "|", 0)
	local status = state[sg.getState()]
  --  print(status)
  --  print("Message array:")
  --  for i=1,#msgArr do
  --	print(i..": "..msgArr[i])
  --  end
	if msgArr[1] == "dial" then
	  if status == 0 then
		print(msgArr[2])
		if pcall(dial, id, msgArr[2]) then
		  rednet.send(id, "dialing")
		else
		  print("Unable to dial. Check fuel and verify address.")
		  rednet.send(id, "unable")
		end
	  else
		print("Stargate active; Closing womhole")
		pcall(close)
		--sleep(7)
		pcall(dial, id, msgArr[2])
		rednet.send(id, "notidle")
	  end
	elseif msgArr[1] == "close" then
	  if status ~= 0 then
		if pcall(close) then
		  print("Closing wormhole")
		else
		  print("Could not close wormhole!")
		end
	  else
		print("No wormhole to close!")
	  end
	elseif msgArr[1] == "ping" then
	  print("Receieve ping from #"..id)
	  rednet.send(id,"pong")
	end
  end
end
run()


From what I have found it the following seems to be causing the issue but I am not sure how to fix it.


    local status = state[sg.getState()]
Edited on 21 September 2017 - 10:33 PM
KingofGamesYami #2
Posted 22 September 2017 - 12:42 AM
Considering sg is not defined anywhere in the script, I would expect an "attempt to index ? (a nil value)" error. I'd guess you haven't posted the full code, nor the full error.

If the error you reported does occur on the line specified, I can only conclude the "sg" peripheral (whatever it is) doesn't have a getState() method (maybe it's not the right peripheral?)
coolmark1995 #3
Posted 22 September 2017 - 12:49 AM
Considering sg is not defined anywhere in the script, I would expect an "attempt to index ? (a nil value)" error. I'd guess you haven't posted the full code, nor the full error.

If the error you reported does occur on the line specified, I can only conclude the "sg" peripheral (whatever it is) doesn't have a getState() method (maybe it's not the right peripheral?)

This is what is in the controller/PC

-- SGController by zenithselenium - © 2014
-- Large portions of this code is adapted from DireWolf20's portal program
-- ( http://pastebin.com/ELAFP3kT )
function loadConfig()
  local out = {}
  if not fs.exists("SGC_config.txt") then
    print("Could not find config file. Please reinstall SGControl.")
    return nil
  end
  local config = fs.open("/SGC_config.txt","r")
  out.monitor = config.readLine()
  print("monitor: "..out.monitor)
  out.modem   = config.readLine()
  print("modem: "..out.modem)
  out.dialer  = config.readLine()
  print("dialer: "..out.dialer)
 
  return out
end
local page = 1
local pages = 0
local names = {}
local dialers = {}
local remove = false
local outOfFuel = false
function printHeader()
  shell.run("clear")
  print("################################################")
  print("#											  #")
  print("#				   SGControl				  #")
  print("#			  by: zenithselenium			  #")
  print("#											  #")
  print("################################################")
  print()
end
function fillDialers(dialer)
   dialers[1] = tonumber(dialer)
end
function printTable(table)
  for k,v in pairs(table) do
    print("key: "..k)
  end
end
function fillTable()
  m.clear()
  button.clearTable()
  local totalrows = 0
  local numNames = 0
  local col = 2
  local row = 11
  local countRow = 1
  local currName = 0
  local npp = 12 --names per page
  for dialer, data in pairs(names) do
    for i,j in pairs(data) do
	  totalrows = totalrows+1
    end
  end
  pages = math.ceil(totalrows/npp)
  print("Total addresses: "..totalrows)
  for dialer, data in pairs(names) do
    currName = 0
    for slot, name in pairs(data) do
	  currName = currName + 1
	  if currName > npp*(page-1) and currName < npp*page+1 then
	    row = 4+(countRow)
	    button.setTable(string.sub(name.name, 0, 17), runStuff, dialer..":"..slot, col, col+17 , row, row)
	    if col == 21 then
		  col = 2
		  countRow = countRow + 2
	    else
		  col = col+19
	    end
	  end
    end
  end
  button.setTable("Prev Page", prevPage, "", 2, 19, 1, 1)
  button.setTable("Next Page", nextPage, "", 21, 38, 1, 1)
  button.setTable("Add Address", addAddress, "", 2, 19, 17, 17)
  button.setTable("Close Gate", closeGate, "", 21, 38, 17, 17)
  button.setTable("Remove Address", removeIt, "", 2, 19, 19, 19)
  button.setTable("Refresh", checkNames, "", 21, 38, 19, 19)
  button.label(15,3, "Page: "..tostring(page).." of "..tostring(pages))
  button.screen()
end	 
function nextPage()
  if page+1 <= pages then
    page = page+1
  end
  fillTable()
  sleep(0.25)
end
function prevPage()
  if page-1 >= 1 then page = page-1 end
  fillTable()
  sleep(0.25)
end  
						  
function getNames()
   names = {}
   for index, dialer in pairs(dialers) do
	  names[dialer] = {}
	  shell.run("rm","/addresses")
	  shell.run("kode","pull addresses /addresses")
	  local file = fs.open("/addresses","r")
	  names[dialer] = textutils.unserialize(file.readAll())
	  file.close()
   end
end
function removeIt()
   remove = not remove
--   print(remove)
   button.toggleButton("Remove Address")
end
function runStuff(info)
  if remove == true then
    removeAddress(info)
  else
    dial(info)
  end	 
end
function removeAddress(info)
  local dialer, slot = string.match(info, "(%d+):(/>%d+)")
  button.toggleButton(names[tonumber(dialer)][tonumber(slot)].name)
  
  local temp = {}
  names[tonumber(dialer)][tonumber(slot)] = nil
  local count = 1
  local addresses = names[tonumber(dialer)]
  for i = 1, #addresses do
    if addresses[i] ~= nil then
	  temp[count] = addresses[i]
	  count = count +1
    end
  end
  local file = fs.open("/addresses","w")
  file.write(textutils.serialize(temp))
  file.close()
  shell.run("kode","push addresses /addresses")
  remove=false
  button.toggleButton("Remove Address")
--   sleep(1)
  getNames()
  fillTable()
end  
function msgBox()
  fillTable()
  m.setBackgroundColor(2)
  for i = 5,14 do
    m.setCursorPos(8,i)
    for j = 1,25 do
	  m.write(" ")
    end
  end
end
function addAddress()
  fillTable()
  msgBox()
  m.setCursorPos(12,8)
  m.setTextColor(colors.black)
  m.write("Please enter the")
  m.setCursorPos(13,9)
  m.write("new address in")
  m.setCursorPos(14,10)
  m.write("the terminal")
  m.setBackgroundColor(colors.black)
  m.setTextColor(colors.white)
  printHeader()
  print("Location Name:")
  local name = read()
  print("Address: ")
  local address = read()
  printHeader()
  local addresses = names[dialers[1]]
  addresses[#addresses + 1] = {["name"]=name,["addr"]=address}
  local file = fs.open("/addresses","w")
  file.write(textutils.serialize(addresses))
  file.close()
  shell.run("kode","push addresses /addresses")
  printHeader()
  print("Addresses updated")
  fillTable()
end
function fuelError()
  print("Stargate out of fuel.")
  msgBox()
  m.setCursorPos(15,8)
  m.setTextColor(colors.black)
  m.write("Out of fuel")
  m.setCursorPos(14,9)
  m.write("Place fuel in")
  m.setCursorPos(12,10)
  m.write("chest, then click")
  m.setCursorPos(17,11)
  m.write("Refresh")
  m.setBackgroundColor(colors.black)
  m.setTextColor(colors.white)
  outOfFuel = true
end
function closeGate()
  button.flash("Close Gate")
  rednet.send(dialers[1], "close|now")
  getNames()
  fillTable()
end
function dial(info)
  local dialer,slot = string.match(info, "(%d+):(/>%d+)")
  local name = names[tonumber(dialer)][tonumber(slot)].name
  local addr = names[tonumber(dialer)] [tonumber(slot)] .addr
  button.toggleButton(name)
  print("Requesting dialer to dial "..name.." ("..addr..")")
  data = "dial|"..addr
  rednet.send(tonumber(dialer), data)
  local id, msg, dis = rednet.receive(8)
  if (msg == nil) then
    term.setTextColor(colors.red)
    print("Dialer failed to respond.")
    term.setTextColor(colors.white)
  elseif msg == "nofuel" then
    fuelError()
  else
    print("Message: "..msg)
  end
  getNames()
  if not outOfFuel then
    button.toggleButton(name)
    fillTable()
  end
end
function checkNames()
  if outOfFuel then
    m.clear()
  else
    button.flash("Refresh")
  end
  
  getNames()
  fillTable()
  outOfFuel = false
end
function controllerOfflineMessage()
  m.clear()
  m.clear()
  msgBox()
  m.setTextColor(colors.black)
  m.setCursorPos(11,9)
  m.write("Controller offline")
  m.setBackgroundColor(colors.black)
  m.setTextColor(colors.white)
end
function initializingMessage()
  m.clear()
  m.clear()
  msgBox()
  m.setTextColor(colors.black)
  m.setCursorPos(14,9)
  m.write("Initializing")
  m.setBackgroundColor(colors.black)
  m.setTextColor(colors.white)
end
function manualDialMessage()
  m.clear()
  msgBox()
  m.setTextColor(colors.black)
  m.setCursorPos(13,9)
  m.write("Manual Dialing")
  m.setBackgroundColor(colors.black)
  m.setTextColor(colors.white)
end
function manualDial()
  manualDialMessage()
  printHeader()
  print("Enter address")
  local addr = read()
  rednet.send(tonumber(dialers[1]), "dial|"..addr)
  id, msg = rednet.receive(5)
  print(msg)
  checkNames()
end
function getClick()
  event, side, x,y = os.pullEventRaw()
  if event == "monitor_touch" then
    button.checkxy(x,y)
  elseif event == "redstone" then
    --print("redstone")
    sleep(5)
    getNames()
    fillTable()
  elseif event == "terminate" then
    print("Terminating")
    controllerOfflineMessage()
    return false
  elseif event == "key" and side == 32 then
    manualDial()
  end
  return true
end

function checkDialer()
  print "Pinging dialer..."
  rednet.send(dialers[1], "ping")
  local success = false
  local id, msg, dis = rednet.receive(5)
  if (msg == nil) then
    for i = 2,5 do
	  term.setTextColor(colors.red)
	  print("Dialer did not respond. Trying again.")
	  term.setTextColor(colors.white)
	  print("Pinging dialer (attempt "..i.. " of 5)...")
	  rednet.send(dialers[1], "ping")
	  local id, msg, dis = rednet.receive(5)
	  if (msg ~= nil) then
	    success = true
	    break
	  end
    end
  else
    success = true
  end
  return success
end
--
function run()
  printHeader()
  print("Initializing...")
  print("Loading config")
  local config = loadConfig()
  if config == nil then
    return
  end
  print("Config loaded")
  m = peripheral.wrap(config.monitor)
  m.clear()
  --initializingMessage()
  rednet.open(config.modem)
  os.loadAPI("button")
  print("button API loaded")
  button.setup(m)
  print("button API initialized")
  fillDialers(config.dialer)
  if not checkDialer() then
    term.setTextColor(colors.red)
    print("Dialer failed to respond. Is it offline?")
    term.setTextColor(colors.white)
    return
  else
    print("Dialer locked in")
  end
  getNames()
  print("Addresses loaded")
  fillTable()
  print("GUI populated")
  print("Initialization complete.")
  local continue = true
  while continue do
    continue = getClick()
    --checkNames()
  end
end
run()
controllerOfflineMessage()

I am using a SGCraft script on the forum from 2014 from: http://www.computercraft.info/forums2/index.php?/topic/17032-sgcontrol-sgcraft-stargate-controller/ the following. I just don't see a way to get it working and I might be mistaken but I don't see any newly updated SGCraft control scripts for the latest 1.7.10 computercraft.
Dog #4
Posted 22 September 2017 - 01:38 AM
Based on your reply it sounds like you're open to trying other programs. If that's the case, you have a choice of dialer programs that work with CC for MC 1.7.10.

[shameless_plug]
I've written 3 myself
[/shameless_plug]

And there is also the dialer program from thatParadox.

Regarding the 3 scripts I've written: If you're looking for a simple dialer/address-book that connects directly to the gate you might want to checkout ccDHDLite or ccDHDBasic (written specifically for SGCraft). Links to both of those scripts can be found by following the link in my signature.

If you'd like a more full featured suite that includes the ability to use an advanced portable computer for dialing gates then check out ccDHD.

If, otoh, you'd prefer to get your current program working, give us a little time and KoGY or I (or someone) will help you get it working.
darkdragon #5
Posted 24 December 2017 - 01:12 PM
Hi DOG i am using same dialer and controller as
coolmark1995

and you said this

If, otoh, you'd prefer to get your current program working, give us a little time and KoGY or I (or someone) will help you get it working.

i was wondering if you have had any luck with it as when i have dialer installed it says last line sgdialer:118:no such modem:right and is an advanced wireless turtle

and as for advanced pc it attempts 5 times and i can not click on monitors to add address

now im running mc 1.7.10 sgcraft 1.8.6 and cc 1.65

now on another note a couple of years ago i cam across an MC map download that had sgc inside a mountain with working PC
to work stargate and iris and you could go to an Atlantis base abydos and back to earth it had no entrance you
used a teleport by hitting a button i think that was at spawn it had everything running but cant find have you
come across this at all as i relay would like to find it again
Dog #6
Posted 24 December 2017 - 06:03 PM
That error means you don't have a modem on the right side of the turtle. You'll either need to configure the program to look at the left side of the turtle or you'll need to move the modem to the right side. You can do that with this simple program, just make sure slot 1 is empty

turtle.select(1)
turtle.equipLeft()
turtle.equipRight()

The code posted above doesn't match the error message you posted so I can only guess as to why monitors don't accept clicks. I'll need to see the exact code you're running, the setup program, and the button api the program uses in order to help troubleshoot that problem. But first, fix the modem problem, then we'll go from there.
Bomb Bloke #7
Posted 24 December 2017 - 11:58 PM
The weird thing about "sides" is that a computer's left/right assumes it's facing you, and a turtle's left/right assumes it's facing away from you.
darkdragon #8
Posted 25 December 2017 - 08:10 AM
ok i have done the turtle on every side possible as for the code it is the exact same from that site coolmark1995 stated above
http://www.computercraft.info/forums2/index.php?/topic/17032-sgcontrol-sgcraft-stargate-controller/

is their a way to copy everything out of the pc to past it here

and as for that sgdialer code it only asks where the dialer is to the base of stargate and what side of the dialer and where the fuel chest is located never about a modem only the sgcontrol asks where the modem on the pc is and where the monitors are to the pc and the dialers number you get when installed
i even did as in the images on his page and still same error
Edited on 25 December 2017 - 09:53 AM
Dog #9
Posted 25 December 2017 - 04:45 PM
One thing I noticed in the screenshots for that program is that there is no stargate/CC adapter block between the stargate and the turtle. Without that adapter block the turtle won't see the stargate.

Regarding the modem sides - you tried my script on the turtle, then ran the program and got the same error?
darkdragon #10
Posted 26 December 2017 - 12:00 AM
One thing I noticed in the screenshots for that program is that there is no stargate/CC adapter block between the stargate and the turtle. Without that adapter block the turtle won't see the stargate.

Regarding the modem sides - you tried my script on the turtle, then ran the program and got the same error?
i did not use the script was not 100% where to use it but i moved the turtle so was facing other way and still nothing

i got the touch screen to work all i did was put monitors on left and pc on right side of them and wireless modem on right of pc but dialer still no
Dog #11
Posted 26 December 2017 - 12:03 AM
But do you have a stargate/CC adapter block between the stargate and the turtle?
darkdragon #12
Posted 26 December 2017 - 02:51 AM
i did but then it cant find stargate at all as the turtle needs to be the one the base block touches and now monitor is not working again so i dont know
Dog #13
Posted 26 December 2017 - 03:47 AM
If the version of SGCraft you're using has the CC adapter block then that block is required and must be between the turtle and the stargate base. If the version you're using doesn't have the block then the turtle should touch the base of the stargate. But, again, if your version has the block then it *must* go between the turtle and the stargate or it won't work - that block contains the CC interface.

As for why the monitors stopped working - I really can't even guess based on the information you've provided.

If I understand correctly, you're version of SGCraft has the adapter block, but the turtle isn't seeing the stargate with or without the adapter block. Can you please verify this for me? Is this correct?
darkdragon #14
Posted 26 December 2017 - 04:49 PM
that is correct so if i put turtle down it has to have naquadria in it for gate then cc block on top how do i get it to power to gate and connect to pc and turtle
and gate i would love this one but i think i would rather try and nut out the ccdhd of yours in the other post as this is like a nightmare lol.

that is why i wish i could find this map i got a few years ago when you spawn you turned around and their was a teleporter you stood on and hit button
and where teleported inside a mountain complex with no entrance it was the sgc with working stargate on a pc system that opened and closed the iris
and dialed to a atlantis base that was just the main tower and command floating in mid air as that would help with all this lol im still trying everything to find it.
Dog #15
Posted 26 December 2017 - 04:54 PM
I think you've hit the nail on the head. Since the adapter block is required the turtle can't fuel the gate. This program was apparently written for an older version of SGCraft. You'll either need to figure out which version of SGCraft doesn't require an adapter block or use another program.

I have no idea about the map your describing - although it sounds quite awesome.
darkdragon #16
Posted 26 December 2017 - 09:51 PM
yea if i do ever find it ill link it to you
darkdragon #17
Posted 28 December 2017 - 04:50 AM
im thinking im going to do my own as i have a good abydos and Atlantis so ill find a good Cheyenne mountain and ill link you the map and credit you as ill use your ccdhd and all the other ppl as well