From 4575e50a69895a996797924918c95a60be0d369d Mon Sep 17 00:00:00 2001 From: frosch Date: Sun, 1 Nov 2015 11:59:17 +0000 Subject: [PATCH] (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) --- src/network/network.cpp | 3 --- src/network/network_func.h | 1 - src/network/network_gui.cpp | 31 ++++++++++++++++++------------- src/network/network_udp.cpp | 28 ++++++++++++++++++++-------- src/pathfinder/follow_track.hpp | 7 ++++++- src/town_cmd.cpp | 7 +++---- src/train_cmd.cpp | 8 +++++--- 7 files changed, 52 insertions(+), 33 deletions(-) diff --git a/src/network/network.cpp b/src/network/network.cpp index ce37aaa3fa..0bbdd0d06c 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -63,7 +63,6 @@ NetworkCompanyState *_network_company_states = NULL; ///< Statistics about some ClientID _network_own_client_id; ///< Our client identifier. ClientID _redirect_console_to_client; ///< If not invalid, redirect the console output to a client. bool _network_need_advertise; ///< Whether we need to advertise. -uint32 _network_last_advertise_frame; ///< Last time we did advertise. uint8 _network_reconnect; ///< Reconnect timeout StringList _network_bind_list; ///< The addresses to bind on. StringList _network_host_list; ///< The servers we know. @@ -759,7 +758,6 @@ bool NetworkServerStart() if (_network_dedicated) IConsoleCmdExec("exec scripts/on_dedicated.scr 0"); /* Try to register us to the master server */ - _network_last_advertise_frame = 0; _network_need_advertise = true; NetworkUDPAdvertise(); @@ -1076,7 +1074,6 @@ void NetworkStartUp() /* Network is available */ _network_available = NetworkCoreInitialize(); _network_dedicated = false; - _network_last_advertise_frame = 0; _network_need_advertise = true; _network_advertise_retries = 0; diff --git a/src/network/network_func.h b/src/network/network_func.h index 375cc3da56..4f1525b5a4 100644 --- a/src/network/network_func.h +++ b/src/network/network_func.h @@ -34,7 +34,6 @@ extern NetworkCompanyState *_network_company_states; extern ClientID _network_own_client_id; extern ClientID _redirect_console_to_client; extern bool _network_need_advertise; -extern uint32 _network_last_advertise_frame; extern uint8 _network_reconnect; extern StringList _network_bind_list; extern StringList _network_host_list; diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 013b375bda..795d28e139 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1863,7 +1863,9 @@ struct NetworkClientListWindow : Window { int selected_item; uint server_client_width; - uint company_icon_width; + uint line_height; + + Dimension icon_size; NetworkClientListWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc), @@ -1885,7 +1887,7 @@ struct NetworkClientListWindow : Window { 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(WID_CL_PANEL)->current_y); /* If height is changed */ @@ -1901,7 +1903,8 @@ struct NetworkClientListWindow : Window { 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->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 const NetworkClientInfo *ci; @@ -1909,7 +1912,7 @@ struct NetworkClientListWindow : Window { 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() @@ -1925,11 +1928,13 @@ struct NetworkClientListWindow : Window { if (widget != WID_CL_PANEL) return; 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 left = r.left + WD_FRAMERECT_LEFT; 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; @@ -1943,24 +1948,24 @@ struct NetworkClientListWindow : Window { FOR_ALL_CLIENT_INFOS(ci) { TextColour colour; 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; } else { colour = TC_BLACK; } 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 { - 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 */ - 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(WID_CL_PANEL)->pos_y; int item = -1; if (IsInsideMM(pt.y, WD_FRAMERECT_TOP, this->GetWidget(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! */ diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index 731d51ca05..1cccbf6441 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -42,9 +42,9 @@ static ThreadMutex *_network_udp_mutex = ThreadMutex::New(); /** Session key to register ourselves to the master server */ static uint64 _session_key = 0; -static const uint ADVERTISE_NORMAL_INTERVAL = 30000; ///< interval between advertising in ticks (15 minutes) -static const uint ADVERTISE_RETRY_INTERVAL = 300; ///< re-advertise when no response after this many ticks (9 seconds) -static const uint ADVERTISE_RETRY_TIMES = 3; ///< give up re-advertising after this much failed retries +static const uint32 ADVERTISE_NORMAL_INTERVAL = 15 * 60 * 1000; ///< interval between advertising in ms (15 minutes) +static const uint32 ADVERTISE_RETRY_INTERVAL = 10 * 1000; ///< re-advertise when no response after this many ms (10 seconds) +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_server_socket = NULL; ///< udp server socket @@ -616,25 +616,37 @@ static void NetworkUDPAdvertiseThread(void *pntr) */ 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 */ 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_advertise_retries = ADVERTISE_RETRY_TIMES; } else { /* Only send once every ADVERTISE_NORMAL_INTERVAL ticks */ 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; + } 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_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)) { NetworkUDPAdvertiseThread(NULL); diff --git a/src/pathfinder/follow_track.hpp b/src/pathfinder/follow_track.hpp index a16512bc06..9f19b029c0 100644 --- a/src/pathfinder/follow_track.hpp +++ b/src/pathfinder/follow_track.hpp @@ -144,7 +144,12 @@ struct CFollowTrackT * missing road bit, or inability to connect the * different bits due to slopes. */ 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; } if (!Allow90degTurns()) { diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index ea44603b0c..ee2828ad7a 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1378,13 +1378,12 @@ static bool GrowTownAtRoad(Town *t, TileIndex tile) /* Try to grow the town from this point */ GrowTownInTile(&tile, cur_rb, target_dir, t); + if (_grow_town_result == GROWTH_SUCCEED) return true; /* Exclude the source position from the bitmask * and return if no more road blocks available */ if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir)); - if (cur_rb == ROAD_NONE) { - return _grow_town_result == GROWTH_SUCCEED; - } + if (cur_rb == ROAD_NONE) return false; if (IsTileType(tile, MP_TUNNELBRIDGE)) { /* 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. */ } while (--_grow_town_result >= 0); - return _grow_town_result == GROWTH_SUCCEED - 1; + return false; } /** diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 8f20973b35..6f2feeaab7 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -1386,13 +1386,15 @@ CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, uint16 data, uint3 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()) { + /* Restore the train we had. */ + RestoreTrainBackup(original); 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? */ if (flags & DC_EXEC) { /* First normalise the sub types of the chain. */