(svn r1322) -Add: banning system (mostly tnx to guru3)
authortruelight
Sun, 02 Jan 2005 12:03:43 +0000
changeset 841 4874b9ce2765
parent 840 10fbbdd22777
child 842 efc3546bc313
(svn r1322) -Add: banning system (mostly tnx to guru3)
A server can ban people via ClientList
Both server and dedicated can do it via console:
'ban', 'unban', 'banlist'.
console_cmds.c
lang/english.txt
network.c
network.h
network_client.c
network_data.h
network_gui.c
network_server.c
settings.c
--- a/console_cmds.c	Sat Jan 01 19:18:48 2005 +0000
+++ b/console_cmds.c	Sun Jan 02 12:03:43 2005 +0000
@@ -144,6 +144,87 @@
 // ********************************* //
 #ifdef ENABLE_NETWORK
 
+DEF_CONSOLE_CMD(ConBan)
+{
+	NetworkClientInfo *ci;
+
+	if (argc == 2) {
+		uint32 index = atoi(argv[1]);
+		if (index == NETWORK_SERVER_INDEX && !_network_dedicated) {
+			IConsolePrint(_iconsole_color_default, "Silly boy, you can not ban yourself!");
+			return NULL;
+		}
+		if (index == 0) {
+			IConsoleError("Invalid Client-ID");
+			return NULL;
+		}
+
+		ci = NetworkFindClientInfoFromIndex(index);
+
+		if (ci != NULL) {
+			uint i;
+			/* Add user to ban-list */
+			for (i = 0; i < lengthof(_network_ban_list); i++) {
+				if (_network_ban_list[i] == NULL || _network_ban_list[i][0] == '\0') {
+					_network_ban_list[i] = strdup(inet_ntoa(*(struct in_addr *)&ci->client_ip));
+					break;
+				}
+			}
+
+			SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromIndex(index), NETWORK_ERROR_KICKED);
+			return NULL;
+		} else {
+			IConsoleError("Client-ID not found");
+			return NULL;
+		}
+	}
+
+	IConsolePrint(_iconsole_color_default, "Unknown usage. Usage: ban <client-id>. For client-ids, see 'clients'.");
+
+	return NULL;
+}
+
+DEF_CONSOLE_CMD(ConUnBan)
+{
+	if (argc == 2) {
+		uint i;
+		for (i = 0; i < lengthof(_network_ban_list); i++) {
+			if (_network_ban_list[i] == NULL || _network_ban_list[i][0] == '\0')
+				continue;
+
+			if (strncmp(_network_ban_list[i], argv[1], strlen(_network_ban_list[i])) == 0) {
+				_network_ban_list[i][0] = '\0';
+				IConsolePrint(_iconsole_color_default, "IP unbanned.");
+				return NULL;
+			}
+		}
+
+		IConsolePrint(_iconsole_color_default, "IP not in ban-list.");
+
+		return NULL;
+	}
+
+	IConsolePrint(_iconsole_color_default, "Unknown usage. Usage: unban <ip>.");
+
+	return NULL;
+}
+
+DEF_CONSOLE_CMD(ConBanList)
+{
+	uint i;
+
+	IConsolePrint(_iconsole_color_default, "Banlist: ");
+
+	for (i = 0; i < lengthof(_network_ban_list); i++) {
+		if (_network_ban_list[i] == NULL || _network_ban_list[i][0] == '\0')
+			continue;
+
+		IConsolePrintF(_iconsole_color_default, "  %d) %s", i + 1, _network_ban_list[i]);
+	}
+
+	return NULL;
+}
+
 DEF_CONSOLE_CMD(ConStatus)
 {
 	const char *status;
@@ -978,6 +1059,13 @@
 	IConsoleCmdHook("status", ICONSOLE_HOOK_ACCESS, ConCmdHookNoNetClient);
 	IConsoleCmdHook("resetengines", ICONSOLE_HOOK_ACCESS, ConCmdHookNoNetwork);
 
+	IConsoleCmdRegister("ban",   ConBan);
+	IConsoleCmdHook("ban", ICONSOLE_HOOK_ACCESS, ConCmdHookNoNetClient);
+	IConsoleCmdRegister("unban",   ConUnBan);
+	IConsoleCmdHook("unban", ICONSOLE_HOOK_ACCESS, ConCmdHookNoNetClient);
+	IConsoleCmdRegister("banlist",   ConBanList);
+	IConsoleCmdHook("banlist", ICONSOLE_HOOK_ACCESS, ConCmdHookNoNetClient);
+
 	IConsoleAliasRegister("clean_company",		"reset_company %A");
 
 	IConsoleVarRegister("net_frame_freq", &_network_frame_freq, ICONSOLE_VAR_UINT8);
--- a/lang/english.txt	Sat Jan 01 19:18:48 2005 +0000
+++ b/lang/english.txt	Sun Jan 02 12:03:43 2005 +0000
@@ -1343,6 +1343,7 @@
 STR_NETWORK_ERR_WRONG_REVISION					:{WHITE} The revision of this client does not match the server's revision
 STR_NETWORK_ERR_WRONG_PASSWORD					:{WHITE} Wrong password
 STR_NETWORK_ERR_SERVER_FULL					:{WHITE} The server is full
+STR_NETWORK_ERR_SERVER_BANNED				:{WHITE} You are banned from this server
 STR_NETWORK_ERR_KICKED						:{WHITE} You were kicked out of the game
 STR_NETWORK_ERR_CHEATER						:{WHITE} Cheating is not allowed on this server
 
--- a/network.c	Sat Jan 01 19:18:48 2005 +0000
+++ b/network.c	Sun Jan 02 12:03:43 2005 +0000
@@ -219,7 +219,8 @@
 		default: errorno = NETWORK_ERROR_GENERAL;
 	}
 	// This means we fucked up and the server closed the connection
-	if (res != NETWORK_RECV_STATUS_SERVER_ERROR && res != NETWORK_RECV_STATUS_SERVER_FULL) {
+	if (res != NETWORK_RECV_STATUS_SERVER_ERROR && res != NETWORK_RECV_STATUS_SERVER_FULL &&
+			res != NETWORK_RECV_STATUS_SERVER_BANNED) {
 		SEND_COMMAND(PACKET_CLIENT_ERROR)(errorno);
 
 		// Dequeue all commands before closing the socket
@@ -615,6 +616,8 @@
 #else
 	LONG sin_len; // for some reason we need a 'LONG' under MorphOS
 #endif
+	int i;
+	bool banned;
 
 	// Should never ever happen.. is it possible??
 	assert(_listensocket != INVALID_SOCKET);
@@ -639,6 +642,33 @@
 		{int b = 1; setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b));}
 		#endif
 
+		/* Check if the client is banned */
+		banned = false;
+		for (i = 0; i < lengthof(_network_ban_list); i++) {
+			if (_network_ban_list[i] == NULL)
+				continue;
+
+			if (sin.sin_addr.s_addr == inet_addr(_network_ban_list[i])) {
+				Packet *p = NetworkSend_Init(PACKET_SERVER_BANNED);
+
+				DEBUG(net, 1)("[NET] Banned ip tried to join (%s), refused", _network_ban_list[i]);
+
+				p->buffer[0] = p->size & 0xFF;
+				p->buffer[1] = p->size >> 8;
+
+				send(s, p->buffer, p->size, 0);
+				closesocket(s);
+
+				free(p);
+
+				banned = true;
+				break;
+			}
+		}
+		/* If this client is banned, continue with next client */
+		if (banned)
+			continue;
+
 		cs = NetworkAllocClient(s);
 		if (cs == NULL) {
 			// no more clients allowed?
@@ -844,15 +874,15 @@
  * by the function that generates the config file. */
 void NetworkRebuildHostList()
 {
-	int i=0;
+	int i = 0;
 	NetworkGameList *item = _network_game_list;
-	while (item != NULL && i!=lengthof(_network_host_list)) {
+	while (item != NULL && i != lengthof(_network_host_list)) {
 		if (item->manually)
 			_network_host_list[i++] = strdup(item->info.hostname);
 		item = item->next;
 	}
 
-	for (; i<lengthof(_network_host_list); i++) {
+	for (; i < lengthof(_network_host_list); i++) {
 		_network_host_list[i] = strdup("");
 	}
 }
@@ -1262,10 +1292,10 @@
 	DEBUG(net, 3) ("[NET][Core] Starting network...");
 
 	#if defined(__MORPHOS__) || defined(__AMIGA__)
-	/* 
+	/*
 	 *  IMPORTANT NOTE: SocketBase needs to be initialized before we use _any_
 	 *  network related function, else: crash.
-	 */	
+	 */
 	{
 		DEBUG(misc,3) ("[NET][Core] Loading bsd socket library");
 		if (!(SocketBase = OpenLibrary("bsdsocket.library", 4))) {
@@ -1291,7 +1321,7 @@
 		#endif // __AMIGA__
 	}
 	#endif // __MORPHOS__ / __AMIGA__
-     
+
     // Network is available
 	_network_available = true;
 	_network_dedicated = false;
--- a/network.h	Sat Jan 01 19:18:48 2005 +0000
+++ b/network.h	Sun Jan 02 12:03:43 2005 +0000
@@ -194,6 +194,8 @@
 // Those variables must always be registered!
 #define MAX_SAVED_SERVERS 10
 VARDEF char *_network_host_list[MAX_SAVED_SERVERS];
+#define MAX_BANS 25
+VARDEF char *_network_ban_list[MAX_BANS];
 VARDEF bool _networking;
 VARDEF bool _network_available;  // is network mode available?
 VARDEF bool _network_server; // network-server is active
--- a/network_client.c	Sat Jan 01 19:18:48 2005 +0000
+++ b/network_client.c	Sun Jan 02 12:03:43 2005 +0000
@@ -263,6 +263,15 @@
 	return NETWORK_RECV_STATUS_SERVER_FULL;
 }
 
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_BANNED)
+{
+	// We try to join a server where we are banned
+	_switch_mode_errorstr = STR_NETWORK_ERR_SERVER_BANNED;
+	DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
+
+	return NETWORK_RECV_STATUS_SERVER_BANNED;
+}
+
 DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_COMPANY_INFO)
 {
 	byte company_info_version;
@@ -737,6 +746,7 @@
 //  packet is found.
 static NetworkClientPacket* const _network_client_packet[] = {
 	RECEIVE_COMMAND(PACKET_SERVER_FULL),
+	RECEIVE_COMMAND(PACKET_SERVER_BANNED),
 	NULL, /*PACKET_CLIENT_JOIN,*/
 	RECEIVE_COMMAND(PACKET_SERVER_ERROR),
 	NULL, /*PACKET_CLIENT_COMPANY_INFO,*/
--- a/network_data.h	Sat Jan 01 19:18:48 2005 +0000
+++ b/network_data.h	Sun Jan 02 12:03:43 2005 +0000
@@ -67,6 +67,7 @@
 	NETWORK_RECV_STATUS_MALFORMED_PACKET,
 	NETWORK_RECV_STATUS_SERVER_ERROR, // The server told us we made an error
 	NETWORK_RECV_STATUS_SERVER_FULL,
+	NETWORK_RECV_STATUS_SERVER_BANNED,
 	NETWORK_RECV_STATUS_CLOSE_QUERY, // Done quering the server
 } NetworkRecvStatus;
 
@@ -130,6 +131,7 @@
 //   is the respond to a wrong revision)
 typedef enum {
 	PACKET_SERVER_FULL,
+	PACKET_SERVER_BANNED,
 	PACKET_CLIENT_JOIN,
 	PACKET_SERVER_ERROR,
 	PACKET_CLIENT_COMPANY_INFO,
--- a/network_gui.c	Sat Jan 01 19:18:48 2005 +0000
+++ b/network_gui.c	Sun Jan 02 12:03:43 2005 +0000
@@ -953,10 +953,21 @@
 		SEND_COMMAND(PACKET_SERVER_ERROR)(&_clients[client_no], NETWORK_ERROR_KICKED);
 }
 
-/*static void ClientList_Ban(byte client_no)
+static void ClientList_Ban(byte client_no)
 {
-// TODO
-}*/
+	uint i;
+	uint32 ip = NetworkFindClientInfo(client_no)->client_ip;
+
+	for (i = 0; i < lengthof(_network_ban_list); i++) {
+		if (_network_ban_list[i] == NULL || _network_ban_list[i][0] == '\0') {
+			_network_ban_list[i] = strdup(inet_ntoa(*(struct in_addr *)&ip));
+			break;
+		}
+	}
+
+	if (client_no < MAX_PLAYERS)
+		SEND_COMMAND(PACKET_SERVER_ERROR)(&_clients[client_no], NETWORK_ERROR_KICKED);
+}
 
 static void ClientList_GiveMoney(byte client_no)
 {
@@ -1090,8 +1101,8 @@
 		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_KICK);
 		_clientlist_proc[i++] = &ClientList_Kick;
 
-/*		sprintf(clientlist_action[i],"Ban");
-		clientlist_proc[i++] = &ClientList_Ban;*/
+		sprintf(_clientlist_action[i],"Ban");
+		_clientlist_proc[i++] = &ClientList_Ban;
 	}
 
 	if (i == 0) {
--- a/network_server.c	Sat Jan 01 19:18:48 2005 +0000
+++ b/network_server.c	Sun Jan 02 12:03:43 2005 +0000
@@ -1069,6 +1069,7 @@
 //  packet is found.
 static NetworkServerPacket* const _network_server_packet[] = {
 	NULL, /*PACKET_SERVER_FULL,*/
+	NULL, /*PACKET_SERVER_BANNED,*/
 	RECEIVE_COMMAND(PACKET_CLIENT_JOIN),
 	NULL, /*PACKET_SERVER_ERROR,*/
 	RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_INFO),
--- a/settings.c	Sat Jan 01 19:18:48 2005 +0000
+++ b/settings.c	Sun Jan 02 12:03:43 2005 +0000
@@ -123,7 +123,7 @@
 	IniGroup *grp = pool_alloc(&ini->pool, sizeof(IniGroup));
 	grp->ini = ini;
 	grp->name = pool_strdup(&ini->pool, grpt, len);
-	if(!strcmp(grp->name, "newgrf") || !strcmp(grp->name, "servers") )
+	if(!strcmp(grp->name, "newgrf") || !strcmp(grp->name, "servers") || !strcmp(grp->name, "bans") )
 		grp->type = IGT_LIST;
 	else
 		grp->type = IGT_VARIABLES;
@@ -983,6 +983,7 @@
 	HandleSettingDescs(ini, load_setting_desc);
 	LoadList(ini, "newgrf", _newgrf_files, lengthof(_newgrf_files));
 	LoadList(ini, "servers", _network_host_list, lengthof(_network_host_list));
+	LoadList(ini, "bans", _network_ban_list, lengthof(_network_ban_list));
 	ini_free(ini);
 }
 
@@ -991,6 +992,7 @@
 	IniFile *ini = ini_load(_config_file);
 	HandleSettingDescs(ini, save_setting_desc);
 	SaveList(ini, "servers", _network_host_list, lengthof(_network_host_list));
+	SaveList(ini, "bans", _network_ban_list, lengthof(_network_ban_list));
 	ini_save(_config_file, ini);
 	ini_free(ini);
 }