open.mp icon indicating copy to clipboard operation
open.mp copied to clipboard

Player state discrepancy; class selection / spectating

Open Vince0789 opened this issue 9 months ago • 0 comments

Describe the bug The player's state remains as PLAYER_STATE_NONE (0) when they enter class selection for the first time. When using TogglePlayerSpectating true inside OnPlayerRequestClass the state also incorrectly updates from PLAYER_STATE_NONE (0) to PLAYER_STATE_SPECTATING (9). This behaviour also exists in SA-MP but seems wrong, it should probably update to PLAYER_STATE_WASTED as per the documentation.

The really strange then is that when the player is then spawned by using TogglePlayerSpectating false, the state updates from PLAYER_STATE_NONE (0) to PLAYER_STATE_SPAWNED (8) even though the player was clearly just in spectate mode.

This bug also seems to be present in SA-MP 0.3.7-R3 Server although it seems to have some kind of protection or detection for this kind of invalid state since it just kicks me out (without any Kick or Ban calls on my side).

To Reproduce Bare script, used on both SA-MP server and open.mp server:

#include <a_samp>

main() { }

forward public MockOnPlayerLogin(playerid);

public MockOnPlayerLogin(playerid)
{
	TogglePlayerSpectating(playerid, false);
	return 1;
}

public OnPlayerSpawn(playerid)
{
	printf("OnPlayerSpawn(playerid = %d) - state = %d", playerid, GetPlayerState(playerid));
	return 1;
}

public OnPlayerDeath(playerid, killerid, reason)
{
	printf("OnPlayerDeath(playerid = %d, killerid = %d, reason = %d) - state = %d", playerid, killerid, reason, GetPlayerState(playerid));
   	return 1;
}

public OnPlayerRequestClass(playerid, classid)
{
	printf("OnPlayerRequestClass(playerid = %d, classid = %d) - state = %d", playerid, classid, GetPlayerState(playerid));
	
	TogglePlayerSpectating(playerid, true);
	SetTimerEx("MockOnPlayerLogin", 10000, false, "d", playerid);
	
	return 1;
}

public OnPlayerStateChange(playerid, newstate, oldstate)
{
	printf("OnPlayerStateChange(playerid = %d, newstate = %d, oldstate = %d)", playerid, newstate, oldstate);
	return 1;
}

public OnGameModeInit()
{
	AddPlayerClass(265,1958.3783,1343.1572,15.3746,270.1425,0,0,0,0,-1,-1);
	return 1;
}

Expected behavior State should probably update from PLAYER_STATE_NONE to PLAYER_STATE_WASTED when the player first enters class selection. State should also properly update when the player is spawned by toggling off spectate mode.

Screenshots and/or logs SA-MP 0.3.7-R3:

[10:52:46] [connection] incoming connection: 127.0.0.1:55747 id: 0
[10:52:46] [join] Vince0789 has joined the server (0:127.0.0.1)
[10:52:46] OnPlayerRequestClass(playerid = 0, classid = 0) - state = 0
[10:52:46] OnPlayerStateChange(playerid = 0, newstate = 9, oldstate = 0)
[10:52:57] [part] Vince0789 has left the server (0:2)

open.mp Nightly:

[10:51:52] [Info] [join] Vince0789 has joined the server (0:127.0.0.1)
[10:51:52] [Info] OnPlayerRequestClass(playerid = 0, classid = 0) - state = 0
[10:51:53] [Info] OnPlayerStateChange(playerid = 0, newstate = 9, oldstate = 0)
[10:52:02] [Info] OnPlayerStateChange(playerid = 0, newstate = 8, oldstate = 0)
[10:52:02] [Info] OnPlayerSpawn(playerid = 0) - state = 8
[10:52:02] [Info] OnPlayerStateChange(playerid = 0, newstate = 1, oldstate = 8)

Commit hash in master 7b22bb036aafda001733649f67f5119ebf18b0cf Issue is also present in release build, though.

Vince0789 avatar Oct 08 '23 09:10 Vince0789