|
|
|
/*==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/PubUtilLib/plNetClientComm/plNetClientComm.cpp
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
#include "plNetClientComm.h"
|
|
|
|
|
|
|
|
#include "pnAsyncCore/pnAsyncCore.h"
|
|
|
|
#include "pnProduct/pnProduct.h"
|
|
|
|
#include "pnNetCli/pnNetCli.h"
|
|
|
|
#include "plNetGameLib/plNetGameLib.h"
|
|
|
|
#include "pnIni/pnIni.h"
|
|
|
|
|
|
|
|
#include "plMessage/plNetCommMsgs.h"
|
|
|
|
#include "plMessage/plNetClientMgrMsg.h"
|
|
|
|
#include "plNetMessage/plNetMessage.h"
|
|
|
|
#include "plNetCommon/plNetCommon.h"
|
|
|
|
#include "plVault/plVault.h"
|
|
|
|
#include "plMessage/plAccountUpdateMsg.h"
|
|
|
|
#include "plNetClient/plNetClientMgr.h"
|
|
|
|
|
|
|
|
#include "pfMessage/pfKIMsg.h"
|
|
|
|
|
|
|
|
#include "hsResMgr.h"
|
|
|
|
|
|
|
|
#include <malloc.h>
|
|
|
|
|
|
|
|
extern hsBool gDataServerLocal;
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* Exported data
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
const unsigned kNetCommAllMsgClasses = (unsigned)-1;
|
|
|
|
FNetCommMsgHandler * kNetCommAllMsgHandlers = (FNetCommMsgHandler*)-1;
|
|
|
|
const void * kNetCommAllUserStates = (void*)-1;
|
|
|
|
|
|
|
|
struct NetCommParam {
|
|
|
|
void * param;
|
|
|
|
plNetCommReplyMsg::EParamType type;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* Private
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* Private data
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
static bool s_shutdown;
|
|
|
|
|
|
|
|
static NetCommAccount s_account;
|
|
|
|
static ARRAY(NetCommPlayer) s_players;
|
|
|
|
static NetCommPlayer * s_player;
|
|
|
|
static NetCommAge s_age;
|
|
|
|
static NetCommAge s_startupAge;
|
|
|
|
static bool s_needAvatarLoad = true;
|
|
|
|
static bool s_loginComplete = false;
|
|
|
|
static bool s_hasFileSrvIpAddress = false;
|
|
|
|
static ENetError s_authResult = kNetErrAuthenticationFailed;
|
|
|
|
static wchar s_fileSrvAddr[256];
|
|
|
|
|
|
|
|
static wchar s_iniServerAddr[256];
|
|
|
|
static wchar s_iniFileServerAddr[256];
|
|
|
|
static wchar s_iniAccountUsername[kMaxAccountNameLength];
|
|
|
|
static ShaDigest s_namePassHash;
|
|
|
|
static wchar s_iniAuthToken[kMaxPublisherAuthKeyLength];
|
|
|
|
static wchar s_iniOS[kMaxGTOSIdLength];
|
|
|
|
static bool s_iniReadAccountInfo = true;
|
|
|
|
static wchar s_iniStartupAgeName[kMaxAgeNameLength];
|
|
|
|
static Uuid s_iniStartupAgeInstId;
|
|
|
|
static wchar s_iniStartupPlayerName[kMaxPlayerNameLength];
|
|
|
|
static bool s_netError = false;
|
|
|
|
|
|
|
|
|
|
|
|
struct NetCommMsgHandler : THashKeyVal<unsigned> {
|
|
|
|
HASHLINK(NetCommMsgHandler) link;
|
|
|
|
FNetCommMsgHandler * proc;
|
|
|
|
void * state;
|
|
|
|
|
|
|
|
NetCommMsgHandler (
|
|
|
|
unsigned msgId,
|
|
|
|
FNetCommMsgHandler * proc,
|
|
|
|
void * state
|
|
|
|
) : THashKeyVal<unsigned>(msgId)
|
|
|
|
, proc(proc)
|
|
|
|
, state(state)
|
|
|
|
{ }
|
|
|
|
};
|
|
|
|
|
|
|
|
static HASHTABLEDECL(
|
|
|
|
NetCommMsgHandler,
|
|
|
|
THashKeyVal<unsigned>,
|
|
|
|
link
|
|
|
|
) s_handlers;
|
|
|
|
|
|
|
|
static NetCommMsgHandler s_defaultHandler(0, nil, nil);
|
|
|
|
static NetCommMsgHandler s_preHandler(0, nil, nil);
|
|
|
|
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetLogCallback (
|
|
|
|
ELogSeverity severity,
|
|
|
|
const wchar msg[]
|
|
|
|
) {
|
|
|
|
// Use the async log facility
|
|
|
|
AsyncLogWriteMsg(ProductShortName(), severity, msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetErrorCallback (
|
|
|
|
ENetProtocol protocol,
|
|
|
|
ENetError error
|
|
|
|
) {
|
|
|
|
NetClientDestroy(false);
|
|
|
|
|
|
|
|
plNetClientMgrMsg * msg = NEWZERO(plNetClientMgrMsg);
|
|
|
|
msg->type = plNetClientMgrMsg::kCmdDisableNet;
|
|
|
|
msg->yes = true;
|
|
|
|
msg->AddReceiver(plNetClientApp::GetInstance()->GetKey());
|
|
|
|
|
|
|
|
switch (error)
|
|
|
|
{
|
|
|
|
case kNetErrKickedByCCR:
|
|
|
|
StrPrintf(
|
|
|
|
msg->str,
|
|
|
|
arrsize(msg->str),
|
|
|
|
"You have been kicked by a CCR."
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
// Until we get some real error handling, this'll ensure no errors
|
|
|
|
// fall thru the cracks and we hang forever wondering what's up.
|
|
|
|
StrPrintf(
|
|
|
|
// buf
|
|
|
|
msg->str,
|
|
|
|
arrsize(msg->str),
|
|
|
|
// fmt
|
|
|
|
"Network error %u, %S.\n"
|
|
|
|
"protocol: %S\n"
|
|
|
|
,// values
|
|
|
|
error,
|
|
|
|
NetErrorToString(error),
|
|
|
|
NetProtocolToString(protocol)
|
|
|
|
);
|
|
|
|
s_netError = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
msg->Send();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void IPreInitNetErrorCallback (
|
|
|
|
ENetProtocol protocol,
|
|
|
|
ENetError error
|
|
|
|
) {
|
|
|
|
s_authResult = error;
|
|
|
|
s_loginComplete = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetBufferCallback (
|
|
|
|
unsigned type,
|
|
|
|
unsigned bytes,
|
|
|
|
const byte buffer[]
|
|
|
|
) {
|
|
|
|
if (!plFactory::IsValidClassIndex(type)) {
|
|
|
|
LogMsg(kLogError, "NetComm: received junk propagated buffer");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
plNetMessage * msg = plNetMessage::ConvertNoRef(plFactory::Create(type));
|
|
|
|
if (!msg) {
|
|
|
|
LogMsg(kLogError, "NetComm: could not convert plNetMessage to class %u", type);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!msg->PeekBuffer((const char *)buffer, bytes)) {
|
|
|
|
LogMsg(kLogError, "NetComm: plNetMessage %u failed to peek buffer", type);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
NetCommRecvMsg(msg);
|
|
|
|
|
|
|
|
msg->UnRef();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INotifyNewBuildCallback () {
|
|
|
|
|
|
|
|
if (!hsgResMgr::ResMgr())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!NetCommGetPlayer())
|
|
|
|
return;
|
|
|
|
if (!NetCommGetPlayer()->playerInt)
|
|
|
|
return;
|
|
|
|
if (!NetCommGetAge())
|
|
|
|
return;
|
|
|
|
if (!NetCommGetAge()->ageInstId)
|
|
|
|
return;
|
|
|
|
|
|
|
|
pfKIMsg * msg = NEW(pfKIMsg)(pfKIMsg::kHACKChatMsg);
|
|
|
|
msg->SetString("Uru has been updated. Please quit the game and log back in.");
|
|
|
|
msg->SetUser("Updater Service", plNetClientApp::GetInstance()->GetPlayerID());
|
|
|
|
msg->SetFlags(pfKIMsg::kAdminMsg);
|
|
|
|
msg->SetBCastFlag(plMessage::kNetPropagate | plMessage::kNetForce, 0);
|
|
|
|
msg->SetBCastFlag(plMessage::kLocalPropagate, 1);
|
|
|
|
msg->Send();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INotifyAuthConnectedCallback () {
|
|
|
|
|
|
|
|
if (!hsgResMgr::ResMgr())
|
|
|
|
return;
|
|
|
|
|
|
|
|
plNetCommAuthConnectedMsg * msg = NEWZERO(plNetCommAuthConnectedMsg);
|
|
|
|
msg->Send();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void PlayerInitCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
if (IS_NET_ERROR(result) && (result != kNetErrVaultNodeNotFound)) {
|
|
|
|
s_player = nil;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Ensure the city link has the required spawn points
|
|
|
|
plAgeInfoStruct info;
|
|
|
|
info.SetAgeFilename(kCityAgeFilename);
|
|
|
|
if (RelVaultNode * rvn = VaultGetOwnedAgeLinkIncRef(&info)) {
|
|
|
|
VaultAgeLinkNode acc(rvn);
|
|
|
|
acc.AddSpawnPoint(plSpawnPointInfo(kCityFerryTerminalLinkTitle, kCityFerryTerminalLinkSpawnPtName));
|
|
|
|
rvn->DecRef();
|
|
|
|
}
|
|
|
|
|
|
|
|
VaultProcessPlayerInbox();
|
|
|
|
}
|
|
|
|
|
|
|
|
plNetCommActivePlayerMsg * msg = NEW(plNetCommActivePlayerMsg);
|
|
|
|
msg->result = result;
|
|
|
|
msg->param = param;
|
|
|
|
msg->Send();
|
|
|
|
|
|
|
|
plAccountUpdateMsg * updateMsg = TRACKED_NEW plAccountUpdateMsg(plAccountUpdateMsg::kActivePlayer);
|
|
|
|
updateMsg->SetPlayerInt(NetCommGetPlayer()->playerInt);
|
|
|
|
updateMsg->SetResult((unsigned)result);
|
|
|
|
updateMsg->SetBCastFlag(plMessage::kBCastByExactType);
|
|
|
|
updateMsg->Send();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetCliAuthSetPlayerRequestCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
if (!s_player) {
|
|
|
|
PlayerInitCallback(result, param);
|
|
|
|
}
|
|
|
|
else if (IS_NET_ERROR(result) && (result != kNetErrVaultNodeNotFound)) {
|
|
|
|
s_player = nil;
|
|
|
|
PlayerInitCallback(result, param);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
s_needAvatarLoad = true;
|
|
|
|
|
|
|
|
VaultDownload(
|
|
|
|
L"SetActivePlayer",
|
|
|
|
s_player->playerInt,
|
|
|
|
PlayerInitCallback,
|
|
|
|
param,
|
|
|
|
nil,
|
|
|
|
nil
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void LoginPlayerInitCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
if (IS_NET_ERROR(result) && (result != kNetErrVaultNodeNotFound))
|
|
|
|
s_player = nil;
|
|
|
|
else
|
|
|
|
VaultProcessPlayerInbox();
|
|
|
|
|
|
|
|
{
|
|
|
|
plNetCommAuthMsg * msg = NEW(plNetCommAuthMsg);
|
|
|
|
msg->result = result;
|
|
|
|
msg->param = param;
|
|
|
|
msg->Send();
|
|
|
|
}
|
|
|
|
{
|
|
|
|
plNetCommActivePlayerMsg * msg = NEW(plNetCommActivePlayerMsg);
|
|
|
|
msg->result = result;
|
|
|
|
msg->param = param;
|
|
|
|
msg->Send();
|
|
|
|
}
|
|
|
|
{
|
|
|
|
plAccountUpdateMsg * msg = TRACKED_NEW plAccountUpdateMsg(plAccountUpdateMsg::kActivePlayer);
|
|
|
|
msg->SetPlayerInt(NetCommGetPlayer()->playerInt);
|
|
|
|
msg->SetResult((unsigned)result);
|
|
|
|
msg->SetBCastFlag(plMessage::kBCastByExactType);
|
|
|
|
msg->Send();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetCliAuthLoginSetPlayerRequestCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
if (IS_NET_ERROR(result) && (result != kNetErrVaultNodeNotFound)) {
|
|
|
|
s_player = nil;
|
|
|
|
|
|
|
|
plNetCommAuthMsg * msg = NEW(plNetCommAuthMsg);
|
|
|
|
msg->result = result;
|
|
|
|
msg->param = param;
|
|
|
|
msg->Send();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
VaultDownload(
|
|
|
|
L"SetActivePlayer",
|
|
|
|
s_player->playerInt,
|
|
|
|
LoginPlayerInitCallback,
|
|
|
|
param,
|
|
|
|
nil,
|
|
|
|
nil
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetCliAuthLoginRequestCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param,
|
|
|
|
const Uuid & accountUuid,
|
|
|
|
unsigned accountFlags,
|
|
|
|
unsigned billingType,
|
|
|
|
const NetCliAuthPlayerInfo playerInfoArr[],
|
|
|
|
unsigned playerCount
|
|
|
|
) {
|
|
|
|
s_authResult = result;
|
|
|
|
|
|
|
|
s_player = nil;
|
|
|
|
s_players.Clear();
|
|
|
|
|
|
|
|
bool wantsStartUpAge = (
|
|
|
|
!StrLen(s_startupAge.ageDatasetName) ||
|
|
|
|
0 == StrCmpI(s_startupAge.ageDatasetName, "StartUp")
|
|
|
|
);
|
|
|
|
|
|
|
|
s_loginComplete = true;
|
|
|
|
|
|
|
|
if (!IS_NET_ERROR(result) || result == kNetErrVaultNodeNotFound) {
|
|
|
|
s_account.accountUuid = accountUuid;
|
|
|
|
s_account.accountFlags = accountFlags;
|
|
|
|
s_account.billingType = billingType;
|
|
|
|
s_players.GrowToCount(playerCount, true);
|
|
|
|
for (unsigned i = 0; i < playerCount; ++i) {
|
|
|
|
LogMsg(kLogDebug, L"Player %u: %s explorer: %u", playerInfoArr[i].playerInt, playerInfoArr[i].playerName, playerInfoArr[i].explorer);
|
|
|
|
s_players[i].playerInt = playerInfoArr[i].playerInt;
|
|
|
|
s_players[i].explorer = playerInfoArr[i].explorer;
|
|
|
|
StrCopy(s_players[i].playerName, playerInfoArr[i].playerName, arrsize(s_players[i].playerName));
|
|
|
|
StrToAnsi(s_players[i].playerNameAnsi, playerInfoArr[i].playerName, arrsize(s_players[i].playerNameAnsi));
|
|
|
|
StrToAnsi(s_players[i].avatarDatasetName, playerInfoArr[i].avatarShape, arrsize(s_players[i].avatarDatasetName));
|
|
|
|
if (!wantsStartUpAge && 0 == StrCmpI(s_players[i].playerName, s_iniStartupPlayerName, (unsigned)-1))
|
|
|
|
s_player = &s_players[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
s_account.accountUuid = kNilGuid;
|
|
|
|
|
|
|
|
// If they specified an alternate age, but we couldn't find the player, force
|
|
|
|
// the StartUp age to load so that they may select/create a player first.
|
|
|
|
if (!wantsStartUpAge && !s_player)
|
|
|
|
StrCopy(s_startupAge.ageDatasetName, "StartUp", arrsize(s_startupAge.ageDatasetName));
|
|
|
|
|
|
|
|
// If they specified an alternate age, and we found the player, set the active player now
|
|
|
|
// so that the link operation will be successful once the client is finished initializing.
|
|
|
|
if (!wantsStartUpAge && s_player) {
|
|
|
|
NetCliAuthSetPlayerRequest(
|
|
|
|
s_player->playerInt,
|
|
|
|
INetCliAuthLoginSetPlayerRequestCallback,
|
|
|
|
param
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetCliAuthCreatePlayerRequestCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param,
|
|
|
|
const NetCliAuthPlayerInfo & playerInfo
|
|
|
|
) {
|
|
|
|
if (IS_NET_ERROR(result)) {
|
|
|
|
LogMsg(kLogDebug, L"Create player failed: %s", NetErrorToString(result));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
LogMsg(kLogDebug, L"Created player %s: %u", playerInfo.playerName, playerInfo.playerInt);
|
|
|
|
|
|
|
|
unsigned currPlayer = s_player ? s_player->playerInt : 0;
|
|
|
|
NetCommPlayer * newPlayer = s_players.New();
|
|
|
|
|
|
|
|
newPlayer->playerInt = playerInfo.playerInt;
|
|
|
|
newPlayer->explorer = playerInfo.explorer;
|
|
|
|
StrCopy(newPlayer->playerName, playerInfo.playerName, arrsize(newPlayer->playerName));
|
|
|
|
StrToAnsi(newPlayer->playerNameAnsi, playerInfo.playerName, arrsize(newPlayer->playerNameAnsi));
|
|
|
|
StrToAnsi(newPlayer->avatarDatasetName, playerInfo.avatarShape, arrsize(newPlayer->avatarDatasetName));
|
|
|
|
|
|
|
|
{ for (unsigned i = 0; i < s_players.Count(); ++i) {
|
|
|
|
if (s_players[i].playerInt == currPlayer) {
|
|
|
|
s_player = &s_players[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
}
|
|
|
|
|
|
|
|
plAccountUpdateMsg* updateMsg = TRACKED_NEW plAccountUpdateMsg(plAccountUpdateMsg::kCreatePlayer);
|
|
|
|
updateMsg->SetPlayerInt(playerInfo.playerInt);
|
|
|
|
updateMsg->SetResult((unsigned)result);
|
|
|
|
updateMsg->SetBCastFlag(plMessage::kBCastByExactType);
|
|
|
|
updateMsg->Send();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetCliAuthDeletePlayerCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
unsigned playerInt = (unsigned)param;
|
|
|
|
|
|
|
|
if (IS_NET_ERROR(result)) {
|
|
|
|
LogMsg(kLogDebug, L"Delete player failed: %d %s", playerInt, NetErrorToString(result));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
LogMsg(kLogDebug, L"Player deleted: %d", playerInt);
|
|
|
|
|
|
|
|
unsigned currPlayer = s_player ? s_player->playerInt : 0;
|
|
|
|
|
|
|
|
{for (unsigned i = 0; i < s_players.Count(); ++i) {
|
|
|
|
if (s_players[i].playerInt == playerInt) {
|
|
|
|
s_players.DeleteUnordered(i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
|
|
|
|
{for (unsigned i = 0; i < s_players.Count(); ++i) {
|
|
|
|
if (s_players[i].playerInt == currPlayer) {
|
|
|
|
s_player = &s_players[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
}
|
|
|
|
|
|
|
|
plAccountUpdateMsg* updateMsg = TRACKED_NEW plAccountUpdateMsg(plAccountUpdateMsg::kDeletePlayer);
|
|
|
|
updateMsg->SetPlayerInt(playerInt);
|
|
|
|
updateMsg->SetResult((unsigned)result);
|
|
|
|
updateMsg->SetBCastFlag(plMessage::kBCastByExactType);
|
|
|
|
updateMsg->Send();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetCliAuthChangePasswordCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
if (IS_NET_ERROR(result)) {
|
|
|
|
LogMsg(kLogDebug, L"Change password failed: %s", NetErrorToString(result));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
LogMsg(kLogDebug, L"Password changed!");
|
|
|
|
}
|
|
|
|
|
|
|
|
plAccountUpdateMsg* updateMsg = TRACKED_NEW plAccountUpdateMsg(plAccountUpdateMsg::kChangePassword);
|
|
|
|
updateMsg->SetPlayerInt(0);
|
|
|
|
updateMsg->SetResult((unsigned)result);
|
|
|
|
updateMsg->SetBCastFlag(plMessage::kBCastByExactType);
|
|
|
|
updateMsg->Send();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetCliAuthGetPublicAgeListCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param,
|
|
|
|
const ARRAY(NetAgeInfo) & ages
|
|
|
|
) {
|
|
|
|
NetCommParam * cp = (NetCommParam *) param;
|
|
|
|
|
|
|
|
plNetCommPublicAgeListMsg * msg = NEWZERO(plNetCommPublicAgeListMsg);
|
|
|
|
msg->result = result;
|
|
|
|
msg->param = cp->param;
|
|
|
|
msg->ptype = cp->type;
|
|
|
|
msg->ages.Set(ages.Ptr(), ages.Count());
|
|
|
|
msg->Send();
|
|
|
|
|
|
|
|
DEL(cp);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetAuthFileListRequestCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param,
|
|
|
|
const NetCliAuthFileInfo infoArr[],
|
|
|
|
unsigned infoCount
|
|
|
|
) {
|
|
|
|
plNetCommFileListMsg * msg = NEW(plNetCommFileListMsg);
|
|
|
|
msg->result = result;
|
|
|
|
msg->param = param;
|
|
|
|
msg->fileInfoArr.Set(infoArr, infoCount);
|
|
|
|
msg->Send();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetCliAuthFileRequestCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param,
|
|
|
|
const wchar filename[],
|
|
|
|
hsStream * writer
|
|
|
|
) {
|
|
|
|
plNetCommFileDownloadMsg * msg = NEW(plNetCommFileDownloadMsg);
|
|
|
|
msg->result = result;
|
|
|
|
msg->writer = writer;
|
|
|
|
StrCopy(msg->filename, filename, arrsize(filename));
|
|
|
|
msg->Send();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetCliGameJoinAgeRequestCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
plNetCommLinkToAgeMsg * msg = NEW(plNetCommLinkToAgeMsg);
|
|
|
|
msg->result = result;
|
|
|
|
msg->param = param;
|
|
|
|
msg->Send();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetCliAuthAgeRequestCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param,
|
|
|
|
unsigned ageMcpId,
|
|
|
|
unsigned ageVaultId,
|
|
|
|
const Uuid & ageInstId,
|
|
|
|
NetAddressNode gameAddr
|
|
|
|
) {
|
|
|
|
if (!IS_NET_ERROR(result) || result == kNetErrVaultNodeNotFound) {
|
|
|
|
s_age.ageInstId = ageInstId;
|
|
|
|
s_age.ageVaultId = ageVaultId;
|
|
|
|
|
|
|
|
wchar gameAddrStr[64];
|
|
|
|
wchar ageInstIdStr[64];
|
|
|
|
NetAddressNodeToString(gameAddr, gameAddrStr, arrsize(gameAddrStr));
|
|
|
|
LogMsg(
|
|
|
|
kLogPerf,
|
|
|
|
L"Connecting to game server %s, ageInstId %s",
|
|
|
|
gameAddrStr,
|
|
|
|
GuidToString(ageInstId, ageInstIdStr, arrsize(ageInstIdStr))
|
|
|
|
);
|
|
|
|
NetCliGameDisconnect();
|
|
|
|
NetCliGameStartConnect(gameAddr);
|
|
|
|
NetCliGameJoinAgeRequest(
|
|
|
|
ageMcpId,
|
|
|
|
s_account.accountUuid,
|
|
|
|
s_player->playerInt,
|
|
|
|
INetCliGameJoinAgeRequestCallback,
|
|
|
|
param
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
INetCliGameJoinAgeRequestCallback(
|
|
|
|
result,
|
|
|
|
param
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetCliAuthUpgradeVisitorRequestCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
unsigned playerInt = (unsigned)param;
|
|
|
|
|
|
|
|
if (IS_NET_ERROR(result)) {
|
|
|
|
LogMsg(kLogDebug, L"Upgrade visitor failed: %d %s", playerInt, NetErrorToString(result));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
LogMsg(kLogDebug, L"Upgrade visitor succeeded: %d", playerInt);
|
|
|
|
|
|
|
|
{for (unsigned i = 0; i < s_players.Count(); ++i) {
|
|
|
|
if (s_players[i].playerInt == playerInt) {
|
|
|
|
s_players[i].explorer = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
}
|
|
|
|
|
|
|
|
plAccountUpdateMsg* updateMsg = TRACKED_NEW plAccountUpdateMsg(plAccountUpdateMsg::kUpgradePlayer);
|
|
|
|
updateMsg->SetPlayerInt(playerInt);
|
|
|
|
updateMsg->SetResult((unsigned)result);
|
|
|
|
updateMsg->SetBCastFlag(plMessage::kBCastByExactType);
|
|
|
|
updateMsg->Send();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void INetCliAuthSendFriendInviteCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
pfKIMsg* kiMsg = TRACKED_NEW pfKIMsg(pfKIMsg::kFriendInviteSent);
|
|
|
|
kiMsg->SetIntValue((Int32)result);
|
|
|
|
kiMsg->Send();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void IReadNetIni() {
|
|
|
|
wchar filename[MAX_PATH];
|
|
|
|
StrPrintf(filename, arrsize(filename), L"%s.cfg", ProductCoreName());
|
|
|
|
|
|
|
|
wchar pathAndName[MAX_PATH];
|
|
|
|
PathGetInitDirectory(pathAndName, arrsize(pathAndName));
|
|
|
|
PathAddFilename(pathAndName, pathAndName, filename, arrsize(pathAndName));
|
|
|
|
|
|
|
|
#ifndef PLASMA_EXTERNAL_RELEASE
|
|
|
|
// internal dev build will override user-based setting with local folder if it's there
|
|
|
|
wchar localPathAndName[MAX_PATH];
|
|
|
|
PathAddFilename(localPathAndName, L"init", filename, arrsize(localPathAndName));
|
|
|
|
if (PathDoesFileExist(localPathAndName))
|
|
|
|
StrCopy(pathAndName, localPathAndName, arrsize(pathAndName));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Ini * ini = IniOpen(pathAndName);
|
|
|
|
|
|
|
|
wchar password[kMaxPasswordLength];
|
|
|
|
|
|
|
|
if (ini) {
|
|
|
|
// Read [Net.Server] section
|
|
|
|
IniGetString(
|
|
|
|
IniGetFirstValue(
|
|
|
|
ini,
|
|
|
|
L"Net.Server",
|
|
|
|
L"Addr",
|
|
|
|
nil
|
|
|
|
),
|
|
|
|
s_iniServerAddr,
|
|
|
|
arrsize(s_iniServerAddr),
|
|
|
|
0,
|
|
|
|
L""
|
|
|
|
);
|
|
|
|
|
|
|
|
// Read [Net.FileServer] section
|
|
|
|
IniGetString(
|
|
|
|
IniGetFirstValue(
|
|
|
|
ini,
|
|
|
|
L"Net.FileServer",
|
|
|
|
L"Addr",
|
|
|
|
nil
|
|
|
|
),
|
|
|
|
s_iniFileServerAddr,
|
|
|
|
arrsize(s_iniFileServerAddr),
|
|
|
|
0,
|
|
|
|
s_iniServerAddr
|
|
|
|
);
|
|
|
|
|
|
|
|
if (s_iniReadAccountInfo) {
|
|
|
|
// Read [Net.Account] section
|
|
|
|
IniGetString(
|
|
|
|
IniGetFirstValue(
|
|
|
|
ini,
|
|
|
|
L"Net.Account",
|
|
|
|
L"Username",
|
|
|
|
nil
|
|
|
|
),
|
|
|
|
s_iniAccountUsername,
|
|
|
|
arrsize(s_iniAccountUsername),
|
|
|
|
0,
|
|
|
|
L""
|
|
|
|
);
|
|
|
|
IniGetString(
|
|
|
|
IniGetFirstValue(
|
|
|
|
ini,
|
|
|
|
L"Net.Account",
|
|
|
|
L"Password",
|
|
|
|
nil
|
|
|
|
),
|
|
|
|
password,
|
|
|
|
arrsize(password),
|
|
|
|
0,
|
|
|
|
L""
|
|
|
|
);
|
|
|
|
|
|
|
|
// Read [Net.Startup] section
|
|
|
|
IniGetString(
|
|
|
|
IniGetFirstValue(
|
|
|
|
ini,
|
|
|
|
L"Net.Startup",
|
|
|
|
L"AgeName",
|
|
|
|
nil
|
|
|
|
),
|
|
|
|
s_iniStartupAgeName,
|
|
|
|
arrsize(s_iniStartupAgeName),
|
|
|
|
0,
|
|
|
|
L"StartUp"
|
|
|
|
);
|
|
|
|
IniGetString(
|
|
|
|
IniGetFirstValue(
|
|
|
|
ini,
|
|
|
|
L"Net.Startup",
|
|
|
|
L"PlayerName",
|
|
|
|
nil
|
|
|
|
),
|
|
|
|
s_iniStartupPlayerName,
|
|
|
|
arrsize(s_iniStartupPlayerName),
|
|
|
|
0,
|
|
|
|
L""
|
|
|
|
);
|
|
|
|
|
|
|
|
CryptHashPassword(s_iniAccountUsername, password, &s_namePassHash);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
StrCopy(s_iniStartupAgeName, L"StartUp", arrsize(s_iniStartupAgeName));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef PLASMA_EXTERNAL_RELEASE
|
|
|
|
// @@@: Internal dev build only: Drop a default version of the file if not found
|
|
|
|
if (!ini && BuildType() == BUILD_TYPE_DEV) {
|
|
|
|
EFileError fileError;
|
|
|
|
qword fileSize;
|
|
|
|
qword lastWrite;
|
|
|
|
AsyncFile file = AsyncFileOpen(
|
|
|
|
pathAndName,
|
|
|
|
nil,
|
|
|
|
&fileError,
|
|
|
|
kAsyncFileReadAccess|kAsyncFileWriteAccess,
|
|
|
|
kAsyncFileModeCreateNew,
|
|
|
|
0,
|
|
|
|
nil,
|
|
|
|
&fileSize,
|
|
|
|
&lastWrite
|
|
|
|
);
|
|
|
|
|
|
|
|
if (file) {
|
|
|
|
char line[2048];
|
|
|
|
StrPrintf(
|
|
|
|
line,
|
|
|
|
arrsize(line),
|
|
|
|
// format
|
|
|
|
"[Net.Server]\r\n"
|
|
|
|
"\tAddr=%S\r\n"
|
|
|
|
"\r\n"
|
|
|
|
"[Net.FileServer]\r\n"
|
|
|
|
"\tAddr=%S\r\n"
|
|
|
|
"\r\n"
|
|
|
|
"[Net.Account]\r\n"
|
|
|
|
"\tUsername=%S\r\n"
|
|
|
|
"\tPassword=AccountPassword\r\n"
|
|
|
|
"\r\n"
|
|
|
|
"[Net.Startup]\r\n"
|
|
|
|
"\tAgeName=%S\r\n"
|
|
|
|
"\tPlayerName=%S\r\n"
|
|
|
|
, // values
|
|
|
|
L"shard",
|
|
|
|
L"shard",
|
|
|
|
L"AccountUserName",
|
|
|
|
L"StartUp",
|
|
|
|
L"PlayerName",
|
|
|
|
nil
|
|
|
|
);
|
|
|
|
AsyncFileWrite(file, 0, line, StrLen(line), kAsyncFileRwSync, nil);
|
|
|
|
AsyncFileClose(file, kAsyncFileDontTruncate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Set startup age info
|
|
|
|
ZERO(s_startupAge);
|
|
|
|
|
|
|
|
if (StrLen(s_iniStartupAgeName) == 0)
|
|
|
|
StrCopy(s_startupAge.ageDatasetName, "StartUp", arrsize(s_startupAge.ageDatasetName));
|
|
|
|
else
|
|
|
|
StrToAnsi(s_startupAge.ageDatasetName, s_iniStartupAgeName, arrsize(s_startupAge.ageDatasetName));
|
|
|
|
|
|
|
|
s_startupAge.ageInstId = s_iniStartupAgeInstId;
|
|
|
|
StrCopy(s_startupAge.spawnPtName, "LinkInPointDefault", arrsize(s_startupAge.spawnPtName));
|
|
|
|
|
|
|
|
IniClose(ini);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
static void FileSrvIpAddressCallback (
|
|
|
|
ENetError result,
|
|
|
|
void * param,
|
|
|
|
const wchar addr[]
|
|
|
|
) {
|
|
|
|
StrCopy(s_fileSrvAddr, addr, arrsize(s_fileSrvAddr));
|
|
|
|
s_hasFileSrvIpAddress = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* Exports
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
const NetCommPlayer * const NetCommGetPlayer () {
|
|
|
|
static NetCommPlayer s_nilPlayer;
|
|
|
|
return s_player ? s_player : &s_nilPlayer;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
const ARRAY(NetCommPlayer)& NetCommGetPlayerList () {
|
|
|
|
return s_players;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
unsigned NetCommGetPlayerCount () {
|
|
|
|
return s_players.Count();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
const NetCommAccount * const NetCommGetAccount () {
|
|
|
|
return &s_account;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
bool NetCommIsLoginComplete() {
|
|
|
|
return s_loginComplete;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
const NetCommAge * const NetCommGetAge () {
|
|
|
|
return &s_age;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
const NetCommAge * const NetCommGetStartupAge () {
|
|
|
|
return &s_startupAge;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
bool NetCommNeedToLoadAvatar () {
|
|
|
|
return s_needAvatarLoad;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommSetAvatarLoaded (bool loaded /* = true */) {
|
|
|
|
s_needAvatarLoad = !loaded;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommChangeMyPassword (
|
|
|
|
const wchar password[]
|
|
|
|
) {
|
|
|
|
NetCliAuthAccountChangePasswordRequest(s_account.accountName, password, INetCliAuthChangePasswordCallback, nil);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommStartup () {
|
|
|
|
s_shutdown = false;
|
|
|
|
|
|
|
|
LogRegisterHandler(INetLogCallback);
|
|
|
|
AsyncCoreInitialize();
|
|
|
|
AsyncLogInitialize(L"Log", false);
|
|
|
|
wchar productString[256];
|
|
|
|
ProductString(productString, arrsize(productString));
|
|
|
|
LogMsg(kLogPerf, L"Client: %s", productString);
|
|
|
|
|
|
|
|
NetClientInitialize();
|
|
|
|
NetClientSetErrorHandler(IPreInitNetErrorCallback);
|
|
|
|
NetCliGameSetRecvBufferHandler(INetBufferCallback);
|
|
|
|
// NetCliAuthSetRecvBufferHandler(INetBufferCallback);
|
|
|
|
NetCliAuthSetNotifyNewBuildHandler(INotifyNewBuildCallback);
|
|
|
|
NetCliAuthSetConnectCallback(INotifyAuthConnectedCallback);
|
|
|
|
|
|
|
|
IReadNetIni();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommShutdown () {
|
|
|
|
s_shutdown = true;
|
|
|
|
|
|
|
|
NetCommSetDefaultMsgHandler(nil, nil);
|
|
|
|
NetCommSetMsgPreHandler(nil, nil);
|
|
|
|
NetCommRemoveMsgHandler(
|
|
|
|
kNetCommAllMsgClasses,
|
|
|
|
kNetCommAllMsgHandlers,
|
|
|
|
kNetCommAllUserStates
|
|
|
|
);
|
|
|
|
|
|
|
|
NetCliGameDisconnect();
|
|
|
|
NetCliAuthDisconnect();
|
|
|
|
if (!gDataServerLocal)
|
|
|
|
NetCliFileDisconnect();
|
|
|
|
|
|
|
|
NetClientDestroy(false);
|
|
|
|
AsyncLogDestroy();
|
|
|
|
AsyncCoreDestroy(30 * 1000);
|
|
|
|
LogUnregisterHandler(INetLogCallback);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommEnableNet (
|
|
|
|
bool enabled,
|
|
|
|
bool wait
|
|
|
|
) {
|
|
|
|
if (enabled) {
|
|
|
|
NetClientInitialize();
|
|
|
|
NetClientSetErrorHandler(INetErrorCallback);
|
|
|
|
NetCliGameSetRecvBufferHandler(INetBufferCallback);
|
|
|
|
// NetCliAuthSetRecvBufferHandler(INetBufferCallback);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
NetClientDestroy(wait);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommActivatePostInitErrorHandler () {
|
|
|
|
NetClientSetErrorHandler(INetErrorCallback);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommUpdate () {
|
|
|
|
// plClient likes to recursively call us on occasion; debounce that crap.
|
|
|
|
static long s_updating;
|
|
|
|
if (0 == AtomicSet(&s_updating, 1)) {
|
|
|
|
NetClientUpdate();
|
|
|
|
AtomicSet(&s_updating, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommConnect () {
|
|
|
|
|
|
|
|
const wchar ** addrs;
|
|
|
|
unsigned count;
|
|
|
|
|
|
|
|
count = GetAuthSrvHostnames(&addrs);
|
|
|
|
NetCliAuthStartConnect(addrs, count);
|
|
|
|
|
|
|
|
if (!gDataServerLocal) {
|
|
|
|
|
|
|
|
// if a cmdline override was specified for a filesrv, connect directly to the fileserver rather than going through the gatekeeper
|
|
|
|
if(GetFileSrvHostnames(&addrs) && FileSrvHostnameOverride())
|
|
|
|
{
|
|
|
|
NetCliFileStartConnect(addrs, count);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
count = GetGateKeeperSrvHostnames(&addrs);
|
|
|
|
NetCliGateKeeperStartConnect(addrs, count);
|
|
|
|
|
|
|
|
// request a file server ip address
|
|
|
|
NetCliGateKeeperFileSrvIpAddressRequest(FileSrvIpAddressCallback, nil, false);
|
|
|
|
|
|
|
|
while(!s_hasFileSrvIpAddress && !s_netError) {
|
|
|
|
NetClientUpdate();
|
|
|
|
AsyncSleep(10);
|
|
|
|
}
|
|
|
|
|
|
|
|
const wchar * fileSrv[] = {
|
|
|
|
s_fileSrvAddr
|
|
|
|
};
|
|
|
|
NetCliFileStartConnect(fileSrv, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommDisconnect () {
|
|
|
|
NetCliAuthDisconnect();
|
|
|
|
|
|
|
|
if (!gDataServerLocal) {
|
|
|
|
NetCliFileDisconnect();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommSendMsg (
|
|
|
|
plNetMessage * msg
|
|
|
|
) {
|
|
|
|
msg->SetPlayerID(NetCommGetPlayer()->playerInt);
|
|
|
|
|
|
|
|
unsigned msgSize = msg->GetPackSize();
|
|
|
|
byte * buf = ALLOCA(byte, msgSize);
|
|
|
|
msg->PokeBuffer((char *)buf, msgSize);
|
|
|
|
|
|
|
|
switch (msg->GetNetProtocol()) {
|
|
|
|
case kNetProtocolCli2Auth:
|
|
|
|
NetCliAuthPropagateBuffer(
|
|
|
|
msg->ClassIndex(),
|
|
|
|
msgSize,
|
|
|
|
buf
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kNetProtocolCli2Game:
|
|
|
|
NetCliGamePropagateBuffer(
|
|
|
|
msg->ClassIndex(),
|
|
|
|
msgSize,
|
|
|
|
buf
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
|
|
|
|
DEFAULT_FATAL(msg->GetNetProtocol());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommRecvMsg (
|
|
|
|
plNetMessage * msg
|
|
|
|
) {
|
|
|
|
for (;;) {
|
|
|
|
if (s_preHandler.proc && kOK_MsgConsumed == s_preHandler.proc(msg, s_preHandler.state))
|
|
|
|
break;
|
|
|
|
|
|
|
|
unsigned msgClassIdx = msg->ClassIndex();
|
|
|
|
NetCommMsgHandler * handler = s_handlers.Find(msgClassIdx);
|
|
|
|
|
|
|
|
if (!handler && s_defaultHandler.proc) {
|
|
|
|
s_defaultHandler.proc(msg, s_defaultHandler.state);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
while (handler) {
|
|
|
|
if (kOK_MsgConsumed == handler->proc(msg, handler->state))
|
|
|
|
break;
|
|
|
|
handler = s_handlers.FindNext(msgClassIdx, handler);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommAddMsgHandlerForType (
|
|
|
|
unsigned msgClassIdx,
|
|
|
|
FNetCommMsgHandler * proc,
|
|
|
|
void * state
|
|
|
|
) {
|
|
|
|
for (unsigned i = 0; i < plFactory::GetNumClasses(); ++i) {
|
|
|
|
if (plFactory::DerivesFrom(msgClassIdx, i))
|
|
|
|
NetCommAddMsgHandlerForExactType(i, proc, state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommAddMsgHandlerForExactType (
|
|
|
|
unsigned msgClassIdx,
|
|
|
|
FNetCommMsgHandler * proc,
|
|
|
|
void * state
|
|
|
|
) {
|
|
|
|
ASSERT(msgClassIdx != kNetCommAllMsgClasses);
|
|
|
|
ASSERT(proc && proc != kNetCommAllMsgHandlers);
|
|
|
|
ASSERT(!state || (state && state != kNetCommAllUserStates));
|
|
|
|
|
|
|
|
NetCommRemoveMsgHandler(msgClassIdx, proc, state);
|
|
|
|
NetCommMsgHandler * handler = NEW(NetCommMsgHandler)(msgClassIdx, proc, state);
|
|
|
|
|
|
|
|
s_handlers.Add(handler);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommRemoveMsgHandler (
|
|
|
|
unsigned msgClassIdx,
|
|
|
|
FNetCommMsgHandler * proc,
|
|
|
|
const void * state
|
|
|
|
) {
|
|
|
|
NetCommMsgHandler * next, * handler = s_handlers.Head();
|
|
|
|
for (; handler; handler = next) {
|
|
|
|
next = handler->link.Next();
|
|
|
|
if (handler->GetValue() != msgClassIdx)
|
|
|
|
if (msgClassIdx != kNetCommAllMsgClasses)
|
|
|
|
continue;
|
|
|
|
if (handler->proc != proc)
|
|
|
|
if (proc != kNetCommAllMsgHandlers)
|
|
|
|
continue;
|
|
|
|
if (handler->state != state)
|
|
|
|
if (state != kNetCommAllUserStates)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// We found a matching handler, delete it
|
|
|
|
DEL(handler);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommSetDefaultMsgHandler (
|
|
|
|
FNetCommMsgHandler * proc,
|
|
|
|
void * state
|
|
|
|
) {
|
|
|
|
s_defaultHandler.proc = proc;
|
|
|
|
s_defaultHandler.state = state;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommSetMsgPreHandler (
|
|
|
|
FNetCommMsgHandler * proc,
|
|
|
|
void * state
|
|
|
|
) {
|
|
|
|
s_preHandler.proc = proc;
|
|
|
|
s_preHandler.state = state;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommSetAccountUsernamePassword (
|
|
|
|
wchar username[],
|
|
|
|
const ShaDigest & namePassHash
|
|
|
|
) {
|
|
|
|
StrCopy(s_iniAccountUsername, username, arrsize(s_iniAccountUsername));
|
|
|
|
s_namePassHash = namePassHash;
|
|
|
|
|
|
|
|
s_iniReadAccountInfo = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommSetAuthTokenAndOS (
|
|
|
|
wchar authToken[],
|
|
|
|
wchar os[]
|
|
|
|
) {
|
|
|
|
if (authToken)
|
|
|
|
StrCopy(s_iniAuthToken, authToken, arrsize(s_iniAuthToken));
|
|
|
|
if (os)
|
|
|
|
StrCopy(s_iniOS, os, arrsize(s_iniOS));
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
ENetError NetCommGetAuthResult () {
|
|
|
|
return s_authResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommSetReadIniAccountInfo(bool readFromIni) {
|
|
|
|
s_iniReadAccountInfo = readFromIni;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommAuthenticate (
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
s_loginComplete = false;
|
|
|
|
|
|
|
|
StrCopy(
|
|
|
|
s_account.accountName,
|
|
|
|
s_iniAccountUsername,
|
|
|
|
arrsize(s_account.accountName)
|
|
|
|
);
|
|
|
|
StrToAnsi(
|
|
|
|
s_account.accountNameAnsi,
|
|
|
|
s_iniAccountUsername,
|
|
|
|
arrsize(s_account.accountNameAnsi)
|
|
|
|
);
|
|
|
|
s_account.accountNamePassHash = s_namePassHash;
|
|
|
|
|
|
|
|
NetCliAuthLoginRequest(
|
|
|
|
s_account.accountName,
|
|
|
|
&s_account.accountNamePassHash,
|
|
|
|
s_iniAuthToken,
|
|
|
|
s_iniOS,
|
|
|
|
INetCliAuthLoginRequestCallback,
|
|
|
|
nil
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommLinkToAge ( // --> plNetCommLinkToAgeMsg
|
|
|
|
const NetCommAge & age,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
s_age = age;
|
|
|
|
|
|
|
|
if (plNetClientMgr::GetInstance()->GetFlagsBit(plNetClientApp::kLinkingToOfflineAge)) {
|
|
|
|
plNetCommLinkToAgeMsg * msg = NEW(plNetCommLinkToAgeMsg);
|
|
|
|
msg->result = kNetSuccess;
|
|
|
|
msg->param = nil;
|
|
|
|
msg->Send();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wchar wAgeName[kMaxAgeNameLength];
|
|
|
|
StrToUnicode(wAgeName, s_age.ageDatasetName, arrsize(wAgeName));
|
|
|
|
|
|
|
|
NetCliAuthAgeRequest(
|
|
|
|
wAgeName,
|
|
|
|
s_age.ageInstId,
|
|
|
|
INetCliAuthAgeRequestCallback,
|
|
|
|
param
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommSetActivePlayer (//--> plNetCommActivePlayerMsg
|
|
|
|
unsigned desiredPlayerInt,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
unsigned playerInt = 0;
|
|
|
|
|
|
|
|
if (s_player) {
|
|
|
|
if (RelVaultNode* rvn = VaultGetPlayerInfoNodeIncRef()) {
|
|
|
|
VaultPlayerInfoNode pInfo(rvn);
|
|
|
|
pInfo.SetAgeInstName(nil);
|
|
|
|
pInfo.SetAgeInstUuid(kNilGuid);
|
|
|
|
pInfo.SetOnline(false);
|
|
|
|
NetCliAuthVaultNodeSave(rvn, nil, nil);
|
|
|
|
|
|
|
|
rvn->DecRef();
|
|
|
|
}
|
|
|
|
|
|
|
|
VaultCull(s_player->playerInt);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (desiredPlayerInt == 0)
|
|
|
|
s_player = nil;
|
|
|
|
else {
|
|
|
|
for (unsigned i = 0; i < s_players.Count(); ++i) {
|
|
|
|
if (s_players[i].playerInt == desiredPlayerInt) {
|
|
|
|
playerInt = desiredPlayerInt;
|
|
|
|
s_player = &s_players[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (0 == StrCmpI(s_players[i].playerName, s_iniStartupPlayerName, arrsize(s_players[i].playerName))) {
|
|
|
|
playerInt = s_players[i].playerInt;
|
|
|
|
s_player = &s_players[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ASSERT(s_player);
|
|
|
|
}
|
|
|
|
|
|
|
|
NetCliAuthSetPlayerRequest(
|
|
|
|
playerInt,
|
|
|
|
INetCliAuthSetPlayerRequestCallback,
|
|
|
|
param
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommCreatePlayer ( // --> plNetCommCreatePlayerMsg
|
|
|
|
const char playerName[],
|
|
|
|
const char avatarShape[],
|
|
|
|
const char friendInvite[],
|
|
|
|
unsigned createFlags,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
wchar wplayerName[kMaxPlayerNameLength];
|
|
|
|
wchar wavatarShape[MAX_PATH];
|
|
|
|
wchar wfriendInvite[MAX_PATH];
|
|
|
|
|
|
|
|
StrToUnicode(wplayerName, playerName, arrsize(wplayerName));
|
|
|
|
StrToUnicode(wavatarShape, avatarShape, arrsize(wavatarShape));
|
|
|
|
StrToUnicode(wfriendInvite, friendInvite, arrsize(wfriendInvite));
|
|
|
|
|
|
|
|
NetCliAuthPlayerCreateRequest(
|
|
|
|
wplayerName,
|
|
|
|
wavatarShape,
|
|
|
|
(friendInvite != NULL) ? wfriendInvite : NULL,
|
|
|
|
INetCliAuthCreatePlayerRequestCallback,
|
|
|
|
param
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommCreatePlayer ( // --> plNetCommCreatePlayerMsg
|
|
|
|
const wchar playerName[],
|
|
|
|
const wchar avatarShape[],
|
|
|
|
const wchar friendInvite[],
|
|
|
|
unsigned createFlags,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
NetCliAuthPlayerCreateRequest(
|
|
|
|
playerName,
|
|
|
|
avatarShape,
|
|
|
|
(friendInvite != NULL) ? friendInvite : NULL,
|
|
|
|
INetCliAuthCreatePlayerRequestCallback,
|
|
|
|
param
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommDeletePlayer ( // --> plNetCommDeletePlayerMsg
|
|
|
|
unsigned playerInt,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
ASSERTMSG(!param, "'param' will not be propagated to your callback function, you may modify the code to support this");
|
|
|
|
ASSERT(NetCommGetPlayer()->playerInt != playerInt);
|
|
|
|
|
|
|
|
NetCliAuthPlayerDeleteRequest(
|
|
|
|
playerInt,
|
|
|
|
INetCliAuthDeletePlayerCallback,
|
|
|
|
(void*)playerInt
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommGetPublicAgeList (//-> plNetCommPublicAgeListMsg
|
|
|
|
const char ageName[],
|
|
|
|
void * param,
|
|
|
|
plNetCommReplyMsg::EParamType ptype
|
|
|
|
) {
|
|
|
|
NetCommParam * cp = NEW(NetCommParam);
|
|
|
|
cp->param = param;
|
|
|
|
cp->type = ptype;
|
|
|
|
|
|
|
|
wchar wStr[MAX_PATH];
|
|
|
|
StrToUnicode(wStr, ageName, arrsize(wStr));
|
|
|
|
NetCliAuthGetPublicAgeList(
|
|
|
|
wStr,
|
|
|
|
INetCliAuthGetPublicAgeListCallback,
|
|
|
|
cp
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommSetAgePublic ( // --> no msg
|
|
|
|
unsigned ageInfoId,
|
|
|
|
bool makePublic
|
|
|
|
) {
|
|
|
|
NetCliAuthSetAgePublic(
|
|
|
|
ageInfoId,
|
|
|
|
makePublic
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommCreatePublicAge (// --> plNetCommPublicAgeMsg
|
|
|
|
const char ageName[],
|
|
|
|
const Uuid & ageInstId,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommRemovePublicAge(// --> plNetCommPublicAgeMsg
|
|
|
|
const Uuid & ageInstId,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommRegisterOwnedAge (
|
|
|
|
const NetCommAge & age,
|
|
|
|
const char ageInstDesc[],
|
|
|
|
unsigned playerInt,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommUnregisterOwnedAge (
|
|
|
|
const char ageName[],
|
|
|
|
unsigned playerInt,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommRegisterVisitAge (
|
|
|
|
const NetCommAge & age,
|
|
|
|
const char ageInstDesc[],
|
|
|
|
unsigned playerInt,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommUnregisterVisitAge (
|
|
|
|
const Uuid & ageInstId,
|
|
|
|
unsigned playerInt,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommConnectPlayerVault (
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommConnectAgeVault (
|
|
|
|
const Uuid & ageInstId,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommUpgradeVisitorToExplorer (
|
|
|
|
unsigned playerInt,
|
|
|
|
void * param
|
|
|
|
) {
|
|
|
|
NetCliAuthUpgradeVisitorRequest(
|
|
|
|
playerInt,
|
|
|
|
INetCliAuthUpgradeVisitorRequestCallback,
|
|
|
|
(void*)playerInt
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommSetCCRLevel (
|
|
|
|
unsigned ccrLevel
|
|
|
|
) {
|
|
|
|
if (RelVaultNode * rvnInfo = VaultGetPlayerInfoNodeIncRef()) {
|
|
|
|
VaultPlayerInfoNode pInfo(rvnInfo);
|
|
|
|
pInfo.SetCCRLevel(ccrLevel);
|
|
|
|
rvnInfo->DecRef();
|
|
|
|
}
|
|
|
|
|
|
|
|
NetCliAuthSetCCRLevel(ccrLevel);
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
void NetCommSendFriendInvite (
|
|
|
|
const wchar emailAddress[],
|
|
|
|
const wchar toName[],
|
|
|
|
const Uuid& inviteUuid
|
|
|
|
) {
|
|
|
|
NetCliAuthSendFriendInvite(
|
|
|
|
emailAddress,
|
|
|
|
toName,
|
|
|
|
inviteUuid,
|
|
|
|
INetCliAuthSendFriendInviteCallback,
|
|
|
|
nil
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* Msg handler interface - compatibility layer with legacy code
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// plNetClientComm ----------------------------------------------
|
|
|
|
plNetClientComm::plNetClientComm()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
// ~plNetClientComm ----------------------------------------------
|
|
|
|
plNetClientComm::~plNetClientComm()
|
|
|
|
{
|
|
|
|
NetCommSetMsgPreHandler(nil, nil);
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddMsgHandlerForType ----------------------------------------------
|
|
|
|
void plNetClientComm::AddMsgHandlerForType( UInt16 msgClassIdx, MsgHandler* handler )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for( i = 0; i < plFactory::GetNumClasses(); i++ )
|
|
|
|
{
|
|
|
|
if ( plFactory::DerivesFrom( msgClassIdx, i ) )
|
|
|
|
AddMsgHandlerForExactType( i, handler );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddMsgHandlerForExactType ----------------------------------------------
|
|
|
|
void plNetClientComm::AddMsgHandlerForExactType( UInt16 msgClassIdx, MsgHandler* handler )
|
|
|
|
{
|
|
|
|
NetCommAddMsgHandlerForExactType(msgClassIdx, MsgHandler::StaticMsgHandler, handler);
|
|
|
|
}
|
|
|
|
|
|
|
|
// RemoveMsgHandler ----------------------------------------------
|
|
|
|
bool plNetClientComm::RemoveMsgHandler( MsgHandler* handler )
|
|
|
|
{
|
|
|
|
NetCommRemoveMsgHandler(kNetCommAllMsgClasses, kNetCommAllMsgHandlers, handler);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetDefaultHandler ----------------------------------------------
|
|
|
|
void plNetClientComm::SetDefaultHandler( MsgHandler* handler) {
|
|
|
|
NetCommSetDefaultMsgHandler(MsgHandler::StaticMsgHandler, handler);
|
|
|
|
}
|
|
|
|
|
|
|
|
// MsgHandler::StaticMsgHandler ----------------------------------------------
|
|
|
|
int plNetClientComm::MsgHandler::StaticMsgHandler (plNetMessage * msg, void * userState) {
|
|
|
|
plNetClientComm::MsgHandler * handler = (plNetClientComm::MsgHandler *) userState;
|
|
|
|
return handler->HandleMessage(msg);
|
|
|
|
}
|