network_server.c
changeset 722 f420fa9bd521
parent 716 8af847728d5b
child 733 ac3d7e1b786e
equal deleted inserted replaced
721:617a397f8b4b 722:f420fa9bd521
   129 	// Data:
   129 	// Data:
   130 	//    uint8:  ErrorID (see network_data.h, NetworkErrorCode)
   130 	//    uint8:  ErrorID (see network_data.h, NetworkErrorCode)
   131 	//
   131 	//
   132 
   132 
   133 	NetworkClientState *new_cs;
   133 	NetworkClientState *new_cs;
   134 	char str1[100], str2[100];
   134 	char str[100];
   135 	char client_name[NETWORK_NAME_LENGTH];
   135 	char client_name[NETWORK_NAME_LENGTH];
   136 
   136 
   137 	Packet *p = NetworkSend_Init(PACKET_SERVER_ERROR);
   137 	Packet *p = NetworkSend_Init(PACKET_SERVER_ERROR);
   138 	NetworkSend_uint8(p, error);
   138 	NetworkSend_uint8(p, error);
   139 	NetworkSend_Packet(p, cs);
   139 	NetworkSend_Packet(p, cs);
   140 
   140 
   141 	// Only send when the current client was in game
   141 	// Only send when the current client was in game
   142 	if (cs->status > STATUS_AUTH) {
   142 	if (cs->status > STATUS_AUTH) {
   143 		NetworkGetClientName(client_name, sizeof(client_name), cs);
   143 		NetworkGetClientName(client_name, sizeof(client_name), cs);
   144 
   144 
   145 		GetString(str1, STR_NETWORK_ERR_LEFT);
   145 		GetString(str, STR_NETWORK_ERR_CLIENT_GENERAL + error);
   146 		GetString(str2, STR_NETWORK_ERR_CLIENT_GENERAL + error);
   146 
   147 
   147 		DEBUG(net, 2)("[NET] %s made an error (%s) and his connection is closed", client_name, str);
   148 		DEBUG(net, 2)("[NET] %s made an error (%s) and his connection is closed", client_name, str2);
   148 
   149 
   149 		NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, str);
   150 		NetworkTextMessage(NETWORK_ACTION_JOIN_LEAVE, 1, client_name, "%s (%s)", str1, str2);
       
   151 
   150 
   152 		FOR_ALL_CLIENTS(new_cs) {
   151 		FOR_ALL_CLIENTS(new_cs) {
   153 			if (new_cs->status > STATUS_AUTH && new_cs != cs) {
   152 			if (new_cs->status > STATUS_AUTH && new_cs != cs) {
   154 				// Some errors we filter to a more general error. Clients don't have to know the real
   153 				// Some errors we filter to a more general error. Clients don't have to know the real
   155 				//  reason a joining failed.
   154 				//  reason a joining failed.
   470 	NetworkSend_uint32(p, cp->frame);
   469 	NetworkSend_uint32(p, cp->frame);
   471 
   470 
   472 	NetworkSend_Packet(p, cs);
   471 	NetworkSend_Packet(p, cs);
   473 }
   472 }
   474 
   473 
   475 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHAT)(NetworkClientState *cs, NetworkAction action, uint16 client_index, const char *msg)
   474 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHAT)(NetworkClientState *cs, NetworkAction action, uint16 client_index, bool self_send, const char *msg)
   476 {
   475 {
   477 	//
   476 	//
   478 	// Packet: SERVER_CHAT
   477 	// Packet: SERVER_CHAT
   479 	// Function: Sends a chat-packet to the client
   478 	// Function: Sends a chat-packet to the client
   480 	// Data:
   479 	// Data:
   485 
   484 
   486 	Packet *p = NetworkSend_Init(PACKET_SERVER_CHAT);
   485 	Packet *p = NetworkSend_Init(PACKET_SERVER_CHAT);
   487 
   486 
   488 	NetworkSend_uint8(p, action);
   487 	NetworkSend_uint8(p, action);
   489 	NetworkSend_uint16(p, client_index);
   488 	NetworkSend_uint16(p, client_index);
       
   489 	NetworkSend_uint8(p, self_send);
   490 	NetworkSend_string(p, msg);
   490 	NetworkSend_string(p, msg);
   491 
   491 
   492 	NetworkSend_Packet(p, cs);
   492 	NetworkSend_Packet(p, cs);
   493 }
   493 }
   494 
   494 
   708 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK)
   708 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK)
   709 {
   709 {
   710 	// Client has the map, now start syncing
   710 	// Client has the map, now start syncing
   711 	if (cs->status == STATUS_DONE_MAP && !cs->quited) {
   711 	if (cs->status == STATUS_DONE_MAP && !cs->quited) {
   712 		char client_name[NETWORK_NAME_LENGTH];
   712 		char client_name[NETWORK_NAME_LENGTH];
   713 		char str[100];
       
   714 		NetworkClientState *new_cs;
   713 		NetworkClientState *new_cs;
   715 		GetString(str, STR_NETWORK_CLIENT_JOINED);
       
   716 
   714 
   717 		NetworkGetClientName(client_name, sizeof(client_name), cs);
   715 		NetworkGetClientName(client_name, sizeof(client_name), cs);
   718 
   716 
   719 		NetworkTextMessage(NETWORK_ACTION_JOIN_LEAVE, 1, client_name, str);
   717 		NetworkTextMessage(NETWORK_ACTION_JOIN, 1, false, client_name, "");
   720 
   718 
   721 		// Mark the client as pre-active, and wait for an ACK
   719 		// Mark the client as pre-active, and wait for an ACK
   722 		//  so we know he is done loading and in sync with us
   720 		//  so we know he is done loading and in sync with us
   723 		cs->status = STATUS_PRE_ACTIVE;
   721 		cs->status = STATUS_PRE_ACTIVE;
   724 		NetworkHandleCommandQueue(cs);
   722 		NetworkHandleCommandQueue(cs);
   832 {
   830 {
   833 	// This packets means a client noticed an error and is reporting this
   831 	// This packets means a client noticed an error and is reporting this
   834 	//  to us. Display the error and report it to the other clients
   832 	//  to us. Display the error and report it to the other clients
   835 	NetworkClientState *new_cs;
   833 	NetworkClientState *new_cs;
   836 	byte errorno = NetworkRecv_uint8(p);
   834 	byte errorno = NetworkRecv_uint8(p);
   837 	char str1[100], str2[100];
   835 	char str[100];
   838 	char client_name[NETWORK_NAME_LENGTH];
   836 	char client_name[NETWORK_NAME_LENGTH];
   839 
   837 
   840 	// The client was never joined.. thank the client for the packet, but ignore it
   838 	// The client was never joined.. thank the client for the packet, but ignore it
   841 	if (cs->status < STATUS_DONE_MAP || cs->quited) {
   839 	if (cs->status < STATUS_DONE_MAP || cs->quited) {
   842 		cs->quited = true;
   840 		cs->quited = true;
   843 		return;
   841 		return;
   844 	}
   842 	}
   845 
   843 
   846 	NetworkGetClientName(client_name, sizeof(client_name), cs);
   844 	NetworkGetClientName(client_name, sizeof(client_name), cs);
   847 
   845 
   848 	GetString(str1, STR_NETWORK_ERR_LEFT);
   846 	GetString(str, STR_NETWORK_ERR_CLIENT_GENERAL + errorno);
   849 	GetString(str2, STR_NETWORK_ERR_CLIENT_GENERAL + errorno);
   847 
   850 
   848 	DEBUG(net, 2)("[NET] %s reported an error and is closing his connection (%s)", client_name, str);
   851 	DEBUG(net, 2)("[NET] %s reported an error and is closing his connection (%s)", client_name, str2);
   849 
   852 
   850 	NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, str);
   853 	NetworkTextMessage(NETWORK_ACTION_JOIN_LEAVE, 1, client_name, "%s (%s)", str1, str2);
       
   854 
   851 
   855 	FOR_ALL_CLIENTS(new_cs) {
   852 	FOR_ALL_CLIENTS(new_cs) {
   856 		if (new_cs->status > STATUS_AUTH) {
   853 		if (new_cs->status > STATUS_AUTH) {
   857 			SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->index, errorno);
   854 			SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->index, errorno);
   858 		}
   855 		}
   864 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_QUIT)
   861 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_QUIT)
   865 {
   862 {
   866 	// The client wants to leave. Display this and report it to the other
   863 	// The client wants to leave. Display this and report it to the other
   867 	//  clients.
   864 	//  clients.
   868 	NetworkClientState *new_cs;
   865 	NetworkClientState *new_cs;
   869 	char str1[100], str2[100];
   866 	char str[100];
   870 	char client_name[NETWORK_NAME_LENGTH];
   867 	char client_name[NETWORK_NAME_LENGTH];
   871 
   868 
   872 	// The client was never joined.. thank the client for the packet, but ignore it
   869 	// The client was never joined.. thank the client for the packet, but ignore it
   873 	if (cs->status < STATUS_DONE_MAP || cs->quited) {
   870 	if (cs->status < STATUS_DONE_MAP || cs->quited) {
   874 		cs->quited = true;
   871 		cs->quited = true;
   875 		return;
   872 		return;
   876 	}
   873 	}
   877 
   874 
   878 	NetworkRecv_string(p, str2, 100);
   875 	NetworkRecv_string(p, str, 100);
   879 
   876 
   880 	NetworkGetClientName(client_name, sizeof(client_name), cs);
   877 	NetworkGetClientName(client_name, sizeof(client_name), cs);
   881 
   878 
   882 	GetString(str1, STR_NETWORK_ERR_LEFT);
   879 	NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, str);
   883 
       
   884 	NetworkTextMessage(NETWORK_ACTION_JOIN_LEAVE, 1, client_name, "%s (%s)", str1, str2);
       
   885 
   880 
   886 	FOR_ALL_CLIENTS(new_cs) {
   881 	FOR_ALL_CLIENTS(new_cs) {
   887 		if (new_cs->status > STATUS_AUTH) {
   882 		if (new_cs->status > STATUS_AUTH) {
   888 			SEND_COMMAND(PACKET_SERVER_QUIT)(new_cs, cs->index, str2);
   883 			SEND_COMMAND(PACKET_SERVER_QUIT)(new_cs, cs->index, str);
   889 		}
   884 		}
   890 	}
   885 	}
   891 
   886 
   892 	cs->quited = true;
   887 	cs->quited = true;
   893 }
   888 }
   911 	NetworkClientState *cs;
   906 	NetworkClientState *cs;
   912 	NetworkClientInfo *ci, *ci_own, *ci_to;
   907 	NetworkClientInfo *ci, *ci_own, *ci_to;
   913 
   908 
   914 	switch (desttype) {
   909 	switch (desttype) {
   915 	case DESTTYPE_CLIENT:
   910 	case DESTTYPE_CLIENT:
   916 		if (dest == 1) {
   911 		/* Are we sending to the server? */
       
   912 		if (dest == NETWORK_SERVER_INDEX) {
   917 			ci = NetworkFindClientInfoFromIndex(from_index);
   913 			ci = NetworkFindClientInfoFromIndex(from_index);
       
   914 			/* Display the text locally, and that is it */
   918 			if (ci != NULL)
   915 			if (ci != NULL)
   919 				NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas-1), ci->client_name, "%s", msg);
   916 				NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas-1), false, ci->client_name, "%s", msg);
   920 		} else {
   917 		} else {
       
   918 			/* Else find the client to send the message to */
   921 			FOR_ALL_CLIENTS(cs) {
   919 			FOR_ALL_CLIENTS(cs) {
   922 				if (cs->index == dest) {
   920 				if (cs->index == dest) {
   923 					SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, msg);
   921 					SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, false, msg);
   924 					break;
   922 					break;
   925 				}
   923 				}
   926 			}
   924 			}
   927 		}
   925 		}
   928 
   926 
   929 		// Display the message locally (so you know you have sent it)
   927 		// Display the message locally (so you know you have sent it)
   930 		if (from_index != dest) {
   928 		if (from_index != dest) {
   931 			if (from_index == 1) {
   929 			if (from_index == NETWORK_SERVER_INDEX) {
   932 				ci = NetworkFindClientInfoFromIndex(from_index);
   930 				ci = NetworkFindClientInfoFromIndex(from_index);
   933 				ci_to = NetworkFindClientInfoFromIndex(dest);
   931 				ci_to = NetworkFindClientInfoFromIndex(dest);
   934 				if (ci != NULL && ci_to != NULL)
   932 				if (ci != NULL && ci_to != NULL)
   935 					NetworkTextMessage(NETWORK_ACTION_CHAT_TO_CLIENT, GetDrawStringPlayerColor(ci->client_playas-1), ci_to->client_name, "%s", msg);
   933 					NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas-1), true, ci_to->client_name, "%s", msg);
   936 			} else {
   934 			} else {
   937 				FOR_ALL_CLIENTS(cs) {
   935 				FOR_ALL_CLIENTS(cs) {
   938 					if (cs->index == from_index) {
   936 					if (cs->index == from_index) {
   939 						SEND_COMMAND(PACKET_SERVER_CHAT)(cs, NETWORK_ACTION_CHAT_TO_CLIENT, dest, msg);
   937 						SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, dest, true, msg);
   940 						break;
   938 						break;
   941 					}
   939 					}
   942 				}
   940 				}
   943 			}
   941 			}
   944 		}
   942 		}
   945 		break;
   943 		break;
   946 	case DESTTYPE_PLAYER: {
   944 	case DESTTYPE_PLAYER: {
   947 		bool show_local = true; // If this is false, the message is already displayed
   945 		bool show_local = true; // If this is false, the message is already displayed
   948 														// on the client who did sent it.
   946 														// on the client who did sent it.
       
   947 		/* Find all clients that belong to this player */
   949 		FOR_ALL_CLIENTS(cs) {
   948 		FOR_ALL_CLIENTS(cs) {
   950 			ci = DEREF_CLIENT_INFO(cs);
   949 			ci = DEREF_CLIENT_INFO(cs);
   951 			if (ci->client_playas == dest) {
   950 			if (ci->client_playas == dest) {
   952 				SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, msg);
   951 				SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, false, msg);
   953 				if (cs->index == from_index)
   952 				if (cs->index == from_index)
   954 					show_local = false;
   953 					show_local = false;
   955 			}
   954 			}
   956 		}
   955 		}
   957 		ci = NetworkFindClientInfoFromIndex(from_index);
   956 		ci = NetworkFindClientInfoFromIndex(from_index);
   958 		ci_own = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
   957 		ci_own = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
   959 		if (ci != NULL && ci_own != NULL && ci_own->client_playas == dest) {
   958 		if (ci != NULL && ci_own != NULL && ci_own->client_playas == dest) {
   960 			NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas-1), ci->client_name, "%s", msg);
   959 			NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas-1), false, ci->client_name, "%s", msg);
   961 			if (from_index == NETWORK_SERVER_INDEX)
   960 			if (from_index == NETWORK_SERVER_INDEX)
   962 				show_local = false;
   961 				show_local = false;
   963 		}
   962 		}
   964 
   963 
   965 		// Display the message locally (so you know you have sent it)
   964 		// Display the message locally (so you know you have sent it)
   966 		if (ci != NULL && show_local) {
   965 		if (ci != NULL && show_local) {
   967 			if (from_index == NETWORK_SERVER_INDEX) {
   966 			if (from_index == NETWORK_SERVER_INDEX) {
   968 				char name[NETWORK_NAME_LENGTH];
   967 				char name[NETWORK_NAME_LENGTH];
   969 				GetString(name, DEREF_PLAYER(ci->client_playas-1)->name_1);
   968 				GetString(name, DEREF_PLAYER(ci->client_playas-1)->name_1);
   970 				NetworkTextMessage(NETWORK_ACTION_CHAT_TO_PLAYER, GetDrawStringPlayerColor(ci->client_playas-1), name, "%s", msg);
   969 				NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas-1), true, name, "%s", msg);
   971 			} else {
   970 			} else {
   972 				FOR_ALL_CLIENTS(cs) {
   971 				FOR_ALL_CLIENTS(cs) {
   973 					if (cs->index == from_index) {
   972 					if (cs->index == from_index) {
   974 						SEND_COMMAND(PACKET_SERVER_CHAT)(cs, NETWORK_ACTION_CHAT_TO_PLAYER, from_index, msg);
   973 						SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, true, msg);
   975 					}
   974 					}
   976 				}
   975 				}
   977 			}
   976 			}
   978 		}
   977 		}
   979 		}
   978 		}
   981 	default:
   980 	default:
   982 		DEBUG(net, 0)("[NET][Server] Received unknown destination type %d. Doing broadcast instead.\n");
   981 		DEBUG(net, 0)("[NET][Server] Received unknown destination type %d. Doing broadcast instead.\n");
   983 		/* fall-through to next case */
   982 		/* fall-through to next case */
   984 	case DESTTYPE_BROADCAST:
   983 	case DESTTYPE_BROADCAST:
   985 		FOR_ALL_CLIENTS(cs) {
   984 		FOR_ALL_CLIENTS(cs) {
   986 			SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, msg);
   985 			SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_index, false, msg);
   987 		}
   986 		}
   988 		ci = NetworkFindClientInfoFromIndex(from_index);
   987 		ci = NetworkFindClientInfoFromIndex(from_index);
   989 		if (ci != NULL)
   988 		if (ci != NULL)
   990 			NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas-1), ci->client_name, "%s", msg);
   989 			NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas-1), false, ci->client_name, "%s", msg);
   991 		break;
   990 		break;
   992 	}
   991 	}
   993 }
   992 }
   994 
   993 
   995 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_CHAT)
   994 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_CHAT)
  1026 	ci = DEREF_CLIENT_INFO(cs);
  1025 	ci = DEREF_CLIENT_INFO(cs);
  1027 
  1026 
  1028 	if (ci != NULL) {
  1027 	if (ci != NULL) {
  1029 		// Display change
  1028 		// Display change
  1030 		if (NetworkFindName(name)) {
  1029 		if (NetworkFindName(name)) {
  1031 			NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, ci->client_name, name);
  1030 			NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, name);
  1032 			ttd_strlcpy(ci->client_name, name, sizeof(ci->client_name));
  1031 			ttd_strlcpy(ci->client_name, name, sizeof(ci->client_name));
  1033 			NetworkUpdateClientInfo(ci->client_index);
  1032 			NetworkUpdateClientInfo(ci->client_index);
  1034 		}
  1033 		}
  1035 	}
  1034 	}
  1036 }
  1035 }