Пример #1
0
        /// <summary>
        /// Register world related network message handlers.
        /// </summary>
        /// <param name="netMessageHandler">The network message handler to register messages to.</param>
        void RegisterNetworkMessagesHandlers(NetMessageHandler netMessageHandler)
        {
            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.PickupableSetPositionMessage msg) => {
                Client.Assert(netPickupables.ContainsKey(msg.id), $"Tried to move pickupable that is not spawned {msg.id}.");
                GameObject gameObject         = netPickupables[msg.id].gameObject;
                gameObject.transform.position = Utils.NetVec3ToGame(msg.position);
            });

            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.PickupableActivateMessage msg) => {
                GameObject gameObject = null;
                if (netPickupables.ContainsKey(msg.id))
                {
                    gameObject = netPickupables[msg.id].gameObject;
                }

                if (msg.activate)
                {
                    Client.Assert(gameObject != null, "Tried to activate pickupable but its not spawned!");
                    gameObject.SetActive(true);
                }
                else
                {
                    if (gameObject != null)
                    {
                        gameObject.SetActive(false);
                    }
                }
            });

            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.PickupableSpawnMessage msg) => {
                SpawnPickupable(msg);
            });

            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.PickupableDestroyMessage msg) => {
                if (!netPickupables.ContainsKey(msg.id))
                {
                    return;
                }

                NetPickupable pickupable = netPickupables[msg.id];
                GameObject.Destroy(pickupable.gameObject);
                netPickupables.Remove(msg.id);
            });

            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.WorldPeriodicalUpdateMessage msg) => {
                // Game reports 'next hour' - we want to have transition so correct it.
                Game.GameWorld.Instance.WorldTime = (float)msg.sunClock - 2.0f;
                Game.GameWorld.Instance.WorldDay  = (int)msg.worldDay;
                Game.GameWeatherManager.Instance.SetWeather(msg.currentWeather);
            });

            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.RemoveBottleMessage msg) => {
                GameObject beerGO          = GetPickupableGameObject(msg.netId);
                Game.Objects.BeerCase beer = Game.BeerCaseManager.Instance.FindBeerCase(beerGO);
                if (beer == null)
                {
                    Logger.Log($"Player tried to drink beer, however, the beercase cannot be found.");
                    return;
                }
                beer.RemoveBottles(1);
            });

            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.PlayerSyncMessage msg) => {
                NetPlayer player = netManager.GetPlayer(sender);
                if (player == null)
                {
                    Logger.Log($"Received synchronization packet from {sender} but there is not player registered using this id.");
                    return;
                }

                player.HandleSynchronize(msg);
            });


            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.OpenDoorsMessage msg) => {
                NetPlayer player = netManager.GetPlayer(sender);
                if (player == null)
                {
                    Logger.Log($"Received OpenDoorsMessage however there is no matching player {sender}! (open: {msg.open}");
                    return;
                }

                Game.Objects.GameDoor doors = Game.GameDoorsManager.Instance.FindGameDoors(Utils.NetVec3ToGame(msg.position));
                if (doors == null)
                {
                    Logger.Log($"Player tried to open door, however, the door could not be found!");
                    return;
                }
                doors.Open(msg.open);
            });

            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.FullWorldSyncMessage msg) => {
                NetPlayer player = netManager.GetPlayer(sender);

                // This one should never happen - if happens there is something done miserably wrong.
                Client.Assert(player != null, $"There is no player matching given steam id {sender}.");

                // Handle full world state synchronization.

                HandleFullWorldSync(msg);

                // Spawn host character.

                player.Spawn();

                // Set player state.

                player.Teleport(Utils.NetVec3ToGame(msg.spawnPosition), Utils.NetQuatToGame(msg.spawnRotation));

                if (msg.occupiedVehicleId != NetVehicle.INVALID_ID)
                {
                    var vehicle = GetVehicle(msg.occupiedVehicleId);
                    Client.Assert(vehicle != null, $"Player {player.GetName()} ({player.SteamId}) you tried to join reported that he drives car that does not exists in your game. Vehicle id: {msg.occupiedVehicleId}, passenger: {msg.passenger}");
                    player.EnterVehicle(vehicle, msg.passenger);
                }

                if (msg.pickedUpObject != NetPickupable.INVALID_ID)
                {
                    player.PickupObject(msg.pickedUpObject);
                }

                // World is loaded! Notify network manager about that.

                netManager.OnNetworkWorldLoaded();
            });

            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.AskForWorldStateMessage msg) => {
                var msgF = new Messages.FullWorldSyncMessage();
                WriteFullWorldSync(msgF);
                netManager.BroadcastMessage(msgF, Steamworks.EP2PSend.k_EP2PSendReliable);
            });

            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.VehicleEnterMessage msg) => {
                NetPlayer player = netManager.GetPlayer(sender);
                if (player == null)
                {
                    Logger.Error($"Steam user of id {sender} send message however there is no active player matching this id.");
                    return;
                }

                NetVehicle vehicle = GetVehicle(msg.vehicleId);
                if (vehicle == null)
                {
                    Logger.Error("Player " + player.SteamId + " tried to enter vehicle " + msg.vehicleId + " but there is no vehicle with such id.");
                    return;
                }

                player.EnterVehicle(vehicle, msg.passenger);
            });

            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.VehicleLeaveMessage msg) => {
                NetPlayer player = netManager.GetPlayer(sender);
                if (player == null)
                {
                    Logger.Error($"Steam user of id {sender} send message however there is no active player matching this id.");
                    return;
                }
                player.LeaveVehicle();
            });


            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.VehicleSyncMessage msg) => {
                NetPlayer player = netManager.GetPlayer(sender);
                if (player == null)
                {
                    Logger.Error($"Steam user of id {sender} send message however there is no active player matching this id.");
                    return;
                }
                player.HandleVehicleSync(msg);
            });


            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.PickupObjectMessage msg) => {
                NetPlayer player = netManager.GetPlayer(sender);
                if (player == null)
                {
                    Logger.Error($"Steam user of id {sender} send message however there is no active player matching this id.");
                    return;
                }
                player.PickupObject(msg.netId);
            });

            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.ReleaseObjectMessage msg) => {
                NetPlayer player = netManager.GetPlayer(sender);
                if (player == null)
                {
                    Logger.Error($"Steam user of id {sender} send message however there is no active player matching this id.");
                    return;
                }
                player.ReleaseObject(msg.drop);
            });



            netMessageHandler.BindMessageHandler((Steamworks.CSteamID sender, Messages.LightSwitchMessage msg) => {
                Game.Objects.LightSwitch light = Game.LightSwitchManager.Instance.FindLightSwitch(Utils.NetVec3ToGame(msg.pos));
                light.TurnOn(msg.toggle);
            });
        }
Пример #2
0
        /// <summary>
        /// Handle full world sync message.
        /// </summary>
        /// <param name="msg">The message to handle.</param>

        public void HandleFullWorldSync(Messages.FullWorldSyncMessage msg)
        {
            // Read time

            Game.GameWorld gameWorld = Game.GameWorld.Instance;
            gameWorld.WorldTime = msg.dayTime;
            gameWorld.WorldDay  = msg.day;

            // Read mailbox name

            gameWorld.PlayerLastName = msg.mailboxName;

            // Doors.

            foreach (Messages.DoorsInitMessage door in msg.doors)
            {
                Vector3 position            = Utils.NetVec3ToGame(door.position);
                Game.Objects.GameDoor doors = Game.GameDoorsManager.Instance.FindGameDoors(position);
                Client.Assert(doors != null, $"Unable to find doors at: {position}.");
                if (doors.IsOpen != door.open)
                {
                    doors.Open(door.open);
                }
            }

            // Lights.

            foreach (Messages.LightSwitchMessage light in msg.lights)
            {
                Vector3 position = Utils.NetVec3ToGame(light.pos);
                Game.Objects.LightSwitch lights = Game.LightSwitchManager.Instance.FindLightSwitch(position);
                Client.Assert(lights != null, $"Unable to find light switch at: {position}.");
                if (lights.SwitchStatus != light.toggle)
                {
                    lights.TurnOn(light.toggle);
                }
            }

            // Weather.

            Game.GameWeatherManager.Instance.SetWeather(msg.currentWeather);

            // Vehicles.

            foreach (Messages.VehicleInitMessage vehicleMsg in msg.vehicles)
            {
                Vector3    pos = Utils.NetVec3ToGame(vehicleMsg.transform.position);
                Quaternion rot = Utils.NetQuatToGame(vehicleMsg.transform.rotation);

                NetVehicle vehicle = GetVehicle(vehicleMsg.id);
                Client.Assert(vehicle != null, $"Received info about non existing vehicle {vehicleMsg.id} in full world sync. (pos: {pos}, rot: {rot})");

                vehicle.Teleport(pos, rot);
            }

            // Pickupables

            List <ushort> pickupablesIds = new List <ushort>();

            foreach (var kv in netPickupables)
            {
                pickupablesIds.Add(kv.Key);
            }

            foreach (Messages.PickupableSpawnMessage pickupableMsg in msg.pickupables)
            {
                SpawnPickupable(pickupableMsg);
                pickupablesIds.Remove(pickupableMsg.id);
            }

            // Remove spawned (and active) pickupables that we did not get info about.

            foreach (ushort id in pickupablesIds)
            {
                GameObject gameObject = netPickupables[id].gameObject;
                if (gameObject && !gameObject.activeSelf)
                {
                    continue;
                }

                DestroyPickupableLocal(id);
            }
        }
Пример #3
0
        /// <summary>
        /// Handle full world sync message.
        /// </summary>
        /// <param name="msg">The message to handle.</param>

        public void HandleFullWorldSync(Messages.FullWorldSyncMessage msg)
        {
            Logger.Debug("Handling full world synchronization message.");
            var watch = System.Diagnostics.Stopwatch.StartNew();

            // Read time

            Game.GameWorld gameWorld = Game.GameWorld.Instance;
            gameWorld.WorldTime = msg.dayTime;
            gameWorld.WorldDay  = msg.day;

            // Read mailbox name

            gameWorld.PlayerLastName = msg.mailboxName;

            // Doors.

            foreach (Messages.DoorsInitMessage door in msg.doors)
            {
                Vector3 position            = Utils.NetVec3ToGame(door.position);
                Game.Objects.GameDoor doors =
                    Game.GameDoorsManager.Instance.FindGameDoors(position);
                Client.Assert(doors != null, $"Unable to find doors at: {position}.");
                if (doors.IsOpen != door.open)
                {
                    doors.Open(door.open);
                }
            }

            // Lights.

            foreach (Messages.LightSwitchMessage light in msg.lights)
            {
                Vector3 position = Utils.NetVec3ToGame(light.pos);
                Game.Objects.LightSwitch lights =
                    Game.LightSwitchManager.Instance.FindLightSwitch(position);
                Client.Assert(
                    lights != null, $"Unable to find light switch at: {position}.");
                if (lights.SwitchStatus != light.toggle)
                {
                    lights.TurnOn(light.toggle);
                }
            }

            // Weather.

            GameWeatherManager.Instance.SetWeather(msg.currentWeather);

            // Pickupables

            foreach (Messages.PickupableSpawnMessage pickupableMsg in msg.pickupables)
            {
                SpawnPickupable(pickupableMsg);
            }

            // Remove spawned (and active) pickupables that we did not get info about.

            foreach (var kv in GamePickupableDatabase.Instance.Pickupables)
            {
                if (kv.Value.GetComponent <ObjectSyncComponent>() == null)
                {
                    GameObject.Destroy(kv.Value);
                }
            }

            GamePickupableDatabase.Instance.Pickupables.Clear();
            playerIsLoading = false;

            watch.Stop();
            Logger.Debug("Full world synchronization message has been handled. Took " +
                         watch.ElapsedMilliseconds + "ms");
        }