/// <summary> /// This method is called when the ClientEnter event fires for a /// player. Its purpose is to check whether the player has a pending /// resync request, and, if so, to execute the resync operation. /// </summary> /// <param name="State">Supplies the player object of the incoming /// player.</param> /// <param name="Script">Supplies the script object.</param> public static void OnClientEnter(uint PCObject, ACR_ServerCommunicator Script) { PlayerState State = Script.TryGetPlayerState(PCObject); if (State == null) { return; } var ResyncInfo = (from RS in PlayerResyncStates where RS.PlayerId == State.PlayerId select RS).FirstOrDefault(); if (ResyncInfo == null) { return; } // // Dequeue the resync state and start attempting to apply it to the // player object once the player has loaded. // PlayerResyncStates.Remove(ResyncInfo); ResynchronizePlayerState(ResyncInfo, PCObject, Script); }
/// <summary> /// This method is called when a cross-server chat select /// resynchronization request is received. Its purpose is to scan the /// player list to check whether the argument player is online, and to /// activate chat select GUI resynchronization if appropriate, else to /// queue the resynchronization until the player does log in. /// </summary> /// <param name="SourceServerId">Supplies the server id of the server /// that requested the GUI resynchronization.</param> /// <param name="ResyncCommand">Supplies the GUI resynchronizer command /// line as generated by SendGUIStateToServer().</param> /// <param name="Script">Supplies the current script object.</param> /// <returns>TRUE on success, else FALSE on failure.</returns> public static int HandleGUIResync(int SourceServerId, string ResyncCommand, ACR_ServerCommunicator Script) { try { ResyncState RemoteResyncInfo; // // Deserialize the remote resynchronization state. On null, an // obviously invalid request was received. Otherwise a protocol // violation that is atypical was received and an exception is // raised. // if ((RemoteResyncInfo = ResyncState.FromString(ResyncCommand)) == null) { Script.WriteTimestampedLogEntry(String.Format( "ACR_ServerCommunicator.GUIResynchronizer.HandleGUIResync({0}, {1}): Invalid request.", SourceServerId, ResyncCommand)); return(ACR_ServerCommunicator.FALSE); } // // If a request was not already enqueued for this player, then // enqueue it. // var ResyncInfo = (from RS in PlayerResyncStates where RS.PlayerId == RemoteResyncInfo.PlayerId select RS).FirstOrDefault(); if (ResyncInfo == null) { // // If the player is logged on, directly enqueue the execute // request now. Otherwise, wait for the ClientEnter event // as the player might still reside on the remote server. // foreach (uint PCObject in Script.GetPlayers(true)) { PlayerState State; if ((State = Script.TryGetPlayerState(PCObject)) == null) { continue; } if (State.PlayerId != RemoteResyncInfo.PlayerId) { continue; } ResynchronizePlayerState(RemoteResyncInfo, PCObject, Script); return(ACR_ServerCommunicator.TRUE); } // // Enqueue the request so that it can be processed at // ClientEnter time. // PlayerResyncStates.Add(RemoteResyncInfo); } else { // // Update the resync flags to match the new request. // ResyncInfo.ResyncFlags = RemoteResyncInfo.ResyncFlags; } } catch (Exception e) { Script.WriteTimestampedLogEntry(String.Format( "ACR_ServerCommunicator.GUIResynchronizer.HandleGUIResync({0}, {1}): Exception: {0}", SourceServerId, ResyncCommand, e)); return(ACR_ServerCommunicator.FALSE); } return(ACR_ServerCommunicator.TRUE); }