|
@@ -81,14 +81,13 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_CO
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
NetworkPopulateCompanyInfo();
|
|
|
|
|
|
FOR_ALL_PLAYERS(player) {
|
|
|
if (!player->is_active)
|
|
|
continue;
|
|
|
if (!player->is_active) continue;
|
|
|
|
|
|
p = NetworkSend_Init(PACKET_SERVER_COMPANY_INFO);
|
|
|
|
|
|
NetworkSend_uint8 (p, NETWORK_COMPANY_INFO_VERSION);
|
|
|
NetworkSend_uint8 (p, active);
|
|
|
NetworkSend_uint8 (p, player->index);
|
|
@@ -99,27 +98,30 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_CO
|
|
|
NetworkSend_uint64(p, _network_player_info[player->index].money);
|
|
|
NetworkSend_uint64(p, _network_player_info[player->index].income);
|
|
|
NetworkSend_uint16(p, _network_player_info[player->index].performance);
|
|
|
|
|
|
/* Send 1 if there is a passord for the company else send 0 */
|
|
|
if (_network_player_info[player->index].password[0] != '\0') {
|
|
|
NetworkSend_uint8 (p, 1);
|
|
|
NetworkSend_uint8(p, 1);
|
|
|
} else {
|
|
|
NetworkSend_uint8 (p, 0);
|
|
|
NetworkSend_uint8(p, 0);
|
|
|
}
|
|
|
|
|
|
for (i = 0; i < NETWORK_VEHICLE_TYPES; i++) {
|
|
|
NetworkSend_uint16(p, _network_player_info[player->index].num_vehicle[i]);
|
|
|
}
|
|
|
|
|
|
for (i = 0; i < NETWORK_VEHICLE_TYPES; i++)
|
|
|
NetworkSend_uint16(p, _network_player_info[player->index].num_vehicle[i]);
|
|
|
|
|
|
for (i = 0; i < NETWORK_STATION_TYPES; i++)
|
|
|
for (i = 0; i < NETWORK_STATION_TYPES; i++) {
|
|
|
NetworkSend_uint16(p, _network_player_info[player->index].num_station[i]);
|
|
|
}
|
|
|
|
|
|
if (_network_player_info[player->index].players[0] == '\0')
|
|
|
if (_network_player_info[player->index].players[0] == '\0') {
|
|
|
NetworkSend_string(p, "<none>");
|
|
|
else
|
|
|
} else {
|
|
|
NetworkSend_string(p, _network_player_info[player->index].players);
|
|
|
}
|
|
|
|
|
|
NetworkSend_Packet(p, cs);
|
|
|
}
|
|
|
|
|
|
p = NetworkSend_Init(PACKET_SERVER_COMPANY_INFO);
|
|
|
|
|
@@ -237,14 +239,13 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WA
|
|
|
int waiting = 0;
|
|
|
NetworkClientState *new_cs;
|
|
|
Packet *p;
|
|
|
|
|
|
// Count how many players are waiting in the queue
|
|
|
FOR_ALL_CLIENTS(new_cs) {
|
|
|
if (new_cs->status == STATUS_MAP_WAIT)
|
|
|
waiting++;
|
|
|
if (new_cs->status == STATUS_MAP_WAIT) waiting++;
|
|
|
}
|
|
|
|
|
|
p = NetworkSend_Init(PACKET_SERVER_WAIT);
|
|
|
NetworkSend_uint8(p, waiting);
|
|
|
NetworkSend_Packet(p, cs);
|
|
|
}
|
|
@@ -575,19 +576,17 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT
|
|
|
char client_revision[NETWORK_REVISION_LENGTH];
|
|
|
|
|
|
NetworkRecv_string(cs, p, client_revision, sizeof(client_revision));
|
|
|
|
|
|
#if defined(WITH_REV) || defined(WITH_REV_HACK)
|
|
|
// Check if the client has revision control enabled
|
|
|
if (strcmp(NOREV_STRING, client_revision) != 0) {
|
|
|
if (strcmp(_network_game_info.server_revision, client_revision) != 0) {
|
|
|
// Different revisions!!
|
|
|
SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_REVISION);
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
if (strcmp(NOREV_STRING, client_revision) != 0 &&
|
|
|
strcmp(_network_game_info.server_revision, client_revision) != 0) {
|
|
|
// Different revisions!!
|
|
|
SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_REVISION);
|
|
|
return;
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
NetworkRecv_string(cs, p, name, sizeof(name));
|
|
|
playas = NetworkRecv_uint8(cs, p);
|
|
|
client_lang = NetworkRecv_uint8(cs, p);
|
|
@@ -626,26 +625,26 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT
|
|
|
ttd_strlcpy(ci->unique_id, unique_id, sizeof(ci->unique_id));
|
|
|
ci->client_playas = playas;
|
|
|
ci->client_lang = client_lang;
|
|
|
|
|
|
// We now want a password from the client
|
|
|
// else we do not allow him in!
|
|
|
if (_network_game_info.use_password)
|
|
|
if (_network_game_info.use_password) {
|
|
|
SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_GAME_PASSWORD);
|
|
|
else {
|
|
|
} else {
|
|
|
if (ci->client_playas > 0 && ci->client_playas <= MAX_PLAYERS && _network_player_info[ci->client_playas - 1].password[0] != '\0') {
|
|
|
SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD);
|
|
|
}
|
|
|
else {
|
|
|
} else {
|
|
|
SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Make sure companies to who people try to join are not autocleaned */
|
|
|
if (playas >= 1 && playas <= MAX_PLAYERS)
|
|
|
if (playas >= 1 && playas <= MAX_PLAYERS) {
|
|
|
_network_player_info[playas-1].months_empty = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD)
|
|
|
{
|
|
|
NetworkPasswordType type;
|
|
|
char password[NETWORK_PASSWORD_LENGTH];
|
|
@@ -1110,14 +1109,13 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT
|
|
|
|
|
|
DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_RCON)
|
|
|
{
|
|
|
char pass[NETWORK_PASSWORD_LENGTH];
|
|
|
char command[NETWORK_RCONCOMMAND_LENGTH];
|
|
|
|
|
|
if (_network_game_info.rcon_password[0] == '\0')
|
|
|
return;
|
|
|
if (_network_game_info.rcon_password[0] == '\0') return;
|
|
|
|
|
|
NetworkRecv_string(cs, p, pass, sizeof(pass));
|
|
|
NetworkRecv_string(cs, p, command, sizeof(command));
|
|
|
|
|
|
if (strcmp(pass, _network_game_info.rcon_password) != 0) {
|
|
|
DEBUG(net, 0)("[RCon] Wrong password from client-id %d", cs->index);
|
|
@@ -1206,67 +1204,74 @@ void NetworkPopulateCompanyInfo(void)
|
|
|
// Grap the company name
|
|
|
SetDParam(0, p->name_1);
|
|
|
SetDParam(1, p->name_2);
|
|
|
GetString(_network_player_info[p->index].company_name, STR_JUST_STRING);
|
|
|
|
|
|
// Check the income
|
|
|
if (_cur_year - 1 == p->inaugurated_year)
|
|
|
if (_cur_year - 1 == p->inaugurated_year) {
|
|
|
// The player is here just 1 year, so display [2], else display[1]
|
|
|
for (i = 0; i < 13; i++)
|
|
|
for (i = 0; i < 13; i++) {
|
|
|
_network_player_info[p->index].income -= p->yearly_expenses[2][i];
|
|
|
else
|
|
|
for (i = 0; i < 13; i++)
|
|
|
}
|
|
|
} else {
|
|
|
for (i = 0; i < 13; i++) {
|
|
|
_network_player_info[p->index].income -= p->yearly_expenses[1][i];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Set some general stuff
|
|
|
_network_player_info[p->index].inaugurated_year = p->inaugurated_year;
|
|
|
_network_player_info[p->index].company_value = p->old_economy[0].company_value;
|
|
|
_network_player_info[p->index].money = p->money64;
|
|
|
_network_player_info[p->index].performance = p->old_economy[0].performance_history;
|
|
|
}
|
|
|
|
|
|
// Go through all vehicles and count the type of vehicles
|
|
|
FOR_ALL_VEHICLES(v) {
|
|
|
if (v->owner < MAX_PLAYERS)
|
|
|
switch (v->type) {
|
|
|
case VEH_Train:
|
|
|
if (IsFrontEngine(v))
|
|
|
_network_player_info[v->owner].num_vehicle[0]++;
|
|
|
break;
|
|
|
case VEH_Road:
|
|
|
if (v->cargo_type != CT_PASSENGERS)
|
|
|
_network_player_info[v->owner].num_vehicle[1]++;
|
|
|
else
|
|
|
_network_player_info[v->owner].num_vehicle[2]++;
|
|
|
break;
|
|
|
case VEH_Aircraft:
|
|
|
if (v->subtype <= 2)
|
|
|
_network_player_info[v->owner].num_vehicle[3]++;
|
|
|
break;
|
|
|
case VEH_Ship:
|
|
|
_network_player_info[v->owner].num_vehicle[4]++;
|
|
|
break;
|
|
|
case VEH_Special:
|
|
|
case VEH_Disaster:
|
|
|
break;
|
|
|
}
|
|
|
if (v->owner >= MAX_PLAYERS) continue;
|
|
|
switch (v->type) {
|
|
|
case VEH_Train:
|
|
|
if (IsFrontEngine(v)) {
|
|
|
_network_player_info[v->owner].num_vehicle[0]++;
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case VEH_Road:
|
|
|
if (v->cargo_type != CT_PASSENGERS) {
|
|
|
_network_player_info[v->owner].num_vehicle[1]++;
|
|
|
} else {
|
|
|
_network_player_info[v->owner].num_vehicle[2]++;
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case VEH_Aircraft:
|
|
|
if (v->subtype <= 2) {
|
|
|
_network_player_info[v->owner].num_vehicle[3]++;
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case VEH_Ship:
|
|
|
_network_player_info[v->owner].num_vehicle[4]++;
|
|
|
break;
|
|
|
|
|
|
case VEH_Special:
|
|
|
case VEH_Disaster:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Go through all stations and count the types of stations
|
|
|
FOR_ALL_STATIONS(s) {
|
|
|
if (s->owner < MAX_PLAYERS) {
|
|
|
if ((s->facilities & FACIL_TRAIN))
|
|
|
_network_player_info[s->owner].num_station[0]++;
|
|
|
if ((s->facilities & FACIL_TRUCK_STOP))
|
|
|
_network_player_info[s->owner].num_station[1]++;
|
|
|
if ((s->facilities & FACIL_BUS_STOP))
|
|
|
_network_player_info[s->owner].num_station[2]++;
|
|
|
if ((s->facilities & FACIL_AIRPORT))
|
|
|
_network_player_info[s->owner].num_station[3]++;
|
|
|
if ((s->facilities & FACIL_DOCK))
|
|
|
_network_player_info[s->owner].num_station[4]++;
|
|
|
NetworkPlayerInfo* npi = &_network_player_info[s->owner];
|
|
|
|
|
|
if (s->facilities & FACIL_TRAIN) npi->num_station[0]++;
|
|
|
if (s->facilities & FACIL_TRUCK_STOP) npi->num_station[1]++;
|
|
|
if (s->facilities & FACIL_BUS_STOP) npi->num_station[2]++;
|
|
|
if (s->facilities & FACIL_AIRPORT) npi->num_station[3]++;
|
|
|
if (s->facilities & FACIL_DOCK) npi->num_station[4]++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
|
|
|
// Register local player (if not dedicated)
|
|
|
if (ci != NULL && ci->client_playas > 0 && ci->client_playas <= MAX_PLAYERS)
|
|
@@ -1292,14 +1297,13 @@ void NetworkUpdateClientInfo(uint16 clie
|
|
|
{
|
|
|
NetworkClientState *cs;
|
|
|
NetworkClientInfo *ci;
|
|
|
|
|
|
ci = NetworkFindClientInfoFromIndex(client_index);
|
|
|
|
|
|
if (ci == NULL)
|
|
|
return;
|
|
|
if (ci == NULL) return;
|
|
|
|
|
|
FOR_ALL_CLIENTS(cs) {
|
|
|
SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, ci);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1327,14 +1331,13 @@ static void NetworkAutoCleanCompanies(vo
|
|
|
{
|
|
|
NetworkClientState *cs;
|
|
|
NetworkClientInfo *ci;
|
|
|
Player *p;
|
|
|
bool clients_in_company[MAX_PLAYERS];
|
|
|
|
|
|
if (!_network_autoclean_companies)
|
|
|
return;
|
|
|
if (!_network_autoclean_companies) return;
|
|
|
|
|
|
memset(clients_in_company, 0, sizeof(clients_in_company));
|
|
|
|
|
|
/* Detect the active companies */
|
|
|
FOR_ALL_CLIENTS(cs) {
|
|
|
ci = DEREF_CLIENT_INFO(cs);
|
|
@@ -1349,14 +1352,13 @@ static void NetworkAutoCleanCompanies(vo
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Go through all the comapnies */
|
|
|
FOR_ALL_PLAYERS(p) {
|
|
|
/* Skip the non-active once */
|
|
|
if (!p->is_active || p->is_ai)
|
|
|
continue;
|
|
|
if (!p->is_active || p->is_ai) continue;
|
|
|
|
|
|
if (!clients_in_company[p->index]) {
|
|
|
/* The company is empty for one month more */
|
|
|
_network_player_info[p->index].months_empty++;
|
|
|
|
|
|
/* Is the company empty for autoclean_unprotected-months, and is there no protection? */
|
|
@@ -1427,16 +1429,17 @@ bool NetworkFindName(char new_name[NETWO
|
|
|
bool NetworkServer_ReadPackets(NetworkClientState *cs)
|
|
|
{
|
|
|
Packet *p;
|
|
|
NetworkRecvStatus res;
|
|
|
while ((p = NetworkRecv_Packet(cs, &res)) != NULL) {
|
|
|
byte type = NetworkRecv_uint8(cs, p);
|
|
|
if (type < PACKET_END && _network_server_packet[type] != NULL && !cs->quited)
|
|
|
if (type < PACKET_END && _network_server_packet[type] != NULL && !cs->quited) {
|
|
|
_network_server_packet[type](cs, p);
|
|
|
else
|
|
|
} else {
|
|
|
DEBUG(net, 0)("[NET][Server] Received invalid packet type %d", type);
|
|
|
}
|
|
|
free(p);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|