mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r23795) [1.1] -Backport from trunk:
- Fix: Make default timeouts for certain network states lower and configurable [FS#4955] (r23764) - Fix: Check whether a water tile is really empty when overbuilding it with an object [FS#4956] (r23763) - Fix: Missing locking causing crash in extreme case when being in the MP lobby [FS#4938] (r23752) - Fix: Clear the backed up orders of a removed station as well, otherwise one could create orders to a station that was never in the original backupped orders. For example a road vehicle trying to go to a buoy [FS#4876] (r23464) - Fix: Do not assume all industries that cut trees have tile (0,0) and wait until all tiles of an industry are completed before starting to cut trees (r23458)
This commit is contained in:
parent
15a9cae86e
commit
7faba28c31
|
@ -376,7 +376,7 @@ static bool DisasterTick_Ufo(DisasterVehicle *v)
|
|||
static void DestructIndustry(Industry *i)
|
||||
{
|
||||
for (TileIndex tile = 0; tile != MapSize(); tile++) {
|
||||
if (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == i->index) {
|
||||
if (i->TileBelongsToIndustry(tile)) {
|
||||
ResetIndustryConstructionStage(tile);
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
|
|
|
@ -79,6 +79,16 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> {
|
|||
|
||||
void RecomputeProductionMultipliers();
|
||||
|
||||
/**
|
||||
* Check if a given tile belongs to this industry.
|
||||
* @param tile The tile to check.
|
||||
* @return True if the tils is part of this industry.
|
||||
*/
|
||||
inline bool TileBelongsToIndustry(TileIndex tile) const
|
||||
{
|
||||
return IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == this->index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the industry of the given tile
|
||||
* @param tile the tile to get the industry from
|
||||
|
|
|
@ -1065,10 +1065,14 @@ static bool SearchLumberMillTrees(TileIndex tile, void *user_data)
|
|||
*/
|
||||
static void ChopLumberMillTrees(Industry *i)
|
||||
{
|
||||
/* We only want to cut trees if all tiles are completed. */
|
||||
TILE_AREA_LOOP(tile_cur, i->location) {
|
||||
if (i->TileBelongsToIndustry(tile_cur)) {
|
||||
if (!IsIndustryCompleted(tile_cur)) return;
|
||||
}
|
||||
}
|
||||
|
||||
TileIndex tile = i->location.tile;
|
||||
|
||||
if (!IsIndustryCompleted(tile)) return; // Can't proceed if not completed.
|
||||
|
||||
if (CircularTileSearch(&tile, 40, SearchLumberMillTrees, NULL)) { // 40x40 tiles to search.
|
||||
i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + 45); // Found a tree, add according value to waiting cargo.
|
||||
}
|
||||
|
|
|
@ -1776,6 +1776,8 @@ STR_NETWORK_ERROR_SERVER_BANNED :{WHITE}You are
|
|||
STR_NETWORK_ERROR_KICKED :{WHITE}You were kicked out of the game
|
||||
STR_NETWORK_ERROR_CHEATER :{WHITE}Cheating is not allowed on this server
|
||||
STR_NETWORK_ERROR_TOO_MANY_COMMANDS :{WHITE}You were sending too many commands to the server
|
||||
STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}You took too long to enter the password
|
||||
STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Your computer took too long to join
|
||||
|
||||
############ Leave those lines in this order!!
|
||||
STR_NETWORK_ERROR_CLIENT_GENERAL :general error
|
||||
|
|
|
@ -819,20 +819,18 @@ static void NetworkSend()
|
|||
}
|
||||
}
|
||||
|
||||
/* We have to do some UDP checking */
|
||||
void NetworkUDPGameLoop()
|
||||
/**
|
||||
* We have to do some (simple) background stuff that runs normally,
|
||||
* even when we are not in multiplayer. For example stuff needed
|
||||
* for finding servers or downloading content.
|
||||
*/
|
||||
void NetworkBackgroundLoop()
|
||||
{
|
||||
_network_content_client.SendReceive();
|
||||
TCPConnecter::CheckCallbacks();
|
||||
NetworkHTTPSocketHandler::HTTPReceive();
|
||||
|
||||
if (_network_udp_server) {
|
||||
_udp_server_socket->ReceivePackets();
|
||||
_udp_master_socket->ReceivePackets();
|
||||
} else {
|
||||
_udp_client_socket->ReceivePackets();
|
||||
if (_network_udp_broadcast > 0) _network_udp_broadcast--;
|
||||
}
|
||||
NetworkBackgroundUDPLoop();
|
||||
}
|
||||
|
||||
/* The main loop called from ttd.c
|
||||
|
|
|
@ -633,6 +633,12 @@ DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_ERROR)
|
|||
case NETWORK_ERROR_TOO_MANY_COMMANDS:
|
||||
_switch_mode_errorstr = STR_NETWORK_ERROR_TOO_MANY_COMMANDS;
|
||||
break;
|
||||
case NETWORK_ERROR_TIMEOUT_PASSWORD:
|
||||
ShowErrorMessage(STR_NETWORK_ERROR_TIMEOUT_PASSWORD, INVALID_STRING_ID, WL_CRITICAL);
|
||||
break;
|
||||
case NETWORK_ERROR_TIMEOUT_COMPUTER:
|
||||
ShowErrorMessage(STR_NETWORK_ERROR_TIMEOUT_COMPUTER, INVALID_STRING_ID, WL_CRITICAL);
|
||||
break;
|
||||
default:
|
||||
_switch_mode_errorstr = STR_NETWORK_ERROR_LOSTCONNECTION;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ const char *NetworkChangeCompanyPassword(CompanyID company_id, const char *passw
|
|||
void NetworkReboot();
|
||||
void NetworkDisconnect(bool blocking = false, bool close_admins = true);
|
||||
void NetworkGameLoop();
|
||||
void NetworkUDPGameLoop();
|
||||
void NetworkBackgroundLoop();
|
||||
void ParseConnectionString(const char **company, const char **port, char *connection_string);
|
||||
void NetworkStartDebugLog(NetworkAddress address);
|
||||
void NetworkPopulateCompanyStats(NetworkCompanyStats *stats);
|
||||
|
|
|
@ -1717,55 +1717,94 @@ void NetworkServer_Tick(bool send_frame)
|
|||
_settings_client.network.bytes_per_frame_burst);
|
||||
|
||||
/* Check if the speed of the client is what we can expect from a client */
|
||||
if (cs->status == NetworkClientSocket::STATUS_ACTIVE) {
|
||||
/* 1 lag-point per day */
|
||||
uint lag = NetworkCalculateLag(cs) / DAY_TICKS;
|
||||
if (lag > 0) {
|
||||
if (lag > 3) {
|
||||
/* Client did still not report in after 4 game-day, drop him
|
||||
* (that is, the 3 of above, + 1 before any lag is counted) */
|
||||
IConsolePrintF(CC_ERROR, cs->last_packet + 3 * DAY_TICKS * MILLISECONDS_PER_TICK > _realtime_tick ?
|
||||
/* A packet was received in the last three game days, so the client is likely lagging behind. */
|
||||
"Client #%d is dropped because the client's game state is more than 4 game-days behind" :
|
||||
/* No packet was received in the last three game days; sounds like a lost connection. */
|
||||
"Client #%d is dropped because the client did not respond for more than 4 game-days",
|
||||
cs->client_id);
|
||||
cs->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
|
||||
uint lag = NetworkCalculateLag(cs);
|
||||
switch (cs->status) {
|
||||
case NetworkClientSocket::STATUS_ACTIVE:
|
||||
/* 1 lag-point per day */
|
||||
lag /= DAY_TICKS;
|
||||
if (lag > 0) {
|
||||
if (lag > 3) {
|
||||
/* Client did still not report in after 4 game-day, drop him
|
||||
* (that is, the 3 of above, + 1 before any lag is counted) */
|
||||
IConsolePrintF(CC_ERROR, cs->last_packet + 3 * DAY_TICKS * MILLISECONDS_PER_TICK > _realtime_tick ?
|
||||
/* A packet was received in the last three game days, so the client is likely lagging behind. */
|
||||
"Client #%d is dropped because the client's game state is more than 4 game-days behind" :
|
||||
/* No packet was received in the last three game days; sounds like a lost connection. */
|
||||
"Client #%d is dropped because the client did not respond for more than 4 game-days",
|
||||
cs->client_id);
|
||||
cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Report once per time we detect the lag, and only when we
|
||||
* received a packet in the last 2000 milliseconds. If we
|
||||
* did not receive a packet, then the client is not just
|
||||
* slow, but the connection is likely severed. Mentioning
|
||||
* frame_freq is not useful in this case. */
|
||||
if (cs->lag_test == 0 && cs->last_packet + DAY_TICKS * MILLISECONDS_PER_TICK > _realtime_tick) {
|
||||
IConsolePrintF(CC_WARNING,"[%d] Client #%d is slow, try increasing [network.]frame_freq to a higher value!", _frame_counter, cs->client_id);
|
||||
cs->lag_test = 1;
|
||||
}
|
||||
} else {
|
||||
cs->lag_test = 0;
|
||||
}
|
||||
if (cs->last_frame_server - cs->last_token_frame >= 5 * DAY_TICKS) {
|
||||
/* This is a bad client! It didn't send the right token back. */
|
||||
IConsolePrintF(CC_ERROR, "Client #%d is dropped because it fails to send valid acks", cs->client_id);
|
||||
cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Report once per time we detect the lag, and only when we
|
||||
* received a packet in the last 2000 milliseconds. If we
|
||||
* did not receive a packet, then the client is not just
|
||||
* slow, but the connection is likely severed. Mentioning
|
||||
* frame_freq is not useful in this case. */
|
||||
if (cs->lag_test == 0 && cs->last_packet + DAY_TICKS * MILLISECONDS_PER_TICK > _realtime_tick) {
|
||||
IConsolePrintF(CC_WARNING,"[%d] Client #%d is slow, try increasing [network.]frame_freq to a higher value!", _frame_counter, cs->client_id);
|
||||
cs->lag_test = 1;
|
||||
case NetworkClientSocket::STATUS_INACTIVE:
|
||||
case NetworkClientSocket::STATUS_NEWGRFS_CHECK:
|
||||
case NetworkClientSocket::STATUS_AUTHORIZED:
|
||||
/* NewGRF check and authorized states should be handled almost instantly.
|
||||
* So give them some lee-way, likewise for the query with inactive. */
|
||||
if (lag > 4 * DAY_TICKS) {
|
||||
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);
|
||||
cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
cs->lag_test = 0;
|
||||
}
|
||||
if (cs->last_frame_server - cs->last_token_frame >= 5 * DAY_TICKS) {
|
||||
/* This is a bad client! It didn't send the right token back. */
|
||||
IConsolePrintF(CC_ERROR, "Client #%d is dropped because it fails to send valid acks", cs->client_id);
|
||||
cs->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
|
||||
continue;
|
||||
}
|
||||
} else if (cs->status == NetworkClientSocket::STATUS_PRE_ACTIVE) {
|
||||
uint lag = NetworkCalculateLag(cs);
|
||||
if (lag > _settings_client.network.max_join_time) {
|
||||
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);
|
||||
cs->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
|
||||
continue;
|
||||
}
|
||||
} else if (cs->status == NetworkClientSocket::STATUS_INACTIVE) {
|
||||
uint lag = NetworkCalculateLag(cs);
|
||||
if (lag > 4 * DAY_TICKS) {
|
||||
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);
|
||||
cs->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case NetworkClientSocket::STATUS_MAP:
|
||||
/* Downloading the map... this is the amount of time since starting the saving. */
|
||||
if (lag > _settings_client.network.max_download_time) {
|
||||
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);
|
||||
cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case NetworkClientSocket::STATUS_DONE_MAP:
|
||||
case NetworkClientSocket::STATUS_PRE_ACTIVE:
|
||||
/* The map has been sent, so this is for loading the map and syncing up. */
|
||||
if (lag > _settings_client.network.max_join_time) {
|
||||
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);
|
||||
cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case NetworkClientSocket::STATUS_AUTH_GAME:
|
||||
case NetworkClientSocket::STATUS_AUTH_COMPANY:
|
||||
/* These don't block? */
|
||||
if (lag > _settings_client.network.max_password_time) {
|
||||
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);
|
||||
cs->SendError(NETWORK_ERROR_TIMEOUT_PASSWORD);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case NetworkClientSocket::STATUS_MAP_WAIT:
|
||||
/* This is an internal state where we do not wait
|
||||
* on the client to move to a different state. */
|
||||
break;
|
||||
|
||||
case NetworkClientSocket::STATUS_END:
|
||||
/* Bad server/code. */
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) {
|
||||
|
|
|
@ -119,6 +119,8 @@ enum NetworkErrorCode {
|
|||
NETWORK_ERROR_CHEATER,
|
||||
NETWORK_ERROR_FULL,
|
||||
NETWORK_ERROR_TOO_MANY_COMMANDS,
|
||||
NETWORK_ERROR_TIMEOUT_PASSWORD,
|
||||
NETWORK_ERROR_TIMEOUT_COMPUTER,
|
||||
};
|
||||
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
|
|
@ -637,4 +637,20 @@ void NetworkUDPClose()
|
|||
DEBUG(net, 1, "[udp] closed listeners");
|
||||
}
|
||||
|
||||
/** Receive the UDP packets. */
|
||||
void NetworkBackgroundUDPLoop()
|
||||
{
|
||||
_network_udp_mutex->BeginCritical();
|
||||
|
||||
if (_network_udp_server) {
|
||||
_udp_server_socket->ReceivePackets();
|
||||
_udp_master_socket->ReceivePackets();
|
||||
} else {
|
||||
_udp_client_socket->ReceivePackets();
|
||||
if (_network_udp_broadcast > 0) _network_udp_broadcast--;
|
||||
}
|
||||
|
||||
_network_udp_mutex->EndCritical();
|
||||
}
|
||||
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
|
|
@ -23,6 +23,7 @@ void NetworkUDPQueryServer(NetworkAddress address, bool manually = false);
|
|||
void NetworkUDPAdvertise();
|
||||
void NetworkUDPRemoveAdvertise(bool blocking);
|
||||
void NetworkUDPClose();
|
||||
void NetworkBackgroundUDPLoop();
|
||||
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
|
|
|
@ -242,7 +242,7 @@ uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte par
|
|||
/* Get random tile bits at offset param */
|
||||
case 0x61:
|
||||
tile = GetNearbyTile(parameter, tile, false);
|
||||
return (IsTileType(tile, MP_INDUSTRY) && Industry::GetByTile(tile) == industry) ? GetIndustryRandomBits(tile) : 0;
|
||||
return industry->TileBelongsToIndustry(tile) ? GetIndustryRandomBits(tile) : 0;
|
||||
|
||||
/* Land info of nearby tiles */
|
||||
case 0x62: return GetNearbyIndustryTileInformation(parameter, tile, INVALID_INDUSTRY, false);
|
||||
|
@ -250,7 +250,7 @@ uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte par
|
|||
/* Animation stage of nearby tiles */
|
||||
case 0x63:
|
||||
tile = GetNearbyTile(parameter, tile, false);
|
||||
if (IsTileType(tile, MP_INDUSTRY) && Industry::GetByTile(tile) == industry) {
|
||||
if (industry->TileBelongsToIndustry(tile)) {
|
||||
return GetAnimationFrame(tile);
|
||||
}
|
||||
return 0xFFFFFFFF;
|
||||
|
|
|
@ -331,7 +331,7 @@ bool StartStopIndustryTileAnimation(const Industry *ind, IndustryAnimationTrigge
|
|||
bool ret = true;
|
||||
uint32 random = Random();
|
||||
TILE_AREA_LOOP(tile, ind->location) {
|
||||
if (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == ind->index) {
|
||||
if (ind->TileBelongsToIndustry(tile)) {
|
||||
if (StartStopIndustryTileAnimation(tile, iat, random)) {
|
||||
SB(random, 0, 16, Random());
|
||||
} else {
|
||||
|
@ -415,7 +415,7 @@ void TriggerIndustry(Industry *ind, IndustryTileTrigger trigger)
|
|||
{
|
||||
uint32 reseed_industry = 0;
|
||||
TILE_AREA_LOOP(tile, ind->location) {
|
||||
if (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == ind->index) {
|
||||
if (ind->TileBelongsToIndustry(tile)) {
|
||||
DoTriggerIndustryTile(tile, trigger, ind, reseed_industry);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "newgrf_object.h"
|
||||
#include "date_func.h"
|
||||
#include "newgrf_debug.h"
|
||||
#include "vehicle_func.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
#include "table/object_land.h"
|
||||
|
@ -221,6 +222,9 @@ CommandCost CmdBuildObject(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
|||
/* Can't build on water owned by another company. */
|
||||
Owner o = GetTileOwner(t);
|
||||
if (o != OWNER_NONE && o != OWNER_WATER) cost.AddCost(CheckOwnership(o, t));
|
||||
|
||||
/* However, the tile has to be clear of vehicles. */
|
||||
cost.AddCost(EnsureNoVehicleOnGround(t));
|
||||
}
|
||||
} else {
|
||||
if (!allow_ground) return_cmd_error(STR_ERROR_MUST_BE_BUILT_ON_WATER);
|
||||
|
|
|
@ -1268,7 +1268,7 @@ void GameLoop()
|
|||
|
||||
#ifdef ENABLE_NETWORK
|
||||
/* Check for UDP stuff */
|
||||
if (_network_available) NetworkUDPGameLoop();
|
||||
if (_network_available) NetworkBackgroundLoop();
|
||||
|
||||
if (_networking && !IsGeneratingWorld()) {
|
||||
/* Multiplayer */
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "order_backup.h"
|
||||
#include "vehicle_base.h"
|
||||
#include "window_func.h"
|
||||
#include "station_map.h"
|
||||
|
||||
OrderBackupPool _order_backup_pool("BackupOrder");
|
||||
INSTANTIATE_POOL_METHODS(OrderBackup)
|
||||
|
@ -262,3 +263,25 @@ void InitializeOrderBackups()
|
|||
{
|
||||
_order_backup_pool.CleanPool();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an order from all vehicles. Triggers when, say, a station is removed.
|
||||
* @param type The type of the order (OT_GOTO_[STATION|DEPOT|WAYPOINT]).
|
||||
* @param destination The destination. Can be a StationID, DepotID or WaypointID.
|
||||
*/
|
||||
/* static */ void OrderBackup::RemoveOrder(OrderType type, DestinationID destination)
|
||||
{
|
||||
OrderBackup *ob;
|
||||
FOR_ALL_ORDER_BACKUPS(ob) {
|
||||
for (Order *order = ob->orders; order != NULL; order = order->next) {
|
||||
OrderType ot = order->GetType();
|
||||
if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue;
|
||||
if (ot == OT_IMPLICIT || (IsHangarTile(ob->tile) && ot == OT_GOTO_DEPOT)) ot = OT_GOTO_STATION;
|
||||
if (ot == type && order->GetDestination() == destination) {
|
||||
/* Remove the order backup! If a station/depot gets removed, we can't/shouldn't restore those broken orders. */
|
||||
delete ob;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
|
||||
static void ClearGroup(GroupID group);
|
||||
static void ClearVehicle(const Vehicle *v);
|
||||
static void RemoveOrder(OrderType type, DestinationID destination);
|
||||
};
|
||||
|
||||
#define FOR_ALL_ORDER_BACKUPS_FROM(var, start) FOR_ALL_ITEMS_FROM(OrderBackup, order_backup_index, var, start)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "station_base.h"
|
||||
#include "waypoint_base.h"
|
||||
#include "company_base.h"
|
||||
#include "order_backup.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
|
@ -1699,6 +1700,8 @@ restart:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
OrderBackup::RemoveOrder(type, destination);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -155,6 +155,8 @@ struct NetworkSettings {
|
|||
uint16 bytes_per_frame; ///< how many bytes may, over a long period, be received per frame?
|
||||
uint16 bytes_per_frame_burst; ///< how many bytes may, over a short period, be received?
|
||||
uint16 max_join_time; ///< maximum amount of time, in game ticks, a client may take to join
|
||||
uint16 max_download_time; ///< maximum amount of time, in game ticks, a client may take to download the map
|
||||
uint16 max_password_time; ///< maximum amount of time, in game ticks, a client may take to enter the password
|
||||
bool pause_on_join; ///< pause the game when people join
|
||||
uint16 server_port; ///< port the server listens on
|
||||
uint16 server_admin_port; ///< port the server listens on for the admin network
|
||||
|
|
|
@ -645,6 +645,8 @@ const SettingDesc _settings[] = {
|
|||
SDTC_VAR(network.bytes_per_frame, SLE_UINT16, S, NO, 8, 1, 65535, 0, STR_NULL, NULL),
|
||||
SDTC_VAR(network.bytes_per_frame_burst,SLE_UINT16, S, NO, 256, 1, 65535, 0, STR_NULL, NULL),
|
||||
SDTC_VAR(network.max_join_time, SLE_UINT16, S, NO, 500, 0, 32000, 0, STR_NULL, NULL),
|
||||
SDTC_VAR(network.max_download_time, SLE_UINT16, S, NO, 1000, 0, 32000, 0, STR_NULL, NULL),
|
||||
SDTC_VAR(network.max_password_time, SLE_UINT16, S, NO, 2000, 0, 32000, 0, STR_NULL, NULL),
|
||||
SDTC_BOOL(network.pause_on_join, S, NO, true, STR_NULL, NULL),
|
||||
SDTC_VAR(network.server_port, SLE_UINT16, S, NO,NETWORK_DEFAULT_PORT,0,65535,0,STR_NULL, NULL),
|
||||
SDTC_VAR(network.server_admin_port, SLE_UINT16, S, NO, NETWORK_ADMIN_PORT,0,65535,0,STR_NULL, NULL),
|
||||
|
|
Loading…
Reference in New Issue