src/network/network_server.cpp
branchgamebalance
changeset 9912 1ac8aac92385
parent 9911 0b8b245a2391
child 9913 e79cd19772dd
equal deleted inserted replaced
9911:0b8b245a2391 9912:1ac8aac92385
   830 {
   830 {
   831 	NetworkTCPSocketHandler *new_cs;
   831 	NetworkTCPSocketHandler *new_cs;
   832 	const NetworkClientInfo *ci;
   832 	const NetworkClientInfo *ci;
   833 	byte callback;
   833 	byte callback;
   834 
   834 
   835 	CommandPacket *cp = MallocT<CommandPacket>(1);
       
   836 
       
   837 	// The client was never joined.. so this is impossible, right?
   835 	// The client was never joined.. so this is impossible, right?
   838 	//  Ignore the packet, give the client a warning, and close his connection
   836 	//  Ignore the packet, give the client a warning, and close his connection
   839 	if (cs->status < STATUS_DONE_MAP || cs->has_quit) {
   837 	if (cs->status < STATUS_DONE_MAP || cs->has_quit) {
   840 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
   838 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
   841 		return;
   839 		return;
   842 	}
   840 	}
   843 
   841 
       
   842 	CommandPacket *cp = MallocT<CommandPacket>(1);
   844 	cp->player = (Owner)p->Recv_uint8();
   843 	cp->player = (Owner)p->Recv_uint8();
   845 	cp->cmd    = p->Recv_uint32();
   844 	cp->cmd    = p->Recv_uint32();
   846 	cp->p1     = p->Recv_uint32();
   845 	cp->p1     = p->Recv_uint32();
   847 	cp->p2     = p->Recv_uint32();
   846 	cp->p2     = p->Recv_uint32();
   848 	cp->tile   = p->Recv_uint32();
   847 	cp->tile   = p->Recv_uint32();
   849 	p->Recv_string(cp->text, lengthof(cp->text));
   848 	p->Recv_string(cp->text, lengthof(cp->text));
   850 
   849 
   851 	callback = p->Recv_uint8();
   850 	callback = p->Recv_uint8();
   852 
   851 
   853 	if (cs->has_quit) return;
   852 	if (cs->has_quit) {
       
   853 		free(cp);
       
   854 		return;
       
   855 	}
   854 
   856 
   855 	ci = DEREF_CLIENT_INFO(cs);
   857 	ci = DEREF_CLIENT_INFO(cs);
   856 
   858 
   857 	/* Check if cp->cmd is valid */
   859 	/* Check if cp->cmd is valid */
   858 	if (!IsValidCommand(cp->cmd)) {
   860 	if (!IsValidCommand(cp->cmd)) {
   859 		IConsolePrintF(_icolour_err, "WARNING: invalid command from client %d (IP: %s).", ci->client_index, GetPlayerIP(ci));
   861 		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);
   862 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
       
   863 		free(cp);
   861 		return;
   864 		return;
   862 	}
   865 	}
   863 
   866 
   864 	if (!CheckCommandFlags(cp, ci)) {
   867 	if (!CheckCommandFlags(cp, ci)) {
   865 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_KICKED);
   868 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_KICKED);
       
   869 		free(cp);
   866 		return;
   870 		return;
   867 	}
   871 	}
   868 
   872 
   869 	/** Only CMD_PLAYER_CTRL is always allowed, for the rest, playas needs
   873 	/** 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
   874 	 * to match the player in the packet. If it doesn't, the client has done
   872 	 */
   876 	 */
   873 	if (!(cp->cmd == CMD_PLAYER_CTRL && cp->p1 == 0) && ci->client_playas != cp->player) {
   877 	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...",
   878 		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);
   879 		               ci->client_playas + 1, GetPlayerIP(ci), cp->player + 1);
   876 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_PLAYER_MISMATCH);
   880 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_PLAYER_MISMATCH);
       
   881 		free(cp);
   877 		return;
   882 		return;
   878 	}
   883 	}
   879 
   884 
   880 	/** @todo CMD_PLAYER_CTRL with p1 = 0 announces a new player to the server. To give the
   885 	/** @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
   886 	 * player the correct ID, the server injects p2 and executes the command. Any other p1
   883 	 * @see CmdPlayerCtrl() players.c:655
   888 	 * @see CmdPlayerCtrl() players.c:655
   884 	 */
   889 	 */
   885 	if (cp->cmd == CMD_PLAYER_CTRL) {
   890 	if (cp->cmd == CMD_PLAYER_CTRL) {
   886 		if (cp->p1 != 0) {
   891 		if (cp->p1 != 0) {
   887 			SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_CHEATER);
   892 			SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_CHEATER);
       
   893 			free(cp);
   888 			return;
   894 			return;
   889 		}
   895 		}
   890 
   896 
   891 		/* XXX - Execute the command as a valid player. Normally this would be done by a
   897 		/* 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
   898 		 * spectator, but that is not allowed any commands. So do an impersonation. The drawback