View Issue Details

IDProjectCategoryView StatusLast Update
0009610Multi Theft Auto : San AndreasSynchronizationpublic2017-07-04 15:58
Reporterjohny46Assigned ToNecktrox 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionwon't fix 
Product Version1.5.4 
Target Version1.5.5Fixed in Version 
Summary0009610: Setting player name in an onPlayerConnect event handler results in desync
Description

When you change the name of a player attempting to join your server upon the "onPlayerConnect" event fires, the client gets desynchronized.
getPlayerName() server-side will then return the new name, and on other clients it will also do that. But on the client whose name was changed, getPlayerName(localPlayer) will instead return the name they initially connected with.

Steps To Reproduce

Execute the following example code:

addEventHandler("onPlayerConnect", root,
function(playerNick)
local player = getPlayerFromName(playerNick)
local newName = string.format("%04d", math.random(9999))
local result = setPlayerName(player, newName)
if not result then
outputDebugString(string.format("Failed to change %q -> %q", playerNick, newName))
end
end
)

Reconnect

TagsNo tags attached.

Activities

arranTuna

2017-04-30 20:21

manager   ~~0025877

Last edited: 2017-05-18 01:18

View 2 revisions

Servers cannot permanently change another players name. In your steps to reproduce you've got "Reconnect" so I'm pretty sure this is a false bug report as you're reporting an intentional feature as a bug.

johny46

2017-04-30 22:42

viewer   ~~0025881

Reconnect so you actually get a chance to trigger that event yourself without the need for any other players on the server.

When you call the (server-sided) setPlayerName function at any moment other than just after the "onPlayerConnect" event is triggered, the value returned by subsequent client-side getPlayerName calls will be the newly set name.

Only when setting the name inside a "onPlayerConnect" (server-side) event handler occurs the problem I described - values returned by getPlayerName will be different if called server-side and if called on the affected client. All the other clients will get the new name of the affected player as well.

To better illustrate the issue, suppose this situation:

  • There are 2 players already connected to the server: "A" and "B".
  • Third player, nicknamed "C" attempts to join the server as well.
  • "onPlayerConnect" is triggered with the string "C" as the playerNick argument
  • Server-side scripts can obtain the player element by calling player = getPlayerFromName("C")
  • Server-side script calls setPlayerName(player, "D")

What happens after that:

  • getPlayerName(player) called server-side will correctly return the new name "D"
  • getPlayerName(player) called client-side on clients "A" and "B" will correctly return the new name "D"
  • getPlayerName(localPlayer) called client-side on the newly connected (third) client will incorrectly return "C"
  • getPlayerFromName("D") called client-side on the third client will return false, as if there was no player named "D"

Hope this helps.

Necktrox

2017-05-18 00:41

developer   ~~0025960

Last edited: 2017-05-29 17:42

View 4 revisions

Edit 2: This issue won't be fixed. The problem is getPlayerFromName, which returns a valid player element to a player, which didn't join the game yet and this particular client won't receive the update packets related to his player element, leading to desynchronization. Instead of synchronizing the server's player with the client's local player on successful join, the code will show a warning if any script tries to use player-modifying functions on the player element.

johny46

2017-05-29 19:53

viewer   ~~0025999

It would be nice if there was a way to assign new nicknames to players on join. Right now it is a bit problematic, because the default "joinquit" resource uses the "onClientPlayerConnect" event to display join messages.
The problem is that the event is triggered so early, that all the other clients still get the original nickname the player used when connecting to the server.

I've been able to workaround this with a bit of hacks, mainly using the "onClientPlayerChangeNick" event instead of "onClientPlayerConnect" in the client-sided "joinquit" resource.

As for the actual desync issue, I think a warning is fine. It'll at least make the script authors aware of some otherwise hard-to-spot problems.

Necktrox

2017-07-04 15:55

developer   ~~0026056

Fixed in https://github.com/multitheftauto/mtasa-blue/commit/5459fc5086ae644fea38831b35c60300e99bc6c1

Issue History

Date Modified Username Field Change