Esempio n. 1
0
        protected override void NetMsgInput(NetworkChunk packet, Unpacker unpacker, int clientId)
        {
            Clients[clientId].LastAckedSnapshot = unpacker.GetInt();
            var intendedTick = unpacker.GetInt();
            var size         = unpacker.GetInt();

            if (unpacker.Error || size / sizeof(int) > BaseServerClient.MAX_INPUT_SIZE)
            {
                return;
            }

            if (Clients[clientId].LastAckedSnapshot > 0)
            {
                Clients[clientId].SnapRate = SnapRate.FULL;
            }

            if (Clients[clientId].SnapshotStorage.Get(
                    Clients[clientId].LastAckedSnapshot,
                    out var tagTime,
                    out var _))
            {
                Clients[clientId].Latency =
                    (int)(((Time.Get() - tagTime) * 1000) / Time.Freq());
            }

            if (intendedTick > Clients[clientId].LastInputTick)
            {
                var timeLeft = (TickStartTime(intendedTick) - Time.Get()) * 1000 / Time.Freq();
                var msg      = new MsgPacker((int)NetworkMessages.SV_INPUT_TIMING);
                msg.AddInt(intendedTick);
                msg.AddInt((int)timeLeft);
                SendMsgEx(msg, MsgFlags.NONE, clientId, true);
            }

            Clients[clientId].LastInputTick = intendedTick;
            var input = Clients[clientId].Inputs[Clients[clientId].CurrentInput];

            if (intendedTick <= Tick)
            {
                intendedTick = Tick + 1;
            }

            var data = new int[size / sizeof(int)];

            for (var i = 0; i < data.Length; i++)
            {
                data[i] = unpacker.GetInt();
            }

            input.Tick = intendedTick;
            input.PlayerInput.Deserialize(data, 0);

            Clients[clientId].CurrentInput++;
            Clients[clientId].CurrentInput %= Clients[clientId].Inputs.Length;

            if (Clients[clientId].State == ServerClientState.IN_GAME)
            {
                GameContext.OnClientDirectInput(clientId, input.PlayerInput);
            }
        }
Esempio n. 2
0
 private async Task SendChunkBuffers(NetworkChunk chunk)
 {
     BinaryPrimitives.WriteInt32BigEndian(outgoingHeader.AsSpan(LENGTH_INDEX), chunk.Data.Length);
     outgoingHeader[INSTRUCTION_INDEX] = chunk.Instruction;
     await SendBuffer(outgoingHeader).ConfigureAwait(false);
     await SendBuffer(chunk.Data).ConfigureAwait(false);
 }
Esempio n. 3
0
        protected override void NetMsgInfo(NetworkChunk packet, Unpacker unpacker, int clientId)
        {
            if (Clients[clientId].State != ServerClientState.AUTH)
            {
                return;
            }

            var version = unpacker.GetString(SanitizeType.SANITIZE_CC);

            if (string.IsNullOrEmpty(version) || !version.StartsWith(GameContext.NetVersion))
            {
                NetworkServer.Drop(clientId, $"Wrong version. Server is running '{GameContext.NetVersion}' and client '{version}'");
                return;
            }

            var password = unpacker.GetString(SanitizeType.SANITIZE_CC);

            if (!string.IsNullOrEmpty(Config["Password"]) && password != Config["Password"])
            {
                NetworkServer.Drop(clientId, "Wrong password");
                return;
            }

            if (clientId >= NetworkServer.ServerConfig.MaxClients - Config["SvReservedSlots"] &&
                !string.IsNullOrEmpty(Config["SvReservedSlotsPass"]) &&
                password != Config["SvReservedSlotsPass"])
            {
                NetworkServer.Drop(clientId, "This server is full");
                return;
            }

            Clients[clientId].State = ServerClientState.CONNECTING;
            SendMap(clientId);
        }
Esempio n. 4
0
        protected override void NetMsgEnterGame(NetworkChunk packet, Unpacker unpacker, int clientId)
        {
            if (Clients[clientId].State != ServerClientState.READY ||
                !GameContext.IsClientReady(clientId))
            {
                return;
            }

            Console.Print(OutputLevel.STANDARD, "server", $"player has entered the game. ClientID={clientId} addr={NetworkServer.ClientEndPoint(clientId)}");
            Clients[clientId].State = ServerClientState.IN_GAME;
            GameContext.OnClientEnter(clientId);
        }
Esempio n. 5
0
        public override bool SendMsgEx(MsgPacker msg, MsgFlags flags, int clientId, bool system)
        {
            if (msg == null)
            {
                return(false);
            }

            var packet = new NetworkChunk()
            {
                ClientId = clientId,
                DataSize = msg.Size(),
                Data     = msg.Data(),
            };

            packet.Data[0] <<= 1;
            if (system)
            {
                packet.Data[0] |= 1;
            }

            if (flags.HasFlag(MsgFlags.VITAL))
            {
                packet.Flags |= SendFlags.VITAL;
            }
            if (flags.HasFlag(MsgFlags.FLUSH))
            {
                packet.Flags |= SendFlags.FLUSH;
            }

            if (!flags.HasFlag(MsgFlags.NOSEND))
            {
                if (clientId == -1)
                {
                    for (var i = 0; i < Clients.Length; i++)
                    {
                        if (Clients[i].State != ServerClientState.IN_GAME)
                        {
                            continue;
                        }

                        packet.ClientId = i;
                        NetworkServer.Send(packet);
                    }
                }
                else
                {
                    NetworkServer.Send(packet);
                }
            }

            return(true);
        }
Esempio n. 6
0
        public async Task SendChunk(NetworkChunk chunk)
        {
            Status currentStatus = (Status)Interlocked.CompareExchange(ref status, 0, 0);

            if (currentStatus is Status.Running)
            {
                await outgoing.Writer.WriteAsync(chunk).ConfigureAwait(false);
            }
            else
            {
                throw new InvalidOperationException($"Cannot send chunk. {nameof(currentStatus)} is {nameof(Status)}.{currentStatus}");
            }
        }
Esempio n. 7
0
        protected override void NetMsgReady(NetworkChunk packet, Unpacker unpacker, int clientId)
        {
            if (Clients[clientId].State != ServerClientState.CONNECTING)
            {
                return;
            }

            Console.Print(OutputLevel.ADDINFO, "server", $"player is ready. ClientID={clientId} addr={NetworkServer.ClientEndPoint(clientId)}");
            Clients[clientId].State = ServerClientState.READY;
            GameContext.OnClientConnected(clientId);

            var msg = new MsgPacker((int)NetworkMessages.SV_CON_READY);

            SendMsgEx(msg, MsgFlags.VITAL | MsgFlags.FLUSH, clientId, true);
        }
Esempio n. 8
0
        protected override void NetMsgRequestMapData(NetworkChunk packet, Unpacker unpacker, int clientId)
        {
            if (Clients[clientId].State < ServerClientState.CONNECTING)
            {
                return;
            }

            var chunk     = unpacker.GetInt();
            var chunkSize = 1024 - 128;
            var offset    = chunk * chunkSize;
            var last      = 0;

            _lastAsk[clientId]     = chunk;
            _lastAskTick[clientId] = Tick;

            if (chunk == 0)
            {
                _lastSent[clientId] = 0;
            }

            if (chunk < 0 || offset > CurrentMap.Size)
            {
                return;
            }

            if (offset + chunkSize >= CurrentMap.Size)
            {
                chunkSize = CurrentMap.Size - offset;
                last      = 1;

                if (chunkSize < 0)
                {
                    chunkSize = 0;
                }
            }

            if (_lastSent[clientId] < chunk + Config["SvMapWindow"] &&
                Config["SvFastDownload"])
            {
                return;
            }

            SendMapData(last, chunk, chunkSize, offset, clientId);
        }
Esempio n. 9
0
        private async Task ProcessOutgoing()
        {
            while (Interlocked.CompareExchange(ref status, 0, 0) == (int)Status.Running)
            {
                Task <NetworkChunk> chunkTask = WaitForOutgoingChunk();
                Task delayTask     = Task.Delay(timeoutOptions.Period);
                Task firstToFinsih = await Task.WhenAny(chunkTask, delayTask).ConfigureAwait(false);

                if (ReferenceEquals(firstToFinsih, chunkTask))
                {
                    NetworkChunk chunk = await chunkTask.ConfigureAwait(false);
                    await SendChunkBuffers(chunk).ConfigureAwait(false);
                }
                else
                {
                    await SendBuffer(KEEP_ALIVE_HEADER).ConfigureAwait(false);
                }
            }
        }
Esempio n. 10
0
        public void OnPacket(NetworkChunk packet)
        {
            // get servers from masterserver
            if (packet.DataSize >= MasterServerPackets.SERVERBROWSE_LIST.Length + 1 &&
                packet.Data.ArrayCompare(
                    MasterServerPackets.SERVERBROWSE_LIST,
                    MasterServerPackets.SERVERBROWSE_LIST.Length))
            {
                if (!IsMasterServer(packet.EndPoint))
                {
                    return;
                }

                var list = packet.Data.ReadStructs <MasterServerAddr>(
                    MasterServerPackets.SERVERBROWSE_LIST.Length);

                for (var i = 0; i < list.Length; i++)
                {
                    IPAddress ip;
                    var       port = (list[i].Port[0] << 8) | list[i].Port[1];

                    if (_IPV4Mapping.ArrayCompare(list[i].Ip, _IPV4Mapping.Length))
                    {
                        ip = new IPAddress(new[]
                        {
                            list[i].Ip[12],
                            list[i].Ip[13],
                            list[i].Ip[14],
                            list[i].Ip[15],
                        });
                    }
                    else
                    {
                        ip = new IPAddress(list[i].Ip);
                    }

                    var serverAddr = new IPEndPoint(ip, port);
                    ServersSnapshot.AddServer(serverAddr);
                    OnServerAddrReceived(serverAddr);
                }
            }
        }
Esempio n. 11
0
        protected override void NetMsgRconAuth(NetworkChunk packet, Unpacker unpacker, int clientId)
        {
            var login    = unpacker.GetString();
            var password = unpacker.GetString();

            SendRconLine(clientId, password);
            if (!packet.Flags.HasFlag(SendFlags.VITAL) || unpacker.Error)
            {
                return;
            }

            if (string.IsNullOrEmpty(Config["SvRconPassword"]) &&
                string.IsNullOrEmpty(Config["SvRconModPassword"]))
            {
                SendRconLine(clientId, "No rcon password set on server. Set sv_rcon_password and/or sv_rcon_mod_password to enable the remote console.");
            }

            var authed = false;

            if (password == Config["SvRconPassword"])
            {
                authed = true;
            }
            else if (password == Config["SvRconModPassword"])
            {
                authed = true;
            }

            if (authed)
            {
                var msg = new MsgPacker((int)NetworkMessages.SV_RCON_AUTH_STATUS);
                msg.AddInt(1);
                msg.AddInt(1);
                SendMsgEx(msg, MsgFlags.VITAL, clientId, true);
            }
        }
 public NetworkChunkRequest(NetworkChunk Chunk)
 {
     Location = Chunk.ChunkCoords;
 }
Esempio n. 13
0
        protected override void NetMsgPing(NetworkChunk packet, Unpacker unpacker, int clientId)
        {
            var msg = new MsgPacker((int)NetworkMessages.PING_REPLY);

            SendMsgEx(msg, 0, clientId, true);
        }
Esempio n. 14
0
 protected override void NetMsgRconCmd(NetworkChunk packet, Unpacker unpacker, int clientId)
 {
 }
 public NetworkChunkResponse()
 {
     Chunk = new NetworkChunk(Game.World.Realm, new Vector3i());
 }
 public NetworkChunkResponse(NetworkChunk Chunk)
 {
     this.Chunk = Chunk;
 }
Esempio n. 17
0
 protected abstract void NetMsgInfo(NetworkChunk packet, Unpacker unpacker, int clientId);
Esempio n. 18
0
 protected abstract void NetMsgRequestMapData(NetworkChunk packet, Unpacker unpacker, int clientId);
Esempio n. 19
0
 protected abstract void NetMsgEnterGame(NetworkChunk packet, Unpacker unpacker, int clientId);
Esempio n. 20
0
 protected abstract void ProcessClientPacket(NetworkChunk packet);
Esempio n. 21
0
        protected override void ProcessClientPacket(NetworkChunk packet)
        {
            var clientId = packet.ClientId;
            var unpacker = new Unpacker();

            unpacker.Reset(packet.Data, packet.DataSize);

            var msg         = unpacker.GetInt();
            var isSystemMsg = (msg & 1) != 0;

            msg >>= 1;

            if (unpacker.Error)
            {
                return;
            }

            if (Config["SvNetlimit"] &&
                !(isSystemMsg && msg == (int)NetworkMessages.CL_REQUEST_MAP_DATA))
            {
                var now   = Time.Get();
                var diff  = now - Clients[clientId].TrafficSince;
                var alpha = Config["SvNetlimitAlpha"] / 100f;
                var limit = (float)Config["SvNetlimit"] * 1024 / Time.Freq();

                if (Clients[clientId].Traffic > limit)
                {
                    NetworkBan.BanAddr(packet.EndPoint, 600, "Stressing network");
                    return;
                }

                if (diff > 100)
                {
                    Clients[clientId].Traffic = (int)(alpha * ((float)packet.DataSize / diff) +
                                                      (1.0f - alpha) * Clients[clientId].Traffic);
                    Clients[clientId].TrafficSince = now;
                }
            }

            if (isSystemMsg)
            {
                var networkMsg = (NetworkMessages)msg;
                switch (networkMsg)
                {
                case NetworkMessages.CL_INFO:
                    NetMsgInfo(packet, unpacker, clientId);
                    break;

                case NetworkMessages.CL_REQUEST_MAP_DATA:
                    NetMsgRequestMapData(packet, unpacker, clientId);
                    break;

                case NetworkMessages.CL_READY:
                    NetMsgReady(packet, unpacker, clientId);
                    break;

                case NetworkMessages.CL_ENTERGAME:
                    NetMsgEnterGame(packet, unpacker, clientId);
                    break;

                case NetworkMessages.CL_INPUT:
                    NetMsgInput(packet, unpacker, clientId);
                    break;

                case NetworkMessages.CL_RCON_CMD:
                    NetMsgRconCmd(packet, unpacker, clientId);
                    break;

                case NetworkMessages.CL_RCON_AUTH:
                    NetMsgRconAuth(packet, unpacker, clientId);
                    break;

                case NetworkMessages.PING:
                    NetMsgPing(packet, unpacker, clientId);
                    break;

                default:
                    Console.Print(OutputLevel.DEBUG, "server", $"strange message clientId={clientId} msg={msg} data_size={packet.DataSize}");
                    break;
                }
            }
            else if (Clients[clientId].State >= ServerClientState.READY)
            {
                GameContext.OnMessage(msg, unpacker, clientId);
            }
        }