/// <summary> /// Bans a client from the network when the kick button is pressed. /// </summary> /// <param name="sender">Object that invoked this event.</param> /// <param name="e">Reason why this event was invoked.</param> private void banPeerButton_Click(object sender, EventArgs e) { string selectedPeer = ""; int clientID = 0; if (peerListView.SelectedItems.Count != 0) { selectedPeer = peerListView.SelectedItems[0].Text; } if (int.TryParse(selectedPeer, out clientID) == false) { return; } // Open ban window. BanWindow banWindow = new BanWindow(); if (banWindow.ShowDialog(this) == DialogResult.OK) { NetworkPacket packet = new NetworkPacket(); packet.ID = "BAN".GetHashCode(); foreach (NetworkClient client in NetworkManager.Connection.ClientList) { if (client.ID == clientID) { // Send it the explanation packet. client.Connection.SendPacket(packet); // Create a ban. NetworkBan ban = new NetworkBan("000.000.000.000", -1, banWindow.BanExpiration); NetworkManager.BansList.Add(ban); // Add its IP to the black list. if (banWindow.BanIP == true) { string currentIP = client.Connection.Socket.RemoteEndPoint.ToString(); if (currentIP.IndexOf(":") >= 0) { currentIP = currentIP.Substring(0, currentIP.IndexOf(":")); } ban.IP = currentIP; } // Ban its account (if its logged in). if (banWindow.BanAccount == true && client.LoggedIn == true) { ban.AccountID = client.AccountID; } // Close its connection. client.Connection.Close(); } } DebugLogger.WriteLog("Banning client " + clientID + "."); } }
protected override void PumpNetwork() { NetworkServer.Update(); Chunk packet = null; uint responseToken = 0; while (NetworkServer.Receive(ref packet, ref responseToken)) { if (packet.Flags.HasFlag(SendFlags.Connless)) { if (Register.RegisterProcessPacket(packet, responseToken)) { continue; } if (packet.DataSize >= MasterServerPackets.GetInfo.Length && packet.Data.ArrayCompare(MasterServerPackets.GetInfo, MasterServerPackets.GetInfo.Length)) { var unpacker = new UnPacker(); unpacker.Reset(packet.Data, packet.DataSize, MasterServerPackets.GetInfo.Length); var serverBrowserToken = unpacker.GetInt(); if (unpacker.Error) { continue; } var packer = new Packer(); GenerateServerInfo(packer, serverBrowserToken); var response = new Chunk() { ClientId = -1, EndPoint = packet.EndPoint, Flags = SendFlags.Connless, Data = packer.Data(), DataSize = packer.Size(), }; NetworkServer.Send(response, responseToken); } } else { ProcessClientPacket(packet); } } // TODO Econ.Update(); NetworkBan.Update(); }
protected override void NetMsgRconAuth(Chunk packet, UnPacker unPacker, int clientId) { if (IsAuthed(clientId)) { return; } var password = unPacker.GetString(SanitizeType.SanitizeCC); if (!packet.Flags.HasFlag(SendFlags.Vital) || unPacker.Error) { return; } // TODO send map list 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."); return; } var authed = false; var format = string.Empty; var authLevel = 0; if (!string.IsNullOrEmpty(Config["SvRconPassword"]) && Config["SvRconPassword"] == password) { authed = true; format = $"clientId={clientId} authed 'admin'"; authLevel = BaseServerClient.AuthedAdmin; SendRconLine(clientId, "Admin authentication successful. Full remote console access granted."); } else if (!string.IsNullOrEmpty(Config["SvRconModPassword"]) && Config["SvRconModPassword"] == password) { authed = true; format = $"clientId={clientId} authed 'moderator'"; authLevel = BaseServerClient.AuthedModerator; SendRconLine(clientId, "Moderator authentication successful. Limited remote console access granted."); } else if (Config["SvRconMaxTries"]) { Clients[clientId].AuthTries++; SendRconLine(clientId, $"Wrong password {Clients[clientId].AuthTries}/{Config["SvRconMaxTries"]}."); if (Clients[clientId].AuthTries >= Config["SvRconMaxTries"]) { if (Config["SvRconBantime"]) { NetworkBan.BanAddr(NetworkServer.ClientEndPoint(clientId), Config["SvRconBantime"] * 60, "Too many remote console authentication tries"); } else { Kick(clientId, "Too many remote console authentication tries"); } } } else { SendRconLine(clientId, "Wrong password"); } if (authed) { var msg = new MsgPacker((int)NetworkMessages.ServerRconAuthOn, true); SendMsg(msg, MsgFlags.Vital, clientId); Console.Print(OutputLevel.Standard, "server", format); Clients[clientId].AccessLevel = authLevel; Clients[clientId].SendCommandsEnumerator = Console.GetCommands(authLevel, ConfigFlags.Server).GetEnumerator(); SendRconCommandsClients.Enqueue(clientId); } }
protected override void PumpNetwork() { NetworkServer.Update(); while (NetworkServer.Receive(out var packet)) { if (packet.ClientId == -1) { if (packet.DataSize == MasterServerPackets.SERVERBROWSE_GETINFO.Length + 1 && packet.Data.ArrayCompare( MasterServerPackets.SERVERBROWSE_GETINFO, MasterServerPackets.SERVERBROWSE_GETINFO.Length)) { SendServerInfo( packet.EndPoint, packet.Data[MasterServerPackets.SERVERBROWSE_GETINFO.Length], false ); } else if (packet.DataSize == MasterServerPackets.SERVERBROWSE_GETINFO_64_LEGACY.Length + 1 && packet.Data.ArrayCompare( MasterServerPackets.SERVERBROWSE_GETINFO_64_LEGACY, MasterServerPackets.SERVERBROWSE_GETINFO_64_LEGACY.Length)) { SendServerInfo( packet.EndPoint, packet.Data[MasterServerPackets.SERVERBROWSE_GETINFO.Length], true ); } continue; } ProcessClientPacket(packet); } if (Config["SvFastDownload"]) { for (var i = 0; i < Clients.Length; i++) { if (Clients[i].State != ServerClientState.CONNECTING) { continue; } if (_lastAskTick[i] < Tick - TickSpeed) { _lastSent[i] = _lastAsk[i]; _lastAskTick[i] = Tick; } if (_lastAsk[i] < _lastSent[i] - Config["SvMapWindow"]) { continue; } var chunk = _lastSent[i]++; var chunkSize = 1024 - 128; var offset = chunk * chunkSize; var last = 0; // drop faulty map data requests if (chunk < 0 || offset > CurrentMap.Size) { continue; } if (offset + chunkSize >= CurrentMap.Size) { chunkSize = CurrentMap.Size - offset; if (chunkSize < 0) { chunkSize = 0; } last = 1; } SendMapData(last, chunk, chunkSize, offset, i); } } NetworkBan.Update(); }
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); } }