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

Greg's SG Craft v1.11.2 attempt to concatenate string and nil

Started by MoRBiiD Legacy, 03 August 2016 - 07:28 PM
MoRBiiD Legacy #1
Posted 03 August 2016 - 09:28 PM
I am trying to use a program created by another person that is an interactive menu for stargates, but when I try to start it, it gives the following:


SGctl (1pre1) -- by qwertz19281

State: Offline
Direction: Closed
Iris: Offline

sgctl:107: attempt to concatenate string and nil

Here is the code:

1.		 local args = {...}
2.			  local MAIN_VERSION = "1pre1"
3.	local SGC_CONTROLLER_VERSION = "0.1(beta)"
4. local LANTEA_CONTROLLER_VERSION = "1pre1"
5.		 term.clear()
6.		 term.setCursorPos(1,1)
7.		 term.write("define config")
8.		
9. -- CONFIGURATION START
10. term.write(" (Edit script to change config)") --Comment out this line
11.
12. local SGCRAFT_REFRESHRATE=0.5
13. local LANTEA_REFRESHRATE=1
14.
15. -- CONFIGURATION END
16.
17.
18.		 print()
19.		 local sg=nil
20.		 local running = false
21.		 local rd_timeout=nil
22.
23. print("define bridge")
24.
25. local gmsg=nil
26.
27. function gloop() --SGCraft loop
28.	 local gdat = {os.pullEvent()}
29.	 if sg.energyAvailable ~= nil then
30.		 gpwr=sg.energyAvailable()
31.	 end
32.	 gir=sg.irisState()
33.	 --tclear()
34.	 if gdat[1]=="key" then
35.		 if gdat[2]==keys.d then
36.			 local h, j = term.getCursorPos()
37.			 print("Enter Address: ")
38.			 term.setCursorPos(1,j+2)
39.			 gtxt=slrd()
40.			 ok, gdp=pcall(sg.energyToDial, gtxt)
41.			 if ok then
42.				 if gpwr==0 then
43.					 print("WARNING: Energy buffer is empty!")
44.					 ok, result = pcall(sg.dial, gtxt)
45.					 if ok then
46.						 print("dial "..gtxt.." now!")
47.					 else
48.						 print("Dialling failed: "..result)
49.						 sleep(3)
50.					 end
51.				 elseif gdp > gpwr then
52.					 print("Not enough energy: "..gtxt.." needs "..tostring(gdp).."SU but only "..tostring(gpwr).."SU are available!")
53.					 sleep(5)
54.				 else  
55.					 ok, result = pcall(sg.dial, gtxt)
56.					 if ok then
57.						 print("dial "..gtxt.." now!")
58.					 else
59.						 print("Dialling failed: "..result)
60.						 sleep(3)
61.					 end
62.				 end
63.			 else
64.				 print("Address error: "..gdp)
65.				 sleep(4)
66.			 end
67.		 elseif gdat[2]==keys.c then
68.			 sg.disconnect()
69.		 elseif gdat[2]==keys.i then
70.			 if gir=="Opening" or gir=="Open" then
71.				 sg.closeIris()
72.			 elseif gir=="Closed" or gir=="Closing" then
73.				 sg.openIris()
74.			 end
75.		 elseif gdat[2]==keys.m then
76.			 local h, j = term.getCursorPos()
77.			 print("Enter Message: ")
78.			 term.setCursorPos(1,j+2)
79.			 local ok, reta = pcall(sg.sendMessage, slrd())
80.			 if ok then
81.				 print("Sent message")
82.			 else
83.				 print("ERROR: "..reta)
84.				 sleep(3)
85.			 end
86.		 elseif gdat[2]==keys.x then
87.			 running=false
88.		 end
89.	 elseif gdat[1]=="sgMessageReceived" then
90.		gmsg=string.gsub(textutils.serialize(gdat),"\n","")
91.	  
92.	 elseif gdat[1]=="timer" and gdat[2]==rd_timeout then
93.		rd_timeout = os.startTimer(SGCRAFT_REFRESHRATE)
94.	 end
95.	 gst, gchr, gdir = sg.stargateState()
96.	 gla=sg.localAddress()
97.	 grm=sg.remoteAddress()
98.	
99.	 tclear()
100.	 --print("State: "..gst)
101.	 prclstate(gst)
102.	 --print("Direction: "..gdir)
103.	 prclwormhole(gdir)
104.	 --print("Iris: "..gir)
105.	 prcliris(gir)
106.	 print()
107.	 print("Local Address: "..gla.."\nRemote Address: "..grm) -- This is where the error is
108.	 print()
109.	 print("SGCraft Controller "..SGC_CONTROLLER_VERSION.." - SU Available: "..tostring(gpwr))
110.	
111.	 if gmsg ~= nil then
112.		print("last message: "..gmsg)
113.	 end
114.	 if gchr ~= nil then
115.		print("engaged chevron "..tostring(gchr))
116.	 end
117.	
118.	 print("\nKeys: Dial (D), Disconnect (C), Toggle Iris(I), Send Message (M), Exit (X)")
119. end
120.
121. local gcs = {Idle=colors.green, Offline=colors.white, Connected=colors.blue, Opening=colors.red, Closing=colors.yellow, Dialling=colors.orange}
122. function prclstate(mesg)
123.	 if mesg~=nil and mesg~="" then
124.		 term.write("State: ")
125.		 coltex(gcs[mesg])
126.		 print(mesg)
127.		 coltex(colors.white)
128.	 else
129.		 print("State: Idle")
130.	 end
131. end
132.
133. local gwh={Outgoing=colors.blue, Incoming=colors.red}
134. function prclwormhole(mesg)
135.	 if mesg~=nil and mesg~="" then
136.		 term.write("Direction: ")
137.		 coltex(gwh[mesg])
138.		 print(mesg)
139.		 coltex(colors.white)
140.	 else
141.		 term.write("Direction: ")
142.		 coltex(colors.green)
143.		 print("Closed")
144.		 coltex(colors.white)
145.	 end
146. end
147.
148. local giirriiss={Closed=colors.green, Closing=colors.lightBlue, Open=colors.blue, Opening=colors.lime, Offline=colors.yellow}
149. function prcliris(mesg)
150.	 if mesg~=nil and mesg~="" then
151.		 term.write("Iris: ")
152.		 coltex(giirriiss[mesg])
153.		 print(mesg)
154.		 coltex(colors.white)
155.	 else
156.		 print("Iris: "..tostring(mesg))
157.	 end
158. end
159.
160. --local lincoming=nil
161. --local loutgoing=nil
162. --local lidle=true
163. --local lwop=false
164. --local lwos=false
165. --local lwoc=false
166. local lstate="idle"
167. local lcs=colors.green
168. local lwh="closed"
169. local lcw=colors.green
170. local lencoded=nil
171. local liv=nil
172. local loa=nil
173.
174. function lloop() --LanteaCraft loop
175.	 local evt, earg = os.pullEvent()
176.	 if not sg.isDialing() then
177.		 lencoded=nil
178.	 end
179.	 if evt=="key" then
180.		 if earg==keys.d then
181.			 local h, j = term.getCursorPos()
182.			 print("Enter Address: ")
183.			 term.setCursorPos(1,j+2)
184.			 ltxt=slrd()
185.			 ok, result = pcall(sg.dial, ltxt)
186.			 if ok then
187.				 print("dial "..ltxt.." now!")
188.			 else
189.				 print("Dialling failed: "..result)
190.				 sleep(3)
191.			 end
192.		 elseif earg==keys.c then
193.			 sg.disconnect()
194.		 elseif earg==keys.x then
195.			 running=false
196.		 end
197.	 elseif evt=="sgIncoming" then
198.		lcs=colors.red
199.		lstate="incoming from - "..earg
200.	 elseif evt=="sgOutgoing" then
201.		lcs=colors.blue
202.		lstate="outgoing to - "..earg
203.	 elseif evt=="sgChevronEncode" then
204.		lencoded=earg
205.	 elseif evt=="sgIdle" then
206.		 if earg then
207.			 lcs=colors.green
208.			 lstate="idle"
209.			
210.			 lcw=colors.green
211.			 lwh="closed"
212.		 end
213.	 elseif evt=="sgWormholeOpening" then
214.		 if earg then
215.			 lcw=colors.red
216.			 lwh="opening"
217.		 end
218.	 elseif evt=="sgWormholeClosing" then
219.		 if earg then
220.			 lcw=colors.yellow
221.			 lwh="closing"
222.		 end
223.	 elseif evt=="sgWormholeStable" then
224.		 if earg then
225.			 lcw=colors.blue
226.			 lwh="open"
227.		 end
228.	 elseif evt=="timer" and earg==rd_timeout then
229.		rd_timeout = os.startTimer(LANTEA_REFRESHRATE)
230.	 end
231.	 lhf=sg.hasFuel()
232.	
233.	 tclear()
234.	 coltex(colors.white)
235.	 term.write("State: ")
236.	 coltex(lcs)
237.	 print(lstate)
238.	 coltex(colors.white)
239.	 term.write("Wormhole: ")
240.	 coltex(lcw)
241.	 print(lwh)
242.	
243.	 coltex(colors.white)
244.	 print()
245.	 print("LanteaCraft controller "..LANTEA_CONTROLLER_VERSION.." - address="..loa)
246.	 term.write("	ModVersion="..liv)
247.	 if lhf then
248.		coltex(colors.green)
249.		print(" (hasFuel=true)")
250.		coltex(colors.white)
251.	 else
252.		coltex(colors.red)
253.		print(" (hasFuel=false)")
254.		coltex(colors.white)
255.	 end
256.	
257.	 if lencoded ~= nil then
258.		print("encoded chevron "..tostring(lencoded))
259.	 end
260.	
261.	 print("\nKeys: Dial (D), Disconnect (C), Exit (X)")
262. end
263.
264. local gsc=nil
265.
266. function checkmod(stbl) --write SGCraft boolean to gsc
267.	gsc=(stbl.stargateState ~= nil)
268. end
269.
270. print("define utils")
271.
272. local colsup=term.isColor()
273. function coltex(col)
274.	 if colsup then
275.		 term.setTextColor(col)
276.	 end
277. end
278.
279. function PREflushX(inp)
280.	if inp=="X" then
281.		error()
282.	else
283.		return inp
284.	end
285. end
286.
287. function flushX(inp)
288.	if inp=="X" then
289.		running=false
290.	else
291.		return inp
292.	end
293. end
294.
295. function curpos(x,y)
296.	term.setCursorPos(x, y+2)
297. end
298.
299. function slrd()
300.	 to_sluk=os.startTimer(0.1)
301.	 while true do
302.		 evrt = {os.pullEvent()}
303.		 --print(string.sub(evrt[1], 1, 2))
304.		 if evrt[1]=="timer" and evrt[2]==to_sluk then
305.			 return read()
306.		 --elseif evrt[1]=="key" then
307.		 --	evrt=nil --Ignore key
308.		 elseif string.sub(evrt[1], 1, 2)=="sg" then
309.			 --sleep(0.1)
310.			 os.queueEvent(unpack(evrt))
311.		 end
312.	 end
313. end
314.
315. function tclear()
316.	term.clear()
317.	term.setCursorPos(1,1)
318.	print("SGctl ("..MAIN_VERSION..") -- by qwertz19281")
319.	print("")
320. end
321.
322. print("execute")
323. print("search stargate")
324. local sc = {peripheral.find("stargate")}
325. local scn=1
326. if sc==nil or #sc<1 then
327.	 print("ERROR: No stargate peripheral found!")
328.	 error()
329. end
330. if #sc > 1 then
331.	 selsolved=false
332.	 if args~=nil and #args>0 then
333.		 scn=tonumber(args[1])
334.		 if not (scn==nil or scn>#sc or scn<1) then
335.			 selsolved=true
336.		 end
337.	 end
338.	 if not selsolved then
339.		 tclear()
340.		 curpos(1, 1)
341.		 print("Please select one from "..tostring(#sc).." stargates! (X for exit)")
342.		 scn=tonumber(PREflushX(slrd()))
343.		 while scn==nil or scn>#sc or scn<1 do
344.			 tclear()
345.			 print("NUMBER MALFORMED OR OUT OF BOUNDS!")
346.			 curpos(1, 2)
347.			 print("Please select one from "..tostring(#sc).." stargates! (type X for exit)")
348.			 scn=tonumber(PREflushX(slrd()))
349.		 end
350.	 end
351. end
352. sg=sc[scn]
353. checkmod(sg)
354. running = true
355. if not gsc then
356.	loa=sg.getAddress()
357.	liv=sg.getInterfaceVersion()
358. end
359. rd_timeout = os.startTimer(LANTEA_REFRESHRATE)
360. while running do
361.	 if gsc then
362.		 gloop()
363.	 else
364.		 lloop()
365.	 end
366. end
367. term.clear()
368. term.setCursorPos(1,1)
369. print("SGctl exited")
Dog #2
Posted 03 August 2016 - 09:46 PM
The only thing I can see is that grm (remote address) may be nil if the gate isn't connected. Try replacing line 107 with this…

print("Local Address: "..gla.."\nRemote Address: "..(grm or "None"))
MoRBiiD Legacy #3
Posted 03 August 2016 - 10:00 PM
The only thing I can see is that grm (remote address) may be nil if the gate isn't connected. Try replacing line 107 with this…

print("Local Address: "..gla.."\nRemote Address: "..(grm or "None"))

Ok, so I think the code works because I am not getting any error messages now, but none of the functions are working. For example when I type "d" to dial and then type an address, nothing happens. If I try connecting the two gates with a standard DHD, it works. I think this a bug in the mod, but not sure.
Dog #4
Posted 03 August 2016 - 10:31 PM
It's not a bug in the mod, it's the way the program is written…frankly, it's a bit of a mess. After pressing 'd' to dial, the program waits 1/10 second then falls back to reading user input - for that initial 1/10 of a second all key input is ignored. Then the program appears to try to get the energy required to dial, but I've never seen that method (it's possible it may not exist) - if that method doesn't exist the pcall will always return false and you'll never be able to dial. Additionally, Greg removed the necessity for pcall starting with SGCraft 1.11.0 and based on how SGCraft now returns info, this program won't work correctly until all the pcalls are removed. Then it *might* work correctly, but no guarantees.

For example, line 40 should read…

ok, gdp=sg.energyToDial(gtxt)

lines 44 &amp; 55 should read…

ok, result = sg.dial(gtxt)

and line 79 should read…

local ok, reta = sg.sendMessage(slrd())
MoRBiiD Legacy #5
Posted 03 August 2016 - 11:46 PM
It's not a bug in the mod, it's the way the program is written…frankly, it's a bit of a mess. After pressing 'd' to dial, the program waits 1/10 second then falls back to reading user input - for that initial 1/10 of a second all key input is ignored. Then the program appears to try to get the energy required to dial, but I've never seen that method (it's possible it may not exist) - if that method doesn't exist the pcall will always return false and you'll never be able to dial. Additionally, Greg removed the necessity for pcall starting with SGCraft 1.11.0 and based on how SGCraft now returns info, this program won't work correctly until all the pcalls are removed. Then it *might* work correctly, but no guarantees. For example, line 40 should read…
 ok, gdp=sg.energyToDial(gtxt) 
lines 44 &amp; 55 should read…
 ok, result = sg.dial(gtxt) 
and line 79 should read…
 local ok, reta = sg.sendMessage(slrd()) 
Ok, so that really helped. Part of the second problem was just misplacing the RF power converter so there was no power going to the stargate, but the other part was that when it did start receiving power it would dial but disconnect in less than a second, but somehow your suggested fixes helped keep it stable. Thanks for the help!