src/network/network_server.cpp
branchNewGRF_ports
changeset 6720 35756db7e577
parent 6719 4cc327ad39d5
child 6868 7eb395287b3d
equal deleted inserted replaced
6719:4cc327ad39d5 6720:35756db7e577
    22 #include "../vehicle.h"
    22 #include "../vehicle.h"
    23 #include "../station.h"
    23 #include "../station.h"
    24 #include "../variables.h"
    24 #include "../variables.h"
    25 #include "../genworld.h"
    25 #include "../genworld.h"
    26 #include "../helpers.hpp"
    26 #include "../helpers.hpp"
       
    27 #include "../fileio.h"
    27 
    28 
    28 // This file handles all the server-commands
    29 // This file handles all the server-commands
    29 
    30 
    30 static void NetworkHandleCommandQueue(NetworkTCPSocketHandler* cs);
    31 static void NetworkHandleCommandQueue(NetworkTCPSocketHandler* cs);
    31 
    32 
   193 
   194 
   194 	Packet *p = NetworkSend_Init(PACKET_SERVER_CHECK_NEWGRFS);
   195 	Packet *p = NetworkSend_Init(PACKET_SERVER_CHECK_NEWGRFS);
   195 	const GRFConfig *c;
   196 	const GRFConfig *c;
   196 	uint grf_count = 0;
   197 	uint grf_count = 0;
   197 
   198 
   198 	for (c = _grfconfig; c != NULL; c = c->next) grf_count++;
   199 	for (c = _grfconfig; c != NULL; c = c->next) {
       
   200 		if (!HASBIT(c->flags, GCF_STATIC)) grf_count++;
       
   201 	}
   199 
   202 
   200 	p->Send_uint8 (grf_count);
   203 	p->Send_uint8 (grf_count);
   201 	for (c = _grfconfig; c != NULL; c = c->next) {
   204 	for (c = _grfconfig; c != NULL; c = c->next) {
   202 		cs->Send_GRFIdentifier(p, c);
   205 		if (!HASBIT(c->flags, GCF_STATIC)) cs->Send_GRFIdentifier(p, c);
   203 	}
   206 	}
   204 
   207 
   205 	cs->Send_Packet(p);
   208 	cs->Send_Packet(p);
   206 }
   209 }
   207 
   210 
   305 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
   308 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
   306 		return;
   309 		return;
   307 	}
   310 	}
   308 
   311 
   309 	if (cs->status == STATUS_AUTH) {
   312 	if (cs->status == STATUS_AUTH) {
   310 		char filename[256];
   313 		const char *filename = "network_server.tmp";
   311 		Packet *p;
   314 		Packet *p;
   312 
   315 
   313 		// Make a dump of the current game
   316 		// Make a dump of the current game
   314 		snprintf(filename, lengthof(filename), "%s%snetwork_server.tmp",  _paths.autosave_dir, PATHSEP);
   317 		if (SaveOrLoad(filename, SL_SAVE, AUTOSAVE_DIR) != SL_OK) error("network savedump failed");
   315 		if (SaveOrLoad(filename, SL_SAVE) != SL_OK) error("network savedump failed");
   318 
   316 
   319 		file_pointer = FioFOpenFile(filename, "rb", AUTOSAVE_DIR);
   317 		file_pointer = fopen(filename, "rb");
       
   318 		fseek(file_pointer, 0, SEEK_END);
   320 		fseek(file_pointer, 0, SEEK_END);
   319 
   321 
   320 		if (ftell(file_pointer) == 0) error("network savedump failed - zero sized savegame?");
   322 		if (ftell(file_pointer) == 0) error("network savedump failed - zero sized savegame?");
   321 
   323 
   322 		// Now send the _frame_counter and how many packets are coming
   324 		// Now send the _frame_counter and how many packets are coming
   487 	p->Send_uint32(cp->p2);
   489 	p->Send_uint32(cp->p2);
   488 	p->Send_uint32(cp->tile);
   490 	p->Send_uint32(cp->tile);
   489 	p->Send_string(cp->text);
   491 	p->Send_string(cp->text);
   490 	p->Send_uint8 (cp->callback);
   492 	p->Send_uint8 (cp->callback);
   491 	p->Send_uint32(cp->frame);
   493 	p->Send_uint32(cp->frame);
       
   494 	p->Send_bool  (cp->my_cmd);
   492 
   495 
   493 	cs->Send_Packet(p);
   496 	cs->Send_Packet(p);
   494 }
   497 }
   495 
   498 
   496 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHAT)(NetworkTCPSocketHandler *cs, NetworkAction action, uint16 client_index, bool self_send, const char *msg)
   499 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHAT)(NetworkTCPSocketHandler *cs, NetworkAction action, uint16 client_index, bool self_send, const char *msg)
   830 {
   833 {
   831 	NetworkTCPSocketHandler *new_cs;
   834 	NetworkTCPSocketHandler *new_cs;
   832 	const NetworkClientInfo *ci;
   835 	const NetworkClientInfo *ci;
   833 	byte callback;
   836 	byte callback;
   834 
   837 
   835 	CommandPacket *cp = MallocT<CommandPacket>(1);
       
   836 
       
   837 	// The client was never joined.. so this is impossible, right?
   838 	// The client was never joined.. so this is impossible, right?
   838 	//  Ignore the packet, give the client a warning, and close his connection
   839 	//  Ignore the packet, give the client a warning, and close his connection
   839 	if (cs->status < STATUS_DONE_MAP || cs->has_quit) {
   840 	if (cs->status < STATUS_DONE_MAP || cs->has_quit) {
   840 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
   841 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
   841 		return;
   842 		return;
   842 	}
   843 	}
   843 
   844 
       
   845 	CommandPacket *cp = MallocT<CommandPacket>(1);
   844 	cp->player = (Owner)p->Recv_uint8();
   846 	cp->player = (Owner)p->Recv_uint8();
   845 	cp->cmd    = p->Recv_uint32();
   847 	cp->cmd    = p->Recv_uint32();
   846 	cp->p1     = p->Recv_uint32();
   848 	cp->p1     = p->Recv_uint32();
   847 	cp->p2     = p->Recv_uint32();
   849 	cp->p2     = p->Recv_uint32();
   848 	cp->tile   = p->Recv_uint32();
   850 	cp->tile   = p->Recv_uint32();
   849 	p->Recv_string(cp->text, lengthof(cp->text));
   851 	p->Recv_string(cp->text, lengthof(cp->text));
   850 
   852 
   851 	callback = p->Recv_uint8();
   853 	callback = p->Recv_uint8();
   852 
   854 
   853 	if (cs->has_quit) return;
   855 	if (cs->has_quit) {
       
   856 		free(cp);
       
   857 		return;
       
   858 	}
   854 
   859 
   855 	ci = DEREF_CLIENT_INFO(cs);
   860 	ci = DEREF_CLIENT_INFO(cs);
   856 
   861 
   857 	/* Check if cp->cmd is valid */
   862 	/* Check if cp->cmd is valid */
   858 	if (!IsValidCommand(cp->cmd)) {
   863 	if (!IsValidCommand(cp->cmd)) {
   859 		IConsolePrintF(_icolour_err, "WARNING: invalid command from client %d (IP: %s).", ci->client_index, GetPlayerIP(ci));
   864 		IConsolePrintF(_icolour_err, "WARNING: invalid command from client %d (IP: %s).", ci->client_index, GetPlayerIP(ci));
   860 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
   865 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
       
   866 		free(cp);
   861 		return;
   867 		return;
   862 	}
   868 	}
   863 
   869 
   864 	if (!CheckCommandFlags(cp, ci)) {
   870 	if (!CheckCommandFlags(cp, ci)) {
   865 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_KICKED);
   871 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_KICKED);
       
   872 		free(cp);
   866 		return;
   873 		return;
   867 	}
   874 	}
   868 
   875 
   869 	/** Only CMD_PLAYER_CTRL is always allowed, for the rest, playas needs
   876 	/** Only CMD_PLAYER_CTRL is always allowed, for the rest, playas needs
   870 	 * to match the player in the packet. If it doesn't, the client has done
   877 	 * to match the player in the packet. If it doesn't, the client has done
   872 	 */
   879 	 */
   873 	if (!(cp->cmd == CMD_PLAYER_CTRL && cp->p1 == 0) && ci->client_playas != cp->player) {
   880 	if (!(cp->cmd == CMD_PLAYER_CTRL && cp->p1 == 0) && ci->client_playas != cp->player) {
   874 		IConsolePrintF(_icolour_err, "WARNING: player %d (IP: %s) tried to execute a command as player %d, kicking...",
   881 		IConsolePrintF(_icolour_err, "WARNING: player %d (IP: %s) tried to execute a command as player %d, kicking...",
   875 		               ci->client_playas + 1, GetPlayerIP(ci), cp->player + 1);
   882 		               ci->client_playas + 1, GetPlayerIP(ci), cp->player + 1);
   876 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_PLAYER_MISMATCH);
   883 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_PLAYER_MISMATCH);
       
   884 		free(cp);
   877 		return;
   885 		return;
   878 	}
   886 	}
   879 
   887 
   880 	/** @todo CMD_PLAYER_CTRL with p1 = 0 announces a new player to the server. To give the
   888 	/** @todo CMD_PLAYER_CTRL with p1 = 0 announces a new player to the server. To give the
   881 	 * player the correct ID, the server injects p2 and executes the command. Any other p1
   889 	 * player the correct ID, the server injects p2 and executes the command. Any other p1
   883 	 * @see CmdPlayerCtrl() players.c:655
   891 	 * @see CmdPlayerCtrl() players.c:655
   884 	 */
   892 	 */
   885 	if (cp->cmd == CMD_PLAYER_CTRL) {
   893 	if (cp->cmd == CMD_PLAYER_CTRL) {
   886 		if (cp->p1 != 0) {
   894 		if (cp->p1 != 0) {
   887 			SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_CHEATER);
   895 			SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_CHEATER);
       
   896 			free(cp);
   888 			return;
   897 			return;
   889 		}
   898 		}
   890 
   899 
   891 		/* XXX - Execute the command as a valid player. Normally this would be done by a
   900 		/* XXX - Execute the command as a valid player. Normally this would be done by a
   892 		 * spectator, but that is not allowed any commands. So do an impersonation. The drawback
   901 		 * spectator, but that is not allowed any commands. So do an impersonation. The drawback
   905 	FOR_ALL_CLIENTS(new_cs) {
   914 	FOR_ALL_CLIENTS(new_cs) {
   906 		if (new_cs->status >= STATUS_MAP) {
   915 		if (new_cs->status >= STATUS_MAP) {
   907 			// Callbacks are only send back to the client who sent them in the
   916 			// Callbacks are only send back to the client who sent them in the
   908 			//  first place. This filters that out.
   917 			//  first place. This filters that out.
   909 			cp->callback = (new_cs != cs) ? 0 : callback;
   918 			cp->callback = (new_cs != cs) ? 0 : callback;
       
   919 			cp->my_cmd = (new_cs == cs);
   910 			NetworkAddCommandQueue(new_cs, cp);
   920 			NetworkAddCommandQueue(new_cs, cp);
   911 		}
   921 		}
   912 	}
   922 	}
   913 
   923 
   914 	cp->callback = 0;
   924 	cp->callback = 0;
       
   925 	cp->my_cmd = false;
   915 	// Queue the command on the server
   926 	// Queue the command on the server
   916 	if (_local_command_queue == NULL) {
   927 	if (_local_command_queue == NULL) {
   917 		_local_command_queue = cp;
   928 		_local_command_queue = cp;
   918 	} else {
   929 	} else {
   919 		// Find last packet
   930 		// Find last packet
  1082 
  1093 
  1083 		// Display the message locally (so you know you have sent it)
  1094 		// Display the message locally (so you know you have sent it)
  1084 		if (ci != NULL && show_local) {
  1095 		if (ci != NULL && show_local) {
  1085 			if (from_index == NETWORK_SERVER_INDEX) {
  1096 			if (from_index == NETWORK_SERVER_INDEX) {
  1086 				char name[NETWORK_NAME_LENGTH];
  1097 				char name[NETWORK_NAME_LENGTH];
  1087 				StringID str = IsValidPlayer(ci_to->client_playas) ? GetPlayer(ci_to->client_playas)->name_1 : (uint16)STR_NETWORK_SPECTATORS;
  1098 				StringID str = IsValidPlayer(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
       
  1099 				SetDParam(0, ci_to->client_playas);
  1088 				GetString(name, str, lastof(name));
  1100 				GetString(name, str, lastof(name));
  1089 				NetworkTextMessage(action, GetDrawStringPlayerColor(ci_own->client_playas), true, name, "%s", msg);
  1101 				NetworkTextMessage(action, GetDrawStringPlayerColor(ci_own->client_playas), true, name, "%s", msg);
  1090 			} else {
  1102 			} else {
  1091 				FOR_ALL_CLIENTS(cs) {
  1103 				FOR_ALL_CLIENTS(cs) {
  1092 					if (cs->index == from_index) {
  1104 					if (cs->index == from_index) {
  1251 		memset(&_network_player_info[p->index], 0, sizeof(NetworkPlayerInfo));
  1263 		memset(&_network_player_info[p->index], 0, sizeof(NetworkPlayerInfo));
  1252 		_network_player_info[p->index].months_empty = months_empty;
  1264 		_network_player_info[p->index].months_empty = months_empty;
  1253 		ttd_strlcpy(_network_player_info[p->index].password, password, sizeof(_network_player_info[p->index].password));
  1265 		ttd_strlcpy(_network_player_info[p->index].password, password, sizeof(_network_player_info[p->index].password));
  1254 
  1266 
  1255 		// Grap the company name
  1267 		// Grap the company name
  1256 		SetDParam(0, p->name_1);
  1268 		SetDParam(0, p->index);
  1257 		SetDParam(1, p->name_2);
  1269 		GetString(_network_player_info[p->index].company_name, STR_COMPANY_NAME, lastof(_network_player_info[p->index].company_name));
  1258 		GetString(_network_player_info[p->index].company_name, STR_JUST_STRING, lastof(_network_player_info[p->index].company_name));
       
  1259 
  1270 
  1260 		// Check the income
  1271 		// Check the income
  1261 		if (_cur_year - 1 == p->inaugurated_year) {
  1272 		if (_cur_year - 1 == p->inaugurated_year) {
  1262 			// The player is here just 1 year, so display [2], else display[1]
  1273 			// The player is here just 1 year, so display [2], else display[1]
  1263 			for (i = 0; i < lengthof(p->yearly_expenses[2]); i++) {
  1274 			for (i = 0; i < lengthof(p->yearly_expenses[2]); i++) {
  1270 		}
  1281 		}
  1271 
  1282 
  1272 		// Set some general stuff
  1283 		// Set some general stuff
  1273 		_network_player_info[p->index].inaugurated_year = p->inaugurated_year;
  1284 		_network_player_info[p->index].inaugurated_year = p->inaugurated_year;
  1274 		_network_player_info[p->index].company_value = p->old_economy[0].company_value;
  1285 		_network_player_info[p->index].company_value = p->old_economy[0].company_value;
  1275 		_network_player_info[p->index].money = p->money64;
  1286 		_network_player_info[p->index].money = p->player_money;
  1276 		_network_player_info[p->index].performance = p->old_economy[0].performance_history;
  1287 		_network_player_info[p->index].performance = p->old_economy[0].performance_history;
  1277 	}
  1288 	}
  1278 
  1289 
  1279 	// Go through all vehicles and count the type of vehicles
  1290 	// Go through all vehicles and count the type of vehicles
  1280 	FOR_ALL_VEHICLES(v) {
  1291 	FOR_ALL_VEHICLES(v) {