From 6c6fa1d444d1d83546b53a29b706d21779cdada5 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Fri, 16 Oct 2015 22:20:16 +0100 Subject: [PATCH] add ability for server to kick player, closes #2071 --- data/language/english_uk.txt | 1 + src/localisation/string_ids.h | 2 ++ src/network/network.cpp | 32 ++++++++++++++++++++- src/network/network.h | 6 +++- src/windows/player_list.c | 53 +++++++++++++++++++++++++++++++++-- 5 files changed, 90 insertions(+), 4 deletions(-) diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index f6d816fa12..fa72826150 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -3894,6 +3894,7 @@ STR_5552 :{POP16}{POP16}Year {COMMA16}, {PUSH16}{PUSH16}{PUSH16}{STRINGID} {M STR_5553 :Pause game when Steam overlay is open STR_5554 :{SMALLFONT}{BLACK}Enable mountain tool STR_5555 :Show vehicles from other track types +STR_5556 :Kick Player ##################### # Rides/attractions # diff --git a/src/localisation/string_ids.h b/src/localisation/string_ids.h index 4ce62fe8c7..ff39a83959 100644 --- a/src/localisation/string_ids.h +++ b/src/localisation/string_ids.h @@ -2140,6 +2140,8 @@ enum { STR_CHEAT_SHOW_VEHICLES_FROM_OTHER_TRACK_TYPES = 5555, + STR_KICK_PLAYER = 5556, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 }; diff --git a/src/network/network.cpp b/src/network/network.cpp index f72fb0c4b1..52f39132e6 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -1042,7 +1042,7 @@ uint32 network_get_server_tick() return gNetwork.GetServerTick(); } -uint8 network_get_player_id() +uint8 network_get_current_player_id() { return gNetwork.GetPlayerID(); } @@ -1067,6 +1067,11 @@ int network_get_player_ping(unsigned int index) return gNetwork.player_list[index]->ping; } +int network_get_player_id(unsigned int index) +{ + return gNetwork.player_list[index]->id; +} + void network_send_map() { gNetwork.Server_Send_MAP(); @@ -1097,6 +1102,29 @@ void network_send_gamecmd(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 } } +void Network::KickPlayer(int playerId) +{ + NetworkPlayer *player = GetPlayerByID(playerId); + for(auto it = client_connection_list.begin(); it != client_connection_list.end(); it++) { + if ((*it)->player->id == playerId) { + char buffer[128]; + sprintf(buffer, "%s has been kicked.", (*it)->player->name); + + // Disconnect the client + closesocket((*it)->socket); + + chat_history_add(buffer); + Server_Send_CHAT(buffer); + break; + } + } +} + +void network_kick_player(int playerId) +{ + gNetwork.KickPlayer(playerId); +} + #ifdef USE_INET_PTON static bool network_get_address(char *dst, size_t dstLength, const char *host) { @@ -1145,6 +1173,8 @@ int network_get_num_players() { return 1; } const char* network_get_player_name(unsigned int index) { return "local (OpenRCT2 compiled without MP)"; } uint32 network_get_player_flags(unsigned int index) { return 0; } int network_get_player_ping(unsigned int index) { return 0; } +int network_get_player_id(unsigned int index) { return 0; } void network_send_chat(const char* text) {} void network_close() {} +void network_kick_player(int playerId) { } #endif /* DISABLE_NETWORK */ diff --git a/src/network/network.h b/src/network/network.h index 9f86bb5bf1..e1d698d5e8 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -173,6 +173,7 @@ public: const char* FormatChat(NetworkPlayer* fromplayer, const char* text); void SendPacketToClients(NetworkPacket& packet); bool CheckSRAND(uint32 tick, uint32 srand0); + void KickPlayer(int playerId); void Client_Send_AUTH(const char* gameversion, const char* name, const char* password); void Server_Send_MAP(NetworkConnection* connection = nullptr); @@ -261,16 +262,19 @@ int network_get_mode(); void network_update(); int network_get_authstatus(); uint32 network_get_server_tick(); -uint8 network_get_player_id(); +uint8 network_get_current_player_id(); int network_get_num_players(); const char* network_get_player_name(unsigned int index); uint32 network_get_player_flags(unsigned int index); int network_get_player_ping(unsigned int index); +int network_get_player_id(unsigned int index); void network_send_map(); void network_send_chat(const char* text); void network_send_gamecmd(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp, uint8 callback); +void network_kick_player(int playerId); + void network_print_error(); #ifdef USE_INET_PTON static bool network_get_address(char *dst, size_t dstLength, const char *host); diff --git a/src/windows/player_list.c b/src/windows/player_list.c index 0556f55e53..2a75e6b42a 100644 --- a/src/windows/player_list.c +++ b/src/windows/player_list.c @@ -24,6 +24,7 @@ #include "../localisation/localisation.h" #include "../network/network.h" #include "../sprites.h" +#include "../windows/dropdown.h" enum WINDOW_PLAYER_LIST_WIDGET_IDX { WIDX_BACKGROUND, @@ -47,8 +48,10 @@ static rct_widget window_player_list_widgets[] = { static void window_player_list_mouseup(rct_window *w, int widgetIndex); static void window_player_list_resize(rct_window *w); static void window_player_list_mousedown(int widgetIndex, rct_window* w, rct_widget* widget); +static void window_player_list_dropdown(rct_window *w, int widgetIndex, int dropdownIndex); static void window_player_list_update(rct_window *w); static void window_player_list_scrollgetsize(rct_window *w, int scrollIndex, int *width, int *height); +static void window_player_list_scrollmousedown(rct_window *w, int scrollIndex, int x, int y); static void window_player_list_scrollmouseover(rct_window *w, int scrollIndex, int x, int y); static void window_player_list_invalidate(rct_window *w); static void window_player_list_paint(rct_window *w, rct_drawpixelinfo *dpi); @@ -59,7 +62,7 @@ static rct_window_event_list window_player_list_events = { window_player_list_mouseup, window_player_list_resize, window_player_list_mousedown, - NULL, + window_player_list_dropdown, NULL, window_player_list_update, NULL, @@ -71,7 +74,7 @@ static rct_window_event_list window_player_list_events = { NULL, NULL, window_player_list_scrollgetsize, - NULL, + window_player_list_scrollmousedown, NULL, window_player_list_scrollmouseover, NULL, @@ -85,8 +88,14 @@ static rct_window_event_list window_player_list_events = { window_player_list_scrollpaint }; +enum { + DDIDX_KICK +}; + static void window_player_list_refresh_list(rct_window *w); +static int _dropdownPlayerId; + void window_player_list_open() { rct_window* window; @@ -154,6 +163,15 @@ static void window_player_list_mousedown(int widgetIndex, rct_window* w, rct_wid } } +static void window_player_list_dropdown(rct_window *w, int widgetIndex, int dropdownIndex) +{ + switch (dropdownIndex) { + case DDIDX_KICK: + network_kick_player(_dropdownPlayerId); + break; + } +} + static void window_player_list_update(rct_window *w) { widget_invalidate(w, WIDX_TAB1 + w->page); @@ -178,6 +196,37 @@ static void window_player_list_scrollgetsize(rct_window *w, int scrollIndex, int } } +static void window_player_list_scrollmousedown(rct_window *w, int scrollIndex, int x, int y) +{ + if (network_get_mode() != NETWORK_MODE_SERVER) { + return; + } + + int index; + + index = y / 10; + if (index >= w->no_list_items) + return; + + w->selected_list_item = index; + window_invalidate(w); + + rct_widget *listWidget = &w->widgets[WIDX_LIST]; + int ddx = w->x + listWidget->left + x; + int ddy = w->y + listWidget->top + y; + + if (index == 0) { + return; + } + _dropdownPlayerId = network_get_player_id(index); + if (_dropdownPlayerId == network_get_current_player_id()) { + return; + } + + gDropdownItemsFormat[0] = STR_KICK_PLAYER; + window_dropdown_show_text(ddx, ddy, 0, 7, 0, 1); +} + static void window_player_list_scrollmouseover(rct_window *w, int scrollIndex, int x, int y) { int index;