14 #include "../stdafx.h"
15 #include "../strings_func.h"
16 #include "../date_func.h"
21 #include "../console_func.h"
22 #include "../company_base.h"
23 #include "../command_func.h"
24 #include "../saveload/saveload.h"
25 #include "../saveload/saveload_filter.h"
26 #include "../station_base.h"
27 #include "../genworld.h"
28 #include "../company_func.h"
29 #include "../company_gui.h"
30 #include "../roadveh.h"
31 #include "../order_backup.h"
32 #include "../core/pool_func.hpp"
33 #include "../core/random_func.hpp"
36 #include "../safeguards.h"
59 ServerNetworkGameSocketHandler *
cs;
69 PacketWriter(ServerNetworkGameSocketHandler *cs) : SaveFilter(NULL), cs(cs), current(NULL), total_size(0), packets(NULL)
79 if (this->cs != NULL && this->mutex != NULL) {
85 while (this->packets != NULL) {
93 if (this->mutex != NULL) this->mutex->
EndCritical();
115 if (this->mutex != NULL) this->mutex->
SendSignal();
117 if (this->mutex != NULL) this->mutex->
EndCritical();
135 return this->packets != NULL;
145 Packet *p = this->packets;
146 this->packets = p->
next;
149 if (this->mutex != NULL) this->mutex->
EndCritical();
157 if (this->current == NULL)
return;
159 Packet **p = &this->packets;
165 this->current = NULL;
168 void Write(byte *buf,
size_t size)
171 if (this->cs == NULL)
SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
177 byte *bufe = buf + size;
178 while (buf != bufe) {
180 memcpy(this->current->
buffer + this->current->size, buf, to_write);
190 if (this->mutex != NULL) this->mutex->
EndCritical();
192 this->total_size += size;
198 if (this->cs == NULL)
SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
212 this->cs->NetworkTCPSocketHandler::SendPacket(p);
214 if (this->mutex != NULL) this->mutex->
EndCritical();
272 if (this->
sock == INVALID_SOCKET)
return status;
277 NetworkClientSocket *new_cs;
281 NetworkTextMessage(NETWORK_ACTION_LEAVE,
CC_DEFAULT,
false, client_name, NULL, STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST);
286 new_cs->SendErrorQuit(this->
client_id, NETWORK_ERROR_CONNECTION_LOST);
297 _network_clients_connected--;
329 NetworkClientSocket *cs;
373 NetworkClientSocket *csi;
374 memset(clients, 0,
sizeof(clients));
402 FOR_ALL_COMPANIES(company) {
440 GetString(str, strid,
lastof(str));
444 NetworkClientSocket *new_cs;
449 DEBUG(net, 1,
"'%s' made an error and has been disconnected. Reason: '%s'", client_name, str);
451 NetworkTextMessage(NETWORK_ACTION_LEAVE,
CC_DEFAULT,
false, client_name, NULL, strid);
457 if (error == NETWORK_ERROR_NOT_AUTHORIZED || error == NETWORK_ERROR_NOT_EXPECTED || error == NETWORK_ERROR_WRONG_REVISION) {
458 error = NETWORK_ERROR_ILLEGAL_PACKET;
460 new_cs->SendErrorQuit(this->
client_id, error);
466 DEBUG(net, 1,
"Client %d made an error and has been disconnected. Reason: '%s'", this->
client_id, str);
529 NetworkClientSocket *new_cs;
560 NetworkClientSocket *new_cs;
578 static uint sent_packets;
582 return this->
SendError(NETWORK_ERROR_NOT_AUTHORIZED);
607 bool has_packets =
false;
609 for (uint i = 0; (has_packets = this->
savegame->
HasPackets()) && i < sent_packets; i++) {
631 NetworkClientSocket *new_cs;
632 NetworkClientSocket *best = NULL;
635 if (best == NULL || best->GetInfo()->join_date > new_cs->GetInfo()->join_date || (best->GetInfo()->join_date == new_cs->GetInfo()->join_date && best->client_id > new_cs->client_id)) {
660 if (has_packets) sent_packets *= 2;
669 if (sent_packets > 1) sent_packets /= 2;
696 #ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
698 #ifdef NETWORK_SEND_DOUBLE_SEED
705 this->
last_token = InteractiveRandomRange(UINT8_MAX - 1) + 1;
720 #ifdef NETWORK_SEND_DOUBLE_SEED
878 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
899 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
907 p->
Recv_string(client_revision,
sizeof(client_revision));
913 return this->
SendError(NETWORK_ERROR_WRONG_REVISION);
926 return this->
SendError(NETWORK_ERROR_FULL);
931 return this->
SendError(NETWORK_ERROR_FULL);
936 return this->
SendError(NETWORK_ERROR_COMPANY_MISMATCH);
946 return this->
SendError(NETWORK_ERROR_NAME_IN_USE);
974 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
984 return this->
SendError(NETWORK_ERROR_WRONG_PASSWORD);
999 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1012 return this->
SendError(NETWORK_ERROR_WRONG_PASSWORD);
1020 NetworkClientSocket *new_cs;
1023 if (this->status < STATUS_AUTHORIZED || this->
HasClientQuit()) {
1024 return this->
SendError(NETWORK_ERROR_NOT_AUTHORIZED);
1045 NetworkClientSocket *new_cs;
1049 NetworkTextMessage(NETWORK_ACTION_JOIN,
CC_DEFAULT,
false, client_name, NULL, this->
client_id);
1065 new_cs->SendClientInfo(this->
GetInfo());
1080 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1091 if (this->status < STATUS_DONE_MAP || this->
HasClientQuit()) {
1092 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1096 return this->
SendError(NETWORK_ERROR_TOO_MANY_COMMANDS);
1108 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1114 return this->
SendError(NETWORK_ERROR_KICKED);
1119 return this->
SendError(NETWORK_ERROR_KICKED);
1128 IConsolePrintF(
CC_ERROR,
"WARNING: client %d (IP: %s) tried to execute a command as company %d, kicking...",
1130 return this->
SendError(NETWORK_ERROR_COMPANY_MISMATCH);
1135 return this->
SendError(NETWORK_ERROR_CHEATER);
1155 NetworkClientSocket *new_cs;
1161 if (this->status < STATUS_DONE_MAP || this->
HasClientQuit()) {
1168 GetString(str, strid,
lastof(str));
1170 DEBUG(net, 2,
"'%s' reported an error and is closing its connection (%s)", client_name, str);
1172 NetworkTextMessage(NETWORK_ACTION_LEAVE,
CC_DEFAULT,
false, client_name, NULL, strid);
1176 new_cs->SendErrorQuit(this->
client_id, errorno);
1189 NetworkClientSocket *new_cs;
1193 if (this->status < STATUS_DONE_MAP || this->
HasClientQuit()) {
1199 NetworkTextMessage(NETWORK_ACTION_LEAVE,
CC_DEFAULT,
false, client_name, NULL, STR_NETWORK_MESSAGE_CLIENT_LEAVING);
1216 return this->
SendError(NETWORK_ERROR_NOT_AUTHORIZED);
1270 NetworkClientSocket *cs;
1289 if (cs->client_id == (
ClientID)dest) {
1290 cs->SendChat(action, from_id,
false, msg, data);
1301 if (ci != NULL && ci_to != NULL) {
1306 if (cs->client_id == from_id) {
1307 cs->SendChat(action, (
ClientID)dest,
true, msg, data);
1316 bool show_local =
true;
1322 cs->SendChat(action, from_id,
false, msg, data);
1323 if (cs->client_id == from_id) show_local =
false;
1335 if (ci != NULL && ci_own != NULL && ci_own->
client_playas == dest) {
1342 if (ci_to == NULL)
break;
1345 if (ci != NULL && show_local) {
1350 GetString(name, str,
lastof(name));
1354 if (cs->client_id == from_id) {
1355 cs->SendChat(action, ci_to->
client_id,
true, msg, data);
1363 DEBUG(net, 0,
"[server] received unknown chat destination type %d. Doing broadcast instead", desttype);
1367 cs->SendChat(action, from_id,
false, msg, data);
1384 return this->
SendError(NETWORK_ERROR_NOT_AUTHORIZED);
1397 case NETWORK_ACTION_GIVE_MONEY:
1400 case NETWORK_ACTION_CHAT:
1401 case NETWORK_ACTION_CHAT_CLIENT:
1402 case NETWORK_ACTION_CHAT_COMPANY:
1407 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1416 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1433 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1468 DEBUG(net, 0,
"[rcon] wrong password from client-id %d", this->
client_id);
1472 DEBUG(net, 0,
"[rcon] client-id %d executed: '%s'", this->
client_id, command);
1497 DEBUG(net, 2,
"[move] wrong password from client-id #%d for company #%d", this->
client_id, company_id + 1);
1520 assert(max_len <=
lengthof(company_name));
1521 GetString(company_name, STR_COMPANY_NAME, company_name + max_len - 1);
1548 for (uint i = 0; i < NETWORK_VEH_END; i++) {
1552 for (uint i = 0; i < NETWORK_VEH_END; i++) {
1575 case VEH_TRAIN: type = NETWORK_VEH_TRAIN;
break;
1578 case VEH_SHIP: type = NETWORK_VEH_SHIP;
break;
1585 FOR_ALL_STATIONS(s) {
1604 NetworkClientSocket *cs;
1607 if (ci == NULL)
return;
1612 cs->SendClientInfo(ci);
1622 DEBUG(net, 0,
"Auto-restarting map. Year %d reached",
_cur_year);
1643 memset(clients_in_company, 0,
sizeof(clients_in_company));
1656 memset(vehicles_in_company, 0,
sizeof(vehicles_in_company));
1661 vehicles_in_company[v->
owner]++;
1666 FOR_ALL_COMPANIES(c) {
1668 if (c->
is_ai)
continue;
1670 if (!clients_in_company[c->
index]) {
1709 bool found_name =
false;
1715 while (!found_name) {
1729 if (strcmp(ci->
client_name, new_name) == 0) found_name =
false;
1737 seprintf(new_name, last,
"%s #%d", original_name, number);
1755 if (strcmp(ci->
client_name, new_name) == 0)
return false;
1759 if (ci == NULL)
return false;
1779 if (!already_hashed) {
1794 while ((cp = cs->outgoing_queue.Pop()) != NULL) {
1795 cs->SendCommand(cp);
1806 NetworkClientSocket *cs;
1807 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
1808 bool send_sync =
false;
1811 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
1827 uint lag = NetworkCalculateLag(cs);
1828 switch (cs->status) {
1829 case NetworkClientSocket::STATUS_ACTIVE:
1834 "Client #%d is dropped because the client's game state is more than %d ticks behind" :
1836 "Client #%d is dropped because the client did not respond for more than %d ticks",
1837 cs->client_id, lag);
1838 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
1855 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
1860 case NetworkClientSocket::STATUS_INACTIVE:
1861 case NetworkClientSocket::STATUS_NEWGRFS_CHECK:
1862 case NetworkClientSocket::STATUS_AUTHORIZED:
1867 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
1872 case NetworkClientSocket::STATUS_MAP:
1876 cs->SendError(NETWORK_ERROR_TIMEOUT_MAP);
1881 case NetworkClientSocket::STATUS_DONE_MAP:
1882 case NetworkClientSocket::STATUS_PRE_ACTIVE:
1886 cs->SendError(NETWORK_ERROR_TIMEOUT_JOIN);
1891 case NetworkClientSocket::STATUS_AUTH_GAME:
1892 case NetworkClientSocket::STATUS_AUTH_COMPANY:
1896 cs->SendError(NETWORK_ERROR_TIMEOUT_PASSWORD);
1901 case NetworkClientSocket::STATUS_MAP_WAIT:
1906 case NetworkClientSocket::STATUS_END:
1911 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) {
1916 if (send_frame) cs->SendFrame();
1918 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
1920 if (send_sync) cs->SendSync();
1963 static const char *
const stat_str[] = {
1966 "authorizing (server password)",
1967 "authorizing (company password)",
1975 assert_compile(
lengthof(stat_str) == NetworkClientSocket::STATUS_END);
1977 NetworkClientSocket *cs;
1980 if (ci == NULL)
continue;
1981 uint lag = NetworkCalculateLag(cs);
1984 status = (cs->status < (ptrdiff_t)
lengthof(stat_str) ? stat_str[cs->status] :
"unknown");
1997 NetworkClientSocket *cs;
2000 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendConfigUpdate();
2016 NetworkClientSocket *cs;
2018 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendCompanyUpdate();
2045 NetworkClientSocket *cs = NetworkClientSocket::GetByClientID(client_id);
2047 if (cs->status < NetworkClientSocket::STATUS_AUTHORIZED)
return;
2048 cs->SendMove(client_id, company_id);
2066 NetworkClientSocket::GetByClientID(client_id)->SendRConResult(colour_code,
string);
2076 NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED);
2098 bool contains =
false;
2100 if (strcmp(*iter, ip) == 0) {
2111 NetworkClientSocket *cs;
2114 if (cs->client_address.IsInNetmask(const_cast<char *>(ip))) {