mirror of https://github.com/OpenTTD/OpenTTD
(svn r27431) [1.5] -Backport from trunk:
- Fix: Consider text and icon sizes when drawing the client list [FS#6265] (r27421) - Fix: GrowTownAtRoad sometimes returned false, even when a house was built [FS#6362] (r27420) - Fix: CmdSellRailWagon did not revert all actions properly when no orderlist could be allocated [FS#6369] (r27419) - Fix: Desync due to incorrect storage of segments with different railtype in the YAPF cache [FS#6329] [FS#6379] (r27418) - Fix: When a dedicated server was paused with no clients, the master server advertisement interval was slowed, causing deadvertisement of the server [FS#6368] (r27400)release/1.5
parent
23a792ad2d
commit
4575e50a69
|
@ -63,7 +63,6 @@ NetworkCompanyState *_network_company_states = NULL; ///< Statistics about some
|
||||||
ClientID _network_own_client_id; ///< Our client identifier.
|
ClientID _network_own_client_id; ///< Our client identifier.
|
||||||
ClientID _redirect_console_to_client; ///< If not invalid, redirect the console output to a client.
|
ClientID _redirect_console_to_client; ///< If not invalid, redirect the console output to a client.
|
||||||
bool _network_need_advertise; ///< Whether we need to advertise.
|
bool _network_need_advertise; ///< Whether we need to advertise.
|
||||||
uint32 _network_last_advertise_frame; ///< Last time we did advertise.
|
|
||||||
uint8 _network_reconnect; ///< Reconnect timeout
|
uint8 _network_reconnect; ///< Reconnect timeout
|
||||||
StringList _network_bind_list; ///< The addresses to bind on.
|
StringList _network_bind_list; ///< The addresses to bind on.
|
||||||
StringList _network_host_list; ///< The servers we know.
|
StringList _network_host_list; ///< The servers we know.
|
||||||
|
@ -759,7 +758,6 @@ bool NetworkServerStart()
|
||||||
if (_network_dedicated) IConsoleCmdExec("exec scripts/on_dedicated.scr 0");
|
if (_network_dedicated) IConsoleCmdExec("exec scripts/on_dedicated.scr 0");
|
||||||
|
|
||||||
/* Try to register us to the master server */
|
/* Try to register us to the master server */
|
||||||
_network_last_advertise_frame = 0;
|
|
||||||
_network_need_advertise = true;
|
_network_need_advertise = true;
|
||||||
NetworkUDPAdvertise();
|
NetworkUDPAdvertise();
|
||||||
|
|
||||||
|
@ -1076,7 +1074,6 @@ void NetworkStartUp()
|
||||||
/* Network is available */
|
/* Network is available */
|
||||||
_network_available = NetworkCoreInitialize();
|
_network_available = NetworkCoreInitialize();
|
||||||
_network_dedicated = false;
|
_network_dedicated = false;
|
||||||
_network_last_advertise_frame = 0;
|
|
||||||
_network_need_advertise = true;
|
_network_need_advertise = true;
|
||||||
_network_advertise_retries = 0;
|
_network_advertise_retries = 0;
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@ extern NetworkCompanyState *_network_company_states;
|
||||||
extern ClientID _network_own_client_id;
|
extern ClientID _network_own_client_id;
|
||||||
extern ClientID _redirect_console_to_client;
|
extern ClientID _redirect_console_to_client;
|
||||||
extern bool _network_need_advertise;
|
extern bool _network_need_advertise;
|
||||||
extern uint32 _network_last_advertise_frame;
|
|
||||||
extern uint8 _network_reconnect;
|
extern uint8 _network_reconnect;
|
||||||
extern StringList _network_bind_list;
|
extern StringList _network_bind_list;
|
||||||
extern StringList _network_host_list;
|
extern StringList _network_host_list;
|
||||||
|
|
|
@ -1863,7 +1863,9 @@ struct NetworkClientListWindow : Window {
|
||||||
int selected_item;
|
int selected_item;
|
||||||
|
|
||||||
uint server_client_width;
|
uint server_client_width;
|
||||||
uint company_icon_width;
|
uint line_height;
|
||||||
|
|
||||||
|
Dimension icon_size;
|
||||||
|
|
||||||
NetworkClientListWindow(WindowDesc *desc, WindowNumber window_number) :
|
NetworkClientListWindow(WindowDesc *desc, WindowNumber window_number) :
|
||||||
Window(desc),
|
Window(desc),
|
||||||
|
@ -1885,7 +1887,7 @@ struct NetworkClientListWindow : Window {
|
||||||
if (ci->client_playas != COMPANY_INACTIVE_CLIENT) num++;
|
if (ci->client_playas != COMPANY_INACTIVE_CLIENT) num++;
|
||||||
}
|
}
|
||||||
|
|
||||||
num *= FONT_HEIGHT_NORMAL;
|
num *= this->line_height;
|
||||||
|
|
||||||
int diff = (num + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM) - (this->GetWidget<NWidgetBase>(WID_CL_PANEL)->current_y);
|
int diff = (num + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM) - (this->GetWidget<NWidgetBase>(WID_CL_PANEL)->current_y);
|
||||||
/* If height is changed */
|
/* If height is changed */
|
||||||
|
@ -1901,7 +1903,8 @@ struct NetworkClientListWindow : Window {
|
||||||
if (widget != WID_CL_PANEL) return;
|
if (widget != WID_CL_PANEL) return;
|
||||||
|
|
||||||
this->server_client_width = max(GetStringBoundingBox(STR_NETWORK_SERVER).width, GetStringBoundingBox(STR_NETWORK_CLIENT).width) + WD_FRAMERECT_RIGHT;
|
this->server_client_width = max(GetStringBoundingBox(STR_NETWORK_SERVER).width, GetStringBoundingBox(STR_NETWORK_CLIENT).width) + WD_FRAMERECT_RIGHT;
|
||||||
this->company_icon_width = GetSpriteSize(SPR_COMPANY_ICON).width + WD_FRAMERECT_LEFT;
|
this->icon_size = GetSpriteSize(SPR_COMPANY_ICON);
|
||||||
|
this->line_height = max(this->icon_size.height + 2U, (uint)FONT_HEIGHT_NORMAL);
|
||||||
|
|
||||||
uint width = 100; // Default width
|
uint width = 100; // Default width
|
||||||
const NetworkClientInfo *ci;
|
const NetworkClientInfo *ci;
|
||||||
|
@ -1909,7 +1912,7 @@ struct NetworkClientListWindow : Window {
|
||||||
width = max(width, GetStringBoundingBox(ci->client_name).width);
|
width = max(width, GetStringBoundingBox(ci->client_name).width);
|
||||||
}
|
}
|
||||||
|
|
||||||
size->width = WD_FRAMERECT_LEFT + this->server_client_width + this->company_icon_width + width + WD_FRAMERECT_RIGHT;
|
size->width = WD_FRAMERECT_LEFT + this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT + width + WD_FRAMERECT_RIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnPaint()
|
virtual void OnPaint()
|
||||||
|
@ -1925,11 +1928,13 @@ struct NetworkClientListWindow : Window {
|
||||||
if (widget != WID_CL_PANEL) return;
|
if (widget != WID_CL_PANEL) return;
|
||||||
|
|
||||||
bool rtl = _current_text_dir == TD_RTL;
|
bool rtl = _current_text_dir == TD_RTL;
|
||||||
int icon_y_offset = 1 + (FONT_HEIGHT_NORMAL - 10) / 2;
|
int icon_offset = (this->line_height - icon_size.height) / 2;
|
||||||
|
int text_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2;
|
||||||
|
|
||||||
uint y = r.top + WD_FRAMERECT_TOP;
|
uint y = r.top + WD_FRAMERECT_TOP;
|
||||||
uint left = r.left + WD_FRAMERECT_LEFT;
|
uint left = r.left + WD_FRAMERECT_LEFT;
|
||||||
uint right = r.right - WD_FRAMERECT_RIGHT;
|
uint right = r.right - WD_FRAMERECT_RIGHT;
|
||||||
uint type_icon_width = this->server_client_width + this->company_icon_width;
|
uint type_icon_width = this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT;
|
||||||
|
|
||||||
|
|
||||||
uint type_left = rtl ? right - this->server_client_width : left;
|
uint type_left = rtl ? right - this->server_client_width : left;
|
||||||
|
@ -1943,24 +1948,24 @@ struct NetworkClientListWindow : Window {
|
||||||
FOR_ALL_CLIENT_INFOS(ci) {
|
FOR_ALL_CLIENT_INFOS(ci) {
|
||||||
TextColour colour;
|
TextColour colour;
|
||||||
if (this->selected_item == i++) { // Selected item, highlight it
|
if (this->selected_item == i++) { // Selected item, highlight it
|
||||||
GfxFillRect(r.left + 1, y, r.right - 1, y + FONT_HEIGHT_NORMAL - 1, PC_BLACK);
|
GfxFillRect(r.left + 1, y, r.right - 1, y + this->line_height - 1, PC_BLACK);
|
||||||
colour = TC_WHITE;
|
colour = TC_WHITE;
|
||||||
} else {
|
} else {
|
||||||
colour = TC_BLACK;
|
colour = TC_BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ci->client_id == CLIENT_ID_SERVER) {
|
if (ci->client_id == CLIENT_ID_SERVER) {
|
||||||
DrawString(type_left, type_right, y, STR_NETWORK_SERVER, colour);
|
DrawString(type_left, type_right, y + text_offset, STR_NETWORK_SERVER, colour);
|
||||||
} else {
|
} else {
|
||||||
DrawString(type_left, type_right, y, STR_NETWORK_CLIENT, colour);
|
DrawString(type_left, type_right, y + text_offset, STR_NETWORK_CLIENT, colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Filter out spectators */
|
/* Filter out spectators */
|
||||||
if (Company::IsValidID(ci->client_playas)) DrawCompanyIcon(ci->client_playas, icon_left, y + icon_y_offset);
|
if (Company::IsValidID(ci->client_playas)) DrawCompanyIcon(ci->client_playas, icon_left, y + icon_offset);
|
||||||
|
|
||||||
DrawString(name_left, name_right, y, ci->client_name, colour);
|
DrawString(name_left, name_right, y + text_offset, ci->client_name, colour);
|
||||||
|
|
||||||
y += FONT_HEIGHT_NORMAL;
|
y += line_height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1993,7 +1998,7 @@ struct NetworkClientListWindow : Window {
|
||||||
pt.y -= this->GetWidget<NWidgetBase>(WID_CL_PANEL)->pos_y;
|
pt.y -= this->GetWidget<NWidgetBase>(WID_CL_PANEL)->pos_y;
|
||||||
int item = -1;
|
int item = -1;
|
||||||
if (IsInsideMM(pt.y, WD_FRAMERECT_TOP, this->GetWidget<NWidgetBase>(WID_CL_PANEL)->current_y - WD_FRAMERECT_BOTTOM)) {
|
if (IsInsideMM(pt.y, WD_FRAMERECT_TOP, this->GetWidget<NWidgetBase>(WID_CL_PANEL)->current_y - WD_FRAMERECT_BOTTOM)) {
|
||||||
item = (pt.y - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL;
|
item = (pt.y - WD_FRAMERECT_TOP) / this->line_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* It did not change.. no update! */
|
/* It did not change.. no update! */
|
||||||
|
|
|
@ -42,9 +42,9 @@ static ThreadMutex *_network_udp_mutex = ThreadMutex::New();
|
||||||
/** Session key to register ourselves to the master server */
|
/** Session key to register ourselves to the master server */
|
||||||
static uint64 _session_key = 0;
|
static uint64 _session_key = 0;
|
||||||
|
|
||||||
static const uint ADVERTISE_NORMAL_INTERVAL = 30000; ///< interval between advertising in ticks (15 minutes)
|
static const uint32 ADVERTISE_NORMAL_INTERVAL = 15 * 60 * 1000; ///< interval between advertising in ms (15 minutes)
|
||||||
static const uint ADVERTISE_RETRY_INTERVAL = 300; ///< re-advertise when no response after this many ticks (9 seconds)
|
static const uint32 ADVERTISE_RETRY_INTERVAL = 10 * 1000; ///< re-advertise when no response after this many ms (10 seconds)
|
||||||
static const uint ADVERTISE_RETRY_TIMES = 3; ///< give up re-advertising after this much failed retries
|
static const uint32 ADVERTISE_RETRY_TIMES = 3; ///< give up re-advertising after this much failed retries
|
||||||
|
|
||||||
NetworkUDPSocketHandler *_udp_client_socket = NULL; ///< udp client socket
|
NetworkUDPSocketHandler *_udp_client_socket = NULL; ///< udp client socket
|
||||||
NetworkUDPSocketHandler *_udp_server_socket = NULL; ///< udp server socket
|
NetworkUDPSocketHandler *_udp_server_socket = NULL; ///< udp server socket
|
||||||
|
@ -616,25 +616,37 @@ static void NetworkUDPAdvertiseThread(void *pntr)
|
||||||
*/
|
*/
|
||||||
void NetworkUDPAdvertise()
|
void NetworkUDPAdvertise()
|
||||||
{
|
{
|
||||||
|
static uint32 _last_advertisement = 0; ///< The time of the last advertisement (used to check for wrapping of time)
|
||||||
|
static uint32 _next_advertisement = 0; ///< The next time we should perform a normal advertisement.
|
||||||
|
static uint32 _next_retry = 0; ///< The next time we should perform a retry of an advertisement.
|
||||||
|
|
||||||
/* Check if we should send an advertise */
|
/* Check if we should send an advertise */
|
||||||
if (!_networking || !_network_server || !_network_udp_server || !_settings_client.network.server_advertise) return;
|
if (!_networking || !_network_server || !_network_udp_server || !_settings_client.network.server_advertise) return;
|
||||||
|
|
||||||
if (_network_need_advertise) {
|
if (_network_need_advertise || _realtime_tick < _last_advertisement) {
|
||||||
|
/* Forced advertisement, or a wrapping of time in which case we determine the advertisement/retry times again. */
|
||||||
_network_need_advertise = false;
|
_network_need_advertise = false;
|
||||||
_network_advertise_retries = ADVERTISE_RETRY_TIMES;
|
_network_advertise_retries = ADVERTISE_RETRY_TIMES;
|
||||||
} else {
|
} else {
|
||||||
/* Only send once every ADVERTISE_NORMAL_INTERVAL ticks */
|
/* Only send once every ADVERTISE_NORMAL_INTERVAL ticks */
|
||||||
if (_network_advertise_retries == 0) {
|
if (_network_advertise_retries == 0) {
|
||||||
if ((_network_last_advertise_frame + ADVERTISE_NORMAL_INTERVAL) > _frame_counter) return;
|
if (_realtime_tick <= _next_advertisement) return;
|
||||||
|
|
||||||
_network_advertise_retries = ADVERTISE_RETRY_TIMES;
|
_network_advertise_retries = ADVERTISE_RETRY_TIMES;
|
||||||
|
} else {
|
||||||
|
/* An actual retry. */
|
||||||
|
if (_realtime_tick <= _next_retry) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_network_last_advertise_frame + ADVERTISE_RETRY_INTERVAL) > _frame_counter) return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_network_advertise_retries--;
|
_network_advertise_retries--;
|
||||||
_network_last_advertise_frame = _frame_counter;
|
_last_advertisement = _realtime_tick;
|
||||||
|
_next_advertisement = _realtime_tick + ADVERTISE_NORMAL_INTERVAL;
|
||||||
|
_next_retry = _realtime_tick + ADVERTISE_RETRY_INTERVAL;
|
||||||
|
|
||||||
|
/* Make sure we do not have an overflow when checking these; when time wraps, we simply force an advertisement. */
|
||||||
|
if (_next_advertisement < _last_advertisement) _next_advertisement = UINT32_MAX;
|
||||||
|
if (_next_retry < _last_advertisement) _next_retry = UINT32_MAX;
|
||||||
|
|
||||||
if (!ThreadObject::New(NetworkUDPAdvertiseThread, NULL)) {
|
if (!ThreadObject::New(NetworkUDPAdvertiseThread, NULL)) {
|
||||||
NetworkUDPAdvertiseThread(NULL);
|
NetworkUDPAdvertiseThread(NULL);
|
||||||
|
|
|
@ -144,7 +144,12 @@ struct CFollowTrackT
|
||||||
* missing road bit, or inability to connect the
|
* missing road bit, or inability to connect the
|
||||||
* different bits due to slopes. */
|
* different bits due to slopes. */
|
||||||
if (IsRoadTT() && !IsTram() && TryReverse()) return true;
|
if (IsRoadTT() && !IsTram() && TryReverse()) return true;
|
||||||
m_err = EC_NO_WAY;
|
|
||||||
|
/* CanEnterNewTile already set a reason.
|
||||||
|
* Do NOT overwrite it (important for example for EC_RAIL_TYPE).
|
||||||
|
* Only set a reason if CanEnterNewTile was not called */
|
||||||
|
if (m_new_td_bits == TRACKDIR_BIT_NONE) m_err = EC_NO_WAY;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!Allow90degTurns()) {
|
if (!Allow90degTurns()) {
|
||||||
|
|
|
@ -1378,13 +1378,12 @@ static bool GrowTownAtRoad(Town *t, TileIndex tile)
|
||||||
|
|
||||||
/* Try to grow the town from this point */
|
/* Try to grow the town from this point */
|
||||||
GrowTownInTile(&tile, cur_rb, target_dir, t);
|
GrowTownInTile(&tile, cur_rb, target_dir, t);
|
||||||
|
if (_grow_town_result == GROWTH_SUCCEED) return true;
|
||||||
|
|
||||||
/* Exclude the source position from the bitmask
|
/* Exclude the source position from the bitmask
|
||||||
* and return if no more road blocks available */
|
* and return if no more road blocks available */
|
||||||
if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
|
if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
|
||||||
if (cur_rb == ROAD_NONE) {
|
if (cur_rb == ROAD_NONE) return false;
|
||||||
return _grow_town_result == GROWTH_SUCCEED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
|
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
|
||||||
/* Only build in the direction away from the tunnel or bridge. */
|
/* Only build in the direction away from the tunnel or bridge. */
|
||||||
|
@ -1419,7 +1418,7 @@ static bool GrowTownAtRoad(Town *t, TileIndex tile)
|
||||||
/* Max number of times is checked. */
|
/* Max number of times is checked. */
|
||||||
} while (--_grow_town_result >= 0);
|
} while (--_grow_town_result >= 0);
|
||||||
|
|
||||||
return _grow_town_result == GROWTH_SUCCEED - 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1386,13 +1386,15 @@ CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, uint16 data, uint3
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandCost cost(EXPENSES_NEW_VEHICLES);
|
|
||||||
for (Train *t = sell_head; t != NULL; t = t->Next()) cost.AddCost(-t->value);
|
|
||||||
|
|
||||||
if (first->orders.list == NULL && !OrderList::CanAllocateItem()) {
|
if (first->orders.list == NULL && !OrderList::CanAllocateItem()) {
|
||||||
|
/* Restore the train we had. */
|
||||||
|
RestoreTrainBackup(original);
|
||||||
return_cmd_error(STR_ERROR_NO_MORE_SPACE_FOR_ORDERS);
|
return_cmd_error(STR_ERROR_NO_MORE_SPACE_FOR_ORDERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommandCost cost(EXPENSES_NEW_VEHICLES);
|
||||||
|
for (Train *t = sell_head; t != NULL; t = t->Next()) cost.AddCost(-t->value);
|
||||||
|
|
||||||
/* do it? */
|
/* do it? */
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
/* First normalise the sub types of the chain. */
|
/* First normalise the sub types of the chain. */
|
||||||
|
|
Loading…
Reference in New Issue