Ticket #3241: t3241_kick_v2.patch
File t3241_kick_v2.patch, 25.1 KB (added by , 9 years ago) |
---|
-
binaries/data/mods/public/gui/common/network.js
5 5 { 6 6 case 0: return translate("Unknown reason"); 7 7 case 1: return translate("Unexpected shutdown"); 8 8 case 2: return translate("Incorrect network protocol version"); 9 9 case 3: return translate("Game has already started"); 10 case 4: return translate("You have been kicked from the match"); 11 case 5: return translate("You have been banned from the match"); 10 12 default: return sprintf(translate("\\[Invalid value %(id)s]"), { id: id }); 11 13 } 12 14 } 13 15 14 16 function reportDisconnect(reason) -
binaries/data/mods/public/gui/gamesetup/gamesetup.js
1705 1705 1706 1706 var message = ""; 1707 1707 if ("text" in msg && msg.text) 1708 1708 message = escapeText(msg.text); 1709 1709 1710 // Kick / ban players 1711 if ("text" in msg) 1712 { 1713 let split = msg.text.split(/\s/); 1714 let kick = msg.text.indexOf("/kick") == 0; 1715 let ban = msg.text.indexOf("/ban") == 0; 1716 let playerGUID = Engine.GetPlayerGUID(); 1717 if (kick || ban) 1718 { 1719 if (!g_IsNetworked || !g_IsController || msg.guid != playerGUID) 1720 return; 1721 var trimmed = msg.text.substr(split[0].length + 1); 1722 var matched = ""; 1723 // Reject names which don't match or are a superset of the intended name. 1724 for each (let player in g_PlayerAssignments) 1725 if (trimmed.indexOf(player.name) == 0 && player.name.length > matched.length) 1726 matched = player.name; 1727 // Prevent the host from kicking him/herself 1728 if (matched.length && matched != g_PlayerAssignments[playerGUID].name) 1729 { 1730 // Sending the message takes a while, so we phrase this past tense. 1731 // The text should be translated for each client individually (see #3304) 1732 Engine.SendNetworkChat(matched + " has been " + (ban ? "banned" : "kicked") + "."); 1733 Engine.KickPlayer(matched, ban); 1734 } 1735 return; 1736 } 1737 } 1738 1710 1739 // TODO: Maybe host should have distinct font/color? 1711 1740 var color = "white"; 1712 1741 1713 1742 if (msg.guid && g_PlayerAssignments[msg.guid] && g_PlayerAssignments[msg.guid].player != -1) 1714 1743 { -
binaries/data/mods/public/gui/session/messages.js
241 241 obj.caption = translate("Connection to the server has been authenticated."); 242 242 obj.hidden = false; 243 243 break; 244 244 case "disconnected": 245 245 g_Disconnected = true; 246 obj.caption = translate("Connection to the server has been lost.") + "\n\n" + translate("The game has ended."); 246 obj.caption = translate("Connection to the server has been lost.") + "\n" + 247 getDisconnectReason(message.reason) 248 if (!message.reason) 249 obj.caption += ".\n" + translate("The game has ended."); 247 250 obj.hidden = false; 248 251 break; 249 252 default: 250 253 error("Unrecognised netstatus type '" + message.status + "'"); 251 254 break; … … 325 328 function submitChatInput() 326 329 { 327 330 var input = Engine.GetGUIObjectByName("chatInput"); 328 331 var text = input.caption; 329 332 var isCheat = false; 333 330 334 if (text.length) 331 335 { 336 // Check cheats 332 337 if (!g_IsObserver && g_Players[Engine.GetPlayerID()].cheatsEnabled) 333 338 { 334 339 for each (var cheat in Object.keys(cheats)) 335 340 { 336 341 // Line must start with the cheat. … … 374 379 isCheat = true; 375 380 break; 376 381 } 377 382 } 378 383 379 // Observers should only send messages to "/all" 380 if (!isCheat && (!g_IsObserver || text.indexOf("/") == -1 || text.indexOf("/all ") == 0)) 384 if (!isCheat) 381 385 { 382 if (Engine.GetGUIObjectByName("toggleTeamChat").checked) 383 text = "/team " + text; 384 385 if (g_IsNetworked) 386 Engine.SendNetworkChat(text); 386 if (text.trim() == "/list") 387 addChatMessage({ "type": "clientlist", "guid": "local"}); 387 388 else 388 addChatMessage({ "type": "message", "guid": "local", "text": text }); 389 { 390 if (Engine.GetGUIObjectByName("toggleTeamChat").checked) 391 text = "/team " + text; 392 393 if (g_IsNetworked) 394 Engine.SendNetworkChat(text); 395 else 396 addChatMessage({ "type": "message", "guid": "local", "text": text }); 397 } 389 398 } 390 399 input.caption = ""; // Clear chat input 391 400 } 392 401 393 402 input.blur(); // Remove focus … … 453 462 if (!g_IsNetworked && msg.player == Engine.GetPlayerID()) 454 463 formatted = translate("You have been defeated."); 455 464 else 456 465 formatted = sprintf(translate("%(player)s has been defeated."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" }); 457 466 break; 467 case "clientlist": 468 var userlist = Object.keys(playerAssignments).sort(function(a,b) 469 { 470 var playerA = playerAssignments[a].player; 471 var playerB = playerAssignments[b].player; 472 if (playerA == -1 || playerB == -1) 473 return 1; 474 else 475 return playerA - playerB; 476 }).map(guid => playerAssignments[guid].name).join(","); 477 formatted = sprintf(translate("Users: %(users)s."), { "users": userlist }); 478 break; 458 479 case "diplomacy": 459 480 var message; 460 481 if (msg.player == Engine.GetPlayerID()) 461 482 { 462 483 [username, playerColor] = getUsernameAndColor(msg.player1); … … 601 622 } 602 623 603 624 // Parses chat messages for commands. 604 625 function parseChatCommands(msg, playerAssignments) 605 626 { 627 var ban = false; 606 628 // Only interested in messages that start with '/'. 607 629 if (!msg.text || msg.text[0] != '/') 608 630 return; 609 631 610 632 var sender; … … 627 649 msg.hide = false; 628 650 recurse = true; 629 651 break; 630 652 case "/team": 631 653 // Check if we are in a team. 632 if ( g_Players[Engine.GetPlayerID()] && g_Players[Engine.GetPlayerID()].team != -1)654 if (!g_IsObserver && g_Players[Engine.GetPlayerID()] && g_Players[Engine.GetPlayerID()].team != -1) 633 655 { 634 656 if (g_Players[Engine.GetPlayerID()].team != g_Players[sender].team) 635 657 msg.hide = true; 636 658 else 637 659 msg.context = translate("Team"); … … 641 663 recurse = true; 642 664 break; 643 665 case "/ally": 644 666 case "/allies": 645 667 // Check if we sent the message, or are the sender's (mutual) ally 646 if ( Engine.GetPlayerID() == sender || (g_Players[sender] && g_Players[sender].isMutualAlly[Engine.GetPlayerID()]))668 if (!g_IsObserver && (Engine.GetPlayerID() == sender || (g_Players[sender] && g_Players[sender].isMutualAlly[Engine.GetPlayerID()]))) 647 669 msg.context = translate("Ally"); 648 670 else 649 671 msg.hide = true; 650 672 651 673 recurse = true; 652 674 break; 653 675 case "/enemy": 654 676 case "/enemies": 655 677 // Check if we sent the message, or are the sender's enemy 656 if ( Engine.GetPlayerID() == sender || (g_Players[sender] && g_Players[sender].isEnemy[Engine.GetPlayerID()]))678 if (!g_IsObserver && (Engine.GetPlayerID() == sender || (g_Players[sender] && g_Players[sender].isEnemy[Engine.GetPlayerID()]))) 657 679 msg.context = translate("Enemy"); 658 680 else 659 681 msg.hide = true; 660 682 661 683 recurse = true; 662 684 break; 663 685 case "/me": 664 686 msg.action = true; 665 687 break; 688 case "/ban": 689 ban = true; 690 case "/kick": 691 msg.hide = true; 692 if (!g_IsNetworked || !g_IsController || msg.guid != Engine.GetPlayerGUID()) 693 break; 694 var trimmed = msg.text.substr(split[0].length + 1); 695 var matched = ""; 696 var playerGUID = Engine.GetPlayerGUID(); 697 // Reject names which don't match or are a superset of the intended name. 698 for each (var player in playerAssignments) 699 if (trimmed.indexOf(player.name) == 0 && player.name.length > matched.length) 700 matched = player.name; 701 // Prevent the host from kicking him/herself 702 if (matched.length && matched != g_PlayerAssignments[playerGUID].name) 703 { 704 Engine.KickPlayer(matched, ban); 705 // Sending the message takes a while, so we phrase this past tense. 706 // The text should be translated for each client individually (see #3304) 707 submitChatDirectly(matched + " has been " + (ban ? "banned" : "kicked") + "."); 708 } 709 return; 666 710 case "/msg": 667 711 var trimmed = msg.text.substr(split[0].length + 1); 668 712 var matched = ""; 669 713 714 // Don't show private messages from observers to players 715 if (g_PlayerAssignments[msg.guid].player == -1 && g_PlayerAssignments[Engine.GetPlayerGUID()].player != -1) 716 { 717 msg.hide = true; 718 return; 719 } 720 670 721 // Reject names which don't match or are a superset of the intended name. 671 722 for each (var player in playerAssignments) 672 723 if (trimmed.indexOf(player.name + " ") == 0 && player.name.length > matched.length) 673 724 matched = player.name; 674 725 675 726 // If the local player's name was the longest one matched, show the message. 676 var playerName = g_Players[Engine.GetPlayerID()].name;677 if (matched.length && (m atched == playerName || sender == Engine.GetPlayerID()))727 // Show the message only for sender and recipient. 728 if (matched.length && (msg.guid == Engine.GetPlayerGUID() || matched == g_PlayerAssignments[Engine.GetPlayerGUID()].name)) 678 729 { 679 730 msg.context = translate("Private"); 680 731 msg.text = trimmed.substr(matched.length + 1); 681 732 msg.hide = false; // Might override team message hiding. 682 733 return; -
binaries/data/mods/public/gui/session/session.xml
5 5 <script file="gui/common/colorFades.js"/> 6 6 <script file="gui/common/functions_civinfo.js"/> 7 7 <script file="gui/common/functions_global_object.js"/> 8 8 <script file="gui/common/functions_utility.js"/> 9 9 <script file="gui/common/l10n.js"/> 10 <script file="gui/common/network.js"/> 10 11 <script file="gui/common/music.js"/> 11 12 <script file="gui/common/timer.js"/> 12 13 <script file="gui/common/tooltips.js"/> 13 14 <!-- load all scripts in this directory --> 14 15 <script directory="gui/session/"/> -
source/gui/scripting/ScriptFunctions.cpp
186 186 if (g_Game) 187 187 return g_Game->GetPlayerID(); 188 188 return -1; 189 189 } 190 190 191 std::string GetPlayerGUID(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) 192 { 193 if (g_NetServer) 194 return g_NetServer->GetHostGUID(); 195 else if (g_NetClient) 196 return g_NetClient->GetGUID(); 197 else 198 return ""; 199 } 200 191 201 void SetPlayerID(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int id) 192 202 { 193 203 if (g_Game) 194 204 g_Game->SetPlayerID(id); 195 205 } … … 345 355 SAFE_DELETE(g_NetServer); 346 356 SAFE_DELETE(g_NetClient); 347 357 SAFE_DELETE(g_Game); 348 358 } 349 359 360 void KickPlayer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring playerName, bool ban) 361 { 362 if (g_NetServer) 363 g_NetServer->KickPlayer(playerName, ban); 364 } 365 350 366 JS::Value PollNetworkClient(ScriptInterface::CxPrivate* pCxPrivate) 351 367 { 352 368 if (!g_NetClient) 353 369 return JS::UndefinedValue(); 354 370 … … 954 970 scriptInterface.RegisterFunction<void, JS::HandleValue, int, &StartGame>("StartGame"); 955 971 scriptInterface.RegisterFunction<void, &Script_EndGame>("EndGame"); 956 972 scriptInterface.RegisterFunction<void, std::wstring, &StartNetworkHost>("StartNetworkHost"); 957 973 scriptInterface.RegisterFunction<void, std::wstring, std::string, &StartNetworkJoin>("StartNetworkJoin"); 958 974 scriptInterface.RegisterFunction<void, &DisconnectNetworkGame>("DisconnectNetworkGame"); 975 scriptInterface.RegisterFunction<void, std::wstring, bool, &KickPlayer>("KickPlayer"); 959 976 scriptInterface.RegisterFunction<JS::Value, &PollNetworkClient>("PollNetworkClient"); 960 977 scriptInterface.RegisterFunction<void, JS::HandleValue, &SetNetworkGameAttributes>("SetNetworkGameAttributes"); 961 978 scriptInterface.RegisterFunction<void, int, std::string, &AssignNetworkPlayer>("AssignNetworkPlayer"); 962 979 scriptInterface.RegisterFunction<void, std::string, int, &SetNetworkPlayerStatus>("SetNetworkPlayerStatus"); 963 980 scriptInterface.RegisterFunction<void, &ClearAllPlayerReady>("ClearAllPlayerReady"); … … 977 994 scriptInterface.RegisterFunction<void, &QuickLoad>("QuickLoad"); 978 995 979 996 // Misc functions 980 997 scriptInterface.RegisterFunction<std::wstring, std::wstring, &SetCursor>("SetCursor"); 981 998 scriptInterface.RegisterFunction<int, &GetPlayerID>("GetPlayerID"); 999 scriptInterface.RegisterFunction<std::string, &GetPlayerGUID>("GetPlayerGUID"); 982 1000 scriptInterface.RegisterFunction<void, int, &SetPlayerID>("SetPlayerID"); 983 1001 scriptInterface.RegisterFunction<void, std::string, &OpenURL>("OpenURL"); 984 1002 scriptInterface.RegisterFunction<std::wstring, &GetMatchID>("GetMatchID"); 985 1003 scriptInterface.RegisterFunction<void, &RestartInAtlas>("RestartInAtlas"); 986 1004 scriptInterface.RegisterFunction<bool, &AtlasIsAvailable>("AtlasIsAvailable"); -
source/network/NetClient.cpp
139 139 ENSURE(!m_Session); // must be called before we start the connection 140 140 141 141 m_UserName = username; 142 142 } 143 143 144 CStr CNetClient::GetGUID() 145 { 146 return m_GUID; 147 } 148 144 149 bool CNetClient::SetupConnection(const CStr& server) 145 150 { 146 151 CNetClientSession* session = new CNetClientSession(*this); 147 152 bool ok = session->Connect(PS_DEFAULT_PORT, server); 148 153 SetAndOwnSession(session); -
source/network/NetClient.h
86 86 * Set the user's name that will be displayed to all players. 87 87 * This must not be called after the connection setup. 88 88 */ 89 89 void SetUserName(const CStrW& username); 90 90 91 /** Returns the GUID of the client. */ 92 CStr GetGUID(); 93 91 94 /** 92 95 * Set up a connection to the remote networked server. 93 96 * @param server IP address or host name to connect to 94 97 * @return true on success, false on connection failure 95 98 */ -
source/network/NetHost.h
1 /* Copyright (C) 201 1Wildfire Games.1 /* Copyright (C) 2015 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 5 * it under the terms of the GNU General Public License as published by 6 6 * the Free Software Foundation, either version 2 of the License, or … … 60 60 enum NetDisconnectReason 61 61 { 62 62 NDR_UNKNOWN = 0, 63 63 NDR_UNEXPECTED_SHUTDOWN, 64 64 NDR_INCORRECT_PROTOCOL_VERSION, 65 NDR_SERVER_ALREADY_IN_GAME 65 NDR_SERVER_ALREADY_IN_GAME, 66 NDR_KICKED, 67 NDR_BANNED 66 68 }; 67 69 68 70 class CNetHost 69 71 { 70 72 public: -
source/network/NetServer.cpp
127 127 128 128 m_ServerTurnManager = NULL; 129 129 130 130 m_ServerName = DEFAULT_SERVER_NAME; 131 131 m_WelcomeMessage = DEFAULT_WELCOME_MESSAGE; 132 m_HostGUID = std::string(""); 132 133 } 133 134 134 135 CNetServerWorker::~CNetServerWorker() 135 136 { 136 137 if (m_State != SERVER_STATE_UNCONNECTED) … … 604 605 session->SetFirstState(NSS_HANDSHAKE); 605 606 } 606 607 607 608 bool CNetServerWorker::HandleConnect(CNetServerSession* session) 608 609 { 610 CNetServerWorker& server = session->GetServer(); 611 612 // Disconnect banned IPs 613 std::string ipAddress = session -> GetIPAddress(); 614 if(std::find(server.m_BannedIPs.begin(), server.m_BannedIPs.end(), ipAddress) != server.m_BannedIPs.end()) 615 { 616 session->Disconnect(NDR_BANNED); 617 return false; 618 } 619 620 // Send handshake challenge 609 621 CSrvHandshakeMessage handshake; 610 622 handshake.m_Magic = PS_PROTOCOL_MAGIC; 611 623 handshake.m_ProtocolVersion = PS_PROTOCOL_VERSION; 612 624 handshake.m_SoftwareVersion = PS_PROTOCOL_VERSION; 613 625 return session->SendMessage(&handshake); … … 615 627 616 628 void CNetServerWorker::OnUserJoin(CNetServerSession* session) 617 629 { 618 630 AddPlayer(session->GetGUID(), session->GetUserName()); 619 631 632 if (m_HostGUID == "") 633 m_HostGUID = session->GetGUID(); 634 620 635 CGameSetupMessage gameSetupMessage(GetScriptInterface()); 621 636 gameSetupMessage.m_Data = m_GameAttributes.get(); 622 637 session->SendMessage(&gameSetupMessage); 623 638 624 639 CPlayerAssignmentMessage assignMessage; … … 630 645 { 631 646 RemovePlayer(session->GetGUID()); 632 647 633 648 if (m_ServerTurnManager && session->GetCurrState() != NSS_JOIN_SYNCING) 634 649 m_ServerTurnManager->UninitialiseClient(session->GetHostID()); // TODO: only for non-observers 635 636 // TODO: ought to switch the player controlled by that client637 // back to AI control, or something?638 650 } 639 651 640 652 void CNetServerWorker::AddPlayer(const CStr& guid, const CStrW& name) 641 653 { 642 654 // Find all player IDs in active use; we mustn't give them to a second player (excluding the unassigned ID: -1) … … 707 719 it->second.m_Status = 0; 708 720 709 721 SendPlayerAssignments(); 710 722 } 711 723 724 void CNetServerWorker::KickPlayer(const CStrW& playerName, bool ban) 725 { 726 if (ban) 727 { 728 // Add playername to blacklist 729 if (std::find(m_BannedPlayers.begin(), m_BannedPlayers.end(), playerName) == m_BannedPlayers.end()) 730 m_BannedPlayers.push_back(playerName); 731 732 // Add IP address to blacklist 733 std::string ipAddress = GetPlayerIPAddress(playerName); 734 if (std::find(m_BannedIPs.begin(), m_BannedIPs.end(), ipAddress) == m_BannedIPs.end()) 735 m_BannedIPs.push_back(ipAddress); 736 } 737 738 // Disconnect everyone with that nick except the host 739 for (auto session : m_Sessions) 740 { 741 if (session->GetUserName() == playerName && session->GetGUID() != m_HostGUID) 742 session->Disconnect(ban ? NDR_BANNED : NDR_KICKED); 743 } 744 } 745 746 std::string CNetServerWorker::GetPlayerIPAddress(const CStrW& playerName) 747 { 748 std::string ipAddress = "error"; 749 for (auto session : m_Sessions) 750 { 751 if (session->GetUserName() == playerName) 752 return session->GetIPAddress(); 753 } 754 return ipAddress; 755 } 756 757 std::string CNetServerWorker::GetHostGUID() 758 { 759 return m_HostGUID; 760 } 761 712 762 void CNetServerWorker::AssignPlayer(int playerID, const CStr& guid) 713 763 { 714 764 // Remove anyone who's already assigned to this player 715 765 for (PlayerAssignmentMap::iterator it = m_PlayerAssignments.begin(); it != m_PlayerAssignments.end(); ++it) 716 766 { … … 764 814 ENSURE(event->GetType() == (uint)NMT_CLIENT_HANDSHAKE); 765 815 766 816 CNetServerSession* session = (CNetServerSession*)context; 767 817 CNetServerWorker& server = session->GetServer(); 768 818 819 // Check protocol version 769 820 CCliHandshakeMessage* message = (CCliHandshakeMessage*)event->GetParamRef(); 770 821 if (message->m_ProtocolVersion != PS_PROTOCOL_VERSION) 771 822 { 772 823 session->Disconnect(NDR_INCORRECT_PROTOCOL_VERSION); 773 824 return false; 774 825 } 775 826 827 // Send handshake response 776 828 CSrvHandshakeResponseMessage handshakeResponse; 777 829 handshakeResponse.m_UseProtocolVersion = PS_PROTOCOL_VERSION; 778 830 handshakeResponse.m_Message = server.m_WelcomeMessage; 779 831 handshakeResponse.m_Flags = 0; 780 832 session->SendMessage(&handshakeResponse); … … 791 843 792 844 CAuthenticateMessage* message = (CAuthenticateMessage*)event->GetParamRef(); 793 845 794 846 CStrW username = server.DeduplicatePlayerName(SanitisePlayerName(message->m_Name)); 795 847 848 // Disconnect banned usernames 849 if(std::find(server.m_BannedPlayers.begin(), server.m_BannedPlayers.end(), username) != server.m_BannedPlayers.end()) 850 { 851 session->Disconnect(NDR_BANNED); 852 return true; 853 } 854 796 855 bool isRejoining = false; 797 856 798 857 if (server.m_State != SERVER_STATE_PREGAME) 799 858 { 800 859 // isRejoining = true; // uncomment this to test rejoining even if the player wasn't connected previously … … 1145 1204 { 1146 1205 CScopeLock lock(m_Worker->m_WorkerMutex); 1147 1206 m_Worker->m_PlayerReadyQueue.push_back(std::make_pair(guid, ready)); 1148 1207 } 1149 1208 1209 void CNetServer::KickPlayer(const CStrW& playerName, bool ban) 1210 { 1211 CScopeLock lock(m_Worker->m_WorkerMutex); 1212 m_Worker->KickPlayer(playerName, ban); 1213 } 1214 1215 std::string CNetServer::GetHostGUID() 1216 { 1217 CScopeLock lock(m_Worker->m_WorkerMutex); 1218 return m_Worker->GetHostGUID(); 1219 } 1220 1150 1221 void CNetServer::ClearAllPlayerReady() 1151 1222 { 1152 1223 CScopeLock lock(m_Worker->m_WorkerMutex); 1153 1224 m_Worker->m_PlayerResetReadyQueue.push_back(false); 1154 1225 } -
source/network/NetServer.h
134 134 * The changes will be asynchronously propagated to all clients. 135 135 */ 136 136 void ClearAllPlayerReady(); 137 137 138 138 /** 139 * Disconnects a player from the gamesetup / session. 140 */ 141 void KickPlayer(const CStrW& playerName, bool ban); 142 143 /** 144 * Returns the GUID of the host. 145 */ 146 std::string GetHostGUID(); 147 148 /** 139 149 * Call from the GUI to asynchronously notify all clients that they should start loading the game. 140 150 */ 141 151 void StartGame(); 142 152 143 153 /** … … 181 191 * Send a message to the given network peer. 182 192 */ 183 193 bool SendMessage(ENetPeer* peer, const CNetMessage* message); 184 194 185 195 /** 196 * Disconnected a player from the match / gamesetup and optionally prevents him/her from rejoining. 197 */ 198 void KickPlayer(const CStrW& playerName, bool ban); 199 200 /** 186 201 * Send a message to all clients who have completed the full connection process 187 202 * (i.e. are in the pre-game or in-game states). 188 203 */ 189 204 bool Broadcast(const CNetMessage* message); 190 205 206 /** 207 * Returns the IP address of the given connected player. 208 */ 209 std::string GetPlayerIPAddress(const CStrW& playerName); 210 191 211 private: 192 212 friend class CNetServer; 193 213 friend class CNetFileReceiveTask_ServerRejoin; 194 214 195 215 CNetServerWorker(int autostartPlayers); … … 244 264 void SetTurnLength(u32 msecs); 245 265 246 266 void AddPlayer(const CStr& guid, const CStrW& name); 247 267 void RemovePlayer(const CStr& guid); 248 268 void SetPlayerReady(const CStr& guid, const int ready); 269 std::string GetHostGUID(); 249 270 void SendPlayerAssignments(); 250 271 void ClearAllPlayerReady(); 251 272 252 273 void SetupSession(CNetServerSession* session); 253 274 bool HandleConnect(CNetServerSession* session); … … 269 290 270 291 void ConstructPlayerAssignmentMessage(CPlayerAssignmentMessage& message); 271 292 272 293 void HandleMessageReceive(const CNetMessage* message, CNetServerSession* session); 273 294 274 275 295 /** 276 296 * Internal script context for (de)serializing script messages, 277 297 * and for storing game attributes. 278 298 * (TODO: we shouldn't bother deserializing (except for debug printing of messages), 279 299 * we should just forward messages blindly and efficiently.) … … 285 305 /** 286 306 * Stores the most current game attributes. 287 307 */ 288 308 DefPersistentRooted<JS::Value> m_GameAttributes; 289 309 310 std::vector<std::string> m_BannedIPs; 311 std::vector<std::wstring> m_BannedPlayers; 312 290 313 int m_AutostartPlayers; 291 314 292 315 ENetHost* m_Host; 293 316 std::vector<CNetServerSession*> m_Sessions; 294 317 … … 301 324 302 325 u32 m_NextHostID; 303 326 304 327 CNetServerTurnManager* m_ServerTurnManager; 305 328 329 std::string m_HostGUID; 330 306 331 /** 307 332 * A copy of all simulation commands received so far, indexed by 308 333 * turn number, to simplify support for rejoining etc. 309 334 * TODO: verify this doesn't use too much RAM. 310 335 */ -
source/network/NetSession.cpp
1 /* Copyright (C) 201 1Wildfire Games.1 /* Copyright (C) 2015 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 5 * it under the terms of the GNU General Public License as published by 6 6 * the Free Software Foundation, either version 2 of the License, or … … 173 173 CNetServerSession::CNetServerSession(CNetServerWorker& server, ENetPeer* peer) : 174 174 m_Server(server), m_FileTransferer(this), m_Peer(peer) 175 175 { 176 176 } 177 177 178 std::string CNetServerSession::GetIPAddress() 179 { 180 char ipAddress[256] = "(error)"; 181 enet_address_get_host_ip(&(m_Peer->address), ipAddress, ARRAY_SIZE(ipAddress)); 182 return std::string(ipAddress); 183 } 184 178 185 void CNetServerSession::Disconnect(u32 reason) 179 186 { 180 187 Update((uint)NMT_CONNECTION_LOST, NULL); 181 188 182 189 enet_peer_disconnect(m_Peer, reason); -
source/network/NetSession.h
1 /* Copyright (C) 201 1Wildfire Games.1 /* Copyright (C) 2015 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 5 * it under the terms of the GNU General Public License as published by 6 6 * the Free Software Foundation, either version 2 of the License, or … … 121 121 122 122 u32 GetHostID() const { return m_HostID; } 123 123 void SetHostID(u32 id) { m_HostID = id; } 124 124 125 125 /** 126 * Returns the IP address of the client. 127 */ 128 std::string GetIPAddress(); 129 130 /** 126 131 * Sends a disconnection notification to the client, 127 132 * and sends a NMT_CONNECTION_LOST message to the session FSM. 128 133 * The server will receive a disconnection notification after a while. 129 134 * The server will not receive any further messages sent via this session. 130 135 */ -
source/ps/GameSetup/GameSetup.cpp
680 680 } 681 681 682 682 683 683 void EndGame() 684 684 { 685 //TODO: The server should send a message telling the clients that the host quit on purpose 685 686 SAFE_DELETE(g_NetClient); 686 687 SAFE_DELETE(g_NetServer); 687 688 SAFE_DELETE(g_Game); 688 689 689 690 ISoundManager::CloseGame();