|
@@ -115,46 +115,46 @@ void HashCurrentCompanyPassword(const ch
|
|
|
************/
|
|
|
|
|
|
DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_COMPANY_INFO)
|
|
|
{
|
|
|
/*
|
|
|
* Packet: CLIENT_COMPANY_INFO
|
|
|
* Function: Request company-info (in detail)
|
|
|
* Data:
|
|
|
* <none>
|
|
|
*/
|
|
|
Packet *p;
|
|
|
_network_join_status = NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO;
|
|
|
InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
|
|
|
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
|
|
|
|
|
|
p = NetworkSend_Init(PACKET_CLIENT_COMPANY_INFO);
|
|
|
MY_CLIENT->Send_Packet(p);
|
|
|
}
|
|
|
|
|
|
DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_JOIN)
|
|
|
{
|
|
|
/*
|
|
|
* Packet: CLIENT_JOIN
|
|
|
* Function: Try to join the server
|
|
|
* Data:
|
|
|
* String: OpenTTD Revision (norev000 if no revision)
|
|
|
* String: Client Name (max NETWORK_NAME_LENGTH)
|
|
|
* uint8: Play as Company id (1..MAX_COMPANIES)
|
|
|
* uint8: Language ID
|
|
|
* String: Unique id to find the client back in server-listing
|
|
|
*/
|
|
|
|
|
|
Packet *p;
|
|
|
_network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
|
|
|
InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
|
|
|
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
|
|
|
|
|
|
p = NetworkSend_Init(PACKET_CLIENT_JOIN);
|
|
|
p->Send_string(_openttd_revision);
|
|
|
p->Send_string(_settings_client.network.client_name); // Client name
|
|
|
p->Send_uint8 (_network_join_as); // PlayAs
|
|
|
p->Send_uint8 (NETLANG_ANY); // Language
|
|
|
p->Send_string(_settings_client.network.network_id);
|
|
|
MY_CLIENT->Send_Packet(p);
|
|
|
}
|
|
|
|
|
|
DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_NEWGRFS_CHECKED)
|
|
|
{
|
|
@@ -390,25 +390,25 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
|
|
|
company_info->money = p->Recv_uint64();
|
|
|
company_info->income = p->Recv_uint64();
|
|
|
company_info->performance = p->Recv_uint16();
|
|
|
company_info->use_password = p->Recv_bool();
|
|
|
for (int i = 0; i < NETWORK_VEHICLE_TYPES; i++)
|
|
|
company_info->num_vehicle[i] = p->Recv_uint16();
|
|
|
for (int i = 0; i < NETWORK_STATION_TYPES; i++)
|
|
|
company_info->num_station[i] = p->Recv_uint16();
|
|
|
company_info->ai = p->Recv_bool();
|
|
|
|
|
|
p->Recv_string(company_info->clients, sizeof(company_info->clients));
|
|
|
|
|
|
InvalidateWindow(WC_NETWORK_WINDOW, 0);
|
|
|
SetWindowDirty(WC_NETWORK_WINDOW, 0);
|
|
|
|
|
|
return NETWORK_RECV_STATUS_OKAY;
|
|
|
}
|
|
|
|
|
|
return NETWORK_RECV_STATUS_CLOSE_QUERY;
|
|
|
}
|
|
|
|
|
|
/* This packet contains info about the client (playas and name)
|
|
|
* as client we save this in NetworkClientInfo, linked via 'client_id'
|
|
|
* which is always an unique number on a server. */
|
|
|
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO)
|
|
|
{
|
|
@@ -425,37 +425,37 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
|
|
|
if (ci != NULL) {
|
|
|
if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) {
|
|
|
/* Client name changed, display the change */
|
|
|
NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, name);
|
|
|
} else if (playas != ci->client_playas) {
|
|
|
/* The client changed from client-player..
|
|
|
* Do not display that for now */
|
|
|
}
|
|
|
|
|
|
ci->client_playas = playas;
|
|
|
strecpy(ci->client_name, name, lastof(ci->client_name));
|
|
|
|
|
|
InvalidateWindow(WC_CLIENT_LIST, 0);
|
|
|
SetWindowDirty(WC_CLIENT_LIST, 0);
|
|
|
|
|
|
return NETWORK_RECV_STATUS_OKAY;
|
|
|
}
|
|
|
|
|
|
/* We don't have this client_id yet, find an empty client_id, and put the data there */
|
|
|
ci = new NetworkClientInfo(client_id);
|
|
|
ci->client_playas = playas;
|
|
|
if (client_id == _network_own_client_id) MY_CLIENT->SetInfo(ci);
|
|
|
|
|
|
strecpy(ci->client_name, name, lastof(ci->client_name));
|
|
|
|
|
|
InvalidateWindow(WC_CLIENT_LIST, 0);
|
|
|
SetWindowDirty(WC_CLIENT_LIST, 0);
|
|
|
|
|
|
return NETWORK_RECV_STATUS_OKAY;
|
|
|
}
|
|
|
|
|
|
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR)
|
|
|
{
|
|
|
NetworkErrorCode error = (NetworkErrorCode)p->Recv_uint8();
|
|
|
|
|
|
switch (error) {
|
|
|
/* We made an error in the protocol, and our connection is closed.... */
|
|
|
case NETWORK_ERROR_NOT_AUTHORIZED:
|
|
|
case NETWORK_ERROR_NOT_EXPECTED:
|
|
@@ -551,25 +551,25 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
|
|
|
_password_game_seed = p->Recv_uint32();
|
|
|
p->Recv_string(_password_server_unique_id, sizeof(_password_server_unique_id));
|
|
|
|
|
|
/* Start receiving the map */
|
|
|
SEND_COMMAND(PACKET_CLIENT_GETMAP)();
|
|
|
return NETWORK_RECV_STATUS_OKAY;
|
|
|
}
|
|
|
|
|
|
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_WAIT)
|
|
|
{
|
|
|
_network_join_status = NETWORK_JOIN_STATUS_WAITING;
|
|
|
_network_join_waiting = p->Recv_uint8();
|
|
|
InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
|
|
|
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
|
|
|
|
|
|
/* We are put on hold for receiving the map.. we need GUI for this ;) */
|
|
|
DEBUG(net, 1, "The server is currently busy sending the map to someone else, please wait..." );
|
|
|
DEBUG(net, 1, "There are %d clients in front of you", _network_join_waiting);
|
|
|
|
|
|
return NETWORK_RECV_STATUS_OKAY;
|
|
|
}
|
|
|
|
|
|
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_MAP)
|
|
|
{
|
|
|
static FILE *file_pointer;
|
|
|
|
|
@@ -592,47 +592,47 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
|
|
|
_network_join_bytes = 0;
|
|
|
_network_join_bytes_total = p->Recv_uint32();
|
|
|
|
|
|
/* If the network connection has been closed due to loss of connection
|
|
|
* or when _network_join_kbytes_total is 0, the join status window will
|
|
|
* do a division by zero. When the connection is lost, we just return
|
|
|
* that. If kbytes_total is 0, the packet must be malformed as a
|
|
|
* savegame less than 1 kilobyte is practically impossible. */
|
|
|
if (MY_CLIENT->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
|
|
|
if (_network_join_bytes_total == 0) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
|
|
|
|
|
|
_network_join_status = NETWORK_JOIN_STATUS_DOWNLOADING;
|
|
|
InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
|
|
|
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
|
|
|
|
|
|
/* The first packet does not contain any more data */
|
|
|
return NETWORK_RECV_STATUS_OKAY;
|
|
|
}
|
|
|
|
|
|
if (maptype == MAP_PACKET_NORMAL) {
|
|
|
/* We are still receiving data, put it to the file */
|
|
|
if (fwrite(p->buffer + p->pos, 1, p->size - p->pos, file_pointer) != (size_t)(p->size - p->pos)) {
|
|
|
_switch_mode_errorstr = STR_NETWORK_ERROR_SAVEGAMEERROR;
|
|
|
return NETWORK_RECV_STATUS_SAVEGAME;
|
|
|
}
|
|
|
|
|
|
_network_join_bytes = ftell(file_pointer);
|
|
|
InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
|
|
|
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
|
|
|
}
|
|
|
|
|
|
/* Check if this was the last packet */
|
|
|
if (maptype == MAP_PACKET_END) {
|
|
|
fclose(file_pointer);
|
|
|
|
|
|
_network_join_status = NETWORK_JOIN_STATUS_PROCESSING;
|
|
|
InvalidateWindow(WC_NETWORK_STATUS_WINDOW, 0);
|
|
|
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
|
|
|
|
|
|
/* The map is done downloading, load it */
|
|
|
if (!SafeSaveOrLoad("network_client.tmp", SL_LOAD, GM_NORMAL, AUTOSAVE_DIR)) {
|
|
|
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
|
|
|
_switch_mode_errorstr = STR_NETWORK_ERROR_SAVEGAMEERROR;
|
|
|
return NETWORK_RECV_STATUS_SAVEGAME;
|
|
|
}
|
|
|
/* If the savegame has successfully loaded, ALL windows have been removed,
|
|
|
* only toolbar/statusbar and gamefield are visible */
|
|
|
|
|
|
/* Say we received the map and loaded it correctly! */
|
|
|
SEND_COMMAND(PACKET_CLIENT_MAP_OK)();
|
|
@@ -766,58 +766,58 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
|
|
|
}
|
|
|
|
|
|
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR_QUIT)
|
|
|
{
|
|
|
ClientID client_id = (ClientID)p->Recv_uint32();
|
|
|
|
|
|
NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(client_id);
|
|
|
if (ci != NULL) {
|
|
|
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, NULL, GetNetworkErrorMsg((NetworkErrorCode)p->Recv_uint8()));
|
|
|
delete ci;
|
|
|
}
|
|
|
|
|
|
InvalidateWindow(WC_CLIENT_LIST, 0);
|
|
|
SetWindowDirty(WC_CLIENT_LIST, 0);
|
|
|
|
|
|
return NETWORK_RECV_STATUS_OKAY;
|
|
|
}
|
|
|
|
|
|
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_QUIT)
|
|
|
{
|
|
|
NetworkClientInfo *ci;
|
|
|
|
|
|
ClientID client_id = (ClientID)p->Recv_uint32();
|
|
|
|
|
|
ci = NetworkFindClientInfoFromClientID(client_id);
|
|
|
if (ci != NULL) {
|
|
|
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, NULL, STR_NETWORK_MESSAGE_CLIENT_LEAVING);
|
|
|
delete ci;
|
|
|
} else {
|
|
|
DEBUG(net, 0, "Unknown client (%d) is leaving the game", client_id);
|
|
|
}
|
|
|
|
|
|
InvalidateWindow(WC_CLIENT_LIST, 0);
|
|
|
SetWindowDirty(WC_CLIENT_LIST, 0);
|
|
|
|
|
|
/* If we come here it means we could not locate the client.. strange :s */
|
|
|
return NETWORK_RECV_STATUS_OKAY;
|
|
|
}
|
|
|
|
|
|
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_JOIN)
|
|
|
{
|
|
|
ClientID client_id = (ClientID)p->Recv_uint32();
|
|
|
|
|
|
NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(client_id);
|
|
|
if (ci != NULL)
|
|
|
NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, ci->client_name);
|
|
|
|
|
|
InvalidateWindow(WC_CLIENT_LIST, 0);
|
|
|
SetWindowDirty(WC_CLIENT_LIST, 0);
|
|
|
|
|
|
return NETWORK_RECV_STATUS_OKAY;
|
|
|
}
|
|
|
|
|
|
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_SHUTDOWN)
|
|
|
{
|
|
|
_switch_mode_errorstr = STR_NETWORK_MESSAGE_SERVER_SHUTDOWN;
|
|
|
|
|
|
return NETWORK_RECV_STATUS_SERVER_ERROR;
|
|
|
}
|
|
|
|
|
|
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEWGAME)
|
|
@@ -872,25 +872,25 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
|
|
|
|
|
|
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CONFIG_UPDATE)
|
|
|
{
|
|
|
_network_server_max_companies = p->Recv_uint8();
|
|
|
_network_server_max_spectators = p->Recv_uint8();
|
|
|
|
|
|
return NETWORK_RECV_STATUS_OKAY;
|
|
|
}
|
|
|
|
|
|
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_COMPANY_UPDATE)
|
|
|
{
|
|
|
_network_company_passworded = p->Recv_uint16();
|
|
|
InvalidateWindowClasses(WC_COMPANY);
|
|
|
SetWindowClassesDirty(WC_COMPANY);
|
|
|
|
|
|
return NETWORK_RECV_STATUS_OKAY;
|
|
|
}
|
|
|
|
|
|
|
|
|
/* The layout for the receive-functions by the client */
|
|
|
typedef NetworkRecvStatus NetworkClientPacket(Packet *p);
|
|
|
|
|
|
/* This array matches PacketType. At an incoming
|
|
|
* packet it is matches against this array
|
|
|
* and that way the right function to handle that
|
|
|
* packet is found. */
|