1
0
forked from 0ad/0ad

Allow kicking/banning players from gamesetup and session. Patch by elexis. Fixes #3241.

This was SVN commit r17217.
This commit is contained in:
leper 2015-11-11 02:05:23 +00:00
parent d3ff090ce7
commit 32da740f14
14 changed files with 245 additions and 13 deletions

View File

@ -1,3 +1,9 @@
/**
* Get a human readable version of the given disconnect reason.
*
* @param reason {number}
* @returns {string}
*/
function getDisconnectReason(id) function getDisconnectReason(id)
{ {
// Must be kept in sync with source/network/NetHost.h // Must be kept in sync with source/network/NetHost.h
@ -8,15 +14,76 @@ function getDisconnectReason(id)
case 2: return translate("Incorrect network protocol version"); case 2: return translate("Incorrect network protocol version");
case 3: return translate("Game is loading, please try later"); case 3: return translate("Game is loading, please try later");
case 4: return translate("Game has already started, no observers allowed"); case 4: return translate("Game has already started, no observers allowed");
case 5: return translate("You have been kicked");
case 6: return translate("You have been banned");
default: return sprintf(translate("\\[Invalid value %(id)s]"), { "id": id }); default: return sprintf(translate("\\[Invalid value %(id)s]"), { "id": id });
} }
} }
/**
* Show the disconnect reason in a message box.
*
* @param {number} reason
*/
function reportDisconnect(reason) function reportDisconnect(reason)
{ {
var reasontext = getDisconnectReason(reason); // Translation: States the reason why the client disconnected from the server.
var reasonText = sprintf(translate("Reason: %(reason)s."), { "reason": getDisconnectReason(reason) })
messageBox(400, 200, messageBox(400, 200, translate("Lost connection to the server.") + "\n\n" + reasonText, translate("Disconnected"), 2);
translate("Lost connection to the server.") + "\n\n" + sprintf(translate("Reason: %(reason)s."), { reason: reasontext }), }
translate("Disconnected"), 2);
/**
* Get usernames sorted by player slot, observers last.
* Requires g_PlayerAssignments.
*
* @returns {string[]}
*/
function getUsernameList()
{
return Object.keys(g_PlayerAssignments).sort((guidA, guidB) => {
var playerIdA = g_PlayerAssignments[guidA].player;
var playerIdB = g_PlayerAssignments[guidB].player;
// Sort observers last
if (playerIdA == -1) return +1;
if (playerIdB == -1) return -1;
// Sort players
return playerIdA - playerIdB;
}).map(guid => g_PlayerAssignments[guid].name);
}
/**
* Execute a command locally. Requires addChatMessage.
*
* @param {string} input
* @returns {Boolean} whether a command was executed
*/
function executeNetworkCommand(input)
{
if (input.indexOf("/") != 0)
return false;
var command = input.split(" ", 1)[0];
var argument = input.substr(command.length + 1);
switch (command)
{
case "/list":
addChatMessage({ "type": "clientlist", "guid": "local" });
return true;
case "/kick":
if (!Engine.KickPlayer(argument, false))
addChatMessage({ "type": "system", "text": sprintf(translate("Could not kick %(name)s."), { "name": argument }) });
return true;
case "/ban":
if (!Engine.KickPlayer(argument, true))
addChatMessage({ "type": "system", "text": sprintf(translate("Could not ban %(name)s."), { "name": argument }) });
return true;
}
return false;
} }

View File

@ -508,6 +508,14 @@ function handleNetMessage(message)
addChatMessage({ "type": "message", "guid": message.guid, "text": message.text }); addChatMessage({ "type": "message", "guid": message.guid, "text": message.text });
break; break;
case "kicked":
addChatMessage({ "type": "system", "text": sprintf(translate("%(username)s has been kicked"), { "username": message.username })});
break;
case "banned":
addChatMessage({ "type": "system", "text": sprintf(translate("%(username)s has been banned"), { "username": message.username })});
break;
// Singular client to host message // Singular client to host message
case "ready": case "ready":
g_ReadyChanged -= 1; g_ReadyChanged -= 1;
@ -1776,8 +1784,12 @@ function submitChatInput()
if (!text.length) if (!text.length)
return; return;
Engine.SendNetworkChat(text);
input.caption = ""; input.caption = "";
if (executeNetworkCommand(text))
return;
Engine.SendNetworkChat(text);
} }
function addChatMessage(msg) function addChatMessage(msg)
@ -1812,6 +1824,14 @@ function addChatMessage(msg)
formatted = '[font="sans-bold-13"] ' + sprintf(translate("== %(message)s"), { "message": sprintf(translate("%(username)s has left"), { "username": formattedUsername }) }) + '[/font]'; formatted = '[font="sans-bold-13"] ' + sprintf(translate("== %(message)s"), { "message": sprintf(translate("%(username)s has left"), { "username": formattedUsername }) }) + '[/font]';
break; break;
case "clientlist":
formatted = sprintf(translate("Users: %(users)s"), { "users": getUsernameList().join(translate(", ")) });
break;
case "system":
formatted = '[font="sans-bold-13"] ' + sprintf(translate("== %(message)s"), { "message": msg.text }) + '[/font]';
break;
case "message": case "message":
var formattedUsername = '[color="'+ color +'"]' + username + '[/color]'; var formattedUsername = '[color="'+ color +'"]' + username + '[/color]';
var formattedUsernamePrefix = '[font="sans-bold-13"]' + sprintf(translate("<%(username)s>"), { "username": formattedUsername }) + '[/font]'; var formattedUsernamePrefix = '[font="sans-bold-13"]' + sprintf(translate("<%(username)s>"), { "username": formattedUsername }) + '[/font]';

View File

@ -269,7 +269,9 @@ function handleNetMessage(message)
break; break;
case "disconnected": case "disconnected":
g_Disconnected = true; g_Disconnected = true;
obj.caption = translate("Connection to the server has been lost.") + "\n\n" + translate("The game has ended."); // Translation: States the reason why the client disconnected from the server.
let reason = sprintf(translate("Reason: %(reason)s."), { "reason": getDisconnectReason(message.reason) });
obj.caption = translate("Connection to the server has been lost.") + "\n" + reason + "\n" + translate("The game has ended.");
obj.hidden = false; obj.hidden = false;
break; break;
default: default:
@ -325,6 +327,14 @@ function handleNetMessage(message)
addChatMessage({ "type": "rejoined", "guid": message.guid }); addChatMessage({ "type": "rejoined", "guid": message.guid });
break; break;
case "kicked":
addChatMessage({ "type": "system", "text": sprintf(translate("%(username)s has been kicked"), { "username": message.username })});
break;
case "banned":
addChatMessage({ "type": "system", "text": sprintf(translate("%(username)s has been banned"), { "username": message.username })});
break;
// To prevent errors, ignore these message types that occur during autostart // To prevent errors, ignore these message types that occur during autostart
case "gamesetup": case "gamesetup":
case "start": case "start":
@ -359,6 +369,9 @@ function submitChatInput()
if (!text.length) if (!text.length)
return; return;
if (executeNetworkCommand(text))
return;
if (executeCheat(text)) if (executeCheat(text))
return; return;
@ -420,6 +433,12 @@ function addChatMessage(msg)
case "rejoined": case "rejoined":
formatted = sprintf(translate("%(player)s has rejoined the game."), { "player": "[color=\"" + playerColor + "\"]" + username + "[/color]" }); formatted = sprintf(translate("%(player)s has rejoined the game."), { "player": "[color=\"" + playerColor + "\"]" + username + "[/color]" });
break; break;
case "clientlist":
formatted = sprintf(translate("Users: %(users)s"), { "users": getUsernameList().join(translate(", ")) });
break;
case "system":
formatted = msg.text;
break;
case "defeat": case "defeat":
// In singleplayer, the local player is "You". "You has" is incorrect. // In singleplayer, the local player is "You". "You has" is incorrect.
if (!g_IsNetworked && msg.player == Engine.GetPlayerID()) if (!g_IsNetworked && msg.player == Engine.GetPlayerID())

View File

@ -8,6 +8,7 @@
<script file="gui/common/functions_utility.js"/> <script file="gui/common/functions_utility.js"/>
<script file="gui/common/l10n.js"/> <script file="gui/common/l10n.js"/>
<script file="gui/common/music.js"/> <script file="gui/common/music.js"/>
<script file="gui/common/network.js"/>
<script file="gui/common/settings.js"/> <script file="gui/common/settings.js"/>
<script file="gui/common/timer.js"/> <script file="gui/common/timer.js"/>
<script file="gui/common/tooltips.js"/> <script file="gui/common/tooltips.js"/>

View File

@ -353,6 +353,14 @@ void DisconnectNetworkGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
SAFE_DELETE(g_Game); SAFE_DELETE(g_Game);
} }
bool KickPlayer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), CStrW playerName, bool ban)
{
if (!g_NetServer)
return false;
return g_NetServer->KickPlayer(playerName, ban);
}
JS::Value PollNetworkClient(ScriptInterface::CxPrivate* pCxPrivate) JS::Value PollNetworkClient(ScriptInterface::CxPrivate* pCxPrivate)
{ {
if (!g_NetClient) if (!g_NetClient)
@ -963,6 +971,7 @@ void GuiScriptingInit(ScriptInterface& scriptInterface)
scriptInterface.RegisterFunction<void, std::wstring, &StartNetworkHost>("StartNetworkHost"); scriptInterface.RegisterFunction<void, std::wstring, &StartNetworkHost>("StartNetworkHost");
scriptInterface.RegisterFunction<void, std::wstring, std::string, &StartNetworkJoin>("StartNetworkJoin"); scriptInterface.RegisterFunction<void, std::wstring, std::string, &StartNetworkJoin>("StartNetworkJoin");
scriptInterface.RegisterFunction<void, &DisconnectNetworkGame>("DisconnectNetworkGame"); scriptInterface.RegisterFunction<void, &DisconnectNetworkGame>("DisconnectNetworkGame");
scriptInterface.RegisterFunction<bool, CStrW, bool, &KickPlayer>("KickPlayer");
scriptInterface.RegisterFunction<JS::Value, &PollNetworkClient>("PollNetworkClient"); scriptInterface.RegisterFunction<JS::Value, &PollNetworkClient>("PollNetworkClient");
scriptInterface.RegisterFunction<void, JS::HandleValue, &SetNetworkGameAttributes>("SetNetworkGameAttributes"); scriptInterface.RegisterFunction<void, JS::HandleValue, &SetNetworkGameAttributes>("SetNetworkGameAttributes");
scriptInterface.RegisterFunction<void, int, std::string, &AssignNetworkPlayer>("AssignNetworkPlayer"); scriptInterface.RegisterFunction<void, int, std::string, &AssignNetworkPlayer>("AssignNetworkPlayer");

View File

@ -93,6 +93,7 @@ CNetClient::CNetClient(CGame* game) :
AddTransition(NCS_PREGAME, (uint)NMT_READY, NCS_PREGAME, (void*)&OnReady, context); AddTransition(NCS_PREGAME, (uint)NMT_READY, NCS_PREGAME, (void*)&OnReady, context);
AddTransition(NCS_PREGAME, (uint)NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnGameSetup, context); AddTransition(NCS_PREGAME, (uint)NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnGameSetup, context);
AddTransition(NCS_PREGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_PREGAME, (void*)&OnPlayerAssignment, context); AddTransition(NCS_PREGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_PREGAME, (void*)&OnPlayerAssignment, context);
AddTransition(NCS_PREGAME, (uint)NMT_KICKED, NCS_PREGAME, (void*)&OnKicked, context);
AddTransition(NCS_PREGAME, (uint)NMT_GAME_START, NCS_LOADING, (void*)&OnGameStart, context); AddTransition(NCS_PREGAME, (uint)NMT_GAME_START, NCS_LOADING, (void*)&OnGameStart, context);
AddTransition(NCS_PREGAME, (uint)NMT_JOIN_SYNC_START, NCS_JOIN_SYNCING, (void*)&OnJoinSyncStart, context); AddTransition(NCS_PREGAME, (uint)NMT_JOIN_SYNC_START, NCS_JOIN_SYNCING, (void*)&OnJoinSyncStart, context);
@ -110,6 +111,7 @@ CNetClient::CNetClient(CGame* game) :
AddTransition(NCS_LOADING, (uint)NMT_LOADED_GAME, NCS_INGAME, (void*)&OnLoadedGame, context); AddTransition(NCS_LOADING, (uint)NMT_LOADED_GAME, NCS_INGAME, (void*)&OnLoadedGame, context);
AddTransition(NCS_INGAME, (uint)NMT_REJOINED, NCS_INGAME, (void*)&OnRejoined, context); AddTransition(NCS_INGAME, (uint)NMT_REJOINED, NCS_INGAME, (void*)&OnRejoined, context);
AddTransition(NCS_INGAME, (uint)NMT_KICKED, NCS_INGAME, (void*)&OnKicked, context);
AddTransition(NCS_INGAME, (uint)NMT_CHAT, NCS_INGAME, (void*)&OnChat, context); AddTransition(NCS_INGAME, (uint)NMT_CHAT, NCS_INGAME, (void*)&OnChat, context);
AddTransition(NCS_INGAME, (uint)NMT_GAME_SETUP, NCS_INGAME, (void*)&OnGameSetup, context); AddTransition(NCS_INGAME, (uint)NMT_GAME_SETUP, NCS_INGAME, (void*)&OnGameSetup, context);
AddTransition(NCS_INGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_INGAME, (void*)&OnPlayerAssignment, context); AddTransition(NCS_INGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_INGAME, (void*)&OnPlayerAssignment, context);
@ -607,6 +609,24 @@ bool CNetClient::OnRejoined(void *context, CFsmEvent* event)
return true; return true;
} }
bool CNetClient::OnKicked(void *context, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_KICKED);
CNetClient* client = (CNetClient*)context;
JSContext* cx = client->GetScriptInterface().GetContext();
CKickedMessage* message = (CKickedMessage*)event->GetParamRef();
JS::RootedValue msg(cx);
client->GetScriptInterface().Eval("({})", &msg);
client->GetScriptInterface().SetProperty(msg, "username", message->m_Name);
client->GetScriptInterface().SetProperty(msg, "type", message->m_Ban ? std::string("banned") : std::string("kicked"));
client->PushGuiMessage(msg);
return true;
}
bool CNetClient::OnLoadedGame(void* context, CFsmEvent* event) bool CNetClient::OnLoadedGame(void* context, CFsmEvent* event)
{ {
ENSURE(event->GetType() == (uint)NMT_LOADED_GAME); ENSURE(event->GetType() == (uint)NMT_LOADED_GAME);

View File

@ -201,6 +201,7 @@ private:
static bool OnJoinSyncStart(void* context, CFsmEvent* event); static bool OnJoinSyncStart(void* context, CFsmEvent* event);
static bool OnJoinSyncEndCommandBatch(void* context, CFsmEvent* event); static bool OnJoinSyncEndCommandBatch(void* context, CFsmEvent* event);
static bool OnRejoined(void* context, CFsmEvent* event); static bool OnRejoined(void* context, CFsmEvent* event);
static bool OnKicked(void* context, CFsmEvent* event);
static bool OnLoadedGame(void* context, CFsmEvent* event); static bool OnLoadedGame(void* context, CFsmEvent* event);
/** /**

View File

@ -63,7 +63,9 @@ enum NetDisconnectReason
NDR_UNEXPECTED_SHUTDOWN, NDR_UNEXPECTED_SHUTDOWN,
NDR_INCORRECT_PROTOCOL_VERSION, NDR_INCORRECT_PROTOCOL_VERSION,
NDR_SERVER_LOADING, NDR_SERVER_LOADING,
NDR_SERVER_ALREADY_IN_GAME NDR_SERVER_ALREADY_IN_GAME,
NDR_KICKED,
NDR_BANNED
}; };
class CNetHost class CNetHost

View File

@ -135,6 +135,10 @@ CNetMessage* CNetMessageFactory::CreateMessage(const void* pData,
pNewMessage = new CRejoinedMessage; pNewMessage = new CRejoinedMessage;
break; break;
case NMT_KICKED:
pNewMessage = new CKickedMessage;
break;
case NMT_LOADED_GAME: case NMT_LOADED_GAME:
pNewMessage = new CLoadedGameMessage; pNewMessage = new CLoadedGameMessage;
break; break;

View File

@ -28,7 +28,7 @@
#define PS_PROTOCOL_MAGIC 0x5073013f // 'P', 's', 0x01, '?' #define PS_PROTOCOL_MAGIC 0x5073013f // 'P', 's', 0x01, '?'
#define PS_PROTOCOL_MAGIC_RESPONSE 0x50630121 // 'P', 'c', 0x01, '!' #define PS_PROTOCOL_MAGIC_RESPONSE 0x50630121 // 'P', 'c', 0x01, '!'
#define PS_PROTOCOL_VERSION 0x01010007 // Arbitrary protocol #define PS_PROTOCOL_VERSION 0x01010008 // Arbitrary protocol
#define PS_DEFAULT_PORT 0x5073 // 'P', 's' #define PS_DEFAULT_PORT 0x5073 // 'P', 's'
// Defines the list of message types. The order of the list must not change. // Defines the list of message types. The order of the list must not change.
@ -58,6 +58,7 @@ enum NetMessageType
NMT_JOIN_SYNC_START, NMT_JOIN_SYNC_START,
NMT_REJOINED, NMT_REJOINED,
NMT_KICKED,
NMT_LOADED_GAME, NMT_LOADED_GAME,
NMT_GAME_START, NMT_GAME_START,
@ -161,6 +162,11 @@ START_NMT_CLASS_(Rejoined, NMT_REJOINED)
NMT_FIELD(CStr8, m_GUID) NMT_FIELD(CStr8, m_GUID)
END_NMT_CLASS() END_NMT_CLASS()
START_NMT_CLASS_(Kicked, NMT_KICKED)
NMT_FIELD(CStrW, m_Name)
NMT_FIELD_INT(m_Ban, u8, 1)
END_NMT_CLASS()
START_NMT_CLASS_(LoadedGame, NMT_LOADED_GAME) START_NMT_CLASS_(LoadedGame, NMT_LOADED_GAME)
NMT_FIELD_INT(m_CurrentTurn, u32, 4) NMT_FIELD_INT(m_CurrentTurn, u32, 4)
END_NMT_CLASS() END_NMT_CLASS()

View File

@ -121,7 +121,7 @@ CNetServerWorker::CNetServerWorker(int autostartPlayers) :
m_AutostartPlayers(autostartPlayers), m_AutostartPlayers(autostartPlayers),
m_Shutdown(false), m_Shutdown(false),
m_ScriptInterface(NULL), m_ScriptInterface(NULL),
m_NextHostID(1), m_Host(NULL), m_Stats(NULL) m_NextHostID(1), m_Host(NULL), m_HostGUID(), m_Stats(NULL)
{ {
m_State = SERVER_STATE_UNCONNECTED; m_State = SERVER_STATE_UNCONNECTED;
@ -610,6 +610,12 @@ void CNetServerWorker::SetupSession(CNetServerSession* session)
bool CNetServerWorker::HandleConnect(CNetServerSession* session) bool CNetServerWorker::HandleConnect(CNetServerSession* session)
{ {
if (std::find(m_BannedIPs.begin(), m_BannedIPs.end(), session->GetIPAddress()) != m_BannedIPs.end())
{
session->Disconnect(NDR_BANNED);
return false;
}
CSrvHandshakeMessage handshake; CSrvHandshakeMessage handshake;
handshake.m_Magic = PS_PROTOCOL_MAGIC; handshake.m_Magic = PS_PROTOCOL_MAGIC;
handshake.m_ProtocolVersion = PS_PROTOCOL_VERSION; handshake.m_ProtocolVersion = PS_PROTOCOL_VERSION;
@ -621,6 +627,10 @@ void CNetServerWorker::OnUserJoin(CNetServerSession* session)
{ {
AddPlayer(session->GetGUID(), session->GetUserName()); AddPlayer(session->GetGUID(), session->GetUserName());
// Host is the first to join
if (m_HostGUID.empty())
m_HostGUID = session->GetGUID();
CGameSetupMessage gameSetupMessage(GetScriptInterface()); CGameSetupMessage gameSetupMessage(GetScriptInterface());
gameSetupMessage.m_Data = m_GameAttributes.get(); gameSetupMessage.m_Data = m_GameAttributes.get();
session->SendMessage(&gameSetupMessage); session->SendMessage(&gameSetupMessage);
@ -713,6 +723,40 @@ void CNetServerWorker::ClearAllPlayerReady()
SendPlayerAssignments(); SendPlayerAssignments();
} }
bool CNetServerWorker::KickPlayer(const CStrW& playerName, const bool ban)
{
// Find the user with that name
std::vector<CNetServerSession*>::iterator it = std::find_if(m_Sessions.begin(), m_Sessions.end(),
[&](CNetServerSession* session) { return session->GetUserName() == playerName; });
// and return if no one or the host has that name
if (it == m_Sessions.end() || (*it)->GetGUID() == m_HostGUID)
return false;
if (ban)
{
// Remember name
if (std::find(m_BannedPlayers.begin(), m_BannedPlayers.end(), playerName) == m_BannedPlayers.end())
m_BannedPlayers.push_back(playerName);
// Remember IP address
CStr ipAddress = (*it)->GetIPAddress();
if (!ipAddress.empty() && std::find(m_BannedIPs.begin(), m_BannedIPs.end(), ipAddress) == m_BannedIPs.end())
m_BannedIPs.push_back(ipAddress);
}
// Disconnect that user
(*it)->Disconnect(ban ? NDR_BANNED : NDR_KICKED);
// Send message notifying other clients
CKickedMessage kickedMessage;
kickedMessage.m_Name = playerName;
kickedMessage.m_Ban = ban;
Broadcast(&kickedMessage);
return true;
}
void CNetServerWorker::AssignPlayer(int playerID, const CStr& guid) void CNetServerWorker::AssignPlayer(int playerID, const CStr& guid)
{ {
// Remove anyone who's already assigned to this player // Remove anyone who's already assigned to this player
@ -804,6 +848,13 @@ bool CNetServerWorker::OnAuthenticate(void* context, CFsmEvent* event)
CAuthenticateMessage* message = (CAuthenticateMessage*)event->GetParamRef(); CAuthenticateMessage* message = (CAuthenticateMessage*)event->GetParamRef();
CStrW username = server.DeduplicatePlayerName(SanitisePlayerName(message->m_Name)); CStrW username = server.DeduplicatePlayerName(SanitisePlayerName(message->m_Name));
// Disconnect banned usernames
if (std::find(server.m_BannedPlayers.begin(), server.m_BannedPlayers.end(), username) != server.m_BannedPlayers.end())
{
session->Disconnect(NDR_BANNED);
return true;
}
// Optionally allow observers to join after the game has started // Optionally allow observers to join after the game has started
bool observerLateJoin = false; bool observerLateJoin = false;
ScriptInterface& scriptInterface = server.GetScriptInterface(); ScriptInterface& scriptInterface = server.GetScriptInterface();
@ -1168,6 +1219,12 @@ bool CNetServer::SetupConnection()
return m_Worker->SetupConnection(); return m_Worker->SetupConnection();
} }
bool CNetServer::KickPlayer(const CStrW& playerName, const bool ban)
{
CScopeLock lock(m_Worker->m_WorkerMutex);
return m_Worker->KickPlayer(playerName, ban);
}
void CNetServer::AssignPlayer(int playerID, const CStr& guid) void CNetServer::AssignPlayer(int playerID, const CStr& guid)
{ {
CScopeLock lock(m_Worker->m_WorkerMutex); CScopeLock lock(m_Worker->m_WorkerMutex);

View File

@ -134,7 +134,12 @@ public:
* The changes will be asynchronously propagated to all clients. * The changes will be asynchronously propagated to all clients.
*/ */
void ClearAllPlayerReady(); void ClearAllPlayerReady();
/**
* Disconnects a player from gamesetup or session.
*/
bool KickPlayer(const CStrW& playerName, const bool ban);
/** /**
* Call from the GUI to asynchronously notify all clients that they should start loading the game. * Call from the GUI to asynchronously notify all clients that they should start loading the game.
*/ */
@ -182,6 +187,11 @@ public:
*/ */
bool SendMessage(ENetPeer* peer, const CNetMessage* message); bool SendMessage(ENetPeer* peer, const CNetMessage* message);
/**
* Disconnects a player from gamesetup or session.
*/
bool KickPlayer(const CStrW& playerName, const bool ban);
/** /**
* Send a message to all clients who have completed the full connection process * Send a message to all clients who have completed the full connection process
* (i.e. are in the pre-game or in-game states). * (i.e. are in the pre-game or in-game states).
@ -299,10 +309,15 @@ private:
CStrW m_ServerName; CStrW m_ServerName;
CStrW m_WelcomeMessage; CStrW m_WelcomeMessage;
std::vector<CStr> m_BannedIPs;
std::vector<CStrW> m_BannedPlayers;
u32 m_NextHostID; u32 m_NextHostID;
CNetServerTurnManager* m_ServerTurnManager; CNetServerTurnManager* m_ServerTurnManager;
CStr m_HostGUID;
/** /**
* A copy of all simulation commands received so far, indexed by * A copy of all simulation commands received so far, indexed by
* turn number, to simplify support for rejoining etc. * turn number, to simplify support for rejoining etc.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2011 Wildfire Games. /* Copyright (C) 2015 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -175,6 +175,15 @@ CNetServerSession::CNetServerSession(CNetServerWorker& server, ENetPeer* peer) :
{ {
} }
CStr CNetServerSession::GetIPAddress() const
{
char ipAddress[256] = "";
if (enet_address_get_host_ip(&m_Peer->address, ipAddress, ARRAY_SIZE(ipAddress)) < 0)
LOGMESSAGE("Could not get IP address of a client!");
return ipAddress;
}
void CNetServerSession::Disconnect(u32 reason) void CNetServerSession::Disconnect(u32 reason)
{ {
Update((uint)NMT_CONNECTION_LOST, NULL); Update((uint)NMT_CONNECTION_LOST, NULL);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2011 Wildfire Games. /* Copyright (C) 2015 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -122,6 +122,8 @@ public:
u32 GetHostID() const { return m_HostID; } u32 GetHostID() const { return m_HostID; }
void SetHostID(u32 id) { m_HostID = id; } void SetHostID(u32 id) { m_HostID = id; }
CStr GetIPAddress() const;
/** /**
* Sends a disconnection notification to the client, * Sends a disconnection notification to the client,
* and sends a NMT_CONNECTION_LOST message to the session FSM. * and sends a NMT_CONNECTION_LOST message to the session FSM.