private void UpdatePlayerWithServerState(SnapshotPlayerInfo snapshotPlayerInfo) { ClientPlayer clientPlayer = playersManager.players[snapshotPlayerInfo.id]; if (clientPlayer.basePlayer.colorable.color != snapshotPlayerInfo.color) { clientPlayer.basePlayer.colorable.ChangeColor(snapshotPlayerInfo.color); } clientPlayer.basePlayer.impostorable.isImpostor = snapshotPlayerInfo.isImpostor; }
public ClientGameSnapshot ReadClientGameSnapshot(bool updateReadPosition = true) { int snapshotId = ReadInt(updateReadPosition); int lastProcessedInputId = ReadInt(updateReadPosition); // Read players information Dictionary <int, SnapshotPlayerInfo> snapshotPlayerInfos = new Dictionary <int, SnapshotPlayerInfo>(); int snapshotPlayersAmount = ReadInt(updateReadPosition); for (int snapshotPlayerIndex = 0; snapshotPlayerIndex < snapshotPlayersAmount; snapshotPlayerIndex++) { int playerId = ReadInt(updateReadPosition); string playerName = ReadString(updateReadPosition); bool isPlayerLobbyHost = ReadBool(updateReadPosition); PlayerInput playerInput = ReadPlayerInput(updateReadPosition); Vector2 playerPosition = ReadVector2(updateReadPosition); bool isPlayerUnseen = ReadBool(updateReadPosition); PlayerColor playerColor = (PlayerColor)ReadInt(updateReadPosition); bool isPlayerImpostor = ReadBool(updateReadPosition); snapshotPlayerInfos[playerId] = new SnapshotPlayerInfo(playerId, playerName, isPlayerLobbyHost, playerInput, playerPosition, isPlayerUnseen, playerColor, isPlayerImpostor); } // Read lobby game starting info bool gameStarts = ReadBool(updateReadPosition); bool gameStarted = ReadBool(updateReadPosition); int impostorsAmount = ReadInt(updateReadPosition); // Read admin panel info Dictionary <int, int> adminPanelInfo = new Dictionary <int, int>(); int adminPanelInfoLength = ReadInt(updateReadPosition); for (int adminPanelInfoPiece = 0; adminPanelInfoPiece < adminPanelInfoLength; adminPanelInfoPiece++) { int roomId = ReadInt(updateReadPosition); int playersAmount = ReadInt(updateReadPosition); adminPanelInfo[roomId] = playersAmount; } // Read security cameras bool securityCamerasEnabled = ReadBool(updateReadPosition); return(new ClientGameSnapshot(snapshotId, lastProcessedInputId, snapshotPlayerInfos, gameStarts, gameStarted, impostorsAmount, adminPanelInfo, securityCamerasEnabled)); }
public void UpdateNotControlledPlayerWithServerState(SnapshotPlayerInfo snapshotPlayerInfo) { if (snapshotPlayerInfo.unseen && playersManager.players[snapshotPlayerInfo.id].gameObject.activeSelf) { playersManager.players[snapshotPlayerInfo.id].gameObject.SetActive(false); return; } else if (!snapshotPlayerInfo.unseen && !playersManager.players[snapshotPlayerInfo.id].gameObject.activeSelf) { // Todo: implement some kind of client anti-cheat (It is impossible to have a clear solution, check out my reddit question about it) // @link https://www.reddit.com/r/gamedev/comments/lcq93c/how_to_use_clientside_prediction_with_fog_of_war/ playersManager.players[snapshotPlayerInfo.id].gameObject.SetActive(true); } // snapshotPlayerInfo.id, snapshotPlayerInfo.position, snapshotPlayerInfo.input, snapshotPlayerInfo.color, snapshotPlayerInfo.isImpostor ClientPlayer clientPlayer = playersManager.players[snapshotPlayerInfo.id]; clientPlayer.basePlayer.controllable.playerInput = snapshotPlayerInfo.input; clientPlayer.basePlayer.movable.Teleport(snapshotPlayerInfo.position); UpdatePlayerWithServerState(snapshotPlayerInfo); }
public override void OnSnapshot(int snappingClient, out SnapshotPlayerInfo playerInfo, out SnapshotSpectatorInfo spectatorInfo, out SnapshotDemoClientInfo demoClientInfo) { playerInfo = null; spectatorInfo = null; demoClientInfo = null; if (!IsDummy && !Server.ClientInGame(ClientId)) { return; } playerInfo = Server.SnapshotItem <SnapshotPlayerInfo>(ClientId); if (playerInfo == null) { return; } playerInfo.PlayerFlags = PlayerFlags & PlayerFlags.Chatting; if (Server.IsAuthed(ClientId)) { playerInfo.PlayerFlags |= PlayerFlags.Admin; } if (!GameContext.GameController.IsPlayerReadyMode() || IsReadyToPlay) { playerInfo.PlayerFlags |= PlayerFlags.Ready; } if (RespawnDisabled && (Character == null || !Character.IsAlive)) { playerInfo.PlayerFlags |= PlayerFlags.Dead; } if (snappingClient != -1 && (Team == Team.Spectators || DeadSpectatorMode) && snappingClient == SpectatorId) { playerInfo.PlayerFlags |= PlayerFlags.Watching; } playerInfo.Latency = snappingClient == -1 ? Latency.Min : GameContext.Players[snappingClient].ActualLatency[ClientId]; playerInfo.Score = GameContext.GameController.Score(ClientId); if (ClientId == snappingClient && (Team == Team.Spectators || DeadSpectatorMode)) { spectatorInfo = Server.SnapshotItem <SnapshotSpectatorInfo>(ClientId); if (spectatorInfo == null) { return; } spectatorInfo.SpectatorMode = SpectatorMode; spectatorInfo.SpectatorId = SpectatorId; if (SpectatorFlag != null) { spectatorInfo.X = (int)SpectatorFlag.Position.x; spectatorInfo.Y = (int)SpectatorFlag.Position.y; } else { spectatorInfo.X = (int)ViewPos.x; spectatorInfo.Y = (int)ViewPos.y; } } if (snappingClient == -1) { demoClientInfo = Server.SnapshotItem <SnapshotDemoClientInfo>(ClientId); if (demoClientInfo == null) { return; } demoClientInfo.Local = 0; demoClientInfo.Team = Team; demoClientInfo.Name = Server.ClientName(ClientId); demoClientInfo.Clan = Server.ClientClan(ClientId); demoClientInfo.Country = Server.ClientCountry(ClientId); for (var part = SkinPart.Body; part < SkinPart.NumParts; part++) { demoClientInfo[part] = TeeInfo[part]; } } }
public abstract void OnSnapshot(int snappingClient, out SnapshotPlayerInfo playerInfo, out SnapshotSpectatorInfo spectatorInfo, out SnapshotDemoClientInfo demoClientInfo);