You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
477 lines
14 KiB
477 lines
14 KiB
14 years ago
|
/*==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/>.
|
||
|
|
||
|
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/plNetClient/plNetCliAgeJoiner.cpp
|
||
|
*
|
||
|
* Encapsulates all of the horrible ugliness that the age load process has become
|
||
|
*
|
||
|
***/
|
||
|
|
||
|
#include "plNetCliAgeJoiner.h"
|
||
|
#include "plNetClientMgr.h"
|
||
|
#include "plNetLinkingMgr.h"
|
||
|
|
||
|
#include "../pnSceneObject/plSceneObject.h"
|
||
|
#include "../pnSceneObject/plCoordinateInterface.h"
|
||
|
|
||
|
#include "../pnMessage/plPlayerPageMsg.h"
|
||
|
#include "../pnMessage/plTimeMsg.h"
|
||
|
|
||
|
#include "../plNetClientComm/plNetClientComm.h"
|
||
|
#include "../plAgeLoader/plAgeLoader.h"
|
||
|
#include "../plAgeLoader/plBackgroundDownloader.h"
|
||
|
#include "../plAvatar/plAvatarMgr.h"
|
||
|
#include "../plVault/plVault.h"
|
||
|
|
||
|
#include "../plNetMessage/plNetMessage.h"
|
||
|
|
||
|
#include "../plMessage/plNetCommMsgs.h"
|
||
|
#include "../plMessage/plAgeLoadedMsg.h"
|
||
|
#include "../plMessage/plInputIfaceMgrMsg.h"
|
||
|
#include "../plMessage/plNetClientMgrMsg.h"
|
||
|
|
||
|
#include "../plProgressMgr/plProgressMgr.h"
|
||
|
#include "../pnDispatch/plDispatch.h"
|
||
|
#include "../plResMgr/plResManager.h"
|
||
|
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* Private
|
||
|
*
|
||
|
***/
|
||
|
|
||
|
struct plNCAgeJoiner {
|
||
|
|
||
|
enum NextOp {
|
||
|
kNoOp,
|
||
|
kLoadAge,
|
||
|
kLoadPlayer,
|
||
|
kRequestAgeState,
|
||
|
kPropagatePlayer,
|
||
|
kDestroyProgressBar,
|
||
|
kEnableClickables,
|
||
|
kSimStateRcvd,
|
||
|
kNotifyAgeLoaded,
|
||
|
};
|
||
|
|
||
|
NextOp nextOp;
|
||
|
NetCommAge age;
|
||
|
FNCAgeJoinerCallback callback;
|
||
|
void * userState;
|
||
|
bool complete;
|
||
|
|
||
|
plOperationProgress* progressBar;
|
||
|
|
||
|
plNCAgeJoiner (
|
||
|
const NetCommAge & age,
|
||
|
FNCAgeJoinerCallback callback,
|
||
|
void * userState
|
||
|
);
|
||
|
~plNCAgeJoiner ();
|
||
|
|
||
|
void Start ();
|
||
|
void Complete (bool success, const char msg[]);
|
||
|
bool MsgReceive (plMessage * msg);
|
||
|
void Update ();
|
||
|
void ExecNextOp ();
|
||
|
|
||
|
static void IDispatchMsgReceiveCallback ();
|
||
|
static void IResMgrProgressBarCallback (plKey key);
|
||
|
|
||
|
static plNCAgeJoiner* s_instance;
|
||
|
};
|
||
|
|
||
|
plNCAgeJoiner* plNCAgeJoiner::s_instance = nil;
|
||
|
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* Local functions
|
||
|
*
|
||
|
***/
|
||
|
|
||
|
//============================================================================
|
||
|
void AgeVaultDownloadCallback (
|
||
|
ENetError result,
|
||
|
void * param
|
||
|
) {
|
||
|
plNCAgeJoiner * joiner = (plNCAgeJoiner *)param;
|
||
|
if (IS_NET_ERROR(result)) {
|
||
|
joiner->Complete(false, "Failed to download age vault");
|
||
|
}
|
||
|
else {
|
||
|
// vault downloaded. start loading age data
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Next:kLoadAge (vault downloaded)");
|
||
|
joiner->nextOp = plNCAgeJoiner::kLoadAge;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* plNCAgeJoiner
|
||
|
*
|
||
|
***/
|
||
|
|
||
|
//============================================================================
|
||
|
plNCAgeJoiner::plNCAgeJoiner (
|
||
|
const NetCommAge & age,
|
||
|
FNCAgeJoinerCallback callback,
|
||
|
void * userState
|
||
|
) : nextOp(kNoOp)
|
||
|
, age(age)
|
||
|
, callback(callback)
|
||
|
, userState(userState)
|
||
|
, progressBar(nil)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//============================================================================
|
||
|
plNCAgeJoiner::~plNCAgeJoiner () {
|
||
|
}
|
||
|
|
||
|
//============================================================================
|
||
|
void plNCAgeJoiner::IDispatchMsgReceiveCallback () {
|
||
|
if (s_instance)
|
||
|
s_instance->progressBar->Increment(1);
|
||
|
}
|
||
|
|
||
|
//============================================================================
|
||
|
void plNCAgeJoiner::IResMgrProgressBarCallback (plKey key) {
|
||
|
#ifndef PLASMA_EXTERNAL_RELEASE
|
||
|
if (s_instance)
|
||
|
s_instance->progressBar->SetStatusText(key->GetName());
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
//============================================================================
|
||
|
void plNCAgeJoiner::Complete (bool success, const char msg[]) {
|
||
|
|
||
|
if (!complete) {
|
||
|
complete = true;
|
||
|
|
||
|
s_instance = nil;
|
||
|
|
||
|
NCAgeJoinerCompleteNotify notify;
|
||
|
notify.success = success;
|
||
|
notify.msg = msg;
|
||
|
|
||
|
callback(this, kAgeJoinerComplete, ¬ify, userState);
|
||
|
DEL(this);
|
||
|
}
|
||
|
|
||
|
if (plBackgroundDownloader::GetInstance())
|
||
|
plBackgroundDownloader::GetInstance()->UnPause();
|
||
|
}
|
||
|
|
||
|
//============================================================================
|
||
|
void plNCAgeJoiner::Start () {
|
||
|
s_instance = this;
|
||
|
|
||
|
plNetClientMgr * nc = plNetClientMgr::GetInstance();
|
||
|
nc->SetFlagsBit(plNetClientMgr::kPlayingGame, false);
|
||
|
nc->fServerTimeOffset = 0; // reset since we're connecting to a new server
|
||
|
nc->fRequiredNumInitialSDLStates = 0;
|
||
|
nc->fNumInitialSDLStates = 0;
|
||
|
nc->SetFlagsBit(plNetClientApp::kNeedInitialAgeStateCount);
|
||
|
nc->SetFlagsBit(plNetClientApp::kLoadingInitialAgeState);
|
||
|
|
||
|
// if we're linking to startup then set the OfflineAge flag
|
||
|
// so we by-pass the game server
|
||
|
if (StrLen(age.ageDatasetName) == 0 || StrCmpI(age.ageDatasetName, "StartUp") == 0)
|
||
|
nc->SetFlagsBit(plNetClientApp::kLinkingToOfflineAge);
|
||
|
else
|
||
|
nc->SetFlagsBit(plNetClientApp::kLinkingToOfflineAge, false);
|
||
|
|
||
|
plAgeLoader* al = plAgeLoader::GetInstance();
|
||
|
al->UpdateAge(age.ageDatasetName);
|
||
|
|
||
|
nc->ResetServerTimeOffset();
|
||
|
|
||
|
NetCommLinkToAge(
|
||
|
age,
|
||
|
this
|
||
|
);
|
||
|
}
|
||
|
|
||
|
//============================================================================
|
||
|
void plNCAgeJoiner::ExecNextOp () {
|
||
|
plNetClientMgr * nc = plNetClientMgr::GetInstance();
|
||
|
plAvatarMgr * am = plAvatarMgr::GetInstance();
|
||
|
plAgeLoader * al = plAgeLoader::GetInstance();
|
||
|
|
||
|
NextOp next = nextOp;
|
||
|
nextOp = kNoOp;
|
||
|
switch (next) {
|
||
|
//====================================================================
|
||
|
case kNoOp: {
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
//====================================================================
|
||
|
case kLoadAge: {
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Exec:kLoadAge");
|
||
|
|
||
|
// Start progress bar
|
||
|
char str[256];
|
||
|
#ifdef PLASMA_EXTERNAL_RELEASE
|
||
|
StrCopy(str, "Loading age...", arrsize(str));
|
||
|
#else
|
||
|
StrPrintf(str, arrsize(str), "Loading age %s...", age.ageDatasetName);
|
||
|
#endif
|
||
|
progressBar = plProgressMgr::GetInstance()->RegisterOperation(0, str, plProgressMgr::kNone, false, true);
|
||
|
plDispatch::SetMsgRecieveCallback(IDispatchMsgReceiveCallback);
|
||
|
((plResManager*)hsgResMgr::ResMgr())->SetProgressBarProc(IResMgrProgressBarCallback);
|
||
|
|
||
|
// Start loading age data
|
||
|
al->LoadAge(age.ageDatasetName);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
//====================================================================
|
||
|
case kLoadPlayer: {
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Exec:kLoadPlayer");
|
||
|
// Start loading local player
|
||
|
const char * avatarName;
|
||
|
if (NetCommNeedToLoadAvatar()) {
|
||
|
if (nc->GetFlagsBit(plNetClientApp::kLinkingToOfflineAge))
|
||
|
avatarName = "Male";
|
||
|
else
|
||
|
avatarName = NetCommGetPlayer()->avatarDatasetName;
|
||
|
const char * linkInName = plNetLinkingMgr::GetInstance()->GetAgeLink()->SpawnPoint().GetName();
|
||
|
am->LoadPlayer( avatarName, nil, linkInName );
|
||
|
}
|
||
|
else {
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Next:kPropagatePlayer");
|
||
|
nextOp = kPropagatePlayer;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
//====================================================================
|
||
|
case kPropagatePlayer: {
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Exec:kPropagatePlayer");
|
||
|
// Add our avatar to the scene
|
||
|
int spawnPt = am->FindSpawnPoint(age.spawnPtName);
|
||
|
nc->IPlayerChangeAge(false /*not exiting*/, spawnPt);
|
||
|
|
||
|
if (!nc->GetFlagsBit(plNetClientApp::kLinkingToOfflineAge))
|
||
|
// Add our avatar to the game state
|
||
|
am->PropagateLocalPlayer(spawnPt);
|
||
|
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Next:kRequestAgeState");
|
||
|
nextOp = kRequestAgeState;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
//============================================================================
|
||
|
case kRequestAgeState: {
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Exec:kRequestAgeState");
|
||
|
if (nc->GetFlagsBit(plNetClientApp::kLinkingToOfflineAge)) {
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Next:kSimStateRcvd");
|
||
|
nextOp = kSimStateRcvd;
|
||
|
}
|
||
|
else {
|
||
|
// Request age player list
|
||
|
nc->ISendMembersListRequest();
|
||
|
|
||
|
// Request initial SDL state
|
||
|
plNetMsgGameStateRequest gsmsg;
|
||
|
gsmsg.SetNetProtocol(kNetProtocolCli2Game);
|
||
|
gsmsg.SetBit(plNetMessage::kInitialAgeStateRequest);
|
||
|
nc->SendMsg(&gsmsg);
|
||
|
|
||
|
// Send our avatar settings
|
||
|
nc->SendLocalPlayerAvatarCustomizations();
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
//====================================================================
|
||
|
case kSimStateRcvd: {
|
||
|
nc->NotifyRcvdAllSDLStates();
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
//============================================================================
|
||
|
case kDestroyProgressBar: {
|
||
|
plDispatch::SetMsgRecieveCallback(nil);
|
||
|
((plResManager*)hsgResMgr::ResMgr())->SetProgressBarProc(nil);
|
||
|
delete progressBar;
|
||
|
progressBar = nil;
|
||
|
|
||
|
nextOp = kEnableClickables;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
//====================================================================
|
||
|
case kEnableClickables: {
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Exec:kEnableClickables");
|
||
|
// Enable scene clickables
|
||
|
(void)(TRACKED_NEW plInputIfaceMgrMsg(plInputIfaceMgrMsg::kEnableClickables))->Send();
|
||
|
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Next:kNotifyAgeLoaded");
|
||
|
nextOp = kNotifyAgeLoaded;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
//====================================================================
|
||
|
case kNotifyAgeLoaded: {
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Exec:kNotifyAgeLoaded");
|
||
|
nc->SetFlagsBit(plNetClientApp::kPlayingGame);
|
||
|
nc->SetFlagsBit(plNetClientApp::kNeedToSendInitialAgeStateLoadedMsg);
|
||
|
plAgeLoader::GetInstance()->NotifyAgeLoaded(true);
|
||
|
Complete(true, "Age joined");
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
DEFAULT_FATAL(nextOp);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//============================================================================
|
||
|
bool plNCAgeJoiner::MsgReceive (plMessage * msg) {
|
||
|
plNetClientMgr * nc = plNetClientMgr::GetInstance();
|
||
|
plAvatarMgr * am = plAvatarMgr::GetInstance();
|
||
|
plAgeLoader * al = plAgeLoader::GetInstance();
|
||
|
|
||
|
//========================================================================
|
||
|
// Connected to age instance
|
||
|
//========================================================================
|
||
|
if (plNetCommLinkToAgeMsg * linkToAgeMsg = plNetCommLinkToAgeMsg::ConvertNoRef(msg)) {
|
||
|
if (IS_NET_ERROR(linkToAgeMsg->result)) {
|
||
|
Complete(false, "LinkToAge failed");
|
||
|
}
|
||
|
else if (unsigned ageVaultId = NetCommGetAge()->ageVaultId) {
|
||
|
// Download the age vault
|
||
|
VaultDownload(
|
||
|
L"AgeJoin",
|
||
|
ageVaultId,
|
||
|
AgeVaultDownloadCallback,
|
||
|
this,
|
||
|
nil, // FVaultDownloadProgressCallback
|
||
|
this
|
||
|
);
|
||
|
}
|
||
|
else {
|
||
|
// not vault to downloaded, just start loading age data
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Next:kLoadAge (no vault)");
|
||
|
nextOp = kLoadAge;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//========================================================================
|
||
|
// All age data paged in
|
||
|
//========================================================================
|
||
|
if (plAgeLoaded2Msg * ageLoaded2Msg = plAgeLoaded2Msg::ConvertNoRef(msg)) {
|
||
|
// Exec custom age settings
|
||
|
al->ExecPendingAgeFniFiles();
|
||
|
al->ExecPendingAgeCsvFiles();
|
||
|
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Next:kLoadPlayer");
|
||
|
nextOp = kLoadPlayer;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//========================================================================
|
||
|
// Local avatar loaded
|
||
|
//========================================================================
|
||
|
plPlayerPageMsg * playerPageMsg = plPlayerPageMsg::ConvertNoRef(msg);
|
||
|
if (playerPageMsg && !playerPageMsg->fUnload && playerPageMsg->fPlayer && playerPageMsg->fLocallyOriginated) {
|
||
|
|
||
|
if (NetCommNeedToLoadAvatar())
|
||
|
NetCommSetAvatarLoaded();
|
||
|
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Next:kPropagatePlayer");
|
||
|
nextOp = kPropagatePlayer;
|
||
|
return false; // NetClientMgr must also handle this message
|
||
|
}
|
||
|
|
||
|
//========================================================================
|
||
|
// Received all SDL states
|
||
|
//========================================================================
|
||
|
plNetClientMgrMsg * netClientMgrMsg = plNetClientMgrMsg::ConvertNoRef(msg);
|
||
|
if (netClientMgrMsg && netClientMgrMsg->type == plNetClientMgrMsg::kNotifyRcvdAllSDLStates) {
|
||
|
LogMsg(kLogPerf, L"AgeJoiner: Next:kEnableClickables");
|
||
|
nextOp = kDestroyProgressBar;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
//============================================================================
|
||
|
void plNCAgeJoiner::Update () {
|
||
|
ExecNextOp();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* Exports
|
||
|
*
|
||
|
***/
|
||
|
|
||
|
//============================================================================
|
||
|
void NCAgeJoinerCreate (
|
||
|
plNCAgeJoiner ** pjoiner,
|
||
|
const NetCommAge & age,
|
||
|
FNCAgeJoinerCallback callback,
|
||
|
void * userState
|
||
|
) {
|
||
|
ASSERT(pjoiner);
|
||
|
ASSERT(callback);
|
||
|
|
||
|
plNCAgeJoiner * joiner;
|
||
|
*pjoiner = joiner = NEWZERO(plNCAgeJoiner)(
|
||
|
age,
|
||
|
callback,
|
||
|
userState
|
||
|
);
|
||
|
joiner->Start();
|
||
|
}
|
||
|
|
||
|
//============================================================================
|
||
|
bool NCAgeJoinerMsgReceive (
|
||
|
plNCAgeJoiner * joiner,
|
||
|
plMessage * msg
|
||
|
) {
|
||
|
ASSERT(joiner);
|
||
|
return joiner->MsgReceive(msg);
|
||
|
}
|
||
|
|
||
|
//============================================================================
|
||
|
void NCAgeJoinerUpdate (
|
||
|
plNCAgeJoiner * joiner
|
||
|
) {
|
||
|
ASSERT(joiner);
|
||
|
joiner->Update();
|
||
|
}
|