Pass on admin state if the admin leaves the network game, so that someone else can start the game.

This commit is contained in:
lotodore
2007-10-03 13:36:47 +00:00
parent 8385b2e28d
commit 076d44b0ae
19 changed files with 239 additions and 49 deletions
+5 -4
View File
@@ -110,10 +110,11 @@ void ServerGuiWrapper::SignalNetClientGameInfo(int actionID) { if (myClientcb) m
void ServerGuiWrapper::SignalNetClientError(int errorID, int osErrorID) { if (myClientcb) myClientcb->SignalNetClientError(errorID, osErrorID); }
void ServerGuiWrapper::SignalNetClientNotification(int notificationId) { if (myClientcb) myClientcb->SignalNetClientNotification(notificationId); }
void ServerGuiWrapper::SignalNetClientRemovedFromGame(int notificationId) { if (myClientcb) myClientcb->SignalNetClientRemovedFromGame(notificationId); }
void ServerGuiWrapper::SignalNetClientSelfJoined(unsigned playerId, const std::string &playerName, PlayerRights rights) { if (myClientcb) myClientcb->SignalNetClientSelfJoined(playerId, playerName, rights); }
void ServerGuiWrapper::SignalNetClientPlayerJoined(unsigned playerId, const std::string &playerName, PlayerRights rights) { if (myClientcb) myClientcb->SignalNetClientPlayerJoined(playerId, playerName, rights); }
void ServerGuiWrapper::SignalNetClientPlayerChanged(unsigned playerId, const std::string &newPlayerName) { if (myClientcb) myClientcb->SignalNetClientPlayerChanged(playerId, newPlayerName); }
void ServerGuiWrapper::SignalNetClientPlayerLeft(unsigned playerId, const std::string &playerName) { if (myClientcb) myClientcb->SignalNetClientPlayerLeft(playerId, playerName); }
void ServerGuiWrapper::SignalNetClientSelfJoined(unsigned playerId, const string &playerName, PlayerRights rights) { if (myClientcb) myClientcb->SignalNetClientSelfJoined(playerId, playerName, rights); }
void ServerGuiWrapper::SignalNetClientPlayerJoined(unsigned playerId, const string &playerName, PlayerRights rights) { if (myClientcb) myClientcb->SignalNetClientPlayerJoined(playerId, playerName, rights); }
void ServerGuiWrapper::SignalNetClientPlayerChanged(unsigned playerId, const string &newPlayerName) { if (myClientcb) myClientcb->SignalNetClientPlayerChanged(playerId, newPlayerName); }
void ServerGuiWrapper::SignalNetClientPlayerLeft(unsigned playerId, const string &playerName) { if (myClientcb) myClientcb->SignalNetClientPlayerLeft(playerId, playerName); }
void ServerGuiWrapper::SignalNetClientNewGameAdmin(unsigned playerId, const string &playerName) { if (myClientcb) myClientcb->SignalNetClientNewGameAdmin(playerId, playerName); }
void ServerGuiWrapper::SignalNetClientGameListNew(unsigned gameId) { if (myClientcb) myClientcb->SignalNetClientGameListNew(gameId); }
void ServerGuiWrapper::SignalNetClientGameListRemove(unsigned gameId) { if (myClientcb) myClientcb->SignalNetClientGameListRemove(gameId); }
void ServerGuiWrapper::SignalNetClientGameListUpdateMode(unsigned gameId, GameMode mode) { if (myClientcb) myClientcb->SignalNetClientGameListUpdateMode(gameId, mode); }
+1
View File
@@ -98,6 +98,7 @@ public:
void SignalNetClientPlayerJoined(unsigned playerId, const std::string &playerName, PlayerRights rights);
void SignalNetClientPlayerChanged(unsigned playerId, const std::string &newPlayerName);
void SignalNetClientPlayerLeft(unsigned playerId, const std::string &playerName);
void SignalNetClientNewGameAdmin(unsigned playerId, const std::string &playerName);
void SignalNetClientChatMsg(const std::string &playerName, const std::string &msg);
void SignalNetClientWaitDialog();
@@ -18,7 +18,7 @@
#include <net/socket_msg.h>
gameLobbyDialogImpl::gameLobbyDialogImpl(QWidget *parent, ConfigFile *c)
: QDialog(parent), myW(NULL), myConfig(c), mySession(NULL), currentGameName(""), isAdmin(false), inGame(false), myChat(NULL)
: QDialog(parent), myW(NULL), myConfig(c), mySession(NULL), currentGameName(""), myPlayerId(0), isAdmin(false), inGame(false), myChat(NULL)
{
setupUi(this);
@@ -343,6 +343,7 @@ void gameLobbyDialogImpl::clearDialog()
myChat->clearChat();
inGame = false;
isAdmin = false;
myPlayerId = 0;
}
void gameLobbyDialogImpl::checkPlayerQuantity() {
@@ -367,6 +368,7 @@ void gameLobbyDialogImpl::joinedNetworkGame(unsigned playerId, QString playerNam
inGame = true;
joinedGameDialogUpdate();
myPlayerId = playerId;
isAdmin = rights == PLAYER_RIGHTS_ADMIN;
addConnectedPlayer(playerId, playerName, rights);
}
@@ -418,6 +420,15 @@ void gameLobbyDialogImpl::removePlayer(unsigned playerId, QString) {
checkPlayerQuantity();
}
void gameLobbyDialogImpl::newGameAdmin(unsigned playerId, QString)
{
if (myPlayerId == playerId)
{
isAdmin = true;
checkPlayerQuantity();
}
}
void gameLobbyDialogImpl::joinedGameDialogUpdate() {
groupBox_GameInfo->setEnabled(true);
groupBox_GameInfo->setTitle(currentGameName);
@@ -71,6 +71,7 @@ public slots:
void addConnectedPlayer(unsigned, QString, int);
void updatePlayer(unsigned, QString);
void removePlayer(unsigned, QString);
void newGameAdmin(unsigned, QString);
void playerSelected(QTreeWidgetItem*, QTreeWidgetItem*);
void refresh(int actionID);
@@ -99,6 +100,7 @@ private:
Session *mySession;
createInternetGameDialogImpl *myCreateInternetGameDialog;
QString currentGameName;
unsigned myPlayerId;
bool isAdmin;
bool inGame;
LobbyChat *myChat;
+1
View File
@@ -126,6 +126,7 @@ void GuiWrapper::SignalNetClientPlayerLeft(unsigned playerId, const string &play
if (!playerName.empty() && playerName[0] != '#')
myLog->signalLogPlayerLeftMsg(tmpName);
}
void GuiWrapper::SignalNetClientNewGameAdmin(unsigned playerId, const string &playerName) { myW->signalNetClientNewGameAdmin(playerId, QString::fromUtf8(playerName.c_str())); }
void GuiWrapper::SignalNetClientGameListNew(unsigned gameId) { myW->signalNetClientGameListNew(gameId); }
void GuiWrapper::SignalNetClientGameListRemove(unsigned gameId) { myW->signalNetClientGameListRemove(gameId); }
+1
View File
@@ -105,6 +105,7 @@ public:
void SignalNetClientPlayerJoined(unsigned playerId, const std::string &playerName, PlayerRights rights);
void SignalNetClientPlayerChanged(unsigned playerId, const std::string &newPlayerName);
void SignalNetClientPlayerLeft(unsigned playerId, const std::string &playerName);
void SignalNetClientNewGameAdmin(unsigned playerId, const std::string &playerName);
void SignalNetClientChatMsg(const std::string &playerName, const std::string &msg);
void SignalNetClientWaitDialog();
+2
View File
@@ -659,11 +659,13 @@ mainWindowImpl::mainWindowImpl(ConfigFile *c, QMainWindow *parent)
connect(this, SIGNAL(signalNetClientPlayerJoined(unsigned, QString, int)), myStartNetworkGameDialog, SLOT(addConnectedPlayer(unsigned, QString, int)));
connect(this, SIGNAL(signalNetClientPlayerChanged(unsigned, QString)), myStartNetworkGameDialog, SLOT(updatePlayer(unsigned, QString)));
connect(this, SIGNAL(signalNetClientPlayerLeft(unsigned, QString)), myStartNetworkGameDialog, SLOT(removePlayer(unsigned, QString)));
connect(this, SIGNAL(signalNetClientNewGameAdmin(unsigned, QString)), myStartNetworkGameDialog, SLOT(newGameAdmin(unsigned, QString)));
connect(this, SIGNAL(signalNetClientSelfJoined(unsigned, QString, int)), myGameLobbyDialog, SLOT(joinedNetworkGame(unsigned, QString, int)));
connect(this, SIGNAL(signalNetClientPlayerJoined(unsigned, QString, int)), myGameLobbyDialog, SLOT(addConnectedPlayer(unsigned, QString, int)));
connect(this, SIGNAL(signalNetClientPlayerChanged(unsigned, QString)), myGameLobbyDialog, SLOT(updatePlayer(unsigned, QString)));
connect(this, SIGNAL(signalNetClientPlayerLeft(unsigned, QString)), myGameLobbyDialog, SLOT(removePlayer(unsigned, QString)));
connect(this, SIGNAL(signalNetClientNewGameAdmin(unsigned, QString)), myGameLobbyDialog, SLOT(newGameAdmin(unsigned, QString)));
connect(this, SIGNAL(signalNetClientGameListNew(unsigned)), myGameLobbyDialog, SLOT(addGame(unsigned)));
connect(this, SIGNAL(signalNetClientGameListRemove(unsigned)), myGameLobbyDialog, SLOT(removeGame(unsigned)));
+1
View File
@@ -132,6 +132,7 @@ signals:
void signalNetClientPlayerJoined(unsigned playerId, QString playerName, int rights);
void signalNetClientPlayerChanged(unsigned playerId, QString newPlayerName);
void signalNetClientPlayerLeft(unsigned playerId, QString playerName);
void signalNetClientNewGameAdmin(unsigned playerId, QString playerName);
void signalNetClientGameListNew(unsigned gameId);
void signalNetClientGameListRemove(unsigned gameId);
void signalNetClientGameListUpdateMode(unsigned gameId, int mode);
@@ -23,7 +23,7 @@
#include <net/socket_msg.h>
startNetworkGameDialogImpl::startNetworkGameDialogImpl(QWidget *parent, ConfigFile *config)
: QDialog(parent), myW(NULL), isAdmin(false), myConfig(config), mySession(NULL)
: QDialog(parent), myW(NULL), myPlayerId(0), isAdmin(false), myConfig(config), mySession(NULL)
{
setupUi(this);
@@ -64,6 +64,7 @@ void startNetworkGameDialogImpl::refresh(int actionID) {
void startNetworkGameDialogImpl::joinedNetworkGame(unsigned playerId, QString playerName, int rights) {
myPlayerId = playerId;
isAdmin = rights == PLAYER_RIGHTS_ADMIN;
addConnectedPlayer(playerId, playerName, rights);
}
@@ -116,6 +117,15 @@ void startNetworkGameDialogImpl::removePlayer(unsigned playerId, QString) {
checkPlayerQuantity();
}
void startNetworkGameDialogImpl::newGameAdmin(unsigned playerId, QString)
{
if (myPlayerId == playerId)
{
isAdmin = true;
checkPlayerQuantity();
}
}
void startNetworkGameDialogImpl::playerSelected(QTreeWidgetItem* item, QTreeWidgetItem*) {
if (item)
@@ -166,6 +176,8 @@ void startNetworkGameDialogImpl::clearDialog()
pushButton_startGame->setEnabled(false);
treeWidget->clear();
checkBox_fillUpWithComputerOpponents->hide();
myPlayerId = 0;
}
void startNetworkGameDialogImpl::setSession(Session *session)
@@ -49,6 +49,8 @@ public slots:
void addConnectedPlayer(unsigned playerId, QString playerName, int rights);
void updatePlayer(unsigned playerId, QString newPlayerName);
void removePlayer(unsigned playerId, QString playerName);
void newGameAdmin(unsigned playerId, QString playerName);
void playerSelected(QTreeWidgetItem*, QTreeWidgetItem*);
void kickPlayer();
void checkPlayerQuantity();
@@ -67,6 +69,7 @@ private:
mainWindowImpl* myW;
int maxPlayerNumber;
unsigned myPlayerId;
bool isAdmin;
ConfigFile *myConfig;
Session *mySession;
+1
View File
@@ -50,6 +50,7 @@ public:
virtual void SignalNetClientPlayerJoined(unsigned playerId, const std::string &playerName, PlayerRights rights) = 0;
virtual void SignalNetClientPlayerChanged(unsigned playerId, const std::string &newPlayerName) = 0;
virtual void SignalNetClientPlayerLeft(unsigned playerId, const std::string &playerName) = 0;
virtual void SignalNetClientNewGameAdmin(unsigned playerId, const std::string &playerName) = 0;
virtual void SignalNetClientChatMsg(const std::string &playerName, const std::string &msg) = 0;
virtual void SignalNetClientWaitDialog() = 0;
+1
View File
@@ -86,6 +86,7 @@ protected:
bool GetCachedPlayerInfo(unsigned id, PlayerInfo &info) const;
void RequestPlayerInfo(unsigned id);
void SetPlayerInfo(unsigned id, const PlayerInfo &info);
void SetNewGameAdmin(unsigned id);
const ClientContext &GetContext() const;
ClientContext &GetContext();
+17 -8
View File
@@ -401,14 +401,6 @@ AbstractClientStateReceiving::Process(ClientThread &client)
client.GetCallback().SignalNetClientRemovedFromGame(removedData.removeReason);
client.SetState(ClientStateWaitJoin::Instance());
}
else if (tmpPacket->ToNetPacketError())
{
// Server reported an error.
NetPacketError::Data errorData;
tmpPacket->ToNetPacketError()->GetData(errorData);
// Show the error.
throw ClientException(errorData.errorCode, 0);
}
else if (tmpPacket->ToNetPacketChatText())
{
// Chat message - display it in the GUI.
@@ -428,6 +420,15 @@ AbstractClientStateReceiving::Process(ClientThread &client)
// Signal to GUI and remove from data list.
client.RemovePlayerData(playerLeftData.playerId);
}
else if (tmpPacket->ToNetPacketGameAdminChanged())
{
// New admin for the game.
NetPacketGameAdminChanged::Data adminChangedData;
tmpPacket->ToNetPacketGameAdminChanged()->GetData(adminChangedData);
// Set new game admin and signal to GUI.
client.SetNewGameAdmin(adminChangedData.playerId);
}
else if (tmpPacket->ToNetPacketGameListNew())
{
// A new game was created on the server.
@@ -478,6 +479,14 @@ AbstractClientStateReceiving::Process(ClientThread &client)
tmpPacket->ToNetPacketGameListPlayerLeft()->GetData(playerLeftData);
client.ModifyGameInfoRemovePlayer(playerLeftData.gameId, playerLeftData.playerId);
}
else if (tmpPacket->ToNetPacketError())
{
// Server reported an error.
NetPacketError::Data errorData;
tmpPacket->ToNetPacketError()->GetData(errorData);
// Show the error.
throw ClientException(errorData.errorCode, 0);
}
else
retVal = InternalProcess(client, tmpPacket);
}
+12
View File
@@ -404,6 +404,18 @@ ClientThread::SetPlayerInfo(unsigned id, const PlayerInfo &info)
GetCallback().SignalNetClientPlayerChanged(id, info.playerName);
}
void
ClientThread::SetNewGameAdmin(unsigned id)
{
// Update player data for current game.
boost::shared_ptr<PlayerData> playerData = GetPlayerDataByUniqueId(id);
if (playerData.get())
{
playerData->SetRights(PLAYER_RIGHTS_ADMIN);
GetCallback().SignalNetClientNewGameAdmin(id, playerData->GetName());
}
}
const ClientContext &
ClientThread::GetContext() const
{
+91 -16
View File
@@ -41,22 +41,23 @@ using namespace std;
#define NET_TYPE_JOIN_GAME_FAILED 0x000C
#define NET_TYPE_PLAYER_JOINED 0x000D
#define NET_TYPE_PLAYER_LEFT 0x000E
#define NET_TYPE_KICK_PLAYER 0x000F
#define NET_TYPE_LEAVE_CURRENT_GAME 0x0010
#define NET_TYPE_START_EVENT 0x0011
#define NET_TYPE_GAME_START 0x0012
#define NET_TYPE_HAND_START 0x0013
#define NET_TYPE_PLAYERS_TURN 0x0014
#define NET_TYPE_PLAYERS_ACTION 0x0015
#define NET_TYPE_PLAYERS_ACTION_DONE 0x0016
#define NET_TYPE_PLAYERS_ACTION_REJECTED 0x0017
#define NET_TYPE_DEAL_FLOP_CARDS 0x0018
#define NET_TYPE_DEAL_TURN_CARD 0x0019
#define NET_TYPE_DEAL_RIVER_CARD 0x001A
#define NET_TYPE_ALL_IN_SHOW_CARDS 0x001B
#define NET_TYPE_END_OF_HAND_SHOW_CARDS 0x001C
#define NET_TYPE_END_OF_HAND_HIDE_CARDS 0x001D
#define NET_TYPE_END_OF_GAME 0x001E
#define NET_TYPE_GAME_ADMIN_CHANGED 0x000F
#define NET_TYPE_KICK_PLAYER 0x0010
#define NET_TYPE_LEAVE_CURRENT_GAME 0x0011
#define NET_TYPE_START_EVENT 0x0012
#define NET_TYPE_GAME_START 0x0013
#define NET_TYPE_HAND_START 0x0014
#define NET_TYPE_PLAYERS_TURN 0x0015
#define NET_TYPE_PLAYERS_ACTION 0x0016
#define NET_TYPE_PLAYERS_ACTION_DONE 0x0017
#define NET_TYPE_PLAYERS_ACTION_REJECTED 0x0018
#define NET_TYPE_DEAL_FLOP_CARDS 0x0019
#define NET_TYPE_DEAL_TURN_CARD 0x001A
#define NET_TYPE_DEAL_RIVER_CARD 0x001B
#define NET_TYPE_ALL_IN_SHOW_CARDS 0x001C
#define NET_TYPE_END_OF_HAND_SHOW_CARDS 0x001D
#define NET_TYPE_END_OF_HAND_HIDE_CARDS 0x001E
#define NET_TYPE_END_OF_GAME 0x001F
#define NET_TYPE_REMOVED_FROM_GAME 0x0100
@@ -239,6 +240,12 @@ struct GCC_PACKED NetPacketPlayerLeftData
u_int32_t playerId;
};
struct GCC_PACKED NetPacketGameAdminChangedData
{
NetPacketHeader head;
u_int32_t playerId;
};
struct GCC_PACKED NetPacketKickPlayerData
{
NetPacketHeader head;
@@ -582,6 +589,9 @@ NetPacket::Create(char *data, unsigned &dataSize)
case NET_TYPE_PLAYER_LEFT:
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketPlayerLeft);
break;
case NET_TYPE_GAME_ADMIN_CHANGED:
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketGameAdminChanged);
break;
case NET_TYPE_KICK_PLAYER:
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketKickPlayer);
break;
@@ -810,6 +820,12 @@ NetPacket::ToNetPacketPlayerLeft() const
return NULL;
}
const NetPacketGameAdminChanged *
NetPacket::ToNetPacketGameAdminChanged() const
{
return NULL;
}
const NetPacketKickPlayer *
NetPacket::ToNetPacketKickPlayer() const
{
@@ -2189,6 +2205,65 @@ NetPacketPlayerLeft::InternalCheck(const NetPacketHeader*) const
// Nothing to do.
}
//-----------------------------------------------------------------------------
NetPacketGameAdminChanged::NetPacketGameAdminChanged()
: NetPacket(NET_TYPE_GAME_ADMIN_CHANGED, sizeof(NetPacketGameAdminChangedData), sizeof(NetPacketGameAdminChangedData))
{
}
NetPacketGameAdminChanged::~NetPacketGameAdminChanged()
{
}
boost::shared_ptr<NetPacket>
NetPacketGameAdminChanged::Clone() const
{
boost::shared_ptr<NetPacket> newPacket(new NetPacketGameAdminChanged);
try
{
newPacket->SetRawData(GetRawData());
} catch (const NetException &)
{
// Need to return the new packet anyway.
}
return newPacket;
}
void
NetPacketGameAdminChanged::SetData(const NetPacketGameAdminChanged::Data &inData)
{
NetPacketGameAdminChangedData *tmpData = (NetPacketGameAdminChangedData *)GetRawData();
// Set the data.
tmpData->playerId = htonl(inData.playerId);
// Check the packet - just in case.
Check(GetRawData());
}
void
NetPacketGameAdminChanged::GetData(NetPacketGameAdminChanged::Data &outData) const
{
// We assume that the data is valid. Validity has already been checked.
NetPacketGameAdminChangedData *tmpData = (NetPacketGameAdminChangedData *)GetRawData();
outData.playerId = ntohl(tmpData->playerId);
}
const NetPacketGameAdminChanged *
NetPacketGameAdminChanged::ToNetPacketGameAdminChanged() const
{
return this;
}
void
NetPacketGameAdminChanged::InternalCheck(const NetPacketHeader*) const
{
// Nothing to do.
}
//-----------------------------------------------------------------------------
NetPacketKickPlayer::NetPacketKickPlayer()
+7 -3
View File
@@ -312,10 +312,14 @@ ServerGameStateInit::InternalProcess(ServerGameThread &server, SessionWrapper se
}
else if (packet->ToNetPacketKickPlayer())
{
NetPacketKickPlayer::Data kickPlayerData;
packet->ToNetPacketKickPlayer()->GetData(kickPlayerData);
// Only admins are allowed to kick.
if (session.playerData->GetRights() == PLAYER_RIGHTS_ADMIN)
{
NetPacketKickPlayer::Data kickPlayerData;
packet->ToNetPacketKickPlayer()->GetData(kickPlayerData);
server.InternalKickPlayer(kickPlayerData.playerId);
server.InternalKickPlayer(kickPlayerData.playerId);
}
}
else
{
+17
View File
@@ -300,6 +300,23 @@ ServerGameThread::GracefulRemoveSession(SessionWrapper session)
static_cast<NetPacketPlayerLeft *>(thisPlayerLeft.get())->SetData(thisPlayerLeftData);
GetSessionManager().SendToAllSessions(GetSender(), thisPlayerLeft, SessionData::Game);
if (tmpPlayerData->GetRights() == PLAYER_RIGHTS_ADMIN)
{
// Find new admin for the game
PlayerIdList idList(GetSessionManager().GetPlayerIdList());
if (!idList.empty())
{
// Send "Game Admin Changed" to clients.
boost::shared_ptr<NetPacket> adminChanged(new NetPacketGameAdminChanged);
NetPacketGameAdminChanged::Data adminChangedData;
adminChangedData.playerId = idList.front(); // Choose next player as admin.
static_cast<NetPacketGameAdminChanged *>(adminChanged.get())->SetData(adminChangedData);
GetSessionManager().SendToAllSessions(GetSender(), adminChanged, SessionData::Game);
}
}
// Reset player rights.
tmpPlayerData->SetRights(PLAYER_RIGHTS_NORMAL);
GetLobbyThread().NotifyPlayerLeftGame(GetId(), session.playerData->GetUniqueId());
}
}
+25
View File
@@ -56,6 +56,7 @@ class NetPacketJoinGameAck;
class NetPacketJoinGameFailed;
class NetPacketPlayerJoined;
class NetPacketPlayerLeft;
class NetPacketGameAdminChanged;
class NetPacketKickPlayer;
class NetPacketLeaveCurrentGame;
class NetPacketStartEvent;
@@ -108,6 +109,7 @@ public:
virtual const NetPacketJoinGameFailed *ToNetPacketJoinGameFailed() const;
virtual const NetPacketPlayerJoined *ToNetPacketPlayerJoined() const;
virtual const NetPacketPlayerLeft *ToNetPacketPlayerLeft() const;
virtual const NetPacketGameAdminChanged *ToNetPacketGameAdminChanged() const;
virtual const NetPacketKickPlayer *ToNetPacketKickPlayer() const;
virtual const NetPacketLeaveCurrentGame *ToNetPacketLeaveCurrentGame() const;
virtual const NetPacketStartEvent *ToNetPacketStartEvent() const;
@@ -484,6 +486,29 @@ protected:
virtual void InternalCheck(const NetPacketHeader* data) const;
};
class NetPacketGameAdminChanged : public NetPacket
{
public:
struct Data
{
u_int32_t playerId;
};
NetPacketGameAdminChanged();
virtual ~NetPacketGameAdminChanged();
virtual boost::shared_ptr<NetPacket> Clone() const;
void SetData(const Data &inData);
void GetData(Data &outData) const;
virtual const NetPacketGameAdminChanged *ToNetPacketGameAdminChanged() const;
protected:
virtual void InternalCheck(const NetPacketHeader* data) const;
};
class NetPacketKickPlayer : public NetPacket
{
public: