src/network/network_client.cpp
changeset 10207 c291a21b304e
parent 10039 1f236afd6cd1
child 10208 72c00af5c95d
equal deleted inserted replaced
10206:0050610c0368 10207:c291a21b304e
    75 
    75 
    76 	return hashed_password;
    76 	return hashed_password;
    77 }
    77 }
    78 
    78 
    79 /**
    79 /**
    80  * Hash the current company password; used when the server 'player' sets his/her password.
    80  * Hash the current company password; used when the server 'company' sets his/her password.
    81  */
    81  */
    82 void HashCurrentCompanyPassword()
    82 void HashCurrentCompanyPassword()
    83 {
    83 {
    84 	if (StrEmpty(_network_player_info[_local_player].password)) return;
    84 	if (StrEmpty(_network_company_info[_local_company].password)) return;
    85 
    85 
    86 	_password_game_seed = _settings_game.game_creation.generation_seed;
    86 	_password_game_seed = _settings_game.game_creation.generation_seed;
    87 	ttd_strlcpy(_password_server_unique_id, _settings_client.network.network_id, sizeof(_password_server_unique_id));
    87 	ttd_strlcpy(_password_server_unique_id, _settings_client.network.network_id, sizeof(_password_server_unique_id));
    88 
    88 
    89 	const char *new_pw = GenerateCompanyPasswordHash(_network_player_info[_local_player].password);
    89 	const char *new_pw = GenerateCompanyPasswordHash(_network_company_info[_local_company].password);
    90 	ttd_strlcpy(_network_player_info[_local_player].password, new_pw, sizeof(_network_player_info[_local_player].password));
    90 	ttd_strlcpy(_network_company_info[_local_company].password, new_pw, sizeof(_network_company_info[_local_company].password));
    91 }
    91 }
    92 
    92 
    93 
    93 
    94 // **********
    94 // **********
    95 // Sending functions
    95 // Sending functions
   117 	//
   117 	//
   118 	// Packet: CLIENT_JOIN
   118 	// Packet: CLIENT_JOIN
   119 	// Function: Try to join the server
   119 	// Function: Try to join the server
   120 	// Data:
   120 	// Data:
   121 	//    String: OpenTTD Revision (norev000 if no revision)
   121 	//    String: OpenTTD Revision (norev000 if no revision)
   122 	//    String: Player Name (max NETWORK_NAME_LENGTH)
   122 	//    String: Client Name (max NETWORK_NAME_LENGTH)
   123 	//    uint8:  Play as Player id (1..MAX_PLAYERS)
   123 	//    uint8:  Play as Company id (1..MAX_COMPANIES)
   124 	//    uint8:  Language ID
   124 	//    uint8:  Language ID
   125 	//    String: Unique id to find the player back in server-listing
   125 	//    String: Unique id to find the client back in server-listing
   126 	//
   126 	//
   127 
   127 
   128 	Packet *p;
   128 	Packet *p;
   129 	_network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
   129 	_network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
   130 	InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
   130 	InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
   131 
   131 
   132 	p = NetworkSend_Init(PACKET_CLIENT_JOIN);
   132 	p = NetworkSend_Init(PACKET_CLIENT_JOIN);
   133 	p->Send_string(_openttd_revision);
   133 	p->Send_string(_openttd_revision);
   134 	p->Send_string(_settings_client.network.player_name); // Player name
   134 	p->Send_string(_settings_client.network.client_name); // Client name
   135 	p->Send_uint8 (_network_playas);      // PlayAs
   135 	p->Send_uint8 (_network_playas);      // PlayAs
   136 	p->Send_uint8 (NETLANG_ANY);          // Language
   136 	p->Send_uint8 (NETLANG_ANY);          // Language
   137 	p->Send_string(_settings_client.network.network_id);
   137 	p->Send_string(_settings_client.network.network_id);
   138 	MY_CLIENT->Send_Packet(p);
   138 	MY_CLIENT->Send_Packet(p);
   139 }
   139 }
   211 {
   211 {
   212 	//
   212 	//
   213 	// Packet: CLIENT_COMMAND
   213 	// Packet: CLIENT_COMMAND
   214 	// Function: Send a DoCommand to the Server
   214 	// Function: Send a DoCommand to the Server
   215 	// Data:
   215 	// Data:
   216 	//    uint8:  PlayerID (0..MAX_PLAYERS-1)
   216 	//    uint8:  CompanyID (0..MAX_COMPANIES-1)
   217 	//    uint32: CommandID (see command.h)
   217 	//    uint32: CommandID (see command.h)
   218 	//    uint32: P1 (free variables used in DoCommand)
   218 	//    uint32: P1 (free variables used in DoCommand)
   219 	//    uint32: P2
   219 	//    uint32: P2
   220 	//    uint32: Tile
   220 	//    uint32: Tile
   221 	//    string: text
   221 	//    string: text
   222 	//    uint8:  CallBackID (see callback_table.c)
   222 	//    uint8:  CallBackID (see callback_table.c)
   223 	//
   223 	//
   224 
   224 
   225 	Packet *p = NetworkSend_Init(PACKET_CLIENT_COMMAND);
   225 	Packet *p = NetworkSend_Init(PACKET_CLIENT_COMMAND);
   226 
   226 
   227 	p->Send_uint8 (cp->player);
   227 	p->Send_uint8 (cp->company);
   228 	p->Send_uint32(cp->cmd);
   228 	p->Send_uint32(cp->cmd);
   229 	p->Send_uint32(cp->p1);
   229 	p->Send_uint32(cp->p1);
   230 	p->Send_uint32(cp->p2);
   230 	p->Send_uint32(cp->p2);
   231 	p->Send_uint32((uint32)cp->tile);
   231 	p->Send_uint32((uint32)cp->tile);
   232 	p->Send_string(cp->text);
   232 	p->Send_string(cp->text);
   242 	// Packet: CLIENT_CHAT
   242 	// Packet: CLIENT_CHAT
   243 	// Function: Send a chat-packet to the serve
   243 	// Function: Send a chat-packet to the serve
   244 	// Data:
   244 	// Data:
   245 	//    uint8:  ActionID (see network_data.h, NetworkAction)
   245 	//    uint8:  ActionID (see network_data.h, NetworkAction)
   246 	//    uint8:  Destination Type (see network_data.h, DestType);
   246 	//    uint8:  Destination Type (see network_data.h, DestType);
   247 	//    uint16: Destination Player
   247 	//    uint16: Destination Company/Client
   248 	//    String: Message (max NETWORK_CHAT_LENGTH)
   248 	//    String: Message (max NETWORK_CHAT_LENGTH)
   249 	//
   249 	//
   250 
   250 
   251 	Packet *p = NetworkSend_Init(PACKET_CLIENT_CHAT);
   251 	Packet *p = NetworkSend_Init(PACKET_CLIENT_CHAT);
   252 
   252 
   288 
   288 
   289 DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_NAME)(const char *name)
   289 DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_NAME)(const char *name)
   290 {
   290 {
   291 	//
   291 	//
   292 	// Packet: PACKET_CLIENT_SET_NAME
   292 	// Packet: PACKET_CLIENT_SET_NAME
   293 	// Function: Gives the player a new name
   293 	// Function: Gives the client a new name
   294 	// Data:
   294 	// Data:
   295 	//    String: Name
   295 	//    String: Name
   296 	//
   296 	//
   297 	Packet *p = NetworkSend_Init(PACKET_CLIENT_SET_NAME);
   297 	Packet *p = NetworkSend_Init(PACKET_CLIENT_SET_NAME);
   298 
   298 
   357 
   357 
   358 	company_info_version = p->Recv_uint8();
   358 	company_info_version = p->Recv_uint8();
   359 
   359 
   360 	if (!MY_CLIENT->has_quit && company_info_version == NETWORK_COMPANY_INFO_VERSION) {
   360 	if (!MY_CLIENT->has_quit && company_info_version == NETWORK_COMPANY_INFO_VERSION) {
   361 		byte total;
   361 		byte total;
   362 		PlayerID current;
   362 		CompanyID current;
   363 
   363 
   364 		total = p->Recv_uint8();
   364 		total = p->Recv_uint8();
   365 
   365 
   366 		// There is no data at all..
   366 		// There is no data at all..
   367 		if (total == 0) return NETWORK_RECV_STATUS_CLOSE_QUERY;
   367 		if (total == 0) return NETWORK_RECV_STATUS_CLOSE_QUERY;
   368 
   368 
   369 		current = (Owner)p->Recv_uint8();
   369 		current = (Owner)p->Recv_uint8();
   370 		if (current >= MAX_PLAYERS) return NETWORK_RECV_STATUS_CLOSE_QUERY;
   370 		if (current >= MAX_COMPANIES) return NETWORK_RECV_STATUS_CLOSE_QUERY;
   371 
   371 
   372 		p->Recv_string(_network_player_info[current].company_name, sizeof(_network_player_info[current].company_name));
   372 		p->Recv_string(_network_company_info[current].company_name, sizeof(_network_company_info[current].company_name));
   373 		_network_player_info[current].inaugurated_year = p->Recv_uint32();
   373 		_network_company_info[current].inaugurated_year = p->Recv_uint32();
   374 		_network_player_info[current].company_value    = p->Recv_uint64();
   374 		_network_company_info[current].company_value    = p->Recv_uint64();
   375 		_network_player_info[current].money            = p->Recv_uint64();
   375 		_network_company_info[current].money            = p->Recv_uint64();
   376 		_network_player_info[current].income           = p->Recv_uint64();
   376 		_network_company_info[current].income           = p->Recv_uint64();
   377 		_network_player_info[current].performance      = p->Recv_uint16();
   377 		_network_company_info[current].performance      = p->Recv_uint16();
   378 		_network_player_info[current].use_password     = p->Recv_bool();
   378 		_network_company_info[current].use_password     = p->Recv_bool();
   379 		for (i = 0; i < NETWORK_VEHICLE_TYPES; i++)
   379 		for (i = 0; i < NETWORK_VEHICLE_TYPES; i++)
   380 			_network_player_info[current].num_vehicle[i] = p->Recv_uint16();
   380 			_network_company_info[current].num_vehicle[i] = p->Recv_uint16();
   381 		for (i = 0; i < NETWORK_STATION_TYPES; i++)
   381 		for (i = 0; i < NETWORK_STATION_TYPES; i++)
   382 			_network_player_info[current].num_station[i] = p->Recv_uint16();
   382 			_network_company_info[current].num_station[i] = p->Recv_uint16();
   383 
   383 
   384 		p->Recv_string(_network_player_info[current].players, sizeof(_network_player_info[current].players));
   384 		p->Recv_string(_network_company_info[current].clients, sizeof(_network_company_info[current].clients));
   385 
   385 
   386 		InvalidateWindow(WC_NETWORK_WINDOW, 0);
   386 		InvalidateWindow(WC_NETWORK_WINDOW, 0);
   387 
   387 
   388 		return NETWORK_RECV_STATUS_OKAY;
   388 		return NETWORK_RECV_STATUS_OKAY;
   389 	}
   389 	}
   396 //  which is always an unique number on a server.
   396 //  which is always an unique number on a server.
   397 DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO)
   397 DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO)
   398 {
   398 {
   399 	NetworkClientInfo *ci;
   399 	NetworkClientInfo *ci;
   400 	uint16 index = p->Recv_uint16();
   400 	uint16 index = p->Recv_uint16();
   401 	PlayerID playas = (Owner)p->Recv_uint8();
   401 	CompanyID playas = (CompanyID)p->Recv_uint8();
   402 	char name[NETWORK_NAME_LENGTH];
   402 	char name[NETWORK_NAME_LENGTH];
   403 
   403 
   404 	p->Recv_string(name, sizeof(name));
   404 	p->Recv_string(name, sizeof(name));
   405 
   405 
   406 	if (MY_CLIENT->has_quit) return NETWORK_RECV_STATUS_CONN_LOST;
   406 	if (MY_CLIENT->has_quit) return NETWORK_RECV_STATUS_CONN_LOST;
   412 	if (ci != NULL) {
   412 	if (ci != NULL) {
   413 		if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) {
   413 		if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) {
   414 			// Client name changed, display the change
   414 			// Client name changed, display the change
   415 			NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, "%s", name);
   415 			NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, "%s", name);
   416 		} else if (playas != ci->client_playas) {
   416 		} else if (playas != ci->client_playas) {
   417 			// The player changed from client-player..
   417 			// The client changed from client-player..
   418 			// Do not display that for now
   418 			// Do not display that for now
   419 		}
   419 		}
   420 
   420 
   421 		ci->client_playas = playas;
   421 		ci->client_playas = playas;
   422 		ttd_strlcpy(ci->client_name, name, sizeof(ci->client_name));
   422 		ttd_strlcpy(ci->client_name, name, sizeof(ci->client_name));
   449 
   449 
   450 	switch (error) {
   450 	switch (error) {
   451 		/* We made an error in the protocol, and our connection is closed.... */
   451 		/* We made an error in the protocol, and our connection is closed.... */
   452 		case NETWORK_ERROR_NOT_AUTHORIZED:
   452 		case NETWORK_ERROR_NOT_AUTHORIZED:
   453 		case NETWORK_ERROR_NOT_EXPECTED:
   453 		case NETWORK_ERROR_NOT_EXPECTED:
   454 		case NETWORK_ERROR_PLAYER_MISMATCH:
   454 		case NETWORK_ERROR_COMPANY_MISMATCH:
   455 			_switch_mode_errorstr = STR_NETWORK_ERR_SERVER_ERROR;
   455 			_switch_mode_errorstr = STR_NETWORK_ERR_SERVER_ERROR;
   456 			break;
   456 			break;
   457 		case NETWORK_ERROR_FULL:
   457 		case NETWORK_ERROR_FULL:
   458 			_switch_mode_errorstr = STR_NETWORK_ERR_SERVER_FULL;
   458 			_switch_mode_errorstr = STR_NETWORK_ERR_SERVER_FULL;
   459 			break;
   459 			break;
   620 		 * only toolbar/statusbar and gamefield are visible */
   620 		 * only toolbar/statusbar and gamefield are visible */
   621 
   621 
   622 		// Say we received the map and loaded it correctly!
   622 		// Say we received the map and loaded it correctly!
   623 		SEND_COMMAND(PACKET_CLIENT_MAP_OK)();
   623 		SEND_COMMAND(PACKET_CLIENT_MAP_OK)();
   624 
   624 
   625 		/* New company/spectator (invalid player) or company we want to join is not active
   625 		/* New company/spectator (invalid company) or company we want to join is not active
   626 		 * Switch local player to spectator and await the server's judgement */
   626 		 * Switch local company to spectator and await the server's judgement */
   627 		if (_network_playas == PLAYER_NEW_COMPANY || !IsValidPlayerID(_network_playas)) {
   627 		if (_network_playas == COMPANY_NEW_COMPANY || !IsValidCompanyID(_network_playas)) {
   628 			SetLocalPlayer(PLAYER_SPECTATOR);
   628 			SetLocalCompany(COMPANY_SPECTATOR);
   629 
   629 
   630 			if (_network_playas != PLAYER_SPECTATOR) {
   630 			if (_network_playas != COMPANY_SPECTATOR) {
   631 				/* We have arrived and ready to start playing; send a command to make a new player;
   631 				/* We have arrived and ready to start playing; send a command to make a new company;
   632 				 * the server will give us a client-id and let us in */
   632 				 * the server will give us a client-id and let us in */
   633 				_network_join_status = NETWORK_JOIN_STATUS_REGISTERING;
   633 				_network_join_status = NETWORK_JOIN_STATUS_REGISTERING;
   634 				ShowJoinStatusWindow();
   634 				ShowJoinStatusWindow();
   635 				NetworkSend_Command(0, 0, 0, CMD_PLAYER_CTRL, NULL);
   635 				NetworkSend_Command(0, 0, 0, CMD_COMPANY_CTRL, NULL);
   636 			}
   636 			}
   637 		} else {
   637 		} else {
   638 			// take control over an existing company
   638 			// take control over an existing company
   639 			SetLocalPlayer(_network_playas);
   639 			SetLocalCompany(_network_playas);
   640 		}
   640 		}
   641 	}
   641 	}
   642 
   642 
   643 	return NETWORK_RECV_STATUS_OKAY;
   643 	return NETWORK_RECV_STATUS_OKAY;
   644 }
   644 }
   683 }
   683 }
   684 
   684 
   685 DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_COMMAND)
   685 DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_COMMAND)
   686 {
   686 {
   687 	CommandPacket *cp = MallocT<CommandPacket>(1);
   687 	CommandPacket *cp = MallocT<CommandPacket>(1);
   688 	cp->player   = (PlayerID)p->Recv_uint8();
   688 	cp->company  = (CompanyID)p->Recv_uint8();
   689 	cp->cmd      = p->Recv_uint32();
   689 	cp->cmd      = p->Recv_uint32();
   690 	cp->p1       = p->Recv_uint32();
   690 	cp->p1       = p->Recv_uint32();
   691 	cp->p2       = p->Recv_uint32();
   691 	cp->p2       = p->Recv_uint32();
   692 	cp->tile     = p->Recv_uint32();
   692 	cp->tile     = p->Recv_uint32();
   693 	p->Recv_string(cp->text, sizeof(cp->text));
   693 	p->Recv_string(cp->text, sizeof(cp->text));
   731 				/* For speaking to client we need the client-name */
   731 				/* For speaking to client we need the client-name */
   732 				snprintf(name, sizeof(name), "%s", ci_to->client_name);
   732 				snprintf(name, sizeof(name), "%s", ci_to->client_name);
   733 				ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
   733 				ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
   734 				break;
   734 				break;
   735 
   735 
   736 			/* For speaking to company or giving money, we need the player-name */
   736 			/* For speaking to company or giving money, we need the company-name */
   737 			case NETWORK_ACTION_GIVE_MONEY:
   737 			case NETWORK_ACTION_GIVE_MONEY:
   738 				if (!IsValidPlayerID(ci_to->client_playas)) return NETWORK_RECV_STATUS_OKAY;
   738 				if (!IsValidCompanyID(ci_to->client_playas)) return NETWORK_RECV_STATUS_OKAY;
   739 				/* fallthrough */
   739 				/* fallthrough */
   740 			case NETWORK_ACTION_CHAT_COMPANY: {
   740 			case NETWORK_ACTION_CHAT_COMPANY: {
   741 				StringID str = IsValidPlayerID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
   741 				StringID str = IsValidCompanyID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
   742 				SetDParam(0, ci_to->client_playas);
   742 				SetDParam(0, ci_to->client_playas);
   743 
   743 
   744 				GetString(name, str, lastof(name));
   744 				GetString(name, str, lastof(name));
   745 				ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
   745 				ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
   746 			} break;
   746 			} break;
   752 		snprintf(name, sizeof(name), "%s", ci_to->client_name);
   752 		snprintf(name, sizeof(name), "%s", ci_to->client_name);
   753 		ci = ci_to;
   753 		ci = ci_to;
   754 	}
   754 	}
   755 
   755 
   756 	if (ci != NULL)
   756 	if (ci != NULL)
   757 		NetworkTextMessage(action, (ConsoleColour)GetDrawStringPlayerColor(ci->client_playas), self_send, name, "%s", msg);
   757 		NetworkTextMessage(action, (ConsoleColour)GetDrawStringCompanyColor(ci->client_playas), self_send, name, "%s", msg);
   758 	return NETWORK_RECV_STATUS_OKAY;
   758 	return NETWORK_RECV_STATUS_OKAY;
   759 }
   759 }
   760 
   760 
   761 DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR_QUIT)
   761 DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR_QUIT)
   762 {
   762 {
   829 }
   829 }
   830 
   830 
   831 DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEWGAME)
   831 DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEWGAME)
   832 {
   832 {
   833 	// To trottle the reconnects a bit, every clients waits
   833 	// To trottle the reconnects a bit, every clients waits
   834 	//  his _local_player value before reconnecting
   834 	//  his _local_company value before reconnecting
   835 	// PLAYER_SPECTATOR is currently 255, so to avoid long wait periods
   835 	// COMPANY_SPECTATOR is currently 255, so to avoid long wait periods
   836 	//  set the max to 10.
   836 	//  set the max to 10.
   837 	_network_reconnect = min(_local_player + 1, 10);
   837 	_network_reconnect = min(_local_company + 1, 10);
   838 	_switch_mode_errorstr = STR_NETWORK_SERVER_REBOOT;
   838 	_switch_mode_errorstr = STR_NETWORK_SERVER_REBOOT;
   839 
   839 
   840 	return NETWORK_RECV_STATUS_SERVER_ERROR;
   840 	return NETWORK_RECV_STATUS_SERVER_ERROR;
   841 }
   841 }
   842 
   842 
   936 void NetworkClientSendRcon(const char *password, const char *command)
   936 void NetworkClientSendRcon(const char *password, const char *command)
   937 {
   937 {
   938 	SEND_COMMAND(PACKET_CLIENT_RCON)(password, command);
   938 	SEND_COMMAND(PACKET_CLIENT_RCON)(password, command);
   939 }
   939 }
   940 
   940 
   941 void NetworkUpdatePlayerName()
   941 void NetworkUpdateClientName()
   942 {
   942 {
   943 	NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
   943 	NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
   944 
   944 
   945 	if (ci == NULL) return;
   945 	if (ci == NULL) return;
   946 
   946 
   947 	/* Don't change the name if it is the same as the old name */
   947 	/* Don't change the name if it is the same as the old name */
   948 	if (strcmp(ci->client_name, _settings_client.network.player_name) != 0) {
   948 	if (strcmp(ci->client_name, _settings_client.network.client_name) != 0) {
   949 		if (!_network_server) {
   949 		if (!_network_server) {
   950 			SEND_COMMAND(PACKET_CLIENT_SET_NAME)(_settings_client.network.player_name);
   950 			SEND_COMMAND(PACKET_CLIENT_SET_NAME)(_settings_client.network.client_name);
   951 		} else {
   951 		} else {
   952 			if (NetworkFindName(_settings_client.network.player_name)) {
   952 			if (NetworkFindName(_settings_client.network.client_name)) {
   953 				NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, "%s", _settings_client.network.player_name);
   953 				NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, "%s", _settings_client.network.client_name);
   954 				ttd_strlcpy(ci->client_name, _settings_client.network.player_name, sizeof(ci->client_name));
   954 				ttd_strlcpy(ci->client_name, _settings_client.network.client_name, sizeof(ci->client_name));
   955 				NetworkUpdateClientInfo(NETWORK_SERVER_INDEX);
   955 				NetworkUpdateClientInfo(NETWORK_SERVER_INDEX);
   956 			}
   956 			}
   957 		}
   957 		}
   958 	}
   958 	}
   959 }
   959 }
   963 	SEND_COMMAND(PACKET_CLIENT_CHAT)(action, type, dest, msg);
   963 	SEND_COMMAND(PACKET_CLIENT_CHAT)(action, type, dest, msg);
   964 }
   964 }
   965 
   965 
   966 void NetworkClientSetPassword()
   966 void NetworkClientSetPassword()
   967 {
   967 {
   968 	SEND_COMMAND(PACKET_CLIENT_SET_PASSWORD)(_network_player_info[_local_player].password);
   968 	SEND_COMMAND(PACKET_CLIENT_SET_PASSWORD)(_network_company_info[_local_company].password);
   969 }
   969 }
   970 
   970 
   971 #endif /* ENABLE_NETWORK */
   971 #endif /* ENABLE_NETWORK */