about summary refs log tree commit diff
path: root/src/engine/shared
diff options
context:
space:
mode:
authoroy <Tom_Adams@web.de>2010-06-03 14:48:32 +0200
committeroy <Tom_Adams@web.de>2010-06-03 14:48:32 +0200
commit5988b9d38801f0987f38c99fb944e1a861d07ef3 (patch)
tree11771e6418a694f98ce2561e865b2f29971649bf /src/engine/shared
parentd581e413c8fa94e4d1069b20bbe4edf1ebe2dbff (diff)
downloadzcatch-5988b9d38801f0987f38c99fb944e1a861d07ef3.tar.gz
zcatch-5988b9d38801f0987f38c99fb944e1a861d07ef3.zip
- show connecting players with rcon status command
- make it possible to limit the number of clients with the same ip that can connect to the server
Diffstat (limited to 'src/engine/shared')
-rw-r--r--src/engine/shared/config_variables.h1
-rw-r--r--src/engine/shared/network.h6
-rw-r--r--src/engine/shared/network_server.cpp37
3 files changed, 42 insertions, 2 deletions
diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h
index cc36b932..e11eab6d 100644
--- a/src/engine/shared/config_variables.h
+++ b/src/engine/shared/config_variables.h
@@ -64,6 +64,7 @@ MACRO_CONFIG_INT(SvPort, sv_port, 8303, 0, 0, CFGFLAG_SERVER, "Port to use for t
 MACRO_CONFIG_INT(SvExternalPort, sv_external_port, 0, 0, 0, CFGFLAG_SERVER, "External port to report to the master servers")
 MACRO_CONFIG_STR(SvMap, sv_map, 128, "dm1", CFGFLAG_SERVER, "Map to use on the server")
 MACRO_CONFIG_INT(SvMaxClients, sv_max_clients, 8, 1, MAX_CLIENTS, CFGFLAG_SERVER, "Maximum number of clients that are allowed on a server")
+MACRO_CONFIG_INT(SvMaxClientsPerIP, sv_max_clients_per_ip, 8, 1, MAX_CLIENTS, CFGFLAG_SERVER, "Maximum number of clients with the same IP that can connect to the server")
 MACRO_CONFIG_INT(SvHighBandwidth, sv_high_bandwidth, 0, 0, 1, CFGFLAG_SERVER, "Use high bandwidth mode. Doubles the bandwidth required for the server. LAN use only")
 MACRO_CONFIG_INT(SvRegister, sv_register, 1, 0, 1, CFGFLAG_SERVER, "Register server with master server for public listing")
 MACRO_CONFIG_STR(SvRconPassword, sv_rcon_password, 32, "", CFGFLAG_SERVER, "Remote console password")
diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h
index 11a1b70d..7de534a4 100644
--- a/src/engine/shared/network.h
+++ b/src/engine/shared/network.h
@@ -244,6 +244,7 @@ private:
 	NETSOCKET m_Socket;
 	CSlot m_aSlots[NET_MAX_CLIENTS];
 	int m_MaxClients;
+	int m_MaxClientsPerIP;
 
 	CBan *m_aBans[256];
 	CBan m_BanPool[NET_SERVER_MAXBANS];
@@ -262,7 +263,7 @@ public:
 	int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser);
 
 	//
-	bool Open(NETADDR BindAddr, int MaxClients, int Flags);
+	bool Open(NETADDR BindAddr, int MaxClients, int MaxClientsPerIP, int Flags);
 	int Close();
 	
 	//
@@ -283,6 +284,9 @@ public:
 	NETADDR ClientAddr(int ClientID) const { return m_aSlots[ClientID].m_Connection.PeerAddress(); }
 	NETSOCKET Socket() const { return m_Socket; }
 	int MaxClients() const { return m_MaxClients; }
+
+	//
+	void SetMaxClientsPerIP(int Max);
 };
 
 
diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp
index 32b08bf6..2d30a7d1 100644
--- a/src/engine/shared/network_server.cpp
+++ b/src/engine/shared/network_server.cpp
@@ -24,7 +24,7 @@
 #define MACRO_LIST_FIND(Start, Next, Expression) \
 	{ while(Start && !(Expression)) Start = Start->Next; }
 
-bool CNetServer::Open(NETADDR BindAddr, int MaxClients, int Flags)
+bool CNetServer::Open(NETADDR BindAddr, int MaxClients, int MaxClientsPerIP, int Flags)
 {
 	// zero out the whole structure
 	mem_zero(this, sizeof(*this));
@@ -40,6 +40,8 @@ bool CNetServer::Open(NETADDR BindAddr, int MaxClients, int Flags)
 		m_MaxClients = NET_MAX_CLIENTS;
 	if(m_MaxClients < 1)
 		m_MaxClients = 1;
+
+	m_MaxClientsPerIP = MaxClientsPerIP;
 	
 	for(int i = 0; i < NET_MAX_CLIENTS; i++)
 		m_aSlots[i].m_Connection.Init(m_Socket);
@@ -335,6 +337,29 @@ int CNetServer::Recv(CNetChunk *pChunk)
 					// client that wants to connect
 					if(!Found)
 					{
+						// only allow a specific number of players with the same ip
+						NETADDR ThisAddr = Addr, OtherAddr;
+						int FoundAddr = 1;
+						ThisAddr.port = 0;
+						for(int i = 0; i < MaxClients(); ++i)
+						{
+							if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_OFFLINE)
+								continue;
+
+							OtherAddr = m_aSlots[i].m_Connection.PeerAddress();
+							OtherAddr.port = 0;
+							if(!net_addr_comp(&ThisAddr, &OtherAddr))
+							{
+								if(FoundAddr++ >= m_MaxClientsPerIP)
+								{
+									char aBuf[128];
+									str_format(aBuf, sizeof(aBuf), "only %i players with same ip allowed", m_MaxClientsPerIP);
+									CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, aBuf, sizeof(aBuf));
+									return 0;
+								}
+							}
+						}
+
 						for(int i = 0; i < MaxClients(); i++)
 						{
 							if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_OFFLINE)
@@ -411,3 +436,13 @@ int CNetServer::Send(CNetChunk *pChunk)
 	return 0;
 }
 
+void CNetServer::SetMaxClientsPerIP(int Max)
+{
+	// clamp
+	if(Max < 1)
+		Max = 1;
+	else if(Max > NET_MAX_CLIENTS)
+		Max = NET_MAX_CLIENTS;
+
+	m_MaxClientsPerIP = Max;
+}