示例#1
0
        private void ProcessLobbyGamePhaseData(ClientGameSnapshot gameSnapshot)
        {
            if (lobbyGamePhase.lobby == null)
            {
                return;
            }

            if (gameSnapshot.gameStarts && !lobbyGamePhase.IsGameStarting)
            {
                lobbyGamePhase.InitiateGameStart();
            }

            if (gameSnapshot.gameStarted && !lobbyGamePhase.IsGameStarted)
            {
                List <int> impostorPlayerIds = new List <int>();

                bool isPlayingAsImpostor = gameSnapshot.playersInfo[playersManager.controlledClientPlayer.basePlayer.information.id].isImpostor;
                if (isPlayingAsImpostor)
                {
                    foreach (SnapshotPlayerInfo snapshotPlayerInfo in gameSnapshot.playersInfo.Values)
                    {
                        if (snapshotPlayerInfo.isImpostor)
                        {
                            impostorPlayerIds.Add(snapshotPlayerInfo.id);
                        }
                    }
                }

                lobbyGamePhase.StartGame(isPlayingAsImpostor, gameSnapshot.impostorsAmount, impostorPlayerIds.ToArray());
            }
        }
示例#2
0
        private void Reconcile(ClientControllablePlayer clientControllablePlayer, ClientGameSnapshot gameSnapshot)
        {
            ClientControllable clientControllable      = clientControllablePlayer.clientControllable;
            Vector2            incorrectClientPosition = clientControllable.stateSnapshots[gameSnapshot.yourLastProcessedInputId].position;
            Vector2            correctServerPosition   = gameSnapshot.playersInfo[clientControllablePlayer.basePlayer.information.id].position;

            Physics2D.simulationMode = SimulationMode2D.Script;

            // Teleport to server location
            clientControllablePlayer.basePlayer.movable.Teleport(correctServerPosition);
            Physics2D.Simulate(Time.fixedDeltaTime);
            clientControllable.UpdateSnapshotStatePosition(gameSnapshot.yourLastProcessedInputId, clientControllablePlayer.transform.position);

            // Apply not yet processed by server inputs
            for (int inputId = gameSnapshot.yourLastProcessedInputId + 1; inputId <= clientControllable.stateSnapshots.Keys.Max(); inputId++)
            {
                clientControllablePlayer.basePlayer.movable.MoveByPlayerInput(clientControllable.stateSnapshots[inputId].input);
                Physics2D.Simulate(Time.fixedDeltaTime);
                clientControllable.UpdateSnapshotStatePosition(inputId, clientControllablePlayer.transform.position);
            }

            Physics2D.simulationMode = SimulationMode2D.FixedUpdate;

            Logger.LogEvent(LoggerSection.ServerReconciliation, $"Reconciled position with the server position. SnapshotId: {gameSnapshot.id}. YourLastProcessedInputId: {gameSnapshot.yourLastProcessedInputId}. Server position: {correctServerPosition}. Client position: {incorrectClientPosition}.");
        }
示例#3
0
        private void UpdateExistentPlayers(ClientGameSnapshot gameSnapshot)
        {
            if (!ShouldProcessServerSnapshots())
            {
                return;
            }

            foreach (SnapshotPlayerInfo snapshotPlayerInfo in gameSnapshot.playersInfo.Values)
            {
                if (!playersManager.players.ContainsKey(snapshotPlayerInfo.id))
                {
                    continue;
                }

                ClientPlayer clientPlayer = playersManager.players[snapshotPlayerInfo.id];

                if (clientPlayer == playersManager.controlledClientPlayer.clientPlayer)
                {
                    UpdateControlledPlayerWithServerState(gameSnapshot);
                }
                else if (gameSnapshot.playersInfo.ContainsKey(clientPlayer.basePlayer.information.id))
                {
                    UpdateNotControlledPlayerWithServerState(gameSnapshot.playersInfo[clientPlayer.basePlayer.information.id]);
                }
            }
        }
示例#4
0
        public void Write(ClientGameSnapshot clientGameSnapshot)
        {
            Write(clientGameSnapshot.id);
            Write(clientGameSnapshot.yourLastProcessedInputId);

            Write(clientGameSnapshot.playersInfo.Count);
            foreach (SnapshotPlayerInfo snapshotPlayerInfo in clientGameSnapshot.playersInfo.Values)
            {
                Write(snapshotPlayerInfo.id);
                Write(snapshotPlayerInfo.name);
                Write(snapshotPlayerInfo.isLobbyHost);
                Write(snapshotPlayerInfo.input);
                Write(snapshotPlayerInfo.position);
                Write(snapshotPlayerInfo.unseen);
                Write((int)snapshotPlayerInfo.color);
                Write(snapshotPlayerInfo.isImpostor);
            }

            Write(clientGameSnapshot.gameStarts);
            Write(clientGameSnapshot.gameStarted);
            Write(clientGameSnapshot.impostorsAmount);

            Write(clientGameSnapshot.adminPanelPositions.Count);
            foreach (KeyValuePair <int, int> pair in clientGameSnapshot.adminPanelPositions)
            {
                Write(pair.Key);
                Write(pair.Value);
            }

            Write(clientGameSnapshot.securityCamerasEnabled);
        }
示例#5
0
        public void ProcessSnapshot(ClientGameSnapshot gameSnapshot)
        {
            ProcessPlayersData(gameSnapshot);
            ProcessLobbyGamePhaseData(gameSnapshot);
            ProcessPlayGamePhaseData(gameSnapshot);

            Logger.LogEvent(LoggerSection.GameSnapshots, $"Updated game state with snapshot {gameSnapshot}");
        }
示例#6
0
        private void ProcessGameSnapshotPacket(Packet packet)
        {
            Action action = () =>
            {
                ClientGameSnapshot gameSnapshot = packet.ReadClientGameSnapshot();
                gameSnapshots.ProcessSnapshot(gameSnapshot);
            };

            networkSimulation.ReceiveThroughNetwork(action);
        }
示例#7
0
        private void RemoveDisconnectedPlayers(ClientGameSnapshot gameSnapshot)
        {
            foreach (int playerId in playersManager.players.Keys.ToList())
            {
                if (gameSnapshot.playersInfo.ContainsKey(playerId))
                {
                    continue;
                }

                playersManager.RemovePlayer(playerId);
            }
        }
        public void RemoveObsoleteSnapshotStates(ClientGameSnapshot gameSnapshot)
        {
            // No snapshots to remove
            if (stateSnapshots.Count == 0)
            {
                return;
            }

            for (int inputId = stateSnapshots.Keys.Min(); inputId < gameSnapshot.yourLastProcessedInputId; inputId++)
            {
                stateSnapshots.Remove(inputId);
            }
        }
示例#9
0
        public void UpdateControlledPlayerWithServerState(ClientGameSnapshot gameSnapshot)
        {
            ClientControllablePlayer controlledClientPlayer = playersManager.controlledClientPlayer;

            controlledClientPlayer.clientControllable.RemoveObsoleteSnapshotStates(gameSnapshot);

            if (IsReconciliationNeeded(controlledClientPlayer, gameSnapshot))
            {
                Reconcile(controlledClientPlayer, gameSnapshot);
            }

            UpdatePlayerWithServerState(gameSnapshot.playersInfo[controlledClientPlayer.basePlayer.information.id]);
        }
示例#10
0
        public void SendGameSnapshotPackets(GameSnapshot gameSnapshot)
        {
            const ServerPacketType packetType = ServerPacketType.GameSnapshot;

            foreach (Client client in playersManager.clients.Values.ToList())
            {
                if (!client.IsFullyInitialized())
                {
                    continue;
                }

                ClientGameSnapshot clientGameSnapshot = clientGameSnapshotsManager.CreateClientGameSnapshot(client, gameSnapshot);

                Packet packet = new Packet((int)packetType);
                packet.Write(clientGameSnapshot);

                SendUdpPacket(client.playerId, packetType, packet);
            }
        }
示例#11
0
        private void ProcessPlayGamePhaseData(ClientGameSnapshot gameSnapshot)
        {
            if (playGamePhase.clientSkeld == null)
            {
                return;
            }

            if (gameSnapshot.adminPanelPositions.Count != 0)
            {
                playGamePhase.UpdateAdminPanelMinimap(gameSnapshot.adminPanelPositions);
            }

            SecurityPanel securityPanel = playGamePhase.clientSkeld.securityPanel;

            if (gameSnapshot.securityCamerasEnabled && !securityPanel.CamerasEnabled)
            {
                securityPanel.EnableSecurityCameras();
            }
            else if (!gameSnapshot.securityCamerasEnabled && securityPanel.CamerasEnabled)
            {
                securityPanel.DisableSecurityCameras();
            }
        }
示例#12
0
        private void AddNewlyConnectedPlayers(ClientGameSnapshot gameSnapshot)
        {
            if (!mainMenuGamePhase.connectionToServer.IsConnected)
            {
                return;
            }

            foreach (SnapshotPlayerInfo snapshotPlayerInfo in gameSnapshot.playersInfo.Values)
            {
                if (playersManager.players.ContainsKey(snapshotPlayerInfo.id))
                {
                    continue;
                }

                if (scenesManager.GetActiveScene() == Scene.MainMenu)
                {
                    mainMenuGamePhase.InitializeLobby(snapshotPlayerInfo.id, snapshotPlayerInfo.name, snapshotPlayerInfo.color, snapshotPlayerInfo.position, snapshotPlayerInfo.isLobbyHost);
                }
                else
                {
                    lobbyGamePhase.AddPlayerToLobby(snapshotPlayerInfo.id, snapshotPlayerInfo.name, snapshotPlayerInfo.color, snapshotPlayerInfo.position, snapshotPlayerInfo.isLobbyHost);
                }
            }
        }
示例#13
0
 private void ProcessPlayersData(ClientGameSnapshot gameSnapshot)
 {
     AddNewlyConnectedPlayers(gameSnapshot);
     UpdateExistentPlayers(gameSnapshot);
     RemoveDisconnectedPlayers(gameSnapshot);
 }
示例#14
0
        private bool IsReconciliationNeeded(ClientControllablePlayer controlledClientPlayer, ClientGameSnapshot gameSnapshot)
        {
            // If player has just spawned, he might not have gameSnapshots with which he may reconcile
            if (!controlledClientPlayer.clientControllable.stateSnapshots.ContainsKey(gameSnapshot.yourLastProcessedInputId))
            {
                return(false);
            }

            const float acceptablePositionError = 0.01f;

            Vector2 serverPosition     = gameSnapshot.playersInfo[controlledClientPlayer.basePlayer.information.id].position;
            Vector2 clientPosition     = controlledClientPlayer.clientControllable.stateSnapshots[gameSnapshot.yourLastProcessedInputId].position;
            Vector2 positionDifference = serverPosition - clientPosition;

            return(positionDifference.magnitude > acceptablePositionError);
        }