00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifdef ENABLE_NETWORK
00013
00014 #include "../stdafx.h"
00015 #include "../strings_func.h"
00016 #include "../date_func.h"
00017 #include "network_admin.h"
00018 #include "network_server.h"
00019 #include "network_udp.h"
00020 #include "network_base.h"
00021 #include "../console_func.h"
00022 #include "../company_base.h"
00023 #include "../command_func.h"
00024 #include "../saveload/saveload.h"
00025 #include "../saveload/saveload_filter.h"
00026 #include "../station_base.h"
00027 #include "../genworld.h"
00028 #include "../company_func.h"
00029 #include "../company_gui.h"
00030 #include "../roadveh.h"
00031 #include "../order_backup.h"
00032 #include "../core/pool_func.hpp"
00033 #include "../core/random_func.hpp"
00034 #include "../rev.h"
00035
00036
00037
00038
00039 DECLARE_POSTFIX_INCREMENT(ClientID)
00041 static ClientID _network_client_id = CLIENT_ID_FIRST;
00042
00044 assert_compile(MAX_CLIENT_SLOTS > MAX_CLIENTS);
00046 assert_compile(NetworkClientSocketPool::MAX_SIZE == MAX_CLIENT_SLOTS);
00047
00049 NetworkClientSocketPool _networkclientsocket_pool("NetworkClientSocket");
00050 INSTANTIATE_POOL_METHODS(NetworkClientSocket)
00051
00053 template SocketList TCPListenHandler<ServerNetworkGameSocketHandler, PACKET_SERVER_FULL, PACKET_SERVER_BANNED>::sockets;
00054
00056 struct PacketWriter : SaveFilter {
00057 ServerNetworkGameSocketHandler *cs;
00058 Packet *current;
00059 size_t total_size;
00060
00065 PacketWriter(ServerNetworkGameSocketHandler *cs) : SaveFilter(NULL), cs(cs), current(NULL), total_size(0)
00066 {
00067 this->cs->savegame_mutex = ThreadMutex::New();
00068 }
00069
00071 ~PacketWriter()
00072 {
00073
00074 if (this->cs != NULL) {
00075 if (this->cs->savegame_mutex != NULL) this->cs->savegame_mutex->BeginCritical();
00076 this->cs->savegame = NULL;
00077 if (this->cs->savegame_mutex != NULL) this->cs->savegame_mutex->EndCritical();
00078
00079 delete this->cs->savegame_mutex;
00080 this->cs->savegame_mutex = NULL;
00081 }
00082
00083 delete this->current;
00084 }
00085
00087 void AppendQueue()
00088 {
00089 if (this->current == NULL) return;
00090
00091 Packet **p = &this->cs->savegame_packets;
00092 while (*p != NULL) {
00093 p = &(*p)->next;
00094 }
00095 *p = this->current;
00096
00097 this->current = NULL;
00098 }
00099
00100 void Write(byte *buf, size_t size)
00101 {
00102
00103 if (this->cs == NULL) SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
00104
00105 if (this->current == NULL) this->current = new Packet(PACKET_SERVER_MAP_DATA);
00106
00107 if (this->cs->savegame_mutex != NULL) this->cs->savegame_mutex->BeginCritical();
00108
00109 byte *bufe = buf + size;
00110 while (buf != bufe) {
00111 size_t to_write = min(SEND_MTU - this->current->size, bufe - buf);
00112 memcpy(this->current->buffer + this->current->size, buf, to_write);
00113 this->current->size += (PacketSize)to_write;
00114 buf += to_write;
00115
00116 if (this->current->size == SEND_MTU) {
00117 this->AppendQueue();
00118 if (buf != bufe) this->current = new Packet(PACKET_SERVER_MAP_DATA);
00119 }
00120 }
00121
00122 if (this->cs->savegame_mutex != NULL) this->cs->savegame_mutex->EndCritical();
00123
00124 this->total_size += size;
00125 }
00126
00127 void Finish()
00128 {
00129
00130 if (this->cs == NULL) SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
00131
00132 if (this->cs->savegame_mutex != NULL) this->cs->savegame_mutex->BeginCritical();
00133
00134
00135 this->AppendQueue();
00136
00137
00138 this->current = new Packet(PACKET_SERVER_MAP_DONE);
00139 this->AppendQueue();
00140
00141
00142 Packet *p = new Packet(PACKET_SERVER_MAP_SIZE);
00143 p->Send_uint32((uint32)this->total_size);
00144 this->cs->NetworkTCPSocketHandler::SendPacket(p);
00145
00146 if (this->cs->savegame_mutex != NULL) this->cs->savegame_mutex->EndCritical();
00147 }
00148 };
00149
00150
00155 ServerNetworkGameSocketHandler::ServerNetworkGameSocketHandler(SOCKET s) : NetworkGameSocketHandler(s)
00156 {
00157 this->status = STATUS_INACTIVE;
00158 this->client_id = _network_client_id++;
00159 this->receive_limit = _settings_client.network.bytes_per_frame_burst;
00160
00161
00162
00163
00164 assert_compile(NetworkClientSocketPool::MAX_SIZE == NetworkClientInfoPool::MAX_SIZE);
00165 }
00166
00170 ServerNetworkGameSocketHandler::~ServerNetworkGameSocketHandler()
00171 {
00172 if (_redirect_console_to_client == this->client_id) _redirect_console_to_client = INVALID_CLIENT_ID;
00173 OrderBackup::ResetUser(this->client_id);
00174
00175 if (this->savegame_mutex != NULL) this->savegame_mutex->BeginCritical();
00176 if (this->savegame != NULL) this->savegame->cs = NULL;
00177 if (this->savegame_mutex != NULL) this->savegame_mutex->EndCritical();
00178
00179
00180
00181
00182
00183 WaitTillSaved();
00184 ProcessAsyncSaveFinish();
00185
00186 while (this->savegame_packets != NULL) {
00187 Packet *p = this->savegame_packets->next;
00188 delete this->savegame_packets;
00189 this->savegame_packets = p;
00190 }
00191
00192 delete this->savegame_mutex;
00193 }
00194
00195 Packet *ServerNetworkGameSocketHandler::ReceivePacket()
00196 {
00197
00198
00199 if (this->receive_limit <= 0) return NULL;
00200
00201
00202
00203 Packet *p = this->NetworkTCPSocketHandler::ReceivePacket();
00204 if (p != NULL) this->receive_limit -= p->size;
00205 return p;
00206 }
00207
00208 void ServerNetworkGameSocketHandler::SendPacket(Packet *packet)
00209 {
00210 if (this->savegame_mutex != NULL) this->savegame_mutex->BeginCritical();
00211 this->NetworkTCPSocketHandler::SendPacket(packet);
00212 if (this->savegame_mutex != NULL) this->savegame_mutex->EndCritical();
00213 }
00214
00215 NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvStatus status)
00216 {
00217 assert(status != NETWORK_RECV_STATUS_OKAY);
00218
00219
00220
00221
00222
00223
00224
00225 if (this->sock == INVALID_SOCKET) return status;
00226
00227 if (status != NETWORK_RECV_STATUS_CONN_LOST && !this->HasClientQuit() && this->status >= STATUS_AUTHORIZED) {
00228
00229 char client_name[NETWORK_CLIENT_NAME_LENGTH];
00230 NetworkClientSocket *new_cs;
00231
00232 this->GetClientName(client_name, sizeof(client_name));
00233
00234 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST);
00235
00236
00237 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00238 if (new_cs->status > STATUS_AUTHORIZED && this != new_cs) {
00239 new_cs->SendErrorQuit(this->client_id, NETWORK_ERROR_CONNECTION_LOST);
00240 }
00241 }
00242 }
00243
00244 NetworkAdminClientError(this->client_id, NETWORK_ERROR_CONNECTION_LOST);
00245 DEBUG(net, 1, "Closed client connection %d", this->client_id);
00246
00247
00248 if (this->status >= STATUS_AUTHORIZED) _network_game_info.clients_on--;
00249 extern byte _network_clients_connected;
00250 _network_clients_connected--;
00251
00252 DeleteWindowById(WC_CLIENT_LIST_POPUP, this->client_id);
00253 SetWindowDirty(WC_CLIENT_LIST, 0);
00254
00255 this->SendPackets(true);
00256
00257 delete this->GetInfo();
00258 delete this;
00259
00260 return status;
00261 }
00262
00267 bool ServerNetworkGameSocketHandler::AllowConnection()
00268 {
00269 extern byte _network_clients_connected;
00270 bool accept = _network_clients_connected < MAX_CLIENTS && _network_game_info.clients_on < _settings_client.network.max_clients;
00271
00272
00273
00274 assert_compile(NetworkClientSocketPool::MAX_SIZE == MAX_CLIENTS + 1);
00275 assert(!accept || ServerNetworkGameSocketHandler::CanAllocateItem());
00276 return accept;
00277 }
00278
00280 void ServerNetworkGameSocketHandler::Send()
00281 {
00282 NetworkClientSocket *cs;
00283 FOR_ALL_CLIENT_SOCKETS(cs) {
00284 if (cs->writable) {
00285 if (cs->SendPackets() != SPS_CLOSED && cs->status == STATUS_MAP) {
00286
00287 cs->SendMap();
00288 }
00289 }
00290 }
00291 }
00292
00293 static void NetworkHandleCommandQueue(NetworkClientSocket *cs);
00294
00295
00296
00297
00298
00299
00304 NetworkRecvStatus ServerNetworkGameSocketHandler::SendClientInfo(NetworkClientInfo *ci)
00305 {
00306 if (ci->client_id != INVALID_CLIENT_ID) {
00307 Packet *p = new Packet(PACKET_SERVER_CLIENT_INFO);
00308 p->Send_uint32(ci->client_id);
00309 p->Send_uint8 (ci->client_playas);
00310 p->Send_string(ci->client_name);
00311
00312 this->SendPacket(p);
00313 }
00314 return NETWORK_RECV_STATUS_OKAY;
00315 }
00316
00318 NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo()
00319 {
00320
00321 NetworkCompanyStats company_stats[MAX_COMPANIES];
00322 NetworkPopulateCompanyStats(company_stats);
00323
00324
00325 char clients[MAX_COMPANIES][NETWORK_CLIENTS_LENGTH];
00326 NetworkClientSocket *csi;
00327 memset(clients, 0, sizeof(clients));
00328
00329
00330 const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
00331 if (ci != NULL && Company::IsValidID(ci->client_playas)) {
00332 strecpy(clients[ci->client_playas], ci->client_name, lastof(clients[ci->client_playas]));
00333 }
00334
00335 FOR_ALL_CLIENT_SOCKETS(csi) {
00336 char client_name[NETWORK_CLIENT_NAME_LENGTH];
00337
00338 ((ServerNetworkGameSocketHandler*)csi)->GetClientName(client_name, sizeof(client_name));
00339
00340 ci = csi->GetInfo();
00341 if (ci != NULL && Company::IsValidID(ci->client_playas)) {
00342 if (!StrEmpty(clients[ci->client_playas])) {
00343 strecat(clients[ci->client_playas], ", ", lastof(clients[ci->client_playas]));
00344 }
00345
00346 strecat(clients[ci->client_playas], client_name, lastof(clients[ci->client_playas]));
00347 }
00348 }
00349
00350
00351
00352 Company *company;
00353 Packet *p;
00354
00355 FOR_ALL_COMPANIES(company) {
00356 p = new Packet(PACKET_SERVER_COMPANY_INFO);
00357
00358 p->Send_uint8 (NETWORK_COMPANY_INFO_VERSION);
00359 p->Send_bool (true);
00360 this->SendCompanyInformation(p, company, &company_stats[company->index]);
00361
00362 if (StrEmpty(clients[company->index])) {
00363 p->Send_string("<none>");
00364 } else {
00365 p->Send_string(clients[company->index]);
00366 }
00367
00368 this->SendPacket(p);
00369 }
00370
00371 p = new Packet(PACKET_SERVER_COMPANY_INFO);
00372
00373 p->Send_uint8 (NETWORK_COMPANY_INFO_VERSION);
00374 p->Send_bool (false);
00375
00376 this->SendPacket(p);
00377 return NETWORK_RECV_STATUS_OKAY;
00378 }
00379
00384 NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error)
00385 {
00386 char str[100];
00387 Packet *p = new Packet(PACKET_SERVER_ERROR);
00388
00389 p->Send_uint8(error);
00390 this->SendPacket(p);
00391
00392 StringID strid = GetNetworkErrorMsg(error);
00393 GetString(str, strid, lastof(str));
00394
00395
00396 if (this->status > STATUS_AUTHORIZED) {
00397 NetworkClientSocket *new_cs;
00398 char client_name[NETWORK_CLIENT_NAME_LENGTH];
00399
00400 this->GetClientName(client_name, sizeof(client_name));
00401
00402 DEBUG(net, 1, "'%s' made an error and has been disconnected. Reason: '%s'", client_name, str);
00403
00404 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, strid);
00405
00406 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00407 if (new_cs->status > STATUS_AUTHORIZED && new_cs != this) {
00408
00409
00410 if (error == NETWORK_ERROR_NOT_AUTHORIZED || error == NETWORK_ERROR_NOT_EXPECTED || error == NETWORK_ERROR_WRONG_REVISION) {
00411 error = NETWORK_ERROR_ILLEGAL_PACKET;
00412 }
00413 new_cs->SendErrorQuit(this->client_id, error);
00414 }
00415 }
00416
00417 NetworkAdminClientError(this->client_id, error);
00418 } else {
00419 DEBUG(net, 1, "Client %d made an error and has been disconnected. Reason: '%s'", this->client_id, str);
00420 }
00421
00422
00423 return this->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
00424 }
00425
00427 NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck()
00428 {
00429 Packet *p = new Packet(PACKET_SERVER_CHECK_NEWGRFS);
00430 const GRFConfig *c;
00431 uint grf_count = 0;
00432
00433 for (c = _grfconfig; c != NULL; c = c->next) {
00434 if (!HasBit(c->flags, GCF_STATIC)) grf_count++;
00435 }
00436
00437 p->Send_uint8 (grf_count);
00438 for (c = _grfconfig; c != NULL; c = c->next) {
00439 if (!HasBit(c->flags, GCF_STATIC)) this->SendGRFIdentifier(p, &c->ident);
00440 }
00441
00442 this->SendPacket(p);
00443 return NETWORK_RECV_STATUS_OKAY;
00444 }
00445
00447 NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedGamePassword()
00448 {
00449
00450 if (this->status >= STATUS_AUTH_GAME) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
00451
00452 this->status = STATUS_AUTH_GAME;
00453
00454 Packet *p = new Packet(PACKET_SERVER_NEED_GAME_PASSWORD);
00455 this->SendPacket(p);
00456 return NETWORK_RECV_STATUS_OKAY;
00457 }
00458
00460 NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedCompanyPassword()
00461 {
00462
00463 if (this->status >= STATUS_AUTH_COMPANY) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
00464
00465 this->status = STATUS_AUTH_COMPANY;
00466
00467 Packet *p = new Packet(PACKET_SERVER_NEED_COMPANY_PASSWORD);
00468 p->Send_uint32(_settings_game.game_creation.generation_seed);
00469 p->Send_string(_settings_client.network.network_id);
00470 this->SendPacket(p);
00471 return NETWORK_RECV_STATUS_OKAY;
00472 }
00473
00475 NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome()
00476 {
00477 Packet *p;
00478 NetworkClientSocket *new_cs;
00479
00480
00481 if (this->status >= STATUS_AUTHORIZED) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
00482
00483 this->status = STATUS_AUTHORIZED;
00484 _network_game_info.clients_on++;
00485
00486 p = new Packet(PACKET_SERVER_WELCOME);
00487 p->Send_uint32(this->client_id);
00488 p->Send_uint32(_settings_game.game_creation.generation_seed);
00489 p->Send_string(_settings_client.network.network_id);
00490 this->SendPacket(p);
00491
00492
00493 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00494 if (new_cs != this && new_cs->status > STATUS_AUTHORIZED) {
00495 this->SendClientInfo(new_cs->GetInfo());
00496 }
00497 }
00498
00499 return this->SendClientInfo(NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER));
00500 }
00501
00503 NetworkRecvStatus ServerNetworkGameSocketHandler::SendWait()
00504 {
00505 int waiting = 0;
00506 NetworkClientSocket *new_cs;
00507 Packet *p;
00508
00509
00510 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00511 if (new_cs->status != STATUS_MAP_WAIT) continue;
00512 if (new_cs->GetInfo()->join_date < this->GetInfo()->join_date || (new_cs->GetInfo()->join_date == this->GetInfo()->join_date && new_cs->client_id < this->client_id)) waiting++;
00513 }
00514
00515 p = new Packet(PACKET_SERVER_WAIT);
00516 p->Send_uint8(waiting);
00517 this->SendPacket(p);
00518 return NETWORK_RECV_STATUS_OKAY;
00519 }
00520
00522 NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
00523 {
00524 static uint sent_packets;
00525
00526 if (this->status < STATUS_AUTHORIZED) {
00527
00528 return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
00529 }
00530
00531 if (this->status == STATUS_AUTHORIZED) {
00532 this->savegame = new PacketWriter(this);
00533
00534
00535 Packet *p = new Packet(PACKET_SERVER_MAP_BEGIN);
00536 p->Send_uint32(_frame_counter);
00537 this->SendPacket(p);
00538
00539 NetworkSyncCommandQueue(this);
00540 this->status = STATUS_MAP;
00541
00542 this->last_frame = _frame_counter;
00543 this->last_frame_server = _frame_counter;
00544
00545 sent_packets = 4;
00546
00547
00548 if (SaveWithFilter(this->savegame, true) != SL_OK) usererror("network savedump failed");
00549 }
00550
00551 if (this->status == STATUS_MAP) {
00552 if (this->savegame_mutex != NULL) this->savegame_mutex->BeginCritical();
00553
00554 bool last_packet = false;
00555
00556 for (uint i = 0; i < sent_packets && this->savegame_packets != NULL; i++) {
00557 Packet *p = this->savegame_packets;
00558 last_packet = p->buffer[2] == PACKET_SERVER_MAP_DONE;
00559
00560
00561 this->savegame_packets = p->next;
00562 p->next = NULL;
00563 this->NetworkTCPSocketHandler::SendPacket(p);
00564
00565 if (last_packet) {
00566
00567 break;
00568 }
00569 }
00570
00571 if (this->savegame_mutex != NULL) this->savegame_mutex->EndCritical();
00572
00573 if (last_packet) {
00574
00575 WaitTillSaved();
00576
00577
00578
00579 this->status = STATUS_DONE_MAP;
00580
00581
00582 NetworkClientSocket *new_cs;
00583 NetworkClientSocket *best = NULL;
00584 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00585 if (new_cs->status == STATUS_MAP_WAIT) {
00586 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)) {
00587 best = new_cs;
00588 }
00589 }
00590 }
00591
00592
00593 if (best != NULL) {
00594
00595 best->status = STATUS_AUTHORIZED;
00596 best->SendMap();
00597
00598
00599 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00600 if (new_cs->status == STATUS_MAP_WAIT) new_cs->SendWait();
00601 }
00602 }
00603 }
00604
00605 switch (this->SendPackets()) {
00606 case SPS_CLOSED:
00607 return NETWORK_RECV_STATUS_CONN_LOST;
00608
00609 case SPS_ALL_SENT:
00610
00611 if (this->savegame_packets != NULL) sent_packets *= 2;
00612 break;
00613
00614 case SPS_PARTLY_SENT:
00615
00616 break;
00617
00618 case SPS_NONE_SENT:
00619
00620 if (sent_packets > 1) sent_packets /= 2;
00621 break;
00622 }
00623 }
00624 return NETWORK_RECV_STATUS_OKAY;
00625 }
00626
00631 NetworkRecvStatus ServerNetworkGameSocketHandler::SendJoin(ClientID client_id)
00632 {
00633 Packet *p = new Packet(PACKET_SERVER_JOIN);
00634
00635 p->Send_uint32(client_id);
00636
00637 this->SendPacket(p);
00638 return NETWORK_RECV_STATUS_OKAY;
00639 }
00640
00642 NetworkRecvStatus ServerNetworkGameSocketHandler::SendFrame()
00643 {
00644 Packet *p = new Packet(PACKET_SERVER_FRAME);
00645 p->Send_uint32(_frame_counter);
00646 p->Send_uint32(_frame_counter_max);
00647 #ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
00648 p->Send_uint32(_sync_seed_1);
00649 #ifdef NETWORK_SEND_DOUBLE_SEED
00650 p->Send_uint32(_sync_seed_2);
00651 #endif
00652 #endif
00653
00654
00655 if (this->last_token == 0) {
00656 this->last_token = InteractiveRandomRange(UINT8_MAX - 1) + 1;
00657 p->Send_uint8(this->last_token);
00658 }
00659
00660 this->SendPacket(p);
00661 return NETWORK_RECV_STATUS_OKAY;
00662 }
00663
00665 NetworkRecvStatus ServerNetworkGameSocketHandler::SendSync()
00666 {
00667 Packet *p = new Packet(PACKET_SERVER_SYNC);
00668 p->Send_uint32(_frame_counter);
00669 p->Send_uint32(_sync_seed_1);
00670
00671 #ifdef NETWORK_SEND_DOUBLE_SEED
00672 p->Send_uint32(_sync_seed_2);
00673 #endif
00674 this->SendPacket(p);
00675 return NETWORK_RECV_STATUS_OKAY;
00676 }
00677
00682 NetworkRecvStatus ServerNetworkGameSocketHandler::SendCommand(const CommandPacket *cp)
00683 {
00684 Packet *p = new Packet(PACKET_SERVER_COMMAND);
00685
00686 this->NetworkGameSocketHandler::SendCommand(p, cp);
00687 p->Send_uint32(cp->frame);
00688 p->Send_bool (cp->my_cmd);
00689
00690 this->SendPacket(p);
00691 return NETWORK_RECV_STATUS_OKAY;
00692 }
00693
00702 NetworkRecvStatus ServerNetworkGameSocketHandler::SendChat(NetworkAction action, ClientID client_id, bool self_send, const char *msg, int64 data)
00703 {
00704 if (this->status != STATUS_ACTIVE) return NETWORK_RECV_STATUS_OKAY;
00705
00706 Packet *p = new Packet(PACKET_SERVER_CHAT);
00707
00708 p->Send_uint8 (action);
00709 p->Send_uint32(client_id);
00710 p->Send_bool (self_send);
00711 p->Send_string(msg);
00712 p->Send_uint64(data);
00713
00714 this->SendPacket(p);
00715 return NETWORK_RECV_STATUS_OKAY;
00716 }
00717
00723 NetworkRecvStatus ServerNetworkGameSocketHandler::SendErrorQuit(ClientID client_id, NetworkErrorCode errorno)
00724 {
00725 Packet *p = new Packet(PACKET_SERVER_ERROR_QUIT);
00726
00727 p->Send_uint32(client_id);
00728 p->Send_uint8 (errorno);
00729
00730 this->SendPacket(p);
00731 return NETWORK_RECV_STATUS_OKAY;
00732 }
00733
00738 NetworkRecvStatus ServerNetworkGameSocketHandler::SendQuit(ClientID client_id)
00739 {
00740 Packet *p = new Packet(PACKET_SERVER_QUIT);
00741
00742 p->Send_uint32(client_id);
00743
00744 this->SendPacket(p);
00745 return NETWORK_RECV_STATUS_OKAY;
00746 }
00747
00749 NetworkRecvStatus ServerNetworkGameSocketHandler::SendShutdown()
00750 {
00751 Packet *p = new Packet(PACKET_SERVER_SHUTDOWN);
00752 this->SendPacket(p);
00753 return NETWORK_RECV_STATUS_OKAY;
00754 }
00755
00757 NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGame()
00758 {
00759 Packet *p = new Packet(PACKET_SERVER_NEWGAME);
00760 this->SendPacket(p);
00761 return NETWORK_RECV_STATUS_OKAY;
00762 }
00763
00769 NetworkRecvStatus ServerNetworkGameSocketHandler::SendRConResult(uint16 colour, const char *command)
00770 {
00771 Packet *p = new Packet(PACKET_SERVER_RCON);
00772
00773 p->Send_uint16(colour);
00774 p->Send_string(command);
00775 this->SendPacket(p);
00776 return NETWORK_RECV_STATUS_OKAY;
00777 }
00778
00784 NetworkRecvStatus ServerNetworkGameSocketHandler::SendMove(ClientID client_id, CompanyID company_id)
00785 {
00786 Packet *p = new Packet(PACKET_SERVER_MOVE);
00787
00788 p->Send_uint32(client_id);
00789 p->Send_uint8(company_id);
00790 this->SendPacket(p);
00791 return NETWORK_RECV_STATUS_OKAY;
00792 }
00793
00795 NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyUpdate()
00796 {
00797 Packet *p = new Packet(PACKET_SERVER_COMPANY_UPDATE);
00798
00799 p->Send_uint16(_network_company_passworded);
00800 this->SendPacket(p);
00801 return NETWORK_RECV_STATUS_OKAY;
00802 }
00803
00805 NetworkRecvStatus ServerNetworkGameSocketHandler::SendConfigUpdate()
00806 {
00807 Packet *p = new Packet(PACKET_SERVER_CONFIG_UPDATE);
00808
00809 p->Send_uint8(_settings_client.network.max_companies);
00810 p->Send_uint8(_settings_client.network.max_spectators);
00811 this->SendPacket(p);
00812 return NETWORK_RECV_STATUS_OKAY;
00813 }
00814
00815
00816
00817
00818
00819
00820 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMPANY_INFO(Packet *p)
00821 {
00822 return this->SendCompanyInfo();
00823 }
00824
00825 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_NEWGRFS_CHECKED(Packet *p)
00826 {
00827 if (this->status != STATUS_NEWGRFS_CHECK) {
00828
00829 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00830 }
00831
00832 NetworkClientInfo *ci = this->GetInfo();
00833
00834
00835 if (!StrEmpty(_settings_client.network.server_password)) {
00836 return this->SendNeedGamePassword();
00837 }
00838
00839 if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) {
00840 return this->SendNeedCompanyPassword();
00841 }
00842
00843 return this->SendWelcome();
00844 }
00845
00846 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
00847 {
00848 if (this->status != STATUS_INACTIVE) {
00849
00850 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00851 }
00852
00853 char name[NETWORK_CLIENT_NAME_LENGTH];
00854 CompanyID playas;
00855 NetworkLanguage client_lang;
00856 char client_revision[NETWORK_REVISION_LENGTH];
00857
00858 p->Recv_string(client_revision, sizeof(client_revision));
00859
00860
00861 if (!IsNetworkCompatibleVersion(client_revision)) {
00862
00863 return this->SendError(NETWORK_ERROR_WRONG_REVISION);
00864 }
00865
00866 p->Recv_string(name, sizeof(name));
00867 playas = (Owner)p->Recv_uint8();
00868 client_lang = (NetworkLanguage)p->Recv_uint8();
00869
00870 if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
00871
00872
00873 switch (playas) {
00874 case COMPANY_NEW_COMPANY:
00875 if (Company::GetNumItems() >= _settings_client.network.max_companies) {
00876 return this->SendError(NETWORK_ERROR_FULL);
00877 }
00878 break;
00879 case COMPANY_SPECTATOR:
00880 if (NetworkSpectatorCount() >= _settings_client.network.max_spectators) {
00881 return this->SendError(NETWORK_ERROR_FULL);
00882 }
00883 break;
00884 default:
00885 if (!Company::IsValidHumanID(playas)) {
00886 return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH);
00887 }
00888 break;
00889 }
00890
00891
00892 if (StrEmpty(name)) strecpy(name, "Player", lastof(name));
00893
00894 if (!NetworkFindName(name)) {
00895
00896 return this->SendError(NETWORK_ERROR_NAME_IN_USE);
00897 }
00898
00899 assert(NetworkClientInfo::CanAllocateItem());
00900 NetworkClientInfo *ci = new NetworkClientInfo(this->client_id);
00901 this->SetInfo(ci);
00902 ci->join_date = _date;
00903 strecpy(ci->client_name, name, lastof(ci->client_name));
00904 ci->client_playas = playas;
00905 ci->client_lang = client_lang;
00906 DEBUG(desync, 1, "client: %08x; %02x; %02x; %04x", _date, _date_fract, (int)ci->client_playas, ci->index);
00907
00908
00909 if (Company::IsValidID(playas)) _network_company_states[playas].months_empty = 0;
00910
00911 this->status = STATUS_NEWGRFS_CHECK;
00912
00913 if (_grfconfig == NULL) {
00914
00915 return this->Receive_CLIENT_NEWGRFS_CHECKED(NULL);
00916 }
00917
00918 return this->SendNewGRFCheck();
00919 }
00920
00921 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GAME_PASSWORD(Packet *p)
00922 {
00923 if (this->status != STATUS_AUTH_GAME) {
00924 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00925 }
00926
00927 char password[NETWORK_PASSWORD_LENGTH];
00928 p->Recv_string(password, sizeof(password));
00929
00930
00931 if (!StrEmpty(_settings_client.network.server_password) &&
00932 strcmp(password, _settings_client.network.server_password) != 0) {
00933
00934 return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
00935 }
00936
00937 const NetworkClientInfo *ci = this->GetInfo();
00938 if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) {
00939 return this->SendNeedCompanyPassword();
00940 }
00941
00942
00943 return this->SendWelcome();
00944 }
00945
00946 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMPANY_PASSWORD(Packet *p)
00947 {
00948 if (this->status != STATUS_AUTH_COMPANY) {
00949 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00950 }
00951
00952 char password[NETWORK_PASSWORD_LENGTH];
00953 p->Recv_string(password, sizeof(password));
00954
00955
00956
00957
00958 CompanyID playas = this->GetInfo()->client_playas;
00959 if (Company::IsValidID(playas) && !StrEmpty(_network_company_states[playas].password) &&
00960 strcmp(password, _network_company_states[playas].password) != 0) {
00961
00962 return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
00963 }
00964
00965 return this->SendWelcome();
00966 }
00967
00968 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet *p)
00969 {
00970 NetworkClientSocket *new_cs;
00971
00972
00973
00974
00975
00976
00977
00978
00979 if (IsReleasedVersion()) {
00980 if (_openttd_newgrf_version != p->Recv_uint32()) {
00981
00982
00983 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00984 }
00985 } else if (p->size != 3) {
00986
00987
00988 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00989 }
00990
00991
00992
00993 if (this->status < STATUS_AUTHORIZED || this->HasClientQuit()) {
00994 return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
00995 }
00996
00997
00998 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00999 if (new_cs->status == STATUS_MAP) {
01000
01001 this->status = STATUS_MAP_WAIT;
01002 return this->SendWait();
01003 }
01004 }
01005
01006
01007 return this->SendMap();
01008 }
01009
01010 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MAP_OK(Packet *p)
01011 {
01012
01013 if (this->status == STATUS_DONE_MAP && !this->HasClientQuit()) {
01014 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01015 NetworkClientSocket *new_cs;
01016
01017 this->GetClientName(client_name, sizeof(client_name));
01018
01019 NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, client_name, NULL, this->client_id);
01020
01021
01022
01023 this->status = STATUS_PRE_ACTIVE;
01024 NetworkHandleCommandQueue(this);
01025 this->SendFrame();
01026 this->SendSync();
01027
01028
01029
01030 this->last_frame = _frame_counter;
01031 this->last_frame_server = _frame_counter;
01032
01033 FOR_ALL_CLIENT_SOCKETS(new_cs) {
01034 if (new_cs->status > STATUS_AUTHORIZED) {
01035 new_cs->SendClientInfo(this->GetInfo());
01036 new_cs->SendJoin(this->client_id);
01037 }
01038 }
01039
01040 NetworkAdminClientInfo(this, true);
01041
01042
01043 this->SendConfigUpdate();
01044
01045
01046 return this->SendCompanyUpdate();
01047 }
01048
01049
01050 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01051 }
01052
01057 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet *p)
01058 {
01059
01060
01061 if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
01062 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01063 }
01064
01065 if (this->incoming_queue.Count() >= _settings_client.network.max_commands_in_queue) {
01066 return this->SendError(NETWORK_ERROR_TOO_MANY_COMMANDS);
01067 }
01068
01069 CommandPacket cp;
01070 const char *err = this->ReceiveCommand(p, &cp);
01071
01072 if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
01073
01074 NetworkClientInfo *ci = this->GetInfo();
01075
01076 if (err != NULL) {
01077 IConsolePrintF(CC_ERROR, "WARNING: %s from client %d (IP: %s).", err, ci->client_id, this->GetClientIP());
01078 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01079 }
01080
01081
01082 if ((GetCommandFlags(cp.cmd) & CMD_SERVER) && ci->client_id != CLIENT_ID_SERVER) {
01083 IConsolePrintF(CC_ERROR, "WARNING: server only command from: client %d (IP: %s), kicking...", ci->client_id, this->GetClientIP());
01084 return this->SendError(NETWORK_ERROR_KICKED);
01085 }
01086
01087 if ((GetCommandFlags(cp.cmd) & CMD_SPECTATOR) == 0 && !Company::IsValidID(cp.company) && ci->client_id != CLIENT_ID_SERVER) {
01088 IConsolePrintF(CC_ERROR, "WARNING: spectator issueing command from client %d (IP: %s), kicking...", ci->client_id, this->GetClientIP());
01089 return this->SendError(NETWORK_ERROR_KICKED);
01090 }
01091
01097 if (!(cp.cmd == CMD_COMPANY_CTRL && cp.p1 == 0 && ci->client_playas == COMPANY_NEW_COMPANY) && ci->client_playas != cp.company) {
01098 IConsolePrintF(CC_ERROR, "WARNING: client %d (IP: %s) tried to execute a command as company %d, kicking...",
01099 ci->client_playas + 1, this->GetClientIP(), cp.company + 1);
01100 return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH);
01101 }
01102
01103 if (cp.cmd == CMD_COMPANY_CTRL) {
01104 if (cp.p1 != 0 || cp.company != COMPANY_SPECTATOR) {
01105 return this->SendError(NETWORK_ERROR_CHEATER);
01106 }
01107
01108
01109 if (Company::GetNumItems() >= _settings_client.network.max_companies) {
01110 NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_CLIENT, ci->client_id, "cannot create new company, server full", CLIENT_ID_SERVER);
01111 return NETWORK_RECV_STATUS_OKAY;
01112 }
01113 }
01114
01115 if (GetCommandFlags(cp.cmd) & CMD_CLIENT_ID) cp.p2 = this->client_id;
01116
01117 this->incoming_queue.Append(&cp);
01118 return NETWORK_RECV_STATUS_OKAY;
01119 }
01120
01121 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p)
01122 {
01123
01124
01125 NetworkClientSocket *new_cs;
01126 char str[100];
01127 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01128 NetworkErrorCode errorno = (NetworkErrorCode)p->Recv_uint8();
01129
01130
01131 if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
01132 return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
01133 }
01134
01135 this->GetClientName(client_name, sizeof(client_name));
01136
01137 StringID strid = GetNetworkErrorMsg(errorno);
01138 GetString(str, strid, lastof(str));
01139
01140 DEBUG(net, 2, "'%s' reported an error and is closing its connection (%s)", client_name, str);
01141
01142 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, strid);
01143
01144 FOR_ALL_CLIENT_SOCKETS(new_cs) {
01145 if (new_cs->status > STATUS_AUTHORIZED) {
01146 new_cs->SendErrorQuit(this->client_id, errorno);
01147 }
01148 }
01149
01150 NetworkAdminClientError(this->client_id, errorno);
01151
01152 return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
01153 }
01154
01155 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p)
01156 {
01157
01158
01159 NetworkClientSocket *new_cs;
01160 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01161
01162
01163 if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
01164 return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
01165 }
01166
01167 this->GetClientName(client_name, sizeof(client_name));
01168
01169 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, STR_NETWORK_MESSAGE_CLIENT_LEAVING);
01170
01171 FOR_ALL_CLIENT_SOCKETS(new_cs) {
01172 if (new_cs->status > STATUS_AUTHORIZED && new_cs != this) {
01173 new_cs->SendQuit(this->client_id);
01174 }
01175 }
01176
01177 NetworkAdminClientQuit(this->client_id);
01178
01179 return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
01180 }
01181
01182 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ACK(Packet *p)
01183 {
01184 if (this->status < STATUS_AUTHORIZED) {
01185
01186 return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
01187 }
01188
01189 uint32 frame = p->Recv_uint32();
01190
01191
01192 if (this->status == STATUS_PRE_ACTIVE) {
01193
01194 if (frame + DAY_TICKS < _frame_counter) return NETWORK_RECV_STATUS_OKAY;
01195
01196
01197 this->status = STATUS_ACTIVE;
01198 this->last_token_frame = _frame_counter;
01199
01200
01201 IConsoleCmdExec("exec scripts/on_server_connect.scr 0");
01202 }
01203
01204
01205 uint8 token = p->Recv_uint8();
01206 if (token == this->last_token) {
01207
01208
01209
01210
01211
01212
01213
01214
01215 this->last_token_frame = _frame_counter;
01216
01217 this->last_token = 0;
01218 }
01219
01220
01221 this->last_frame = frame;
01222
01223 this->last_frame_server = _frame_counter;
01224 return NETWORK_RECV_STATUS_OKAY;
01225 }
01226
01227
01238 void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const char *msg, ClientID from_id, int64 data, bool from_admin)
01239 {
01240 NetworkClientSocket *cs;
01241 const NetworkClientInfo *ci, *ci_own, *ci_to;
01242
01243 switch (desttype) {
01244 case DESTTYPE_CLIENT:
01245
01246 if ((ClientID)dest == CLIENT_ID_SERVER) {
01247 ci = NetworkClientInfo::GetByClientID(from_id);
01248
01249 if (ci != NULL) {
01250 NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01251
01252 if (_settings_client.network.server_admin_chat) {
01253 NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
01254 }
01255 }
01256 } else {
01257
01258 FOR_ALL_CLIENT_SOCKETS(cs) {
01259 if (cs->client_id == (ClientID)dest) {
01260 cs->SendChat(action, from_id, false, msg, data);
01261 break;
01262 }
01263 }
01264 }
01265
01266
01267 if (from_id != (ClientID)dest) {
01268 if (from_id == CLIENT_ID_SERVER) {
01269 ci = NetworkClientInfo::GetByClientID(from_id);
01270 ci_to = NetworkClientInfo::GetByClientID((ClientID)dest);
01271 if (ci != NULL && ci_to != NULL) {
01272 NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), true, ci_to->client_name, msg, data);
01273 }
01274 } else {
01275 FOR_ALL_CLIENT_SOCKETS(cs) {
01276 if (cs->client_id == from_id) {
01277 cs->SendChat(action, (ClientID)dest, true, msg, data);
01278 break;
01279 }
01280 }
01281 }
01282 }
01283 break;
01284 case DESTTYPE_TEAM: {
01285
01286 bool show_local = true;
01287
01288 ci_to = NULL;
01289 FOR_ALL_CLIENT_SOCKETS(cs) {
01290 ci = cs->GetInfo();
01291 if (ci != NULL && ci->client_playas == (CompanyID)dest) {
01292 cs->SendChat(action, from_id, false, msg, data);
01293 if (cs->client_id == from_id) show_local = false;
01294 ci_to = ci;
01295 }
01296 }
01297
01298
01299 if (_local_company == (CompanyID)dest && _settings_client.network.server_admin_chat) {
01300 NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
01301 }
01302
01303 ci = NetworkClientInfo::GetByClientID(from_id);
01304 ci_own = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
01305 if (ci != NULL && ci_own != NULL && ci_own->client_playas == dest) {
01306 NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01307 if (from_id == CLIENT_ID_SERVER) show_local = false;
01308 ci_to = ci_own;
01309 }
01310
01311
01312 if (ci_to == NULL) break;
01313
01314
01315 if (ci != NULL && show_local) {
01316 if (from_id == CLIENT_ID_SERVER) {
01317 char name[NETWORK_NAME_LENGTH];
01318 StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
01319 SetDParam(0, ci_to->client_playas);
01320 GetString(name, str, lastof(name));
01321 NetworkTextMessage(action, GetDrawStringCompanyColour(ci_own->client_playas), true, name, msg, data);
01322 } else {
01323 FOR_ALL_CLIENT_SOCKETS(cs) {
01324 if (cs->client_id == from_id) {
01325 cs->SendChat(action, ci_to->client_id, true, msg, data);
01326 }
01327 }
01328 }
01329 }
01330 break;
01331 }
01332 default:
01333 DEBUG(net, 0, "[server] received unknown chat destination type %d. Doing broadcast instead", desttype);
01334
01335 case DESTTYPE_BROADCAST:
01336 FOR_ALL_CLIENT_SOCKETS(cs) {
01337 cs->SendChat(action, from_id, false, msg, data);
01338 }
01339
01340 NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
01341
01342 ci = NetworkClientInfo::GetByClientID(from_id);
01343 if (ci != NULL) {
01344 NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01345 }
01346 break;
01347 }
01348 }
01349
01350 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_CHAT(Packet *p)
01351 {
01352 if (this->status < STATUS_AUTHORIZED) {
01353
01354 return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
01355 }
01356
01357 NetworkAction action = (NetworkAction)p->Recv_uint8();
01358 DestType desttype = (DestType)p->Recv_uint8();
01359 int dest = p->Recv_uint32();
01360 char msg[NETWORK_CHAT_LENGTH];
01361
01362 p->Recv_string(msg, NETWORK_CHAT_LENGTH);
01363 int64 data = p->Recv_uint64();
01364
01365 NetworkClientInfo *ci = this->GetInfo();
01366 switch (action) {
01367 case NETWORK_ACTION_GIVE_MONEY:
01368 if (!Company::IsValidID(ci->client_playas)) break;
01369
01370 case NETWORK_ACTION_CHAT:
01371 case NETWORK_ACTION_CHAT_CLIENT:
01372 case NETWORK_ACTION_CHAT_COMPANY:
01373 NetworkServerSendChat(action, desttype, dest, msg, this->client_id, data);
01374 break;
01375 default:
01376 IConsolePrintF(CC_ERROR, "WARNING: invalid chat action from client %d (IP: %s).", ci->client_id, this->GetClientIP());
01377 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01378 }
01379 return NETWORK_RECV_STATUS_OKAY;
01380 }
01381
01382 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_PASSWORD(Packet *p)
01383 {
01384 if (this->status != STATUS_ACTIVE) {
01385
01386 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01387 }
01388
01389 char password[NETWORK_PASSWORD_LENGTH];
01390 const NetworkClientInfo *ci;
01391
01392 p->Recv_string(password, sizeof(password));
01393 ci = this->GetInfo();
01394
01395 NetworkServerSetCompanyPassword(ci->client_playas, password);
01396 return NETWORK_RECV_STATUS_OKAY;
01397 }
01398
01399 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet *p)
01400 {
01401 if (this->status != STATUS_ACTIVE) {
01402
01403 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01404 }
01405
01406 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01407 NetworkClientInfo *ci;
01408
01409 p->Recv_string(client_name, sizeof(client_name));
01410 ci = this->GetInfo();
01411
01412 if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
01413
01414 if (ci != NULL) {
01415
01416 if (NetworkFindName(client_name)) {
01417 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, client_name);
01418 strecpy(ci->client_name, client_name, lastof(ci->client_name));
01419 NetworkUpdateClientInfo(ci->client_id);
01420 }
01421 }
01422 return NETWORK_RECV_STATUS_OKAY;
01423 }
01424
01425 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_RCON(Packet *p)
01426 {
01427 if (this->status != STATUS_ACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01428
01429 char pass[NETWORK_PASSWORD_LENGTH];
01430 char command[NETWORK_RCONCOMMAND_LENGTH];
01431
01432 if (StrEmpty(_settings_client.network.rcon_password)) return NETWORK_RECV_STATUS_OKAY;
01433
01434 p->Recv_string(pass, sizeof(pass));
01435 p->Recv_string(command, sizeof(command));
01436
01437 if (strcmp(pass, _settings_client.network.rcon_password) != 0) {
01438 DEBUG(net, 0, "[rcon] wrong password from client-id %d", this->client_id);
01439 return NETWORK_RECV_STATUS_OKAY;
01440 }
01441
01442 DEBUG(net, 0, "[rcon] client-id %d executed: '%s'", this->client_id, command);
01443
01444 _redirect_console_to_client = this->client_id;
01445 IConsoleCmdExec(command);
01446 _redirect_console_to_client = INVALID_CLIENT_ID;
01447 return NETWORK_RECV_STATUS_OKAY;
01448 }
01449
01450 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MOVE(Packet *p)
01451 {
01452 if (this->status != STATUS_ACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01453
01454 CompanyID company_id = (Owner)p->Recv_uint8();
01455
01456
01457 if (company_id != COMPANY_SPECTATOR && !Company::IsValidHumanID(company_id)) return NETWORK_RECV_STATUS_OKAY;
01458
01459
01460 if (company_id != COMPANY_SPECTATOR && !StrEmpty(_network_company_states[company_id].password)) {
01461
01462 char password[NETWORK_PASSWORD_LENGTH];
01463 p->Recv_string(password, sizeof(password));
01464
01465
01466 if (strcmp(password, _network_company_states[company_id].password) != 0) {
01467 DEBUG(net, 2, "[move] wrong password from client-id #%d for company #%d", this->client_id, company_id + 1);
01468 return NETWORK_RECV_STATUS_OKAY;
01469 }
01470 }
01471
01472
01473 NetworkServerDoMove(this->client_id, company_id);
01474 return NETWORK_RECV_STATUS_OKAY;
01475 }
01476
01484 void NetworkSocketHandler::SendCompanyInformation(Packet *p, const Company *c, const NetworkCompanyStats *stats, uint max_len)
01485 {
01486
01487 char company_name[NETWORK_COMPANY_NAME_LENGTH];
01488 SetDParam(0, c->index);
01489
01490 assert(max_len <= lengthof(company_name));
01491 GetString(company_name, STR_COMPANY_NAME, company_name + max_len - 1);
01492
01493
01494 Money income = 0;
01495 if (_cur_year - 1 == c->inaugurated_year) {
01496
01497 for (uint i = 0; i < lengthof(c->yearly_expenses[2]); i++) {
01498 income -= c->yearly_expenses[2][i];
01499 }
01500 } else {
01501 for (uint i = 0; i < lengthof(c->yearly_expenses[1]); i++) {
01502 income -= c->yearly_expenses[1][i];
01503 }
01504 }
01505
01506
01507 p->Send_uint8 (c->index);
01508 p->Send_string(company_name);
01509 p->Send_uint32(c->inaugurated_year);
01510 p->Send_uint64(c->old_economy[0].company_value);
01511 p->Send_uint64(c->money);
01512 p->Send_uint64(income);
01513 p->Send_uint16(c->old_economy[0].performance_history);
01514
01515
01516 p->Send_bool (!StrEmpty(_network_company_states[c->index].password));
01517
01518 for (uint i = 0; i < NETWORK_VEH_END; i++) {
01519 p->Send_uint16(stats->num_vehicle[i]);
01520 }
01521
01522 for (uint i = 0; i < NETWORK_VEH_END; i++) {
01523 p->Send_uint16(stats->num_station[i]);
01524 }
01525
01526 p->Send_bool(c->is_ai);
01527 }
01528
01533 void NetworkPopulateCompanyStats(NetworkCompanyStats *stats)
01534 {
01535 const Vehicle *v;
01536 const Station *s;
01537
01538 memset(stats, 0, sizeof(*stats) * MAX_COMPANIES);
01539
01540
01541 FOR_ALL_VEHICLES(v) {
01542 if (!Company::IsValidID(v->owner) || !v->IsPrimaryVehicle()) continue;
01543 byte type = 0;
01544 switch (v->type) {
01545 case VEH_TRAIN: type = NETWORK_VEH_TRAIN; break;
01546 case VEH_ROAD: type = RoadVehicle::From(v)->IsBus() ? NETWORK_VEH_BUS : NETWORK_VEH_LORRY; break;
01547 case VEH_AIRCRAFT: type = NETWORK_VEH_PLANE; break;
01548 case VEH_SHIP: type = NETWORK_VEH_SHIP; break;
01549 default: continue;
01550 }
01551 stats[v->owner].num_vehicle[type]++;
01552 }
01553
01554
01555 FOR_ALL_STATIONS(s) {
01556 if (Company::IsValidID(s->owner)) {
01557 NetworkCompanyStats *npi = &stats[s->owner];
01558
01559 if (s->facilities & FACIL_TRAIN) npi->num_station[NETWORK_VEH_TRAIN]++;
01560 if (s->facilities & FACIL_TRUCK_STOP) npi->num_station[NETWORK_VEH_LORRY]++;
01561 if (s->facilities & FACIL_BUS_STOP) npi->num_station[NETWORK_VEH_BUS]++;
01562 if (s->facilities & FACIL_AIRPORT) npi->num_station[NETWORK_VEH_PLANE]++;
01563 if (s->facilities & FACIL_DOCK) npi->num_station[NETWORK_VEH_SHIP]++;
01564 }
01565 }
01566 }
01567
01572 void NetworkUpdateClientInfo(ClientID client_id)
01573 {
01574 NetworkClientSocket *cs;
01575 NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
01576
01577 if (ci == NULL) return;
01578
01579 DEBUG(desync, 1, "client: %08x; %02x; %02x; %04x", _date, _date_fract, (int)ci->client_playas, client_id);
01580
01581 FOR_ALL_CLIENT_SOCKETS(cs) {
01582 cs->SendClientInfo(ci);
01583 }
01584
01585 NetworkAdminClientUpdate(ci);
01586 }
01587
01589 static void NetworkCheckRestartMap()
01590 {
01591 if (_settings_client.network.restart_game_year != 0 && _cur_year >= _settings_client.network.restart_game_year) {
01592 DEBUG(net, 0, "Auto-restarting map. Year %d reached", _cur_year);
01593
01594 StartNewGameWithoutGUI(GENERATE_NEW_SEED);
01595 }
01596 }
01597
01604 static void NetworkAutoCleanCompanies()
01605 {
01606 const NetworkClientInfo *ci;
01607 const Company *c;
01608 bool clients_in_company[MAX_COMPANIES];
01609 int vehicles_in_company[MAX_COMPANIES];
01610
01611 if (!_settings_client.network.autoclean_companies) return;
01612
01613 memset(clients_in_company, 0, sizeof(clients_in_company));
01614
01615
01616 FOR_ALL_CLIENT_INFOS(ci) {
01617 if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true;
01618 }
01619
01620 if (!_network_dedicated) {
01621 ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
01622 if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true;
01623 }
01624
01625 if (_settings_client.network.autoclean_novehicles != 0) {
01626 memset(vehicles_in_company, 0, sizeof(vehicles_in_company));
01627
01628 const Vehicle *v;
01629 FOR_ALL_VEHICLES(v) {
01630 if (!Company::IsValidID(v->owner) || !v->IsPrimaryVehicle()) continue;
01631 vehicles_in_company[v->owner]++;
01632 }
01633 }
01634
01635
01636 FOR_ALL_COMPANIES(c) {
01637
01638 if (c->is_ai) continue;
01639
01640 if (!clients_in_company[c->index]) {
01641
01642 _network_company_states[c->index].months_empty++;
01643
01644
01645 if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && StrEmpty(_network_company_states[c->index].password)) {
01646
01647 DoCommandP(0, 2 | c->index << 16, CRR_AUTOCLEAN, CMD_COMPANY_CTRL);
01648 IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no password", c->index + 1);
01649 }
01650
01651 if (_settings_client.network.autoclean_protected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_protected && !StrEmpty(_network_company_states[c->index].password)) {
01652
01653 _network_company_states[c->index].password[0] = '\0';
01654 IConsolePrintF(CC_DEFAULT, "Auto-removed protection from company #%d", c->index + 1);
01655 _network_company_states[c->index].months_empty = 0;
01656 NetworkServerUpdateCompanyPassworded(c->index, false);
01657 }
01658
01659 if (_settings_client.network.autoclean_novehicles != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_novehicles && vehicles_in_company[c->index] == 0) {
01660
01661 DoCommandP(0, 2 | c->index << 16, CRR_AUTOCLEAN, CMD_COMPANY_CTRL);
01662 IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no vehicles", c->index + 1);
01663 }
01664 } else {
01665
01666 _network_company_states[c->index].months_empty = 0;
01667 }
01668 }
01669 }
01670
01676 bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH])
01677 {
01678 bool found_name = false;
01679 uint number = 0;
01680 char original_name[NETWORK_CLIENT_NAME_LENGTH];
01681
01682
01683 ttd_strlcpy(original_name, new_name, NETWORK_CLIENT_NAME_LENGTH);
01684
01685 while (!found_name) {
01686 const NetworkClientInfo *ci;
01687
01688 found_name = true;
01689 FOR_ALL_CLIENT_INFOS(ci) {
01690 if (strcmp(ci->client_name, new_name) == 0) {
01691
01692 found_name = false;
01693 break;
01694 }
01695 }
01696
01697 ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
01698 if (ci != NULL) {
01699 if (strcmp(ci->client_name, new_name) == 0) found_name = false;
01700 }
01701
01702 if (!found_name) {
01703
01704
01705
01706 if (number++ > MAX_CLIENTS) break;
01707 snprintf(new_name, NETWORK_CLIENT_NAME_LENGTH, "%s #%d", original_name, number);
01708 }
01709 }
01710
01711 return found_name;
01712 }
01713
01720 bool NetworkServerChangeClientName(ClientID client_id, const char *new_name)
01721 {
01722 NetworkClientInfo *ci;
01723
01724 FOR_ALL_CLIENT_INFOS(ci) {
01725 if (strcmp(ci->client_name, new_name) == 0) return false;
01726 }
01727
01728 ci = NetworkClientInfo::GetByClientID(client_id);
01729 if (ci == NULL) return false;
01730
01731 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, true, ci->client_name, new_name);
01732
01733 strecpy(ci->client_name, new_name, lastof(ci->client_name));
01734
01735 NetworkUpdateClientInfo(client_id);
01736 return true;
01737 }
01738
01745 void NetworkServerSetCompanyPassword(CompanyID company_id, const char *password, bool already_hashed)
01746 {
01747 if (!Company::IsValidHumanID(company_id)) return;
01748
01749 if (!already_hashed) {
01750 password = GenerateCompanyPasswordHash(password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed);
01751 }
01752
01753 strecpy(_network_company_states[company_id].password, password, lastof(_network_company_states[company_id].password));
01754 NetworkServerUpdateCompanyPassworded(company_id, !StrEmpty(_network_company_states[company_id].password));
01755 }
01756
01761 static void NetworkHandleCommandQueue(NetworkClientSocket *cs)
01762 {
01763 CommandPacket *cp;
01764 while ((cp = cs->outgoing_queue.Pop()) != NULL) {
01765 cs->SendCommand(cp);
01766 free(cp);
01767 }
01768 }
01769
01774 void NetworkServer_Tick(bool send_frame)
01775 {
01776 NetworkClientSocket *cs;
01777 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01778 bool send_sync = false;
01779 #endif
01780
01781 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01782 if (_frame_counter >= _last_sync_frame + _settings_client.network.sync_freq) {
01783 _last_sync_frame = _frame_counter;
01784 send_sync = true;
01785 }
01786 #endif
01787
01788
01789
01790 FOR_ALL_CLIENT_SOCKETS(cs) {
01791
01792
01793 cs->receive_limit = min(cs->receive_limit + _settings_client.network.bytes_per_frame,
01794 _settings_client.network.bytes_per_frame_burst);
01795
01796
01797 uint lag = NetworkCalculateLag(cs);
01798 switch (cs->status) {
01799 case NetworkClientSocket::STATUS_ACTIVE:
01800
01801 lag /= DAY_TICKS;
01802 if (lag > 0) {
01803 if (lag > 3) {
01804
01805
01806 IConsolePrintF(CC_ERROR, cs->last_packet + 3 * DAY_TICKS * MILLISECONDS_PER_TICK > _realtime_tick ?
01807
01808 "Client #%d is dropped because the client's game state is more than 4 game-days behind" :
01809
01810 "Client #%d is dropped because the client did not respond for more than 4 game-days",
01811 cs->client_id);
01812 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
01813 continue;
01814 }
01815
01816
01817
01818
01819
01820
01821 if (cs->lag_test == 0 && cs->last_packet + DAY_TICKS * MILLISECONDS_PER_TICK > _realtime_tick) {
01822 IConsolePrintF(CC_WARNING,"[%d] Client #%d is slow, try increasing [network.]frame_freq to a higher value!", _frame_counter, cs->client_id);
01823 cs->lag_test = 1;
01824 }
01825 } else {
01826 cs->lag_test = 0;
01827 }
01828 if (cs->last_frame_server - cs->last_token_frame >= 5 * DAY_TICKS) {
01829
01830 IConsolePrintF(CC_ERROR, "Client #%d is dropped because it fails to send valid acks", cs->client_id);
01831 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
01832 continue;
01833 }
01834 break;
01835
01836 case NetworkClientSocket::STATUS_INACTIVE:
01837 case NetworkClientSocket::STATUS_NEWGRFS_CHECK:
01838 case NetworkClientSocket::STATUS_AUTHORIZED:
01839
01840
01841 if (lag > 4 * DAY_TICKS) {
01842 IConsolePrintF(CC_ERROR,"Client #%d is dropped because it took longer than %d ticks to start the joining process", cs->client_id, 4 * DAY_TICKS);
01843 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
01844 continue;
01845 }
01846 break;
01847
01848 case NetworkClientSocket::STATUS_MAP:
01849
01850 if (lag > _settings_client.network.max_download_time) {
01851 IConsolePrintF(CC_ERROR,"Client #%d is dropped because it took longer than %d ticks for him to download the map", cs->client_id, _settings_client.network.max_download_time);
01852 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
01853 continue;
01854 }
01855 break;
01856
01857 case NetworkClientSocket::STATUS_DONE_MAP:
01858 case NetworkClientSocket::STATUS_PRE_ACTIVE:
01859
01860 if (lag > _settings_client.network.max_join_time) {
01861 IConsolePrintF(CC_ERROR,"Client #%d is dropped because it took longer than %d ticks for him to join", cs->client_id, _settings_client.network.max_join_time);
01862 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
01863 continue;
01864 }
01865 break;
01866
01867 case NetworkClientSocket::STATUS_AUTH_GAME:
01868 case NetworkClientSocket::STATUS_AUTH_COMPANY:
01869
01870 if (lag > _settings_client.network.max_password_time) {
01871 IConsolePrintF(CC_ERROR,"Client #%d is dropped because it took longer than %d to enter the password", cs->client_id, _settings_client.network.max_password_time);
01872 cs->SendError(NETWORK_ERROR_TIMEOUT_PASSWORD);
01873 continue;
01874 }
01875 break;
01876
01877 case NetworkClientSocket::STATUS_MAP_WAIT:
01878
01879
01880 break;
01881
01882 case NetworkClientSocket::STATUS_END:
01883
01884 NOT_REACHED();
01885 }
01886
01887 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) {
01888
01889 NetworkHandleCommandQueue(cs);
01890
01891
01892 if (send_frame) cs->SendFrame();
01893
01894 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01895
01896 if (send_sync) cs->SendSync();
01897 #endif
01898 }
01899 }
01900
01901
01902 NetworkUDPAdvertise();
01903 }
01904
01906 void NetworkServerYearlyLoop()
01907 {
01908 NetworkCheckRestartMap();
01909 NetworkAdminUpdate(ADMIN_FREQUENCY_ANUALLY);
01910 }
01911
01913 void NetworkServerMonthlyLoop()
01914 {
01915 NetworkAutoCleanCompanies();
01916 NetworkAdminUpdate(ADMIN_FREQUENCY_MONTHLY);
01917 if ((_cur_month % 3) == 0) NetworkAdminUpdate(ADMIN_FREQUENCY_QUARTERLY);
01918 }
01919
01921 void NetworkServerDailyLoop()
01922 {
01923 NetworkAdminUpdate(ADMIN_FREQUENCY_DAILY);
01924 if ((_date % 7) == 3) NetworkAdminUpdate(ADMIN_FREQUENCY_WEEKLY);
01925 }
01926
01931 const char *ServerNetworkGameSocketHandler::GetClientIP()
01932 {
01933 return this->client_address.GetHostname();
01934 }
01935
01937 void NetworkServerShowStatusToConsole()
01938 {
01939 static const char * const stat_str[] = {
01940 "inactive",
01941 "checking NewGRFs",
01942 "authorizing (server password)",
01943 "authorizing (company password)",
01944 "authorized",
01945 "waiting",
01946 "loading map",
01947 "map done",
01948 "ready",
01949 "active"
01950 };
01951 assert_compile(lengthof(stat_str) == NetworkClientSocket::STATUS_END);
01952
01953 NetworkClientSocket *cs;
01954 FOR_ALL_CLIENT_SOCKETS(cs) {
01955 NetworkClientInfo *ci = cs->GetInfo();
01956 if (ci == NULL) continue;
01957 uint lag = NetworkCalculateLag(cs);
01958 const char *status;
01959
01960 status = (cs->status < (ptrdiff_t)lengthof(stat_str) ? stat_str[cs->status] : "unknown");
01961 IConsolePrintF(CC_INFO, "Client #%1d name: '%s' status: '%s' frame-lag: %3d company: %1d IP: %s",
01962 cs->client_id, ci->client_name, status, lag,
01963 ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0),
01964 cs->GetClientIP());
01965 }
01966 }
01967
01971 void NetworkServerSendConfigUpdate()
01972 {
01973 NetworkClientSocket *cs;
01974
01975 FOR_ALL_CLIENT_SOCKETS(cs) {
01976 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendConfigUpdate();
01977 }
01978 }
01979
01985 void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded)
01986 {
01987 if (NetworkCompanyIsPassworded(company_id) == passworded) return;
01988
01989 SB(_network_company_passworded, company_id, 1, !!passworded);
01990 SetWindowClassesDirty(WC_COMPANY);
01991
01992 NetworkClientSocket *cs;
01993 FOR_ALL_CLIENT_SOCKETS(cs) {
01994 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendCompanyUpdate();
01995 }
01996
01997 NetworkAdminCompanyUpdate(Company::GetIfValid(company_id));
01998 }
01999
02006 void NetworkServerDoMove(ClientID client_id, CompanyID company_id)
02007 {
02008
02009 if (client_id == CLIENT_ID_SERVER && _network_dedicated) return;
02010
02011 NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
02012
02013
02014 if (ci->client_playas == company_id) return;
02015
02016 ci->client_playas = company_id;
02017
02018 if (client_id == CLIENT_ID_SERVER) {
02019 SetLocalCompany(company_id);
02020 } else {
02021 NetworkClientSocket *cs = NetworkClientSocket::GetByClientID(client_id);
02022
02023 if (cs->status < NetworkClientSocket::STATUS_AUTHORIZED) return;
02024 cs->SendMove(client_id, company_id);
02025 }
02026
02027
02028 NetworkUpdateClientInfo(client_id);
02029
02030 NetworkAction action = (company_id == COMPANY_SPECTATOR) ? NETWORK_ACTION_COMPANY_SPECTATOR : NETWORK_ACTION_COMPANY_JOIN;
02031 NetworkServerSendChat(action, DESTTYPE_BROADCAST, 0, "", client_id, company_id + 1);
02032 }
02033
02040 void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const char *string)
02041 {
02042 NetworkClientSocket::GetByClientID(client_id)->SendRConResult(colour_code, string);
02043 }
02044
02049 void NetworkServerKickClient(ClientID client_id)
02050 {
02051 if (client_id == CLIENT_ID_SERVER) return;
02052 NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED);
02053 }
02054
02060 uint NetworkServerKickOrBanIP(ClientID client_id, bool ban)
02061 {
02062 return NetworkServerKickOrBanIP(NetworkClientSocket::GetByClientID(client_id)->GetClientIP(), ban);
02063 }
02064
02070 uint NetworkServerKickOrBanIP(const char *ip, bool ban)
02071 {
02072
02073 if (ban) *_network_ban_list.Append() = strdup(ip);
02074
02075 uint n = 0;
02076
02077
02078 NetworkClientSocket *cs;
02079 FOR_ALL_CLIENT_SOCKETS(cs) {
02080 if (cs->client_id == CLIENT_ID_SERVER) continue;
02081 if (cs->client_address.IsInNetmask(const_cast<char *>(ip))) {
02082 NetworkServerKickClient(cs->client_id);
02083 n++;
02084 }
02085 }
02086
02087 return n;
02088 }
02089
02095 bool NetworkCompanyHasClients(CompanyID company)
02096 {
02097 const NetworkClientInfo *ci;
02098 FOR_ALL_CLIENT_INFOS(ci) {
02099 if (ci->client_playas == company) return true;
02100 }
02101 return false;
02102 }
02103
02104
02110 void ServerNetworkGameSocketHandler::GetClientName(char *client_name, size_t size) const
02111 {
02112 const NetworkClientInfo *ci = this->GetInfo();
02113
02114 if (ci == NULL || StrEmpty(ci->client_name)) {
02115 snprintf(client_name, size, "Client #%4d", this->client_id);
02116 } else {
02117 ttd_strlcpy(client_name, ci->client_name, size);
02118 }
02119 }
02120
02124 void NetworkPrintClients()
02125 {
02126 NetworkClientInfo *ci;
02127 FOR_ALL_CLIENT_INFOS(ci) {
02128 IConsolePrintF(CC_INFO, _network_server ? "Client #%1d name: '%s' company: %1d IP: %s" : "Client #%1d name: '%s' company: %1d",
02129 ci->client_id,
02130 ci->client_name,
02131 ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0),
02132 _network_server ? (ci->client_id == CLIENT_ID_SERVER ? "server" : NetworkClientSocket::GetByClientID(ci->client_id)->GetClientIP()) : "");
02133 }
02134 }
02135
02136 #endif