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