Page 1 of 1

Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 12:04 am
by dispensershell
Hi all,

I am trying to get a mod (https://mods.factorio.com/mods/kij336/autorun) working with my save.

The mod works on a new single player save but with a save that has had multiple users playing it throws an error:

Code: Select all

Error while running event on_tick (ID 0)
User isn't connected; can't read character
stack traceback:
	__autorun__/control.lua:59: in function <__autorun__/control.lua:54>
I'm guessing it's because I'm not player 0 on this save or something like that.

I had a look at the source around line 59 and it seems to be referencing b.character (b being a local variable referencing game.players)

.

Here is a snippet of the source:

Code: Select all

--autorun
function autorun(a)
	local b=game.players[a]	
	b.clean_cursor()
	b.cursor_stack.set_stack({name="autorun",count=1})
	b.character_build_distance_bonus=b.character_build_distance_bonus+200
	b.build_from_cursor()	
	b.cursor_stack.clear()
	b.character_build_distance_bonus=b.character_build_distance_bonus-200
end
function stoprun(a)
	global.autorun.target[a]=false
	global.autorun.auto[a]=false
end
script.on_event(defines.events.on_tick, function(event)	
	if global.autorun==nil then global.autorun={} end
	if global.autorun.target==nil then global.autorun.target={} end
	if global.autorun.auto==nil then global.autorun.auto={} end
	for a,b in pairs(game.players) do
		if b.character and global.autorun.auto[a] then
			autorun(a)
		end
		if b.character and global.autorun.target[a] then
			local direction=rotation(b.character,global.autorun.target[a])
			b.walking_state = {walking = true, direction = direction}	
			if distance(b.position,global.autorun.target[a])<=0.2 or b.mining_state.mining then
				global.autorun.target[a]=false
			end
		end
	end	
end)
Also, at the start there are multiple references to event.player_index which seems to be fed into the autorun function as 'a'.

Code: Select all

--press key
script.on_event("move", function(event)	
	stoprun(event.player_index)
	autorun(event.player_index)
end)
script.on_event("autorun", function(event)
	if global.autorun.auto[event.player_index] then global.autorun.auto[event.player_index]=false
	else global.autorun.auto[event.player_index]=true end	
end)
I am learning how to write code at the moment and this has taught me a lot so far but I just can't seem to get it right.

Any help appreciated.

EDIT: I ran

Code: Select all

/c game.player.print(game.player.index)
and it returned 2. So I think the mod will only work for index 0 or 1?

Re: Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 12:09 am
by mophydeen

Re: Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 12:14 am
by dispensershell
Thanks for your cryptic reply.. ;)

You've referenced a key in game.player called connected. Are you implying that I should check if the user is connected before completing an action? I don't think that will help in my case as the problem is mod is referencing a player that isn't connected. I need it to reference the local player (me).

Re: Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 12:22 am
by mophydeen
dispensershell wrote:
Thanks for your cryptic reply.. ;)

You've referenced a key in game.player called connected. Are you implying that I should check if the user is connected before completing an action? I don't think that will help in my case as the problem is mod is referencing a player that isn't connected. I need it to reference the local player (me).

You're running code for a player that isn't connected. Don't run that code.

There is a loop for all player on each tick so you will get your code run if you re connected.

Re: Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 12:24 am
by dispensershell
But I need to run that code. I just need to run it for me, not the disconnected user it is trying to run it for.

EDIT: I ran

Code: Select all

/c game.player.print(game.player.index)
and it returned 2. So I think the mod will only work for index 0 or 1?

Re: Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 12:38 am
by mophydeen
dispensershell wrote:But I need to run that code. I just need to run it for me, not the disconnected user it is trying to run it for.

EDIT: I ran

Code: Select all

/c game.player.print(game.player.index)
and it returned 2. So I think the mod will only work for index 0 or 1?

the mod crashes before it reaches 2

Re: Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 12:43 am
by dispensershell
mophydeen wrote:the mod crashes before it reaches 2
Right. Because it tries to reference player index 0 or 1 which are disconnected.

How can I make it reference not any particular player but the player that is actually playing? or the player that presses the key binding etc.?

EDIT: just noting again, the mod WORKS with a fresh single player save.

Re: Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 12:46 am
by mophydeen
dispensershell wrote:
mophydeen wrote:the mod crashes before it reaches 2
Right. Because it tries to reference player index 0 or 1 which are disconnected.

How can I make it reference not any particular player but the player that is actually playing? or the player that presses the key binding etc.?

EDIT: just noting again, the mod WORKS with a fresh single player save.
or you check if the player is connected
or you dont loop over all players and just hard code your 2 in it.
local player = game.players[2]

Re: Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 12:54 am
by dispensershell
mophydeen wrote: or you check if the player is connected
or you dont loop over all players and just hard code your 2 in it.
local player = game.players[2]
Can you show me where in the code it is looping through all players? Perhaps I can put a connect check there.

I tried hard coding by replacing all entries of event.player_index with 2 but it threw the same user disconnected error.

Thank you for your replies :)

Re: Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 1:00 am
by mophydeen
dispensershell wrote:
mophydeen wrote: or you check if the player is connected
or you dont loop over all players and just hard code your 2 in it.
local player = game.players[2]
Can you show me where in the code it is looping through all players? Perhaps I can put a connect check there.

I tried hard coding by replacing all entries of event.player_index with 2 but it threw the same user disconnected error.

Thank you for your replies :)

for a,b in pairs(game.players) do

if the above is around line 59.

Haven't looked at the source only a quick look over your snippets.

btw: it's probably in the ontick not in an event cause a player causes an event and is there otherwise you can't cause it ...

Re: Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 1:01 am
by daniel34
dispensershell wrote:Can you show me where in the code it is looping through all players? Perhaps I can put a connect check there.
In the script.on_event(defines.events.on_tick, function(event):

Code: Select all

for a,b in pairs(game.players) do
In theory it should be enough to replace any instance of if b.character with if b.connected and b.character (the first and fourth line after the for-loop) to make it work.

Re: Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 1:07 am
by dispensershell
daniel34 wrote:
dispensershell wrote:Can you show me where in the code it is looping through all players? Perhaps I can put a connect check there.
In the script.on_event(defines.events.on_tick, function(event):

Code: Select all

for a,b in pairs(game.players) do
In theory it should be enough to replace any instance of if b.character with if b.connected and b.character (the first and fourth line after the for-loop) to make it work.
You're my hero :D :D :D

I was thinking I would need an outer if loop to check .connected before checking .character but I guess because .connected is checked and it fails, the program doesn't bother checking any further conditions?

Re: Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 1:12 am
by daniel34
dispensershell wrote:I was thinking I would need an outer if loop to check .connected before checking .character but I guess because .connected is checked and it fails, the program doesn't bother checking any further conditions?
Correct. It would also be possible (and probably the cleaner way) to make an if-statement directly after the for-statement covering the whole loop.

In Lua (and many other programming languages) the leftmost condition is evaluated first, and if it is an and-construct where the first condition is already false it won't bother checking the other conditions, therefore never calling b.character if b.connected is already false.

Re: Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 1:35 am
by dispensershell
daniel34 wrote: Correct. It would also be possible (and probably the cleaner way) to make an if-statement directly after the for-statement covering the whole loop.

In Lua (and many other programming languages) the leftmost condition is evaluated first, and if it is an and-construct where the first condition is already false it won't bother checking the other conditions, therefore never calling b.character if b.connected is already false.
Thanks so much for your help! TIL =).

Re: Error: User isn't connected. Autorun Mod

Posted: Tue Jan 03, 2017 1:37 am
by Nexela
I may attempt at redoing this mod to be more efficient and mp friendly too. we will see how I feel after I put the kids to bed.