public void OnDisconnected(IConnection conn, MpDisconnectReason reason)
        {
            if (conn.State == ConnectionStateEnum.Disconnected)
            {
                return;
            }

            ServerPlayer player = conn.serverPlayer;

            players.Remove(player);

            if (player.IsPlaying)
            {
                if (!players.Any(p => p.FactionId == player.FactionId))
                {
                    byte[] data = ByteWriter.GetBytes(player.FactionId);
                    SendCommand(CommandType.FactionOffline, ScheduledCommand.NoFaction, ScheduledCommand.Global, data);
                }

                SendNotification("MpPlayerDisconnected", conn.username);
                SendChat($"{conn.username} has left.");

                SendToAll(Packets.Server_PlayerList, new object[] { (byte)PlayerListAction.Remove, player.id });
            }

            conn.State = ConnectionStateEnum.Disconnected;

            MpLog.Log($"Disconnected ({reason}): {conn}");
        }
예제 #2
0
        public void HandleProtocol(ByteReader data)
        {
            int clientProtocol = data.ReadInt32();

            if (clientProtocol != MpVersion.Protocol)
            {
                Player.Disconnect(MpDisconnectReason.Protocol, ByteWriter.GetBytes(MpVersion.Version, MpVersion.Protocol));
                return;
            }

            var modConfigFiles = MultiplayerMod.settings.syncModConfigs ? ModManagement.GetSyncableConfigFiles() : new Dictionary <string, string>();
            // Compress configs, to keep packet size < 50kb limit. JSON encode first, as the many tiny files are better compressed together
            var modConfigsCompressed = GZipStream.CompressString(SimpleJson.SerializeObject(modConfigFiles));

            if (MpVersion.IsDebug)
            {
                Log.Message($"Sending {modConfigFiles.Keys.Count} mod config files");
                foreach (KeyValuePair <string, string> modConfigFile in modConfigFiles)
                {
                    Log.Message(modConfigFile.Key + ": " + modConfigFile.Value.Length);
                }
                Log.Message($"modConfigsCompressed size: {modConfigsCompressed.Length}");
            }

            connection.SendFragmented(Packets.Server_ModList, Server.rwVersion, Server.modNames, Server.modIds, Server.workshopModIds, modConfigsCompressed);
        }
예제 #3
0
        public void HandleProtocol(ByteReader data)
        {
            int clientProtocol = data.ReadInt32();

            if (clientProtocol != MpVersion.Protocol)
            {
                Player.Disconnect(MpDisconnectReason.Protocol, ByteWriter.GetBytes(MpVersion.Version, MpVersion.Protocol));
                return;
            }

            connection.Send(Packets.Server_ModList, Server.rwVersion, Server.modNames, Server.modIds, Server.workshopModIds);
        }
예제 #4
0
        public void Tick()
        {
            SendToAll(Packets.Server_TimeControl, ByteWriter.GetBytes(gameTimer, cmdId), reliable: false);

            gameTimer++;

            if (settings.autosaveInterval <= 0)
            {
                return;
            }

            var curSpeed = Client.Multiplayer.WorldComp.TimeSpeed;

            autosaveCountdown -= (curSpeed == Verse.TimeSpeed.Paused && !Client.MultiplayerMod.settings.pauseAutosaveCounter)
                ? 1 : Client.Multiplayer.WorldComp.TickRateMultiplier(curSpeed);

            if (autosaveCountdown <= 0)
            {
                DoAutosave();
            }
        }
 public void SendToAll(Packets id, object[] data)
 {
     SendToAll(id, ByteWriter.GetBytes(data));
 }
예제 #6
0
        private void SendWorldData()
        {
            int factionId = MultiplayerServer.instance.coopFactionId;

            MultiplayerServer.instance.playerFactions[connection.username] = factionId;

            /*if (!MultiplayerServer.instance.playerFactions.TryGetValue(connection.Username, out int factionId))
             * {
             *  factionId = MultiplayerServer.instance.nextUniqueId++;
             *  MultiplayerServer.instance.playerFactions[connection.Username] = factionId;
             *
             *  byte[] extra = ByteWriter.GetBytes(factionId);
             *  MultiplayerServer.instance.SendCommand(CommandType.SETUP_FACTION, ScheduledCommand.NoFaction, ScheduledCommand.Global, extra);
             * }*/

            if (Server.PlayingPlayers.Count(p => p.FactionId == factionId) == 1)
            {
                byte[] extra = ByteWriter.GetBytes(factionId);
                MultiplayerServer.instance.SendCommand(CommandType.FactionOnline, ScheduledCommand.NoFaction, ScheduledCommand.Global, extra);
            }

            ByteWriter writer = new ByteWriter();

            writer.WriteInt32(factionId);
            writer.WriteInt32(MultiplayerServer.instance.gameTimer);
            writer.WritePrefixedBytes(MultiplayerServer.instance.savedGame);

            writer.WriteInt32(MultiplayerServer.instance.mapCmds.Count);

            foreach (var kv in MultiplayerServer.instance.mapCmds)
            {
                int mapId = kv.Key;

                //MultiplayerServer.instance.SendCommand(CommandType.CreateMapFactionData, ScheduledCommand.NoFaction, mapId, ByteWriter.GetBytes(factionId));

                List <byte[]> mapCmds = kv.Value;

                writer.WriteInt32(mapId);

                writer.WriteInt32(mapCmds.Count);
                foreach (var arr in mapCmds)
                {
                    writer.WritePrefixedBytes(arr);
                }
            }

            writer.WriteInt32(MultiplayerServer.instance.mapData.Count);

            foreach (var kv in MultiplayerServer.instance.mapData)
            {
                int    mapId   = kv.Key;
                byte[] mapData = kv.Value;

                writer.WriteInt32(mapId);
                writer.WritePrefixedBytes(mapData);
            }

            connection.State = ConnectionStateEnum.ServerPlaying;

            byte[] packetData = writer.ToArray();
            connection.SendFragmented(Packets.Server_WorldData, packetData);

            Player.SendPlayerList();

            MpLog.Log("World response sent: " + packetData.Length);
        }
예제 #7
0
 public void Disconnect(string reasonKey)
 {
     Disconnect(MpDisconnectReason.GenericKeyed, ByteWriter.GetBytes(reasonKey));
 }