From ee005fbaf557f3c3c7fdc7b88ac401060c7d8dd4 Mon Sep 17 00:00:00 2001 From: frosch Date: Mon, 11 Dec 2017 19:20:44 +0000 Subject: [PATCH] (svn r27939) [1.7] -Backport from trunk: - Fix: 'unban' console command was not handling IPv6 adresses properly (r27914, r27913) - Fix: Keep the 'link' between industry chain and smallmap windows whenever possible [FS#6585] (r27905) - Fix: When the last vehicle is removed from a shared orders group, hide the 'Stop sharing' button in the vehicle orders window [FS#6593] (r27904) - Fix: Tooltip of 'increase service interval' said 'decrease' [FS#6606] (r27895) - Fix: Console command parser passed invalid strings to the debug output, if command lines had many parameters [FS#6576] (r27884, r27883) --- src/console.cpp | 15 +++++++++++++-- src/console_cmds.cpp | 35 +++++++++++++++++++++-------------- src/smallmap_gui.cpp | 19 ++++++++++++++++--- src/smallmap_gui.h | 3 ++- src/vehicle.cpp | 2 +- src/vehicle_gui.cpp | 2 +- 6 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/console.cpp b/src/console.cpp index 511019281a..ece8599168 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -434,7 +434,10 @@ void IConsoleCmdExec(const char *cmdstr) * enclosed in "" are taken as one token. We can only go as far as the amount * of characters in our stream or the max amount of tokens we can handle */ for (cmdptr = cmdstr, t_index = 0, tstream_i = 0; *cmdptr != '\0'; cmdptr++) { - if (t_index >= lengthof(tokens) || tstream_i >= lengthof(tokenstream)) break; + if (tstream_i >= lengthof(tokenstream)) { + IConsoleError("command line too long"); + return; + } switch (*cmdptr) { case ' ': // Token separator @@ -452,6 +455,10 @@ void IConsoleCmdExec(const char *cmdstr) case '"': // Tokens enclosed in "" are one token longtoken = !longtoken; if (!foundtoken) { + if (t_index >= lengthof(tokens)) { + IConsoleError("command line too long"); + return; + } tokens[t_index++] = &tokenstream[tstream_i]; foundtoken = true; } @@ -466,6 +473,10 @@ void IConsoleCmdExec(const char *cmdstr) tokenstream[tstream_i++] = *cmdptr; if (!foundtoken) { + if (t_index >= lengthof(tokens)) { + IConsoleError("command line too long"); + return; + } tokens[t_index++] = &tokenstream[tstream_i - 1]; foundtoken = true; } @@ -473,7 +484,7 @@ void IConsoleCmdExec(const char *cmdstr) } } - for (uint i = 0; tokens[i] != NULL; i++) { + for (uint i = 0; i < lengthof(tokens) && tokens[i] != NULL; i++) { DEBUG(console, 8, "Token %d is: '%s'", i, tokens[i]); } diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 9cfc8e8f9d..3b65224de8 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -553,29 +553,36 @@ DEF_CONSOLE_CMD(ConBan) DEF_CONSOLE_CMD(ConUnBan) { - if (argc == 0) { - IConsoleHelp("Unban a client from a network game. Usage: 'unban '"); + IConsoleHelp("Unban a client from a network game. Usage: 'unban '"); IConsoleHelp("For a list of banned IP's, see the command 'banlist'"); return true; } if (argc != 2) return false; - uint index = (strchr(argv[1], '.') == NULL) ? atoi(argv[1]) : 0; - index--; - uint i = 0; - - for (char **iter = _network_ban_list.Begin(); iter != _network_ban_list.End(); iter++, i++) { - if (strcmp(_network_ban_list[i], argv[1]) == 0 || index == i) { - free(_network_ban_list[i]); - _network_ban_list.Erase(iter); - IConsolePrint(CC_DEFAULT, "IP unbanned."); - return true; - } + /* Try by IP. */ + uint index; + for (index = 0; index < _network_ban_list.Length(); index++) { + if (strcmp(_network_ban_list[index], argv[1]) == 0) break; + } + + /* Try by index. */ + if (index >= _network_ban_list.Length()) { + index = atoi(argv[1]) - 1U; // let it wrap + } + + if (index < _network_ban_list.Length()) { + char msg[64]; + seprintf(msg, lastof(msg), "Unbanned %s", _network_ban_list[index]); + IConsolePrint(CC_DEFAULT, msg); + free(_network_ban_list[index]); + _network_ban_list.Erase(_network_ban_list.Get(index)); + } else { + IConsolePrint(CC_DEFAULT, "Invalid list index or IP not in ban-list."); + IConsolePrint(CC_DEFAULT, "For a list of banned IP's, see the command 'banlist'"); } - IConsolePrint(CC_DEFAULT, "IP not in ban-list."); return true; } diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index f4bcdece18..c9d4ae4c8c 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -572,6 +572,12 @@ static const byte _vehicle_type_colours[6] = { }; +/** Notify the industry chain window to stop sending newly selected industries. */ +/* static */ void SmallMapWindow::BreakIndustryChainLink() +{ + InvalidateWindowClassesData(WC_INDUSTRY_CARGOES, NUM_INDUSTRYTYPES); +} + inline Point SmallMapWindow::SmallmapRemapCoords(int x, int y) const { Point pt; @@ -1069,6 +1075,12 @@ SmallMapWindow::SmallMapWindow(WindowDesc *desc, int window_number) : Window(des this->SetOverlayCargoMask(); } +SmallMapWindow::~SmallMapWindow() +{ + delete this->overlay; + this->BreakIndustryChainLink(); +} + /** * Rebuilds the colour indices used for fast access to the smallmap contour colours based on the heightlevel. */ @@ -1275,6 +1287,7 @@ void SmallMapWindow::SwitchMapType(SmallMapType map_type) this->SetupWidgetData(); if (map_type == SMT_LINKSTATS) this->overlay->RebuildCache(); + if (map_type != SMT_INDUSTRY) this->BreakIndustryChainLink(); this->SetDirty(); } @@ -1326,6 +1339,8 @@ void SmallMapWindow::SelectLegendItem(int click_pos, LegendAndColour *legend, in } else { legend[click_pos].show_on_map = !legend[click_pos].show_on_map; } + + if (this->map_type == SMT_INDUSTRY) this->BreakIndustryChainLink(); } /** @@ -1380,9 +1395,6 @@ int SmallMapWindow::GetPositionOnLegend(Point pt) /* virtual */ void SmallMapWindow::OnClick(Point pt, int widget, int click_count) { - /* User clicked something, notify the industry chain window to stop sending newly selected industries. */ - InvalidateWindowClassesData(WC_INDUSTRY_CARGOES, NUM_INDUSTRYTYPES); - switch (widget) { case WID_SM_MAP: { // Map window /* @@ -1471,6 +1483,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt) switch (this->map_type) { case SMT_INDUSTRY: tbl = _legend_from_industries; + this->BreakIndustryChainLink(); break; case SMT_OWNER: tbl = &(_legend_land_owners[NUM_NO_COMPANY_ENTRIES]); diff --git a/src/smallmap_gui.h b/src/smallmap_gui.h index 2903544a69..c3151b1a71 100644 --- a/src/smallmap_gui.h +++ b/src/smallmap_gui.h @@ -82,6 +82,7 @@ protected: uint8 refresh; ///< Refresh counter, zeroed every FORCE_REFRESH_PERIOD ticks. LinkGraphOverlay *overlay; + static void BreakIndustryChainLink(); Point SmallmapRemapCoords(int x, int y) const; /** @@ -173,7 +174,7 @@ public: friend class NWidgetSmallmapDisplay; SmallMapWindow(WindowDesc *desc, int window_number); - virtual ~SmallMapWindow() { delete this->overlay; } + virtual ~SmallMapWindow(); void SmallMapCenterOnCurrentPos(); Point GetStationMiddle(const Station *st) const; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index b686461316..9c39857eb3 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -2676,7 +2676,7 @@ void Vehicle::RemoveFromShared() if (this->orders.list->GetNumVehicles() == 1) { /* When there is only one vehicle, remove the shared order list window. */ DeleteWindowById(GetWindowClassForVehicleType(this->type), vli.Pack()); - InvalidateVehicleOrder(this->FirstShared(), 0); + InvalidateVehicleOrder(this->FirstShared(), VIWD_MODIFY_ORDERS); } else if (were_first) { /* If we were the first one, update to the new first one. * Note: FirstShared() is already the new first */ diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index b8f0ae875d..9adc0872fc 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1830,7 +1830,7 @@ static const NWidgetPart _nested_train_vehicle_details_widgets[] = { NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_VD_DECREASE_SERVICING_INTERVAL), SetFill(0, 1), SetDataTip(AWV_DECREASE, STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_VD_INCREASE_SERVICING_INTERVAL), SetFill(0, 1), - SetDataTip(AWV_INCREASE, STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP), + SetDataTip(AWV_INCREASE, STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VD_SERVICE_INTERVAL_DROPDOWN), SetFill(0, 1), SetDataTip(STR_EMPTY, STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP), NWidget(WWT_PANEL, COLOUR_GREY, WID_VD_SERVICING_INTERVAL), SetFill(1, 1), SetResize(1, 0), EndContainer(),