|
|
|
/*==LICENSE==*
|
|
|
|
|
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools
|
|
|
|
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
Additional permissions under GNU GPL version 3 section 7
|
|
|
|
|
|
|
|
If you modify this Program, or any covered work, by linking or
|
|
|
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
|
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
|
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
|
|
(or a modified version of those libraries),
|
|
|
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
|
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
|
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
|
|
licensors of this Program grant you additional
|
|
|
|
permission to convey the resulting work. Corresponding Source for a
|
|
|
|
non-source form of such a combination shall include the source code for
|
|
|
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
|
|
work.
|
|
|
|
|
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
|
|
or by snail mail at:
|
|
|
|
Cyan Worlds, Inc.
|
|
|
|
14617 N Newport Hwy
|
|
|
|
Mead, WA 99021
|
|
|
|
|
|
|
|
*==LICENSE==*/
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* $/Plasma20/Sources/Plasma/FeatureLib/pfGameMgr/pfGameMgr.cpp
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
#include "Pch.h"
|
|
|
|
#pragma hdrstop
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* Local types
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
// pfGameCli factory
|
|
|
|
//============================================================================
|
|
|
|
struct Factory : THashKeyVal<Uuid> {
|
|
|
|
|
|
|
|
HASHLINK(Factory) link;
|
|
|
|
const GameTypeReg & reg;
|
|
|
|
|
|
|
|
Factory (const GameTypeReg & reg);
|
|
|
|
Factory & operator= (const Factory &); // not impl
|
|
|
|
};
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
// pfGameCli internal state
|
|
|
|
//============================================================================
|
|
|
|
struct IGameCli : THashKeyVal<unsigned> {
|
|
|
|
|
|
|
|
HASHLINK(IGameCli) link;
|
|
|
|
pfGameCli * gameCli;
|
|
|
|
Factory * factory;
|
|
|
|
plKey receiver;
|
|
|
|
unsigned playerCount;
|
|
|
|
|
|
|
|
IGameCli (
|
|
|
|
pfGameCli * gameCli,
|
|
|
|
unsigned gameId,
|
|
|
|
plKey receiver
|
|
|
|
);
|
|
|
|
|
|
|
|
void Recv (GameMsgHeader * msg, void * param);
|
|
|
|
void RecvPlayerJoined (const Srv2Cli_Game_PlayerJoined & msg, void * param);
|
|
|
|
void RecvPlayerLeft (const Srv2Cli_Game_PlayerLeft & msg, void * param);
|
|
|
|
void RecvInviteFailed (const Srv2Cli_Game_InviteFailed & msg, void * param);
|
|
|
|
void RecvOwnerChange (const Srv2Cli_Game_OwnerChange & msg, void * param);
|
|
|
|
};
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
// Transaction states
|
|
|
|
//============================================================================
|
|
|
|
struct TransState : THashKeyVal<unsigned> {
|
|
|
|
|
|
|
|
HASHLINK(TransState) link;
|
|
|
|
void * param;
|
|
|
|
TransState (unsigned transId, void * param);
|
|
|
|
};
|
|
|
|
struct JoinTransState {
|
|
|
|
|
|
|
|
plKey receiver;
|
|
|
|
JoinTransState (plKey receiver)
|
|
|
|
: receiver(receiver)
|
|
|
|
{ }
|
|
|
|
};
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
// IGameMgr
|
|
|
|
//============================================================================
|
|
|
|
struct IGameMgr {
|
|
|
|
|
|
|
|
pfGameCli * CreateGameCli (const Uuid & gameTypeId, unsigned gameId, plKey receiver);
|
|
|
|
|
|
|
|
void Recv (GameMsgHeader * msg);
|
|
|
|
void RecvGameInstance (const Srv2Cli_GameMgr_GameInstance & msg, void * param);
|
|
|
|
void RecvInviteReceived (const Srv2Cli_GameMgr_InviteReceived & msg, void * param);
|
|
|
|
void RecvInviteRevoked (const Srv2Cli_GameMgr_InviteRevoked & msg, void * param);
|
|
|
|
|
|
|
|
static void StaticRecv (GameMsgHeader * msg);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* Local data
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
static HASHTABLEDECL(TransState, THashKeyVal<unsigned>, link) s_trans;
|
|
|
|
static HASHTABLEDECL(IGameCli, THashKeyVal<unsigned>, link) s_games;
|
|
|
|
static HASHTABLEDECL(Factory, THashKeyVal<Uuid>, link) s_factories;
|
|
|
|
|
|
|
|
static long s_transId;
|
|
|
|
static ARRAYOBJ(plKey) s_receivers;
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* Local functions
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void ShutdownFactories () {
|
|
|
|
|
|
|
|
while (Factory * factory = s_factories.Head())
|
|
|
|
DEL(factory);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
AUTO_INIT_FUNC (SetGameMgrMsgHandler) {
|
|
|
|
|
|
|
|
NetCliGameSetRecvGameMgrMsgHandler(IGameMgr::StaticRecv);
|
|
|
|
atexit(ShutdownFactories);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static inline unsigned INextTransId () {
|
|
|
|
|
|
|
|
unsigned transId = AtomicAdd(&s_transId, 1);
|
|
|
|
while (!transId)
|
|
|
|
transId = AtomicAdd(&s_transId, 1);
|
|
|
|
return transId;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* IGameMgr
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
pfGameCli * IGameMgr::CreateGameCli (const Uuid & gameTypeId, unsigned gameId, plKey receiver) {
|
|
|
|
|
|
|
|
if (Factory * factory = s_factories.Find(gameTypeId)) {
|
|
|
|
pfGameCli * gameCli = factory->reg.create(gameId, receiver);
|
|
|
|
gameCli->internal->factory = factory;
|
|
|
|
return gameCli;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void IGameMgr::RecvGameInstance (const Srv2Cli_GameMgr_GameInstance & msg, void * param) {
|
|
|
|
|
|
|
|
JoinTransState * state = (JoinTransState *)param;
|
|
|
|
|
|
|
|
pfGameCli * cli = nil;
|
|
|
|
IGameCli * internal = nil;
|
|
|
|
if (msg.result == kGameJoinSuccess) {
|
|
|
|
if (nil == (internal = s_games.Find(msg.newGameId)))
|
|
|
|
cli = CreateGameCli(msg.gameTypeId, msg.newGameId, state->receiver);
|
|
|
|
else
|
|
|
|
cli = internal->gameCli;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEL(state);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void IGameMgr::RecvInviteReceived (const Srv2Cli_GameMgr_InviteReceived & msg, void * param) {
|
|
|
|
REF(param);
|
|
|
|
|
|
|
|
pfGameMgrMsg * gameMgrMsg = NEWZERO(pfGameMgrMsg);
|
|
|
|
gameMgrMsg->Set(msg);
|
|
|
|
for (unsigned i = 0; i < s_receivers.Count(); ++i)
|
|
|
|
gameMgrMsg->AddReceiver(s_receivers[i]);
|
|
|
|
gameMgrMsg->Send();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void IGameMgr::RecvInviteRevoked (const Srv2Cli_GameMgr_InviteRevoked & msg, void * param) {
|
|
|
|
REF(param);
|
|
|
|
|
|
|
|
pfGameMgrMsg * gameMgrMsg = NEWZERO(pfGameMgrMsg);
|
|
|
|
gameMgrMsg->Set(msg);
|
|
|
|
for (unsigned i = 0; i < s_receivers.Count(); ++i)
|
|
|
|
gameMgrMsg->AddReceiver(s_receivers[i]);
|
|
|
|
gameMgrMsg->Send();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void IGameMgr::Recv (GameMsgHeader * msg) {
|
|
|
|
|
|
|
|
// Look for transaction state associated with this message
|
|
|
|
void * param;
|
|
|
|
if (TransState * trans = s_trans.Find(msg->transId)) {
|
|
|
|
param = trans->param;
|
|
|
|
DEL(trans);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
param = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the message has a receiver gameId specified, then
|
|
|
|
// hand it off to that game client for dispatch.
|
|
|
|
if (unsigned gameId = msg->recvGameId) {
|
|
|
|
if (IGameCli * node = s_games.Find(gameId)) {
|
|
|
|
node->Recv(msg, param);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The message was meant for the game manager (that's us); dispatch it.
|
|
|
|
#define DISPATCH(a) case kSrv2Cli_GameMgr_##a: { \
|
|
|
|
const Srv2Cli_GameMgr_##a & m = *(const Srv2Cli_GameMgr_##a *)msg; \
|
|
|
|
Recv##a(m, param); \
|
|
|
|
} \
|
|
|
|
break; //
|
|
|
|
switch (msg->messageId) {
|
|
|
|
DISPATCH(GameInstance);
|
|
|
|
DISPATCH(InviteReceived);
|
|
|
|
DISPATCH(InviteRevoked);
|
|
|
|
DEFAULT_FATAL(msg->messageId);
|
|
|
|
}
|
|
|
|
#undef DISPATCH
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void IGameMgr::StaticRecv (GameMsgHeader * msg) {
|
|
|
|
|
|
|
|
pfGameMgr::GetInstance()->internal->Recv(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* pfGameMgrMsg
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
pfGameMgrMsg::pfGameMgrMsg () {
|
|
|
|
|
|
|
|
netMsg = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
pfGameMgrMsg::~pfGameMgrMsg () {
|
|
|
|
|
|
|
|
FREE(netMsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void pfGameMgrMsg::Set (const GameMsgHeader & msg) {
|
|
|
|
|
|
|
|
netMsg = (GameMsgHeader *)ALLOC(msg.messageBytes);
|
|
|
|
MemCopy(netMsg, &msg, msg.messageBytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* pfGameCliMsg
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
pfGameCliMsg::pfGameCliMsg () {
|
|
|
|
|
|
|
|
gameCli = nil;
|
|
|
|
netMsg = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
pfGameCliMsg::~pfGameCliMsg () {
|
|
|
|
|
|
|
|
FREE(netMsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void pfGameCliMsg::Set (pfGameCli * cli, const GameMsgHeader & msg) {
|
|
|
|
|
|
|
|
netMsg = (GameMsgHeader *)ALLOC(msg.messageBytes);
|
|
|
|
MemCopy(netMsg, &msg, msg.messageBytes);
|
|
|
|
gameCli = cli;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* pfGameMgr
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
pfGameMgr::pfGameMgr () {
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
pfGameMgr * pfGameMgr::GetInstance () {
|
|
|
|
|
|
|
|
static pfGameMgr s_instance;
|
|
|
|
return &s_instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void pfGameMgr::GetGameIds (ARRAY(unsigned) * arr) const {
|
|
|
|
|
|
|
|
for (IGameCli * node = s_games.Head(); node; node = s_games.Next(node))
|
|
|
|
arr->Add(node->GetValue());
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
pfGameCli * pfGameMgr::GetGameCli (unsigned gameId) const {
|
|
|
|
|
|
|
|
if (IGameCli * node = s_games.Find(gameId))
|
|
|
|
return node->gameCli;
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
const wchar * pfGameMgr::GetGameNameByTypeId (const Uuid & gameTypeId) const {
|
|
|
|
|
|
|
|
if (Factory * factory = s_factories.Find(gameTypeId))
|
|
|
|
return factory->reg.name;
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void pfGameMgr::RemoveReceiver (plKey receiver) {
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < s_receivers.Count(); ++i) {
|
|
|
|
if (s_receivers[i] == receiver) {
|
|
|
|
s_receivers.DeleteUnordered(i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void pfGameMgr::AddReceiver (plKey receiver) {
|
|
|
|
|
|
|
|
RemoveReceiver(receiver);
|
|
|
|
s_receivers.Add(receiver);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void pfGameMgr::JoinGame (
|
|
|
|
plKey receiver,
|
|
|
|
unsigned gameId
|
|
|
|
) {
|
|
|
|
Cli2Srv_GameMgr_JoinGame msg;
|
|
|
|
ZERO(msg);
|
|
|
|
|
|
|
|
msg.messageId = kCli2Srv_GameMgr_JoinGame;
|
|
|
|
msg.recvGameId = 0; // send to GameMgr on server
|
|
|
|
msg.newGameId = gameId; // the GameSrv we wish to join
|
|
|
|
|
|
|
|
// Don't send "common game" message fields
|
|
|
|
unsigned msgBytes
|
|
|
|
= sizeof(msg)
|
|
|
|
- sizeof(msg.gameTypeId)
|
|
|
|
- sizeof(msg.createDataBytes)
|
|
|
|
- sizeof(msg.createData);
|
|
|
|
|
|
|
|
msg.messageBytes = msgBytes;
|
|
|
|
|
|
|
|
GameMgrSend(&msg, NEWZERO(JoinTransState)(receiver));
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void pfGameMgr::CreateGame (
|
|
|
|
plKey receiver,
|
|
|
|
const Uuid & gameTypeId,
|
|
|
|
unsigned createOptions,
|
|
|
|
unsigned initBytes,
|
|
|
|
const void * initData
|
|
|
|
) {
|
|
|
|
Cli2Srv_GameMgr_CreateGame * msg;
|
|
|
|
|
|
|
|
unsigned msgBytes
|
|
|
|
= sizeof(*msg)
|
|
|
|
- sizeof(msg->createData)
|
|
|
|
+ initBytes;
|
|
|
|
|
|
|
|
msg = (Cli2Srv_GameMgr_CreateGame *)_alloca(msgBytes);
|
|
|
|
|
|
|
|
msg->messageId = kCli2Srv_GameMgr_CreateGame;
|
|
|
|
msg->recvGameId = 0; // send to GameMgr on server
|
|
|
|
msg->gameTypeId = gameTypeId; // The type of game we wish to create
|
|
|
|
msg->createOptions = createOptions;
|
|
|
|
msg->messageBytes = msgBytes;
|
|
|
|
msg->createDataBytes = initBytes;
|
|
|
|
MemCopy(msg->createData, initData, initBytes);
|
|
|
|
|
|
|
|
GameMgrSend(msg, NEWZERO(JoinTransState)(receiver));
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void pfGameMgr::JoinCommonGame (
|
|
|
|
plKey receiver,
|
|
|
|
const Uuid & gameTypeId,
|
|
|
|
unsigned gameNumber,
|
|
|
|
unsigned initBytes,
|
|
|
|
const void * initData
|
|
|
|
) {
|
|
|
|
Cli2Srv_GameMgr_JoinGame * msg;
|
|
|
|
|
|
|
|
unsigned msgBytes
|
|
|
|
= sizeof(*msg)
|
|
|
|
- sizeof(msg->createData)
|
|
|
|
+ initBytes;
|
|
|
|
|
|
|
|
msg = (Cli2Srv_GameMgr_JoinGame *)_alloca(msgBytes);
|
|
|
|
|
|
|
|
msg->messageId = kCli2Srv_GameMgr_JoinGame;
|
|
|
|
msg->recvGameId = 0; // send to GameMgr on server
|
|
|
|
msg->gameTypeId = gameTypeId; // the type of common game we with to join
|
|
|
|
msg->newGameId = gameNumber; // the "table number" of th common game we wish to join
|
|
|
|
msg->createOptions = kGameJoinCommon;
|
|
|
|
msg->messageBytes = msgBytes;
|
|
|
|
msg->createDataBytes = initBytes;
|
|
|
|
MemCopy(msg->createData, initData, initBytes);
|
|
|
|
|
|
|
|
GameMgrSend(msg, NEWZERO(JoinTransState)(receiver));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* pfGameCli
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
pfGameCli::pfGameCli (
|
|
|
|
unsigned gameId,
|
|
|
|
plKey receiver
|
|
|
|
) {
|
|
|
|
internal = NEWZERO(IGameCli)(this, gameId, receiver);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
pfGameCli::~pfGameCli () {
|
|
|
|
|
|
|
|
DEL(internal);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
unsigned pfGameCli::GetGameId () const {
|
|
|
|
|
|
|
|
return internal->GetValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
const Uuid & pfGameCli::GetGameTypeId () const {
|
|
|
|
|
|
|
|
return internal->factory->GetValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
const wchar * pfGameCli::GetName () const {
|
|
|
|
|
|
|
|
return internal->factory->reg.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
plKey pfGameCli::GetReceiver () const {
|
|
|
|
|
|
|
|
return internal->receiver;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
unsigned pfGameCli::GetPlayerCount () const {
|
|
|
|
|
|
|
|
return internal->playerCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void pfGameCli::InvitePlayer (unsigned playerId) {
|
|
|
|
|
|
|
|
Cli2Srv_Game_Invite msg;
|
|
|
|
msg.messageId = kCli2Srv_Game_Invite;
|
|
|
|
msg.recvGameId = GetGameId(); // send to GameSrv on server
|
|
|
|
msg.playerId = playerId;
|
|
|
|
msg.messageBytes = sizeof(msg);
|
|
|
|
|
|
|
|
GameMgrSend(&msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void pfGameCli::UninvitePlayer (unsigned playerId) {
|
|
|
|
|
|
|
|
Cli2Srv_Game_Uninvite msg;
|
|
|
|
msg.messageId = kCli2Srv_Game_Uninvite;
|
|
|
|
msg.recvGameId = GetGameId(); // send to GameSrv on server
|
|
|
|
msg.playerId = playerId;
|
|
|
|
msg.messageBytes = sizeof(msg);
|
|
|
|
|
|
|
|
GameMgrSend(&msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void pfGameCli::LeaveGame () {
|
|
|
|
|
|
|
|
Cli2Srv_Game_LeaveGame msg;
|
|
|
|
msg.messageId = kCli2Srv_Game_LeaveGame;
|
|
|
|
msg.recvGameId = GetGameId(); // send to GameSrv on server
|
|
|
|
msg.messageBytes = sizeof(msg);
|
|
|
|
|
|
|
|
GameMgrSend(&msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* IGameCli
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
IGameCli::IGameCli (
|
|
|
|
pfGameCli * gameCli,
|
|
|
|
unsigned gameId,
|
|
|
|
plKey receiver
|
|
|
|
) : THashKeyVal<unsigned>(gameId)
|
|
|
|
, gameCli(gameCli)
|
|
|
|
, receiver(receiver)
|
|
|
|
{
|
|
|
|
s_games.Add(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void IGameCli::Recv (GameMsgHeader * msg, void * param) {
|
|
|
|
|
|
|
|
#define DISPATCH(a) case kSrv2Cli_Game_##a: { \
|
|
|
|
const Srv2Cli_Game_##a & m = *(const Srv2Cli_Game_##a *)msg; \
|
|
|
|
Recv##a(m, param); \
|
|
|
|
} \
|
|
|
|
break;
|
|
|
|
switch (msg->messageId) {
|
|
|
|
DISPATCH(PlayerJoined);
|
|
|
|
DISPATCH(PlayerLeft);
|
|
|
|
DISPATCH(InviteFailed);
|
|
|
|
DISPATCH(OwnerChange);
|
|
|
|
default:
|
|
|
|
gameCli->Recv(msg, param);
|
|
|
|
}
|
|
|
|
#undef DISPATCH
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void IGameCli::RecvPlayerJoined (const Srv2Cli_Game_PlayerJoined & msg, void * param) {
|
|
|
|
REF(param);
|
|
|
|
|
|
|
|
++playerCount;
|
|
|
|
gameCli->OnPlayerJoined(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void IGameCli::RecvPlayerLeft (const Srv2Cli_Game_PlayerLeft & msg, void * param) {
|
|
|
|
REF(param);
|
|
|
|
|
|
|
|
--playerCount;
|
|
|
|
gameCli->OnPlayerLeft(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void IGameCli::RecvInviteFailed (const Srv2Cli_Game_InviteFailed & msg, void * param) {
|
|
|
|
REF(param);
|
|
|
|
|
|
|
|
gameCli->OnInviteFailed(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void IGameCli::RecvOwnerChange (const Srv2Cli_Game_OwnerChange & msg, void * param) {
|
|
|
|
REF(param);
|
|
|
|
|
|
|
|
gameCli->OnOwnerChange(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* Factory
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
Factory::Factory (const GameTypeReg & reg)
|
|
|
|
: reg(reg)
|
|
|
|
, THashKeyVal<Uuid>(reg.typeId)
|
|
|
|
{
|
|
|
|
s_factories.Add(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* TransState
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
TransState::TransState (unsigned transId, void * param)
|
|
|
|
: THashKeyVal<unsigned>(transId)
|
|
|
|
, param(param)
|
|
|
|
{
|
|
|
|
s_trans.Add(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* Module functions
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void GameMgrRegisterGameType (const GameTypeReg & reg) {
|
|
|
|
|
|
|
|
(void)NEWZERO(Factory)(reg);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void GameMgrSend (GameMsgHeader * msg, void * param) {
|
|
|
|
|
|
|
|
if (param) {
|
|
|
|
msg->transId = INextTransId();
|
|
|
|
(void)NEW(TransState)(msg->transId, param);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
msg->transId = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
NetCliGameSendGameMgrMsg(msg);
|
|
|
|
}
|