2
3
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-13 18:17:49 -04:00

Fix line endings and tabs

This commit is contained in:
Branan Purvine-Riley
2011-04-11 16:27:55 -07:00
parent d4250e19b5
commit 908aaeb6f6
2738 changed files with 702562 additions and 702562 deletions

View File

@ -1,47 +1,47 @@
include_directories("../../CoreLib")
include_directories("../../FeatureLib")
include_directories("../../NucleusLib/inc")
include_directories("../../NucleusLib")
include_directories("../../PubUtilLib")
include_directories(${OPENSSL_INCLUDE_DIR})
set(plNetClient_SOURCES
plLinkEffectsMgr.cpp
plNetCliAgeJoiner.cpp
plNetCliAgeLeaver.cpp
plNetClientCommInterface.cpp
plNetClientGroup.cpp
plNetClientMgr.cpp
plNetClientMgrLoad.cpp
plNetClientMgrRecord.cpp
plNetClientMgrSend.cpp
plNetClientMgrShow.cpp
plNetClientMgrVoice.cpp
plNetClientMsgHandler.cpp
plNetClientMsgScreener.cpp
plNetClientStats.cpp
plNetLinkingMgr.cpp
plNetObjectDebugger.cpp
plNetVoiceList.cpp
)
set(plNetClient_HEADERS
plLinkEffectsMgr.h
plNetCliAgeJoiner.h
plNetCliAgeLeaver.h
plNetClientCreatable.h
plNetClientGroup.h
plNetClientMgr.h
plNetClientMsgHandler.h
plNetClientMsgScreener.h
plNetClientStats.h
plNetLinkingMgr.h
plNetObjectDebugger.h
plNetVoiceList.h
)
add_library(plNetClient STATIC ${plNetClient_SOURCES} ${plNetClient_HEADERS})
source_group("Source Files" FILES ${plNetClient_SOURCES})
source_group("Header Files" FILES ${plNetClient_HEADERS})
include_directories("../../CoreLib")
include_directories("../../FeatureLib")
include_directories("../../NucleusLib/inc")
include_directories("../../NucleusLib")
include_directories("../../PubUtilLib")
include_directories(${OPENSSL_INCLUDE_DIR})
set(plNetClient_SOURCES
plLinkEffectsMgr.cpp
plNetCliAgeJoiner.cpp
plNetCliAgeLeaver.cpp
plNetClientCommInterface.cpp
plNetClientGroup.cpp
plNetClientMgr.cpp
plNetClientMgrLoad.cpp
plNetClientMgrRecord.cpp
plNetClientMgrSend.cpp
plNetClientMgrShow.cpp
plNetClientMgrVoice.cpp
plNetClientMsgHandler.cpp
plNetClientMsgScreener.cpp
plNetClientStats.cpp
plNetLinkingMgr.cpp
plNetObjectDebugger.cpp
plNetVoiceList.cpp
)
set(plNetClient_HEADERS
plLinkEffectsMgr.h
plNetCliAgeJoiner.h
plNetCliAgeLeaver.h
plNetClientCreatable.h
plNetClientGroup.h
plNetClientMgr.h
plNetClientMsgHandler.h
plNetClientMsgScreener.h
plNetClientStats.h
plNetLinkingMgr.h
plNetObjectDebugger.h
plNetVoiceList.h
)
add_library(plNetClient STATIC ${plNetClient_SOURCES} ${plNetClient_HEADERS})
source_group("Source Files" FILES ${plNetClient_SOURCES})
source_group("Header Files" FILES ${plNetClient_HEADERS})

File diff suppressed because it is too large Load Diff

View File

@ -1,81 +1,81 @@
/*==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==*/
#ifndef plLinkEffectsMgr_inc
#define plLinkEffectsMgr_inc
#include "pnKeyedObject/hsKeyedObject.h"
class plLinkEffectsTriggerMsg;
class plPseudoLinkEffectMsg;
class plLinkEffectsMgr : public hsKeyedObject
{
protected:
// Collection of links in progress (in or out)
hsTArray<plLinkEffectsTriggerMsg *> fLinks;
// Players we know exist, but aren't ready to link yet
hsTArray<plLinkEffectsTriggerMsg *> fWaitlist;
// Queue of delayed messages from people linking in that
// we haven't received yet but are no longer necessary,
// because we either received the trigger from them, or
// they're no longer in the age.
hsTArray<plLinkEffectsTriggerMsg *> fDeadlist;
// queue of pseudo link messages
hsTArray<plPseudoLinkEffectMsg *> fPseudolist;
plLinkEffectsTriggerMsg *IFindLinkTriggerMsg(plKey avatarKey);
void IAddLink(plLinkEffectsTriggerMsg *msg);
void IAddWait(plLinkEffectsTriggerMsg *msg);
void IAddDead(plLinkEffectsTriggerMsg *msg);
void IAddPsuedo(plPseudoLinkEffectMsg *msg);
void IRemovePseudo(plKey avatarKey);
plPseudoLinkEffectMsg* IFindPseudo(plKey avatarKey);
hsBool IHuntWaitlist(plLinkEffectsTriggerMsg *msg);
hsBool IHuntWaitlist(plKey linkKey);
hsBool IHuntDeadlist(plLinkEffectsTriggerMsg *msg);
void ISendAllReadyCallbacks();
public:
plLinkEffectsMgr();
~plLinkEffectsMgr();
void Init();
CLASSNAME_REGISTER( plLinkEffectsMgr );
GETINTERFACE_ANY( plLinkEffectsMgr, hsKeyedObject );
void WaitForEffect(plKey linkKey, hsScalar time);
void WaitForPseudoEffect(plKey linkKey, hsScalar time);
plMessage *WaitForEffect(plKey linkKey);
virtual hsBool MsgReceive(plMessage *msg);
};
#endif // plLinkEffectsMgr_inc
/*==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==*/
#ifndef plLinkEffectsMgr_inc
#define plLinkEffectsMgr_inc
#include "pnKeyedObject/hsKeyedObject.h"
class plLinkEffectsTriggerMsg;
class plPseudoLinkEffectMsg;
class plLinkEffectsMgr : public hsKeyedObject
{
protected:
// Collection of links in progress (in or out)
hsTArray<plLinkEffectsTriggerMsg *> fLinks;
// Players we know exist, but aren't ready to link yet
hsTArray<plLinkEffectsTriggerMsg *> fWaitlist;
// Queue of delayed messages from people linking in that
// we haven't received yet but are no longer necessary,
// because we either received the trigger from them, or
// they're no longer in the age.
hsTArray<plLinkEffectsTriggerMsg *> fDeadlist;
// queue of pseudo link messages
hsTArray<plPseudoLinkEffectMsg *> fPseudolist;
plLinkEffectsTriggerMsg *IFindLinkTriggerMsg(plKey avatarKey);
void IAddLink(plLinkEffectsTriggerMsg *msg);
void IAddWait(plLinkEffectsTriggerMsg *msg);
void IAddDead(plLinkEffectsTriggerMsg *msg);
void IAddPsuedo(plPseudoLinkEffectMsg *msg);
void IRemovePseudo(plKey avatarKey);
plPseudoLinkEffectMsg* IFindPseudo(plKey avatarKey);
hsBool IHuntWaitlist(plLinkEffectsTriggerMsg *msg);
hsBool IHuntWaitlist(plKey linkKey);
hsBool IHuntDeadlist(plLinkEffectsTriggerMsg *msg);
void ISendAllReadyCallbacks();
public:
plLinkEffectsMgr();
~plLinkEffectsMgr();
void Init();
CLASSNAME_REGISTER( plLinkEffectsMgr );
GETINTERFACE_ANY( plLinkEffectsMgr, hsKeyedObject );
void WaitForEffect(plKey linkKey, hsScalar time);
void WaitForPseudoEffect(plKey linkKey, hsScalar time);
plMessage *WaitForEffect(plKey linkKey);
virtual hsBool MsgReceive(plMessage *msg);
};
#endif // plLinkEffectsMgr_inc

View File

@ -1,476 +1,476 @@
/*==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, &notify, 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();
}
/*==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, &notify, 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();
}

View File

@ -1,85 +1,85 @@
/*==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.h
*
***/
#ifndef PLASMA20_SOURCES_PLASMA_PUBUTILLIB_PLNETCLIENT_PLNETCLIAGEJOINER_H
#define PLASMA20_SOURCES_PLASMA_PUBUTILLIB_PLNETCLIENT_PLNETCLIAGEJOINER_H
#include "HeadSpin.h"
#include "pnUtils/pnUtils.h"
#include "plNetClientComm/plNetClientComm.h"
/*****************************************************************************
*
*
*
***/
class plMessage;
struct plNCAgeJoiner;
enum ENCAgeJoinerNotify {
kAgeJoinerComplete, // notify --> NCAgeJoinerCompleteNotify *, after callback, joiner is destroyed
kNumAgeJoinerNotifications
};
struct NCAgeJoinerCompleteNotify {
bool success;
const char * msg;
};
typedef void (* FNCAgeJoinerCallback)(
plNCAgeJoiner * joiner,
unsigned type, // ENCAgeJoinerNotify
void * notify,
void * userState
);
void NCAgeJoinerCreate (
plNCAgeJoiner ** joiner,
const NetCommAge & age,
FNCAgeJoinerCallback callback,
void * userState
);
bool NCAgeJoinerMsgReceive ( // returns true of message was processed
plNCAgeJoiner * joiner,
plMessage * msg
);
void NCAgeJoinerUpdate (
plNCAgeJoiner * joiner
);
#endif // PLASMA20_SOURCES_PLASMA_PUBUTILLIB_PLNETCLIENT_PLNETCLIAGEJOINER_H
/*==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.h
*
***/
#ifndef PLASMA20_SOURCES_PLASMA_PUBUTILLIB_PLNETCLIENT_PLNETCLIAGEJOINER_H
#define PLASMA20_SOURCES_PLASMA_PUBUTILLIB_PLNETCLIENT_PLNETCLIAGEJOINER_H
#include "HeadSpin.h"
#include "pnUtils/pnUtils.h"
#include "plNetClientComm/plNetClientComm.h"
/*****************************************************************************
*
*
*
***/
class plMessage;
struct plNCAgeJoiner;
enum ENCAgeJoinerNotify {
kAgeJoinerComplete, // notify --> NCAgeJoinerCompleteNotify *, after callback, joiner is destroyed
kNumAgeJoinerNotifications
};
struct NCAgeJoinerCompleteNotify {
bool success;
const char * msg;
};
typedef void (* FNCAgeJoinerCallback)(
plNCAgeJoiner * joiner,
unsigned type, // ENCAgeJoinerNotify
void * notify,
void * userState
);
void NCAgeJoinerCreate (
plNCAgeJoiner ** joiner,
const NetCommAge & age,
FNCAgeJoinerCallback callback,
void * userState
);
bool NCAgeJoinerMsgReceive ( // returns true of message was processed
plNCAgeJoiner * joiner,
plMessage * msg
);
void NCAgeJoinerUpdate (
plNCAgeJoiner * joiner
);
#endif // PLASMA20_SOURCES_PLASMA_PUBUTILLIB_PLNETCLIENT_PLNETCLIAGEJOINER_H

View File

@ -1,284 +1,284 @@
/*==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/plNetCliAgeLeaver.cpp
*
***/
#include "plNetCliAgeLeaver.h"
#include "plNetClientMgr.h"
#include "plNetLinkingMgr.h"
#include "pnMessage/plTimeMsg.h"
#include "plNetClientComm/plNetClientComm.h"
#include "plNetGameLib/plNetGameLib.h"
#include "plAgeLoader/plAgeLoader.h"
#include "plAgeLoader/plBackgroundDownloader.h"
#include "plAvatar/plAvatarMgr.h"
#include "plVault/plVault.h"
#include "plMessage/plLoadAgeMsg.h"
#include "plMessage/plAgeLoadedMsg.h"
#include "plMessage/plInputIfaceMgrMsg.h"
/*****************************************************************************
*
* Private
*
***/
struct plNCAgeLeaver {
enum NextOp {
kNoOp,
kDisableClickables,
kLinkOutFX,
kUnloadAge,
kNotifyAgeUnloaded,
};
NextOp nextOp;
bool quitting;
bool complete;
FNCAgeLeaverCallback callback;
void * userState;
plNCAgeLeaver (
bool quitting,
FNCAgeLeaverCallback callback,
void * userState
);
~plNCAgeLeaver ();
void Start ();
void Complete (bool success, const char msg[]);
bool MsgReceive (plMessage * msg);
void Update ();
void ExecNextOp ();
};
/*****************************************************************************
*
* plNCAgeLeaver
*
***/
//============================================================================
plNCAgeLeaver::plNCAgeLeaver (
bool quitting,
FNCAgeLeaverCallback callback,
void * userState
) : nextOp(kNoOp)
, quitting(quitting)
, complete(false)
, callback(callback)
, userState(userState)
{
}
//============================================================================
plNCAgeLeaver::~plNCAgeLeaver () {
}
//============================================================================
void plNCAgeLeaver::Start () {
if (plBackgroundDownloader::GetInstance())
plBackgroundDownloader::GetInstance()->Pause();
nextOp = kLinkOutFX;
}
//============================================================================
void plNCAgeLeaver::Complete (bool success, const char msg[]) {
if (!complete) {
complete = true;
NCAgeLeaveCompleteNotify notify;
notify.success = success;
notify.msg = msg;
callback(this, kAgeLeaveComplete, &notify, userState);
DEL(this);
}
}
//============================================================================
bool plNCAgeLeaver::MsgReceive (plMessage * msg) {
plNetClientMgr * nc = plNetClientMgr::GetInstance();
plAvatarMgr * am = plAvatarMgr::GetInstance();
plAgeLoader * al = plAgeLoader::GetInstance();
//========================================================================
// Done with link out effects
//========================================================================
if (plLinkOutUnloadMsg * linkOutUnloadMsg = plLinkOutUnloadMsg::ConvertNoRef(msg))
{
if (!linkOutUnloadMsg->HasBCastFlag(plMessage::kNetNonLocal)
&& linkOutUnloadMsg->GetPlayerID() == NetCommGetPlayer()->playerInt
) {
nextOp = kUnloadAge;
}
return true;
}
//========================================================================
// Age data unloaded
//========================================================================
if (plAgeLoadedMsg * ageLoadedMsg = plAgeLoadedMsg::ConvertNoRef(msg)) {
if (!ageLoadedMsg->fLoaded) {
nextOp = kNotifyAgeUnloaded;
return true;
}
return false;
}
return false;
}
//============================================================================
void plNCAgeLeaver::ExecNextOp () {
plNetClientMgr * nc = plNetClientMgr::GetInstance();
plAvatarMgr * am = plAvatarMgr::GetInstance();
plAgeLoader * al = plAgeLoader::GetInstance();
NextOp next = nextOp;
nextOp = kNoOp;
switch (next) {
//====================================================================
case kNoOp: {
}
break;
//====================================================================
case kDisableClickables: {
(TRACKED_NEW plInputIfaceMgrMsg(plInputIfaceMgrMsg::kDisableClickables))->Send();
nextOp = kLinkOutFX;
}
break;
//====================================================================
case kLinkOutFX: {
nc->StartLinkOutFX();
}
break;
//====================================================================
case kUnloadAge: {
NetCliGameDisconnect();
// Cull nodes that were part of this age vault (but not shared by the player's vault)
VaultCull(NetCommGetAge()->ageVaultId);
// remove the age device inbox mappings
VaultClearDeviceInboxMap();
// Tell our local player that he's unspawning (if that is indeed the case)
nc->IPlayerChangeAge(true /* exiting */, 0/* respawn */);
// disconnect age vault
// @@@ TODO: Unload age vault here
plAgeLoader::GetInstance()->UnloadAge(); // unload age
nc->ISendCameraReset(false/*leaving age*/); // reset camera
nc->IUnloadRemotePlayers(); // unload other players
if (NetCommNeedToLoadAvatar())
am->UnLoadLocalPlayer();
}
break;
//====================================================================
case kNotifyAgeUnloaded: {
// Set "Playing Game" bit to false
nc->SetFlagsBit(plNetClientMgr::kPlayingGame, false);
// Release AgeSDL object, if any
if (nc->fAgeSDLObjectKey)
nc->GetKey()->Release(nc->fAgeSDLObjectKey);
// All done leaving age
Complete(true, "Age unloaded");
}
break;
DEFAULT_FATAL(nextOp);
}
}
//============================================================================
void plNCAgeLeaver::Update () {
ExecNextOp();
}
/*****************************************************************************
*
* Exports
*
***/
//============================================================================
void NCAgeLeaverCreate (
plNCAgeLeaver ** pleaver,
bool quitting,
FNCAgeLeaverCallback callback,
void * userState
) {
ASSERT(pleaver);
ASSERT(callback);
plNCAgeLeaver * leaver;
*pleaver = leaver = NEWZERO(plNCAgeLeaver)(
quitting,
callback,
userState
);
leaver->Start();
}
//============================================================================
bool NCAgeLeaverMsgReceive (
plNCAgeLeaver * leaver,
plMessage * msg
) {
ASSERT(leaver);
return leaver->MsgReceive(msg);
}
//============================================================================
void NCAgeLeaverUpdate (
plNCAgeLeaver * leaver
) {
ASSERT(leaver);
leaver->Update();
}
/*==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/plNetCliAgeLeaver.cpp
*
***/
#include "plNetCliAgeLeaver.h"
#include "plNetClientMgr.h"
#include "plNetLinkingMgr.h"
#include "pnMessage/plTimeMsg.h"
#include "plNetClientComm/plNetClientComm.h"
#include "plNetGameLib/plNetGameLib.h"
#include "plAgeLoader/plAgeLoader.h"
#include "plAgeLoader/plBackgroundDownloader.h"
#include "plAvatar/plAvatarMgr.h"
#include "plVault/plVault.h"
#include "plMessage/plLoadAgeMsg.h"
#include "plMessage/plAgeLoadedMsg.h"
#include "plMessage/plInputIfaceMgrMsg.h"
/*****************************************************************************
*
* Private
*
***/
struct plNCAgeLeaver {
enum NextOp {
kNoOp,
kDisableClickables,
kLinkOutFX,
kUnloadAge,
kNotifyAgeUnloaded,
};
NextOp nextOp;
bool quitting;
bool complete;
FNCAgeLeaverCallback callback;
void * userState;
plNCAgeLeaver (
bool quitting,
FNCAgeLeaverCallback callback,
void * userState
);
~plNCAgeLeaver ();
void Start ();
void Complete (bool success, const char msg[]);
bool MsgReceive (plMessage * msg);
void Update ();
void ExecNextOp ();
};
/*****************************************************************************
*
* plNCAgeLeaver
*
***/
//============================================================================
plNCAgeLeaver::plNCAgeLeaver (
bool quitting,
FNCAgeLeaverCallback callback,
void * userState
) : nextOp(kNoOp)
, quitting(quitting)
, complete(false)
, callback(callback)
, userState(userState)
{
}
//============================================================================
plNCAgeLeaver::~plNCAgeLeaver () {
}
//============================================================================
void plNCAgeLeaver::Start () {
if (plBackgroundDownloader::GetInstance())
plBackgroundDownloader::GetInstance()->Pause();
nextOp = kLinkOutFX;
}
//============================================================================
void plNCAgeLeaver::Complete (bool success, const char msg[]) {
if (!complete) {
complete = true;
NCAgeLeaveCompleteNotify notify;
notify.success = success;
notify.msg = msg;
callback(this, kAgeLeaveComplete, &notify, userState);
DEL(this);
}
}
//============================================================================
bool plNCAgeLeaver::MsgReceive (plMessage * msg) {
plNetClientMgr * nc = plNetClientMgr::GetInstance();
plAvatarMgr * am = plAvatarMgr::GetInstance();
plAgeLoader * al = plAgeLoader::GetInstance();
//========================================================================
// Done with link out effects
//========================================================================
if (plLinkOutUnloadMsg * linkOutUnloadMsg = plLinkOutUnloadMsg::ConvertNoRef(msg))
{
if (!linkOutUnloadMsg->HasBCastFlag(plMessage::kNetNonLocal)
&& linkOutUnloadMsg->GetPlayerID() == NetCommGetPlayer()->playerInt
) {
nextOp = kUnloadAge;
}
return true;
}
//========================================================================
// Age data unloaded
//========================================================================
if (plAgeLoadedMsg * ageLoadedMsg = plAgeLoadedMsg::ConvertNoRef(msg)) {
if (!ageLoadedMsg->fLoaded) {
nextOp = kNotifyAgeUnloaded;
return true;
}
return false;
}
return false;
}
//============================================================================
void plNCAgeLeaver::ExecNextOp () {
plNetClientMgr * nc = plNetClientMgr::GetInstance();
plAvatarMgr * am = plAvatarMgr::GetInstance();
plAgeLoader * al = plAgeLoader::GetInstance();
NextOp next = nextOp;
nextOp = kNoOp;
switch (next) {
//====================================================================
case kNoOp: {
}
break;
//====================================================================
case kDisableClickables: {
(TRACKED_NEW plInputIfaceMgrMsg(plInputIfaceMgrMsg::kDisableClickables))->Send();
nextOp = kLinkOutFX;
}
break;
//====================================================================
case kLinkOutFX: {
nc->StartLinkOutFX();
}
break;
//====================================================================
case kUnloadAge: {
NetCliGameDisconnect();
// Cull nodes that were part of this age vault (but not shared by the player's vault)
VaultCull(NetCommGetAge()->ageVaultId);
// remove the age device inbox mappings
VaultClearDeviceInboxMap();
// Tell our local player that he's unspawning (if that is indeed the case)
nc->IPlayerChangeAge(true /* exiting */, 0/* respawn */);
// disconnect age vault
// @@@ TODO: Unload age vault here
plAgeLoader::GetInstance()->UnloadAge(); // unload age
nc->ISendCameraReset(false/*leaving age*/); // reset camera
nc->IUnloadRemotePlayers(); // unload other players
if (NetCommNeedToLoadAvatar())
am->UnLoadLocalPlayer();
}
break;
//====================================================================
case kNotifyAgeUnloaded: {
// Set "Playing Game" bit to false
nc->SetFlagsBit(plNetClientMgr::kPlayingGame, false);
// Release AgeSDL object, if any
if (nc->fAgeSDLObjectKey)
nc->GetKey()->Release(nc->fAgeSDLObjectKey);
// All done leaving age
Complete(true, "Age unloaded");
}
break;
DEFAULT_FATAL(nextOp);
}
}
//============================================================================
void plNCAgeLeaver::Update () {
ExecNextOp();
}
/*****************************************************************************
*
* Exports
*
***/
//============================================================================
void NCAgeLeaverCreate (
plNCAgeLeaver ** pleaver,
bool quitting,
FNCAgeLeaverCallback callback,
void * userState
) {
ASSERT(pleaver);
ASSERT(callback);
plNCAgeLeaver * leaver;
*pleaver = leaver = NEWZERO(plNCAgeLeaver)(
quitting,
callback,
userState
);
leaver->Start();
}
//============================================================================
bool NCAgeLeaverMsgReceive (
plNCAgeLeaver * leaver,
plMessage * msg
) {
ASSERT(leaver);
return leaver->MsgReceive(msg);
}
//============================================================================
void NCAgeLeaverUpdate (
plNCAgeLeaver * leaver
) {
ASSERT(leaver);
leaver->Update();
}

View File

@ -1,84 +1,84 @@
/*==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/plNetCliAgeLeaver.h
*
***/
#ifndef PLASMA20_SOURCES_PLASMA_PUBUTILLIB_PLNETCLIENT_PLNETCLIAGELEAVER_H
#define PLASMA20_SOURCES_PLASMA_PUBUTILLIB_PLNETCLIENT_PLNETCLIAGELEAVER_H
#include "HeadSpin.h"
#include "pnUtils/pnUtils.h"
#include "pnNetBase/pnNetBase.h"
/*****************************************************************************
*
*
*
***/
class plMessage;
struct plNCAgeLeaver;
enum ENCAgeLeaverNotify {
kAgeLeaveComplete, // notify --> NCAgeLeaveCompleteNotify *, after callback, leaver is destroyed
kNumAgeLeaverNotifications
};
struct NCAgeLeaveCompleteNotify {
bool success;
const char * msg;
};
typedef void (* FNCAgeLeaverCallback)(
plNCAgeLeaver * leaver,
unsigned type, // ENCAgeLeaverNotify
void * notify,
void * userState
);
void NCAgeLeaverCreate (
plNCAgeLeaver ** leaver,
bool quitting,
FNCAgeLeaverCallback callback,
void * userState
);
bool NCAgeLeaverMsgReceive ( // returns true of message was processed
plNCAgeLeaver * leaver,
plMessage * msg
);
void NCAgeLeaverUpdate (
plNCAgeLeaver * leaver
);
#endif // PLASMA20_SOURCES_PLASMA_PUBUTILLIB_PLNETCLIENT_PLNETCLIAGELEAVER_H
/*==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/plNetCliAgeLeaver.h
*
***/
#ifndef PLASMA20_SOURCES_PLASMA_PUBUTILLIB_PLNETCLIENT_PLNETCLIAGELEAVER_H
#define PLASMA20_SOURCES_PLASMA_PUBUTILLIB_PLNETCLIENT_PLNETCLIAGELEAVER_H
#include "HeadSpin.h"
#include "pnUtils/pnUtils.h"
#include "pnNetBase/pnNetBase.h"
/*****************************************************************************
*
*
*
***/
class plMessage;
struct plNCAgeLeaver;
enum ENCAgeLeaverNotify {
kAgeLeaveComplete, // notify --> NCAgeLeaveCompleteNotify *, after callback, leaver is destroyed
kNumAgeLeaverNotifications
};
struct NCAgeLeaveCompleteNotify {
bool success;
const char * msg;
};
typedef void (* FNCAgeLeaverCallback)(
plNCAgeLeaver * leaver,
unsigned type, // ENCAgeLeaverNotify
void * notify,
void * userState
);
void NCAgeLeaverCreate (
plNCAgeLeaver ** leaver,
bool quitting,
FNCAgeLeaverCallback callback,
void * userState
);
bool NCAgeLeaverMsgReceive ( // returns true of message was processed
plNCAgeLeaver * leaver,
plMessage * msg
);
void NCAgeLeaverUpdate (
plNCAgeLeaver * leaver
);
#endif // PLASMA20_SOURCES_PLASMA_PUBUTILLIB_PLNETCLIENT_PLNETCLIAGELEAVER_H

View File

@ -1,68 +1,68 @@
/*==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==*/
#include "hsTimer.h"
#include "plNetClientMgr.h"
#include "plNetLinkingMgr.h"
#include "plNetClientRecorder/plNetClientRecorder.h"
#include "plNetMessage/plNetMessage.h"
#include "plgDispatch.h"
//
// Code for interfacing with plNetClientComm library, which in turn
// handles most client-server communication
//
int plNetClientCommMsgHandler::HandleMessage( plNetMessage* msg )
{
plNetClientMgr* nc=plNetClientMgr::GetInstance();
int ret = nc->fMsgHandler.ReceiveMsg(msg);
return ret;
}
int plNetClientMgr::IInitNetClientComm()
{
NetCommActivatePostInitErrorHandler();
ASSERT(!GetFlagsBit(kNetClientCommInited));
fNetClientComm.SetDefaultHandler(&fNetClientCommMsgHandler);
SetFlagsBit(kNetClientCommInited);
return hsOK;
}
//
// Cleanup netClientComm related stuff
//
int plNetClientMgr::IDeInitNetClientComm()
{
SetFlagsBit(kNetClientCommInited, false);
return hsOK;
}
/*==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==*/
#include "hsTimer.h"
#include "plNetClientMgr.h"
#include "plNetLinkingMgr.h"
#include "plNetClientRecorder/plNetClientRecorder.h"
#include "plNetMessage/plNetMessage.h"
#include "plgDispatch.h"
//
// Code for interfacing with plNetClientComm library, which in turn
// handles most client-server communication
//
int plNetClientCommMsgHandler::HandleMessage( plNetMessage* msg )
{
plNetClientMgr* nc=plNetClientMgr::GetInstance();
int ret = nc->fMsgHandler.ReceiveMsg(msg);
return ret;
}
int plNetClientMgr::IInitNetClientComm()
{
NetCommActivatePostInitErrorHandler();
ASSERT(!GetFlagsBit(kNetClientCommInited));
fNetClientComm.SetDefaultHandler(&fNetClientCommMsgHandler);
SetFlagsBit(kNetClientCommInited);
return hsOK;
}
//
// Cleanup netClientComm related stuff
//
int plNetClientMgr::IDeInitNetClientComm()
{
SetFlagsBit(kNetClientCommInited, false);
return hsOK;
}

View File

@ -1,41 +1,41 @@
/*==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==*/
#ifndef plNetClientCreatable_inc
#define plNetClientCreatable_inc
#include "pnFactory/plCreator.h"
#include "plNetClientMgr.h"
REGISTER_CREATABLE( plNetClientMgr );
#include "plNetTransport/plNetTransportMember.h"
REGISTER_CREATABLE( plNetTransportMember );
#include "plLinkEffectsMgr.h"
REGISTER_CREATABLE( plLinkEffectsMgr );
#endif // plNetClientCreatable_inc
/*==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==*/
#ifndef plNetClientCreatable_inc
#define plNetClientCreatable_inc
#include "pnFactory/plCreator.h"
#include "plNetClientMgr.h"
REGISTER_CREATABLE( plNetClientMgr );
#include "plNetTransport/plNetTransportMember.h"
REGISTER_CREATABLE( plNetTransportMember );
#include "plLinkEffectsMgr.h"
REGISTER_CREATABLE( plLinkEffectsMgr );
#endif // plNetClientCreatable_inc

View File

@ -1,55 +1,55 @@
/*==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==*/
#include "hsResMgr.h"
#include "plNetClientGroup.h"
#include "plResMgr/plKeyFinder.h"
#include "plResMgr/plPageInfo.h"
//
// cache room desc string, from fID
//
void plNetClientGroups::ISetGroupDesc(plNetGroupId& grpId)
{
if (grpId.Room() == plNetGroup::kNetGroupUnknown.Room())
grpId.SetDesc("Unknown");
else
if (grpId.Room()== plNetGroup::kNetGroupLocalPlayer.Room())
grpId.SetDesc("LocalPlayer");
else
if (grpId.Room()== plNetGroup::kNetGroupRemotePlayer.Room())
grpId.SetDesc("RemotePlayer");
else
if (grpId.Room()== plNetGroup::kNetGroupLocalPhysicals.Room())
grpId.SetDesc("LocalPhysicals");
else
if (grpId.Room()== plNetGroup::kNetGroupRemotePhysicals.Room())
grpId.SetDesc("RemotePhysicals");
else
{
const plPageInfo* pageInfo=plKeyFinder::Instance().GetLocationInfo(grpId.Room());
grpId.SetDesc(pageInfo->GetPage());
}
/*==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==*/
#include "hsResMgr.h"
#include "plNetClientGroup.h"
#include "plResMgr/plKeyFinder.h"
#include "plResMgr/plPageInfo.h"
//
// cache room desc string, from fID
//
void plNetClientGroups::ISetGroupDesc(plNetGroupId& grpId)
{
if (grpId.Room() == plNetGroup::kNetGroupUnknown.Room())
grpId.SetDesc("Unknown");
else
if (grpId.Room()== plNetGroup::kNetGroupLocalPlayer.Room())
grpId.SetDesc("LocalPlayer");
else
if (grpId.Room()== plNetGroup::kNetGroupRemotePlayer.Room())
grpId.SetDesc("RemotePlayer");
else
if (grpId.Room()== plNetGroup::kNetGroupLocalPhysicals.Room())
grpId.SetDesc("LocalPhysicals");
else
if (grpId.Room()== plNetGroup::kNetGroupRemotePhysicals.Room())
grpId.SetDesc("RemotePhysicals");
else
{
const plPageInfo* pageInfo=plKeyFinder::Instance().GetLocationInfo(grpId.Room());
grpId.SetDesc(pageInfo->GetPage());
}
}

View File

@ -1,126 +1,126 @@
/*==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==*/
#ifndef plNetClientGroup_h
#define plNetClientGroup_h
#include "hsStlUtils.h"
#include "pnNetCommon/plNetGroup.h"
//
// represents a collection of net groups.
// abstracted so that we can switch to a different container structure if necessary
//
class plNetClientGroups
{
friend class plNetClientMgr;
private:
struct OwnedGroup
{
plNetGroupId fGroup;
bool fOwnIt;
bool operator<(const OwnedGroup& other) const { return other.fGroup<fGroup; }
bool operator==(const OwnedGroup& other) const { return (other.fGroup==fGroup && other.fOwnIt==fOwnIt); }
OwnedGroup(plNetGroupId g, bool o) : fGroup(g),fOwnIt(o) { fGroup.SetDesc(g.GetDesc()); }
OwnedGroup() : fOwnIt(false) {}
};
std::set<OwnedGroup> fGroups;
std::set<OwnedGroup>::iterator IFind(const plNetGroupId& grpId)
{
std::set<OwnedGroup>::iterator it=fGroups.begin();
for( ; it != fGroups.end(); it++)
if ((*it).fGroup==grpId)
break;
return it;
}
// const version
std::set<OwnedGroup>::const_iterator IFind(const plNetGroupId& grpId) const
{
std::set<OwnedGroup>::const_iterator it=fGroups.begin();
for( ; it != fGroups.end(); it++)
if ((*it).fGroup==grpId)
break;
return it;
}
void ISetGroupDesc(plNetGroupId& grpId);
public:
void Reset()
{
ClearGroups();
SetGroup(plNetGroup::kNetGroupLocalPlayer, true /*ownit*/);
SetGroup(plNetGroup::kNetGroupRemotePlayer, false /*ownit*/);
SetGroup(plNetGroup::kNetGroupLocalPhysicals, true /*ownit*/);
SetGroup(plNetGroup::kNetGroupRemotePhysicals, false /*ownit*/);
}
void SetGroup(plNetGroupId& grpId, bool ownIt)
{
std::set<OwnedGroup>::iterator it=IFind(grpId);
if (it != fGroups.end())
{
OwnedGroup grp(it->fGroup, it->fOwnIt);
fGroups.erase(it);
fGroups.insert(grp);
}
else
{
ISetGroupDesc(grpId);
fGroups.insert(OwnedGroup(grpId, ownIt));
}
}
#if 0
void RemoveGroup(const plNetGroupId& grpId)
{
std::set<OwnedGroup>::iterator it=IFind(grpId);
if (it != fGroups.end())
fGroups.erase(it);
}
#else
void ClearGroups()
{
fGroups.clear();
}
#endif
int IsGroupLocal(const plNetGroupId& grpId) const
{
std::set<OwnedGroup>::const_iterator it=IFind(grpId);
if (it != fGroups.end())
{
if ((*it).fOwnIt)
return 1; // yes
return 0; // no
}
return -1; // don't know about it
}
};
#endif // plNetClientGroup_h
/*==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==*/
#ifndef plNetClientGroup_h
#define plNetClientGroup_h
#include "hsStlUtils.h"
#include "pnNetCommon/plNetGroup.h"
//
// represents a collection of net groups.
// abstracted so that we can switch to a different container structure if necessary
//
class plNetClientGroups
{
friend class plNetClientMgr;
private:
struct OwnedGroup
{
plNetGroupId fGroup;
bool fOwnIt;
bool operator<(const OwnedGroup& other) const { return other.fGroup<fGroup; }
bool operator==(const OwnedGroup& other) const { return (other.fGroup==fGroup && other.fOwnIt==fOwnIt); }
OwnedGroup(plNetGroupId g, bool o) : fGroup(g),fOwnIt(o) { fGroup.SetDesc(g.GetDesc()); }
OwnedGroup() : fOwnIt(false) {}
};
std::set<OwnedGroup> fGroups;
std::set<OwnedGroup>::iterator IFind(const plNetGroupId& grpId)
{
std::set<OwnedGroup>::iterator it=fGroups.begin();
for( ; it != fGroups.end(); it++)
if ((*it).fGroup==grpId)
break;
return it;
}
// const version
std::set<OwnedGroup>::const_iterator IFind(const plNetGroupId& grpId) const
{
std::set<OwnedGroup>::const_iterator it=fGroups.begin();
for( ; it != fGroups.end(); it++)
if ((*it).fGroup==grpId)
break;
return it;
}
void ISetGroupDesc(plNetGroupId& grpId);
public:
void Reset()
{
ClearGroups();
SetGroup(plNetGroup::kNetGroupLocalPlayer, true /*ownit*/);
SetGroup(plNetGroup::kNetGroupRemotePlayer, false /*ownit*/);
SetGroup(plNetGroup::kNetGroupLocalPhysicals, true /*ownit*/);
SetGroup(plNetGroup::kNetGroupRemotePhysicals, false /*ownit*/);
}
void SetGroup(plNetGroupId& grpId, bool ownIt)
{
std::set<OwnedGroup>::iterator it=IFind(grpId);
if (it != fGroups.end())
{
OwnedGroup grp(it->fGroup, it->fOwnIt);
fGroups.erase(it);
fGroups.insert(grp);
}
else
{
ISetGroupDesc(grpId);
fGroups.insert(OwnedGroup(grpId, ownIt));
}
}
#if 0
void RemoveGroup(const plNetGroupId& grpId)
{
std::set<OwnedGroup>::iterator it=IFind(grpId);
if (it != fGroups.end())
fGroups.erase(it);
}
#else
void ClearGroups()
{
fGroups.clear();
}
#endif
int IsGroupLocal(const plNetGroupId& grpId) const
{
std::set<OwnedGroup>::const_iterator it=IFind(grpId);
if (it != fGroups.end())
{
if ((*it).fOwnIt)
return 1; // yes
return 0; // no
}
return -1; // don't know about it
}
};
#endif // plNetClientGroup_h

File diff suppressed because it is too large Load Diff

View File

@ -1,398 +1,398 @@
/*==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==*/
#ifndef PL_NET_CLIENT_inc
#define PL_NET_CLIENT_inc
#include "hsConfig.h"
#include "hsUtils.h"
#include "hsStlUtils.h"
#include "plNetClientGroup.h"
#include "plNetVoiceList.h"
#include "plNetClientMsgHandler.h"
#include "plNetClientStats.h" // STATS Counters
#include "pnNetCommon/plNetApp.h"
#include "plNetTransport/plNetTransport.h"
#include "plEncryption/plChecksum.h"
#include "plNetCommon/plNetServerSessionInfo.h"
#include "plNetClientComm/plNetClientComm.h"
#include "plUnifiedTime/plUnifiedTime.h"
#pragma warning(disable: 4284)
////////////////////////////////////////////////////////////////////
class plUoid;
class hsStream;
class plKey;
class plNetMessage;
class plSynchedObject;
struct DistSqInfo;
class plStatusLog;
class plOperationProgress;
class plIDataServer;
class plPlate;
class plLoadCloneMsg;
class plPlayerPageMsg;
class plNetClientRecorder;
class plVaultPlayerNode;
class plVaultAgeNode;
class plNetVoiceListMsg;
class plStateDataRecord;
class plCCRPetitionMsg;
class plNetMsgPagingRoom;
struct plNetClientCommMsgHandler : plNetClientComm::MsgHandler {
int HandleMessage( plNetMessage* msg );
};
class plNetClientMgr : public plNetClientApp
{
private:
typedef std::vector<plKey> plKeyVec;
public:
enum NetChannels
{
kNetChanDefault,
kNetChanVoice,
kNetChanListenListUpdate,
kNetChanDirectedMsg,
kNetNumChannels
};
enum DirectedSendFlags
{
kInterAgeMsg = 0x1
};
enum ListenListMode
{
kListenList_Distance = 0,
kListenList_Forced,
kListenList_End,
};
enum RefContext
{
kVaultImage = 0,
kAgeSDLHook = 1
};
struct PendingLoad
{
// must be set by user
plStateDataRecord* fSDRec; // the sdl data record
plUoid fUoid; // the object it's meant for
UInt32 fPlayerID; // the player that originally sent the state
// set by NetClient
plKey fKey; // the key of the object it's meant for
double fQueuedTime;
int fQueueTimeResets;
PendingLoad() : fSDRec(nil),fPlayerID(0),fKey(nil),fQueuedTime(0.0),fQueueTimeResets(0) {}
~PendingLoad();
};
private:
// plOperationProgress *fProgressBar;
plOperationProgress *fTaskProgBar;
typedef std::list<PendingLoad*> PendingLoadsList;
PendingLoadsList fPendingLoads;
// pending room page msgs
std::vector<plNetMsgPagingRoom*> fPendingPagingRoomMsgs;
plNetTransport fTransport;
// groups of objects in the game. Each group is mastered by a single client.
plNetClientGroups fNetGroups;
// cached char info
plKey fLocalPlayerKey;
plKeyVec fRemotePlayerKeys;
// plKeyVec fNPCKeys;
class plNetClientMgrMsg * fDisableMsg;
// ini info
std::string fIniAccountName;
std::string fIniAccountPass;
std::string fIniAuthServer;
UInt32 fIniPlayerID; // the player we want to load from vault.
std::string fSPDesiredPlayerName; // SP: the player we want to load from vault.
// server info
double fServerTimeOffset; // diff between our unified time and server's unified time
UInt32 fTimeSamples;
double fLastTimeUpdate;
UInt8 fJoinOrder; // returned by the server
// voice lists
int fListenListMode; // how we are generating our listen list
plNetListenList fListenList; // other players I'm listening to
plNetTalkList fTalkList; // other players I'm talking to
plNetClientMsgHandler fMsgHandler;
// recorder support
plNetClientRecorder* fMsgRecorder;
std::vector<plNetClientRecorder*> fMsgPlayers;
plKey fAgeSDLObjectKey;
UInt8 fExperimentalLevel;
plNetClientStats fNetClientStats;
UInt8 fPingServerType; // non-zero if we're pinging someone
float fOverrideAgeTimeOfDayPercent; // for console debugging
int fNumInitialSDLStates;
int fRequiredNumInitialSDLStates;
// simplification of object ownership...one player owns all non-physical objects in the world
// physical objects are owned by whoever touched them most recently (or the "owner" if nobody
// has touched it yet)
bool fIsOwner;
//
void ICheckPendingStateLoad(double secs);
int IDeduceLocallyOwned(const plUoid& loc) const;
bool IHandlePlayerPageMsg(plPlayerPageMsg *playerMsg); // ***
void IShowLists();
void IShowRooms();
void IShowAvatars();
void IShowRelevanceRegions();
int ISendDirtyState(double secs);
int ISendMembersListRequest();
int ISendRoomsReset();
void ISendCCRPetition(plCCRPetitionMsg* petMsg);
void ISendCameraReset(hsBool bEnteringAge);
hsBool IUpdateListenList(double secs);
void IHandleNetVoiceListMsg(plNetVoiceListMsg* msg);
hsBool IApplyNewListenList(std::vector<DistSqInfo>& newListenList, hsBool forceSynch);
int IPrepMsg(plNetMessage* msg);
void IPlayerChangeAge(hsBool exiting, Int32 spawnPt);
void IAddCloneRoom();
void IRemoveCloneRoom();
void IUnloadRemotePlayers();
plKey ILoadClone(plLoadCloneMsg *cloneMsg);
bool IFindModifier(plSynchedObject* obj, Int16 classIdx);
void IClearPendingLoads();
// recorder
bool IIsRecordableMsg(plNetMessage* msg);
void IPlaybackMsgs();
void IRequestAgeState();
void IDumpOSVersionInfo() const;
int ISendGameMessage(plMessage* msg);
void IDisableNet ();
public:
plNetClientMgr();
~plNetClientMgr();
CLASSNAME_REGISTER( plNetClientMgr );
GETINTERFACE_ANY( plNetClientMgr, plNetClientApp );
static plNetClientMgr* GetInstance() { return plNetClientMgr::ConvertNoRef(fInstance); }
void StartLinkOutFX();
void StartLinkInFX();
hsBool MsgReceive(plMessage* msg);
void Shutdown();
int Init();
void QueueDisableNet (bool showDlg, const char msg[]);
int SendMsg(plNetMessage* msg);
int Update(double secs);
int IsLocallyOwned(const plSynchedObject* obj) const; // returns yes/no/maybe
int IsLocallyOwned(const plUoid&) const; // for special cases, like sceneNodes. returns yes/no/maybe
plNetGroupId GetEffectiveNetGroup(const plSynchedObject*& obj) const;
plNetGroupId SelectNetGroup(plSynchedObject* objIn, plKey groupKey);
void SendLocalPlayerAvatarCustomizations();
void SendApplyAvatarCustomizationsMsg(const plKey msgReceiver, bool netPropagate=true, bool localPropagate=true);
// plLoggable
bool Log(const char* str) const;
// setters
void SetIniAuthServer(const char * value) { fIniAuthServer=value;}
void SetIniAccountName(const char * value) { fIniAccountName=value;}
void SetIniAccountPass(const char * value) { fIniAccountPass=value;}
void SetIniPlayerID(UInt32 value) { fIniPlayerID=value;}
void SetSPDesiredPlayerName( const char * value ) { fSPDesiredPlayerName=value;}
const char * GetSPDesiredPlayerName() const { return fSPDesiredPlayerName.c_str(); }
void SetLocalPlayerKey(plKey l, hsBool pageOut=false);
void SetNullSend(hsBool on); // turn null send on/off
void SetPingServer(UInt8 serverType) { fPingServerType = serverType; }
// getters
UInt32 GetPlayerID( void ) const;
const char * GetPlayerName( const plKey avKey=nil ) const;
const char * GetPlayerNameById (unsigned playerId) const;
unsigned GetPlayerIdByName(const char name[]) const;
UInt8 GetJoinOrder() const { return fJoinOrder; } // only valid at join time
plKey GetLocalPlayerKey() const { return fLocalPlayerKey; }
plSynchedObject* GetLocalPlayer(hsBool forceLoad=false) const;
hsBool IsPeerToPeer() const { return false; }
hsBool IsConnected() const { return true; }
void IncNumInitialSDLStates();
void ResetNumInitialSDLStates() { fNumInitialSDLStates=0; }
int GetNumInitialSDLStates() const { return fNumInitialSDLStates; }
void SetRequiredNumInitialSDLStates( int v ) { fRequiredNumInitialSDLStates=v; }
int GetRequiredNumInitialSDLStates() const { return fRequiredNumInitialSDLStates; }
// Linking progress
void StartTaskProgress( const char *msg, int numSteps );
void IncTaskProgress( const char *msg );
// avatar vault actions
int UploadPlayerVault(UInt32 vaultFlags);
// remote players
const std::vector<plKey>& RemotePlayerKeys() const { return fRemotePlayerKeys; }
plSynchedObject* GetRemotePlayer(int i) const;
void AddRemotePlayerKey(plKey p);
hsBool IsRemotePlayerKey(const plKey p, int* idx=nil);
bool IsAPlayerKey(const plKey pKey) { return (pKey==GetLocalPlayerKey() || IsRemotePlayerKey(pKey)); }
void SetConsoleOutput( bool b ) { SetFlagsBit(kConsoleOutput, b); }
bool GetConsoleOutput() const { return GetFlagsBit(kConsoleOutput); }
// Net groups
const plNetClientGroups* GetNetGroups() const { return &fNetGroups; }
plNetClientGroups* GetNetGroups() { return &fNetGroups; }
// Voice Lists
plNetListenList* GetListenList() { return &fListenList; }
plNetTalkList* GetTalkList() { return &fTalkList; }
void SetListenListMode (int i);
void SynchTalkList();
int GetListenListMode() { return fListenListMode; }
// network activity-generated events, passed to current task
bool CanSendMsg(plNetMessage * msg);
const plNetTransport& TransportMgr() const { return fTransport; }
plNetTransport& TransportMgr() { return fTransport; }
bool ObjectInLocalAge(const plSynchedObject* obj) const;
// time converters
plUnifiedTime GetServerTime() const;
const char* GetServerLogTimeAsString(std::string& ts) const;
double GetCurrentAgeElapsedSeconds() const;
float GetCurrentAgeTimeOfDayPercent() const;
bool RecordMsgs(const char* recType, const char* recName);
bool PlaybackMsgs(const char* recName);
void MakeCCRInvisible(plKey avKey, int level);
bool CCRVaultConnected() const { return GetFlagsBit(kCCRVaultConnected); }
UInt8 GetExperimentalLevel() const { return fExperimentalLevel; }
void AddPendingLoad(PendingLoad *pl);
const plKey& GetAgeSDLObjectKey() const { return fAgeSDLObjectKey; }
plUoid GetAgeSDLObjectUoid(const char* ageName) const;
plNetClientComm& GetNetClientComm() { return fNetClientComm; }
const char* plNetClientMgr::GetNextAgeFilename();
plNetClientStats& GetNetClientStats() { return fNetClientStats; }
void SetOverrideAgeTimeOfDayPercent(float f) { fOverrideAgeTimeOfDayPercent=f; }
void AddPendingPagingRoomMsg( plNetMsgPagingRoom * msg );
void MaybeSendPendingPagingRoomMsgs();
void SendPendingPagingRoomMsgs();
void ClearPendingPagingRoomMsgs();
void NotifyRcvdAllSDLStates();
plOperationProgress* GetTaskProgBar() { return fTaskProgBar; }
bool DebugMsgV(const char* fmt, va_list args) const;
bool ErrorMsgV(const char* fmt, va_list args) const;
bool WarningMsgV(const char* fmt, va_list args) const;
bool AppMsgV(const char* fmt, va_list args) const;
bool IsObjectOwner();
void SetObjectOwner(bool own);
void StoreSDLState(const plStateDataRecord* sdRec, const plUoid& uoid, UInt32 sendFlags, UInt32 writeOptions);
void UpdateServerTimeOffset(plNetMessage* msg);
void ResetServerTimeOffset();
private:
plNetClientComm fNetClientComm;
plNetClientCommMsgHandler fNetClientCommMsgHandler;
int IInitNetClientComm();
int IDeInitNetClientComm();
void INetClientCommOpStarted(UInt32 context);
void INetClientCommOpComplete(UInt32 context, int resultCode);
friend struct plNCAgeJoiner;
friend struct plNCAgeLeaver;
friend class plNetDniInfoSource;
friend class plNetTalkList;
friend class plNetClientMsgHandler;
friend struct plNetClientCommMsgHandler;
};
#define plCheckNetMgrResult_VoidReturn(r,s) if (hsFailed(r)) { ErrorMsg(s); hsAssert(false,s); return; }
// returns int
#define plCheckNetMgrResult_ValReturn(r,s) if (hsFailed(r)) { ErrorMsg(s); hsAssert(false,s); return r; }
// returns bool
#define plCheckNetMgrResult_BoolReturn(r,s) if (hsFailed(r)) { ErrorMsg(s); hsAssert(false,s); return false; }
#endif // PL_NET_CLIENT_inc
/*==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==*/
#ifndef PL_NET_CLIENT_inc
#define PL_NET_CLIENT_inc
#include "hsConfig.h"
#include "hsUtils.h"
#include "hsStlUtils.h"
#include "plNetClientGroup.h"
#include "plNetVoiceList.h"
#include "plNetClientMsgHandler.h"
#include "plNetClientStats.h" // STATS Counters
#include "pnNetCommon/plNetApp.h"
#include "plNetTransport/plNetTransport.h"
#include "plEncryption/plChecksum.h"
#include "plNetCommon/plNetServerSessionInfo.h"
#include "plNetClientComm/plNetClientComm.h"
#include "plUnifiedTime/plUnifiedTime.h"
#pragma warning(disable: 4284)
////////////////////////////////////////////////////////////////////
class plUoid;
class hsStream;
class plKey;
class plNetMessage;
class plSynchedObject;
struct DistSqInfo;
class plStatusLog;
class plOperationProgress;
class plIDataServer;
class plPlate;
class plLoadCloneMsg;
class plPlayerPageMsg;
class plNetClientRecorder;
class plVaultPlayerNode;
class plVaultAgeNode;
class plNetVoiceListMsg;
class plStateDataRecord;
class plCCRPetitionMsg;
class plNetMsgPagingRoom;
struct plNetClientCommMsgHandler : plNetClientComm::MsgHandler {
int HandleMessage( plNetMessage* msg );
};
class plNetClientMgr : public plNetClientApp
{
private:
typedef std::vector<plKey> plKeyVec;
public:
enum NetChannels
{
kNetChanDefault,
kNetChanVoice,
kNetChanListenListUpdate,
kNetChanDirectedMsg,
kNetNumChannels
};
enum DirectedSendFlags
{
kInterAgeMsg = 0x1
};
enum ListenListMode
{
kListenList_Distance = 0,
kListenList_Forced,
kListenList_End,
};
enum RefContext
{
kVaultImage = 0,
kAgeSDLHook = 1
};
struct PendingLoad
{
// must be set by user
plStateDataRecord* fSDRec; // the sdl data record
plUoid fUoid; // the object it's meant for
UInt32 fPlayerID; // the player that originally sent the state
// set by NetClient
plKey fKey; // the key of the object it's meant for
double fQueuedTime;
int fQueueTimeResets;
PendingLoad() : fSDRec(nil),fPlayerID(0),fKey(nil),fQueuedTime(0.0),fQueueTimeResets(0) {}
~PendingLoad();
};
private:
// plOperationProgress *fProgressBar;
plOperationProgress *fTaskProgBar;
typedef std::list<PendingLoad*> PendingLoadsList;
PendingLoadsList fPendingLoads;
// pending room page msgs
std::vector<plNetMsgPagingRoom*> fPendingPagingRoomMsgs;
plNetTransport fTransport;
// groups of objects in the game. Each group is mastered by a single client.
plNetClientGroups fNetGroups;
// cached char info
plKey fLocalPlayerKey;
plKeyVec fRemotePlayerKeys;
// plKeyVec fNPCKeys;
class plNetClientMgrMsg * fDisableMsg;
// ini info
std::string fIniAccountName;
std::string fIniAccountPass;
std::string fIniAuthServer;
UInt32 fIniPlayerID; // the player we want to load from vault.
std::string fSPDesiredPlayerName; // SP: the player we want to load from vault.
// server info
double fServerTimeOffset; // diff between our unified time and server's unified time
UInt32 fTimeSamples;
double fLastTimeUpdate;
UInt8 fJoinOrder; // returned by the server
// voice lists
int fListenListMode; // how we are generating our listen list
plNetListenList fListenList; // other players I'm listening to
plNetTalkList fTalkList; // other players I'm talking to
plNetClientMsgHandler fMsgHandler;
// recorder support
plNetClientRecorder* fMsgRecorder;
std::vector<plNetClientRecorder*> fMsgPlayers;
plKey fAgeSDLObjectKey;
UInt8 fExperimentalLevel;
plNetClientStats fNetClientStats;
UInt8 fPingServerType; // non-zero if we're pinging someone
float fOverrideAgeTimeOfDayPercent; // for console debugging
int fNumInitialSDLStates;
int fRequiredNumInitialSDLStates;
// simplification of object ownership...one player owns all non-physical objects in the world
// physical objects are owned by whoever touched them most recently (or the "owner" if nobody
// has touched it yet)
bool fIsOwner;
//
void ICheckPendingStateLoad(double secs);
int IDeduceLocallyOwned(const plUoid& loc) const;
bool IHandlePlayerPageMsg(plPlayerPageMsg *playerMsg); // ***
void IShowLists();
void IShowRooms();
void IShowAvatars();
void IShowRelevanceRegions();
int ISendDirtyState(double secs);
int ISendMembersListRequest();
int ISendRoomsReset();
void ISendCCRPetition(plCCRPetitionMsg* petMsg);
void ISendCameraReset(hsBool bEnteringAge);
hsBool IUpdateListenList(double secs);
void IHandleNetVoiceListMsg(plNetVoiceListMsg* msg);
hsBool IApplyNewListenList(std::vector<DistSqInfo>& newListenList, hsBool forceSynch);
int IPrepMsg(plNetMessage* msg);
void IPlayerChangeAge(hsBool exiting, Int32 spawnPt);
void IAddCloneRoom();
void IRemoveCloneRoom();
void IUnloadRemotePlayers();
plKey ILoadClone(plLoadCloneMsg *cloneMsg);
bool IFindModifier(plSynchedObject* obj, Int16 classIdx);
void IClearPendingLoads();
// recorder
bool IIsRecordableMsg(plNetMessage* msg);
void IPlaybackMsgs();
void IRequestAgeState();
void IDumpOSVersionInfo() const;
int ISendGameMessage(plMessage* msg);
void IDisableNet ();
public:
plNetClientMgr();
~plNetClientMgr();
CLASSNAME_REGISTER( plNetClientMgr );
GETINTERFACE_ANY( plNetClientMgr, plNetClientApp );
static plNetClientMgr* GetInstance() { return plNetClientMgr::ConvertNoRef(fInstance); }
void StartLinkOutFX();
void StartLinkInFX();
hsBool MsgReceive(plMessage* msg);
void Shutdown();
int Init();
void QueueDisableNet (bool showDlg, const char msg[]);
int SendMsg(plNetMessage* msg);
int Update(double secs);
int IsLocallyOwned(const plSynchedObject* obj) const; // returns yes/no/maybe
int IsLocallyOwned(const plUoid&) const; // for special cases, like sceneNodes. returns yes/no/maybe
plNetGroupId GetEffectiveNetGroup(const plSynchedObject*& obj) const;
plNetGroupId SelectNetGroup(plSynchedObject* objIn, plKey groupKey);
void SendLocalPlayerAvatarCustomizations();
void SendApplyAvatarCustomizationsMsg(const plKey msgReceiver, bool netPropagate=true, bool localPropagate=true);
// plLoggable
bool Log(const char* str) const;
// setters
void SetIniAuthServer(const char * value) { fIniAuthServer=value;}
void SetIniAccountName(const char * value) { fIniAccountName=value;}
void SetIniAccountPass(const char * value) { fIniAccountPass=value;}
void SetIniPlayerID(UInt32 value) { fIniPlayerID=value;}
void SetSPDesiredPlayerName( const char * value ) { fSPDesiredPlayerName=value;}
const char * GetSPDesiredPlayerName() const { return fSPDesiredPlayerName.c_str(); }
void SetLocalPlayerKey(plKey l, hsBool pageOut=false);
void SetNullSend(hsBool on); // turn null send on/off
void SetPingServer(UInt8 serverType) { fPingServerType = serverType; }
// getters
UInt32 GetPlayerID( void ) const;
const char * GetPlayerName( const plKey avKey=nil ) const;
const char * GetPlayerNameById (unsigned playerId) const;
unsigned GetPlayerIdByName(const char name[]) const;
UInt8 GetJoinOrder() const { return fJoinOrder; } // only valid at join time
plKey GetLocalPlayerKey() const { return fLocalPlayerKey; }
plSynchedObject* GetLocalPlayer(hsBool forceLoad=false) const;
hsBool IsPeerToPeer() const { return false; }
hsBool IsConnected() const { return true; }
void IncNumInitialSDLStates();
void ResetNumInitialSDLStates() { fNumInitialSDLStates=0; }
int GetNumInitialSDLStates() const { return fNumInitialSDLStates; }
void SetRequiredNumInitialSDLStates( int v ) { fRequiredNumInitialSDLStates=v; }
int GetRequiredNumInitialSDLStates() const { return fRequiredNumInitialSDLStates; }
// Linking progress
void StartTaskProgress( const char *msg, int numSteps );
void IncTaskProgress( const char *msg );
// avatar vault actions
int UploadPlayerVault(UInt32 vaultFlags);
// remote players
const std::vector<plKey>& RemotePlayerKeys() const { return fRemotePlayerKeys; }
plSynchedObject* GetRemotePlayer(int i) const;
void AddRemotePlayerKey(plKey p);
hsBool IsRemotePlayerKey(const plKey p, int* idx=nil);
bool IsAPlayerKey(const plKey pKey) { return (pKey==GetLocalPlayerKey() || IsRemotePlayerKey(pKey)); }
void SetConsoleOutput( bool b ) { SetFlagsBit(kConsoleOutput, b); }
bool GetConsoleOutput() const { return GetFlagsBit(kConsoleOutput); }
// Net groups
const plNetClientGroups* GetNetGroups() const { return &fNetGroups; }
plNetClientGroups* GetNetGroups() { return &fNetGroups; }
// Voice Lists
plNetListenList* GetListenList() { return &fListenList; }
plNetTalkList* GetTalkList() { return &fTalkList; }
void SetListenListMode (int i);
void SynchTalkList();
int GetListenListMode() { return fListenListMode; }
// network activity-generated events, passed to current task
bool CanSendMsg(plNetMessage * msg);
const plNetTransport& TransportMgr() const { return fTransport; }
plNetTransport& TransportMgr() { return fTransport; }
bool ObjectInLocalAge(const plSynchedObject* obj) const;
// time converters
plUnifiedTime GetServerTime() const;
const char* GetServerLogTimeAsString(std::string& ts) const;
double GetCurrentAgeElapsedSeconds() const;
float GetCurrentAgeTimeOfDayPercent() const;
bool RecordMsgs(const char* recType, const char* recName);
bool PlaybackMsgs(const char* recName);
void MakeCCRInvisible(plKey avKey, int level);
bool CCRVaultConnected() const { return GetFlagsBit(kCCRVaultConnected); }
UInt8 GetExperimentalLevel() const { return fExperimentalLevel; }
void AddPendingLoad(PendingLoad *pl);
const plKey& GetAgeSDLObjectKey() const { return fAgeSDLObjectKey; }
plUoid GetAgeSDLObjectUoid(const char* ageName) const;
plNetClientComm& GetNetClientComm() { return fNetClientComm; }
const char* plNetClientMgr::GetNextAgeFilename();
plNetClientStats& GetNetClientStats() { return fNetClientStats; }
void SetOverrideAgeTimeOfDayPercent(float f) { fOverrideAgeTimeOfDayPercent=f; }
void AddPendingPagingRoomMsg( plNetMsgPagingRoom * msg );
void MaybeSendPendingPagingRoomMsgs();
void SendPendingPagingRoomMsgs();
void ClearPendingPagingRoomMsgs();
void NotifyRcvdAllSDLStates();
plOperationProgress* GetTaskProgBar() { return fTaskProgBar; }
bool DebugMsgV(const char* fmt, va_list args) const;
bool ErrorMsgV(const char* fmt, va_list args) const;
bool WarningMsgV(const char* fmt, va_list args) const;
bool AppMsgV(const char* fmt, va_list args) const;
bool IsObjectOwner();
void SetObjectOwner(bool own);
void StoreSDLState(const plStateDataRecord* sdRec, const plUoid& uoid, UInt32 sendFlags, UInt32 writeOptions);
void UpdateServerTimeOffset(plNetMessage* msg);
void ResetServerTimeOffset();
private:
plNetClientComm fNetClientComm;
plNetClientCommMsgHandler fNetClientCommMsgHandler;
int IInitNetClientComm();
int IDeInitNetClientComm();
void INetClientCommOpStarted(UInt32 context);
void INetClientCommOpComplete(UInt32 context, int resultCode);
friend struct plNCAgeJoiner;
friend struct plNCAgeLeaver;
friend class plNetDniInfoSource;
friend class plNetTalkList;
friend class plNetClientMsgHandler;
friend struct plNetClientCommMsgHandler;
};
#define plCheckNetMgrResult_VoidReturn(r,s) if (hsFailed(r)) { ErrorMsg(s); hsAssert(false,s); return; }
// returns int
#define plCheckNetMgrResult_ValReturn(r,s) if (hsFailed(r)) { ErrorMsg(s); hsAssert(false,s); return r; }
// returns bool
#define plCheckNetMgrResult_BoolReturn(r,s) if (hsFailed(r)) { ErrorMsg(s); hsAssert(false,s); return false; }
#endif // PL_NET_CLIENT_inc

View File

@ -1,176 +1,176 @@
/*==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==*/
#if 1 // for debugging
#include "plCreatableIndex.h"
#include "plModifier/plResponderModifier.h"
#include "plSurface/plLayerAnimation.h"
#endif
#include "hsStream.h"
#include "plNetClientMgr.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
#include "hsTimer.h"
#include "plNetMessage/plNetMessage.h"
#include "pnKeyedObject/plKey.h"
#include "pnKeyedObject/plFixedKey.h"
#include "pnKeyedObject/hsKeyedObject.h"
#include "pnSceneObject/plSceneObject.h"
#include "pnModifier/plModifier.h"
#include "pnMessage/plNodeRefMsg.h"
#include "pnMessage/plClientMsg.h"
#include "pnMessage/plNodeChangeMsg.h"
#include "pnMessage/plPlayerPageMsg.h"
#include "plScene/plSceneNode.h"
#include "plScene/plRelevanceMgr.h"
#include "plNetTransport/plNetTransportMember.h"
#include "plResMgr/plKeyFinder.h"
#include "plAgeDescription/plAgeDescription.h"
#include "plAvatar/plArmatureMod.h"
#include "plAvatar/plAvatarMgr.h"
#include "plSDL/plSDL.h"
/// TEMP HACK TO LOAD CONSOLE INIT FILES ON AGE LOAD
#include "plMessage/plConsoleMsg.h"
#include "plMessage/plLoadAvatarMsg.h"
#include "plMessage/plAgeLoadedMsg.h"
#include "plAgeLoader/plResPatcher.h"
#include "plProgressMgr/plProgressMgr.h"
#include "plResMgr/plRegistryHelpers.h"
#include "plResMgr/plRegistryNode.h"
#include "plResMgr/plResManager.h"
#ifdef _MSC_VER
#include <process.h> // for getpid()
#else
#include <sys/types.h>
#include <unistd.h>
#endif
extern hsBool gDataServerLocal;
// Load Player object
// a clone will be created if cloneNum>0
// returns the playerKey if successful.
//
// Don't call this directly. Send a clone message to the NetClientManager instead.
// Load an object, optionally cloning if necessary.
plKey plNetClientMgr::ILoadClone(plLoadCloneMsg *pCloneMsg)
{
plKey cloneKey = pCloneMsg->GetCloneKey();
if(pCloneMsg->GetIsLoading())
{
if (cloneKey->ObjectIsLoaded())
{
char tmp[256];
DebugMsg("ILoadClone: object %s is already loaded, ignoring", cloneKey->GetUoid().StringIze(tmp));
return cloneKey;
}
// check if local or remote player before loading
plLoadAvatarMsg* loadAvMsg=plLoadAvatarMsg::ConvertNoRef(pCloneMsg);
if (loadAvMsg && loadAvMsg->GetIsPlayer())
{
bool originating = ( pCloneMsg->GetOriginatingPlayerID() == this->GetPlayerID() );
if (originating)
fLocalPlayerKey = cloneKey;
else
AddRemotePlayerKey(cloneKey);
}
plKey cloneNodeKey = hsgResMgr::ResMgr()->FindKey(kNetClientCloneRoom_KEY);
// Put the clone into the room, which also forces it to load.
plNodeRefMsg* nodeRefCloneMsg = TRACKED_NEW plNodeRefMsg(cloneNodeKey, plNodeRefMsg::kOnRequest, -1, plNodeRefMsg::kObject);
hsgResMgr::ResMgr()->AddViaNotify(cloneKey, nodeRefCloneMsg, plRefFlags::kActiveRef);
// Finally, pump the dispatch system so all the new refs get delivered. ?
plgDispatch::Dispatch()->MsgQueueProcess();
}
else // we're unloading a clone
{
if (!cloneKey->ObjectIsLoaded())
{
DebugMsg("ILoadClone: object %s is already unloaded, ignoring", cloneKey->GetName());
return cloneKey;
}
ICheckPendingStateLoad(hsTimer::GetSysSeconds());
plSynchEnabler p(false); // turn off dirty tracking while in this function
GetKey()->Release(cloneKey); // undo the active ref we took in ILoadClone
// send message to scene object to remove him from the room
plNodeChangeMsg* nodeChange = TRACKED_NEW plNodeChangeMsg(GetKey(), cloneKey, nil);
plgDispatch::MsgSend(nodeChange);
}
plKey requestorKey = pCloneMsg->GetRequestorKey();
// Readdress the message to the requestor and send it again
plKey myKey = GetKey();
pCloneMsg->SetBCastFlag(plMessage::kNetPropagate, false);
pCloneMsg->ClearReceivers();
pCloneMsg->AddReceiver(requestorKey);
pCloneMsg->Ref(); // each message send unrefs once
pCloneMsg->Send();
return cloneKey;
}
//
// Cause a player to respawn. This is typically called on the local player when he links to a new age.
// or for unspawn:
//
void plNetClientMgr::IPlayerChangeAge(hsBool exitAge, Int32 spawnPt)
{
plArmatureMod *avatar = plAvatarMgr::GetInstance()->GetLocalAvatar();
if (avatar)
{
plSynchEnabler ps(false); // disable state change tracking while we change ages
if (exitAge)
avatar->LeaveAge();
else
{
hsBool validSpawn = (spawnPt >= 0);
avatar->EnterAge(!validSpawn);
if (validSpawn)
avatar->SpawnAt(spawnPt, hsTimer::GetSysSeconds());
}
}
else if (fLocalPlayerKey)
{
ErrorMsg("Can't find avatarMod %s", fLocalPlayerKey->GetName());
}
}
/*==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==*/
#if 1 // for debugging
#include "plCreatableIndex.h"
#include "plModifier/plResponderModifier.h"
#include "plSurface/plLayerAnimation.h"
#endif
#include "hsStream.h"
#include "plNetClientMgr.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
#include "hsTimer.h"
#include "plNetMessage/plNetMessage.h"
#include "pnKeyedObject/plKey.h"
#include "pnKeyedObject/plFixedKey.h"
#include "pnKeyedObject/hsKeyedObject.h"
#include "pnSceneObject/plSceneObject.h"
#include "pnModifier/plModifier.h"
#include "pnMessage/plNodeRefMsg.h"
#include "pnMessage/plClientMsg.h"
#include "pnMessage/plNodeChangeMsg.h"
#include "pnMessage/plPlayerPageMsg.h"
#include "plScene/plSceneNode.h"
#include "plScene/plRelevanceMgr.h"
#include "plNetTransport/plNetTransportMember.h"
#include "plResMgr/plKeyFinder.h"
#include "plAgeDescription/plAgeDescription.h"
#include "plAvatar/plArmatureMod.h"
#include "plAvatar/plAvatarMgr.h"
#include "plSDL/plSDL.h"
/// TEMP HACK TO LOAD CONSOLE INIT FILES ON AGE LOAD
#include "plMessage/plConsoleMsg.h"
#include "plMessage/plLoadAvatarMsg.h"
#include "plMessage/plAgeLoadedMsg.h"
#include "plAgeLoader/plResPatcher.h"
#include "plProgressMgr/plProgressMgr.h"
#include "plResMgr/plRegistryHelpers.h"
#include "plResMgr/plRegistryNode.h"
#include "plResMgr/plResManager.h"
#ifdef _MSC_VER
#include <process.h> // for getpid()
#else
#include <sys/types.h>
#include <unistd.h>
#endif
extern hsBool gDataServerLocal;
// Load Player object
// a clone will be created if cloneNum>0
// returns the playerKey if successful.
//
// Don't call this directly. Send a clone message to the NetClientManager instead.
// Load an object, optionally cloning if necessary.
plKey plNetClientMgr::ILoadClone(plLoadCloneMsg *pCloneMsg)
{
plKey cloneKey = pCloneMsg->GetCloneKey();
if(pCloneMsg->GetIsLoading())
{
if (cloneKey->ObjectIsLoaded())
{
char tmp[256];
DebugMsg("ILoadClone: object %s is already loaded, ignoring", cloneKey->GetUoid().StringIze(tmp));
return cloneKey;
}
// check if local or remote player before loading
plLoadAvatarMsg* loadAvMsg=plLoadAvatarMsg::ConvertNoRef(pCloneMsg);
if (loadAvMsg && loadAvMsg->GetIsPlayer())
{
bool originating = ( pCloneMsg->GetOriginatingPlayerID() == this->GetPlayerID() );
if (originating)
fLocalPlayerKey = cloneKey;
else
AddRemotePlayerKey(cloneKey);
}
plKey cloneNodeKey = hsgResMgr::ResMgr()->FindKey(kNetClientCloneRoom_KEY);
// Put the clone into the room, which also forces it to load.
plNodeRefMsg* nodeRefCloneMsg = TRACKED_NEW plNodeRefMsg(cloneNodeKey, plNodeRefMsg::kOnRequest, -1, plNodeRefMsg::kObject);
hsgResMgr::ResMgr()->AddViaNotify(cloneKey, nodeRefCloneMsg, plRefFlags::kActiveRef);
// Finally, pump the dispatch system so all the new refs get delivered. ?
plgDispatch::Dispatch()->MsgQueueProcess();
}
else // we're unloading a clone
{
if (!cloneKey->ObjectIsLoaded())
{
DebugMsg("ILoadClone: object %s is already unloaded, ignoring", cloneKey->GetName());
return cloneKey;
}
ICheckPendingStateLoad(hsTimer::GetSysSeconds());
plSynchEnabler p(false); // turn off dirty tracking while in this function
GetKey()->Release(cloneKey); // undo the active ref we took in ILoadClone
// send message to scene object to remove him from the room
plNodeChangeMsg* nodeChange = TRACKED_NEW plNodeChangeMsg(GetKey(), cloneKey, nil);
plgDispatch::MsgSend(nodeChange);
}
plKey requestorKey = pCloneMsg->GetRequestorKey();
// Readdress the message to the requestor and send it again
plKey myKey = GetKey();
pCloneMsg->SetBCastFlag(plMessage::kNetPropagate, false);
pCloneMsg->ClearReceivers();
pCloneMsg->AddReceiver(requestorKey);
pCloneMsg->Ref(); // each message send unrefs once
pCloneMsg->Send();
return cloneKey;
}
//
// Cause a player to respawn. This is typically called on the local player when he links to a new age.
// or for unspawn:
//
void plNetClientMgr::IPlayerChangeAge(hsBool exitAge, Int32 spawnPt)
{
plArmatureMod *avatar = plAvatarMgr::GetInstance()->GetLocalAvatar();
if (avatar)
{
plSynchEnabler ps(false); // disable state change tracking while we change ages
if (exitAge)
avatar->LeaveAge();
else
{
hsBool validSpawn = (spawnPt >= 0);
avatar->EnterAge(!validSpawn);
if (validSpawn)
avatar->SpawnAt(spawnPt, hsTimer::GetSysSeconds());
}
}
else if (fLocalPlayerKey)
{
ErrorMsg("Can't find avatarMod %s", fLocalPlayerKey->GetName());
}
}

View File

@ -1,117 +1,117 @@
/*==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==*/
#include "plgDispatch.h"
#include "plNetClientMgr.h"
#include "pnNetCommon/pnNetCommon.h"
#include "pnMessage/plTimeMsg.h"
#include "plNetClientRecorder/plNetClientRecorder.h"
//
// make a recording of current play
//
bool plNetClientMgr::RecordMsgs(const char* recType, const char* recName)
{
if (!fMsgRecorder)
{
if (stricmp(recType,"stream") == 0)
fMsgRecorder = TRACKED_NEW plNetClientStreamRecorder;
if (stricmp(recType,"stressstream") == 0)
fMsgRecorder = TRACKED_NEW plNetClientStressStreamRecorder;
if (stricmp(recType,"stats") == 0)
fMsgRecorder = TRACKED_NEW plNetClientStatsRecorder;
if (stricmp(recType,"streamandstats") == 0)
fMsgRecorder = TRACKED_NEW plNetClientStreamAndStatsRecorder(TRACKED_NEW plNetClientStreamRecorder(), TRACKED_NEW plNetClientStatsRecorder());
if (stricmp(recType,"stressstreamandstats") == 0)
fMsgRecorder = TRACKED_NEW plNetClientStreamAndStatsRecorder(TRACKED_NEW plNetClientStressStreamRecorder(), TRACKED_NEW plNetClientStatsRecorder());
if (!fMsgRecorder || !fMsgRecorder->BeginRecording(recName))
{
delete fMsgRecorder;
fMsgRecorder = nil;
return false;
}
return true;
}
return false;
}
//
// play a recording
//
bool plNetClientMgr::PlaybackMsgs(const char* recName)
{
hsLogEntry(DebugMsg("DEMO: Beginning Playback"));
plNetClientRecorder* player = TRACKED_NEW plNetClientStreamRecorder;
if (player->BeginPlayback(recName))
{
fMsgPlayers.push_back(player);
// plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey());
return true;
}
else
{
delete player;
return false;
}
}
//
//
//
void plNetClientMgr::IPlaybackMsgs()
{
for (int i = 0; i < fMsgPlayers.size(); i++)
{
plNetClientRecorder* recorder = fMsgPlayers[i];
if (recorder->IsQueueEmpty())
{
delete recorder;
fMsgPlayers.erase(fMsgPlayers.begin()+i);
i--;
if (fMsgPlayers.empty())
{
// plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
}
}
else
{
while (plNetMessage* msg = recorder->GetNextMessage())
{
hsLogEntry(DebugMsg("<Recorded Msg>"));
fMsgHandler.ReceiveMsg(msg);
}
}
}
}
/*==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==*/
#include "plgDispatch.h"
#include "plNetClientMgr.h"
#include "pnNetCommon/pnNetCommon.h"
#include "pnMessage/plTimeMsg.h"
#include "plNetClientRecorder/plNetClientRecorder.h"
//
// make a recording of current play
//
bool plNetClientMgr::RecordMsgs(const char* recType, const char* recName)
{
if (!fMsgRecorder)
{
if (stricmp(recType,"stream") == 0)
fMsgRecorder = TRACKED_NEW plNetClientStreamRecorder;
if (stricmp(recType,"stressstream") == 0)
fMsgRecorder = TRACKED_NEW plNetClientStressStreamRecorder;
if (stricmp(recType,"stats") == 0)
fMsgRecorder = TRACKED_NEW plNetClientStatsRecorder;
if (stricmp(recType,"streamandstats") == 0)
fMsgRecorder = TRACKED_NEW plNetClientStreamAndStatsRecorder(TRACKED_NEW plNetClientStreamRecorder(), TRACKED_NEW plNetClientStatsRecorder());
if (stricmp(recType,"stressstreamandstats") == 0)
fMsgRecorder = TRACKED_NEW plNetClientStreamAndStatsRecorder(TRACKED_NEW plNetClientStressStreamRecorder(), TRACKED_NEW plNetClientStatsRecorder());
if (!fMsgRecorder || !fMsgRecorder->BeginRecording(recName))
{
delete fMsgRecorder;
fMsgRecorder = nil;
return false;
}
return true;
}
return false;
}
//
// play a recording
//
bool plNetClientMgr::PlaybackMsgs(const char* recName)
{
hsLogEntry(DebugMsg("DEMO: Beginning Playback"));
plNetClientRecorder* player = TRACKED_NEW plNetClientStreamRecorder;
if (player->BeginPlayback(recName))
{
fMsgPlayers.push_back(player);
// plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey());
return true;
}
else
{
delete player;
return false;
}
}
//
//
//
void plNetClientMgr::IPlaybackMsgs()
{
for (int i = 0; i < fMsgPlayers.size(); i++)
{
plNetClientRecorder* recorder = fMsgPlayers[i];
if (recorder->IsQueueEmpty())
{
delete recorder;
fMsgPlayers.erase(fMsgPlayers.begin()+i);
i--;
if (fMsgPlayers.empty())
{
// plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
}
}
else
{
while (plNetMessage* msg = recorder->GetNextMessage())
{
hsLogEntry(DebugMsg("<Recorded Msg>"));
fMsgHandler.ReceiveMsg(msg);
}
}
}
}

View File

@ -1,460 +1,460 @@
/*==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==*/
#include "hsTimer.h"
#include "hsResMgr.h"
#include "plNetClientMgr.h"
#include "plCreatableIndex.h"
#include "plNetObjectDebugger.h"
#include "plNetClientMsgScreener.h"
#include "pnNetCommon/plSynchedObject.h"
#include "pnNetCommon/plSDLTypes.h"
#include "pnMessage/plCameraMsg.h"
#include "plNetClientRecorder/plNetClientRecorder.h"
#include "plMessage/plLoadCloneMsg.h"
#include "plMessage/plLoadAvatarMsg.h"
#include "plAvatar/plAvatarClothing.h"
#include "plAvatar/plArmatureMod.h"
#include "plAvatar/plAvatarMgr.h"
#include "plNetMessage/plNetMessage.h"
#include "plMessage/plCCRMsg.h"
#include "plVault/plVault.h"
#include "plContainer/plConfigInfo.h"
#include "plDrawable/plMorphSequence.h"
#include "plParticleSystem/plParticleSystem.h"
#include "plParticleSystem/plParticleSDLMod.h"
#include "plResMgr/plLocalization.h"
#include "pfMessage/pfKIMsg.h" // TMP
#include "plNetGameLib/plNetGameLib.h"
#include "plSDL/plSDL.h"
//
// request members list from server
//
int plNetClientMgr::ISendMembersListRequest()
{
plNetMsgMembersListReq msg;
msg.SetNetProtocol(kNetProtocolCli2Game);
return SendMsg(&msg);
}
//
// reset paged in rooms list on server
//
int plNetClientMgr::ISendRoomsReset()
{
plNetMsgPagingRoom msg;
msg.SetPageFlags(plNetMsgPagingRoom::kResetList);
msg.SetNetProtocol(kNetProtocolCli2Game);
return SendMsg(&msg);
}
//
// Make sure all dirty objects save their state.
// Mark those objects as clean and clear the dirty list.
//
int plNetClientMgr::ISendDirtyState(double secs)
{
std::vector<plSynchedObject::StateDefn> carryOvers;
Int32 num=plSynchedObject::GetNumDirtyStates();
#if 0
if (num)
{
DebugMsg("%d dirty sdl state msgs queued, t=%f", num, secs);
}
#endif
Int32 i;
for(i=0;i<num;i++)
{
plSynchedObject::StateDefn* state=plSynchedObject::GetDirtyState(i);
plSynchedObject* obj=state->GetObject();
if (!obj)
continue; // could add to carryOvers
if (!(state->fSendFlags & plSynchedObject::kSkipLocalOwnershipCheck))
{
int localOwned=obj->IsLocallyOwned();
if (localOwned==plSynchedObject::kNo)
{
DebugMsg("Late rejection of queued SDL state, obj %s, sdl %s",
state->fObjKey->GetName(), state->fSDLName.c_str());
continue;
}
}
obj->CallDirtyNotifiers();
obj->SendSDLStateMsg(state->fSDLName.c_str(), state->fSendFlags);
}
plSynchedObject::ClearDirtyState(carryOvers);
return hsOK;
}
//
// Given a plasma petition msg, send a petition text node to the vault
// vault will detect and fwd to CCR system.
//
void plNetClientMgr::ISendCCRPetition(plCCRPetitionMsg* petMsg)
{
// petition msg info
UInt8 type = petMsg->GetType();
const char* title = petMsg->GetTitle();
const char* note = petMsg->GetNote();
std::string work = note;
std::replace( work.begin(), work.end(), '\n', '\t' );
note = work.c_str();
// stuff petition info fields into a config info object
plConfigInfo info;
info.AddValue( "Petition", "Type", type );
info.AddValue( "Petition", "Content", note );
info.AddValue( "Petition", "Title", title );
info.AddValue( "Petition", "Language", plLocalization::GetLanguageName( plLocalization::GetLanguage() ) );
info.AddValue( "Petition", "AcctName", NetCommGetAccount()->accountNameAnsi );
char buffy[20];
sprintf( buffy, "%lu", GetPlayerID() );
info.AddValue( "Petition", "PlayerID", buffy );
info.AddValue( "Petition", "PlayerName", GetPlayerName() );
// write config info formatted like an ini file to a buffer
hsRAMStream ram;
info.WriteTo( &plIniStreamConfigSource( &ram ) );
int size = ram.GetPosition();
ram.Rewind();
std::string buf;
buf.resize( size );
ram.CopyToMem( (void*)buf.data() );
wchar * wStr = StrDupToUnicode(buf.c_str());
NetCliAuthSendCCRPetition(wStr);
FREE(wStr);
}
//
// send a msg to reset the camera in a new age
//
void plNetClientMgr::ISendCameraReset(hsBool bEnteringAge)
{
plCameraMsg* pCamMsg = TRACKED_NEW plCameraMsg;
if (bEnteringAge)
pCamMsg->SetCmd(plCameraMsg::kResetOnEnter);
else
pCamMsg->SetCmd(plCameraMsg::kResetOnExit);
pCamMsg->SetBCastFlag(plMessage::kBCastByExactType, false);
plUoid U2(kVirtualCamera1_KEY);
plKey pCamKey = hsgResMgr::ResMgr()->FindKey(U2);
if (pCamKey)
pCamMsg->AddReceiver(pCamKey);
pCamMsg->Send();
}
//
// When we link in to a new age, we need to send our avatar state up to the gameserver
//
void plNetClientMgr::SendLocalPlayerAvatarCustomizations()
{
plSynchEnabler ps(true); // make sure synching is enabled, since this happens during load
const plArmatureMod * avMod = plAvatarMgr::GetInstance()->GetLocalAvatar();
hsAssert(avMod,"Failed to get local avatar armature modifier.");
avMod->GetClothingOutfit()->DirtySynchState(kSDLClothing, plSynchedObject::kBCastToClients | plSynchedObject::kForceFullSend);
plSceneObject* pObj = (const_cast<plArmatureMod*>(avMod))->GetFollowerParticleSystemSO();
if (pObj)
{
const plParticleSystem* sys = plParticleSystem::ConvertNoRef(pObj->GetModifierByType(plParticleSystem::Index()));
if (sys)
(const_cast<plParticleSystem*>(sys))->GetSDLMod()->SendState(plSynchedObject::kBCastToClients | plSynchedObject::kForceFullSend);
}
// may want to do this all the time, but for now stealthmode is the only extra avatar state we care about
// don't bcast this to other clients, the invis level is contained in the linkIn msg which will synch other clients
if (avMod->IsInStealthMode() && avMod->GetTarget(0))
avMod->GetTarget(0)->DirtySynchState(kSDLAvatar, plSynchedObject::kForceFullSend);
hsTArray<const plMorphSequence*> morphs;
plMorphSequence::FindMorphMods(avMod->GetTarget(0), morphs);
int i;
for (i = 0; i < morphs.GetCount(); i++)
if (morphs[i]->GetTarget(0))
morphs[i]->GetTarget(0)->DirtySynchState(kSDLMorphSequence, plSynchedObject::kBCastToClients);
}
//
// Called to send a plasma msg out over the network. Called by the dispatcher.
// return hsOK if ok
//
int plNetClientMgr::ISendGameMessage(plMessage* msg)
{
if (GetFlagsBit(kDisabled))
return hsOK;
static plNetClientMsgScreener screener; // make static so that there's only 1 log per session
if (!screener.AllowMessage(msg))
{
if (GetFlagsBit(kScreenMessages))
return hsOK; // filter out illegal messages
}
// TEMP
if (GetFlagsBit(kSilencePlayer))
{
pfKIMsg* kiMsg = pfKIMsg::ConvertNoRef(msg);
if (kiMsg && kiMsg->GetCommand()==pfKIMsg::kHACKChatMsg)
return hsOK;
}
plNetPlayerIDList* dstIDs = msg->GetNetReceivers();
#ifdef HS_DEBUGGING
if ( dstIDs )
{
DebugMsg( "Preparing to send %s to specific players.", msg->ClassName() );
}
#endif
// get sender object
plSynchedObject* synchedObj = msg->GetSender() ? plSynchedObject::ConvertNoRef(msg->GetSender()->ObjectIsLoaded()) : nil;
// if sender is flagged as localOnly, he shouldn't talk to the network
if (synchedObj && !synchedObj->IsNetSynched() )
return hsOK;
// choose appropriate type of net game msg wrapper
plNetMsgGameMessage* netMsgWrap=nil;
plLoadCloneMsg* loadClone = plLoadCloneMsg::ConvertNoRef(msg);
if (loadClone)
{
plLoadAvatarMsg* lam=plLoadAvatarMsg::ConvertNoRef(msg);
netMsgWrap = TRACKED_NEW plNetMsgLoadClone;
plNetMsgLoadClone* netLoadClone=plNetMsgLoadClone::ConvertNoRef(netMsgWrap);
netLoadClone->SetIsPlayer(lam && lam->GetIsPlayer());
netLoadClone->SetIsLoading(loadClone->GetIsLoading()!=0);
netLoadClone->ObjectInfo()->SetFromKey(loadClone->GetCloneKey());
}
else
if (dstIDs)
{
netMsgWrap = TRACKED_NEW plNetMsgGameMessageDirected;
int i;
for(i=0;i<dstIDs->size();i++)
{
UInt32 playerID = (*dstIDs)[i];
if (playerID == NetCommGetPlayer()->playerInt)
continue;
hsLogEntry( DebugMsg( "\tAdding receiver: %lu" , playerID ) );
((plNetMsgGameMessageDirected*)netMsgWrap)->Receivers()->AddReceiverPlayerID( playerID );
}
}
else
netMsgWrap = TRACKED_NEW plNetMsgGameMessage;
// check delivery timestamp
if (msg->GetTimeStamp()<=hsTimer::GetSysSeconds())
msg->SetTimeStamp(0);
else
netMsgWrap->GetDeliveryTime().SetFromGameTime(msg->GetTimeStamp(), hsTimer::GetSysSeconds());
// write message (and label) to ram stream
hsRAMStream stream;
hsgResMgr::ResMgr()->WriteCreatable(&stream, msg);
// put stream in net msg wrapper
netMsgWrap->StreamInfo()->CopyStream(&stream);
// hsLogEntry( DebugMsg(plDispatchLog::GetInstance()->MakeMsgInfoString(msg, "\tActionMsg:",0)) );
// check if this msg uses direct communication (sent to specific rcvrs)
// if so the server can filter it
hsBool bCast = msg->HasBCastFlag(plMessage::kBCastByExactType) ||
msg->HasBCastFlag(plMessage::kBCastByType);
hsBool directCom = msg->GetNumReceivers()>0;
if( directCom )
{
// It's direct if we have receivers AND any of them are in non-virtual locations
int i;
for( i = 0, directCom = false; i < msg->GetNumReceivers(); i++ )
{
if( !msg->GetReceiver( i )->GetUoid().GetLocation().IsVirtual() &&
!msg->GetReceiver( i )->GetUoid().GetLocation().IsReserved()
// && !IsBuiltIn
)
{
directCom = true;
break;
}
}
if (!directCom)
bCast = true;
}
if (!directCom && !bCast && !dstIDs)
WarningMsg("Msg %s has no rcvrs or bcast instructions?", msg->ClassName());
hsAssert(!(directCom && bCast), "msg has both rcvrs and bcast instructions, rcvrs ignored");
if (directCom && !bCast)
{
netMsgWrap->SetBit(plNetMessage::kHasGameMsgRcvrs); // for quick server filtering
netMsgWrap->StreamInfo()->SetCompressionType(plNetMessage::kCompressionDont);
}
//
// check for net propagated plasma msgs which should be filtered by relevance regions.
// currently only avatar control messages.
//
if (msg->HasBCastFlag(plMessage::kNetUseRelevanceRegions))
{
netMsgWrap->SetBit(plNetMessage::kUseRelevanceRegions);
}
//
// CCRs can route a plMessage to all online players.
//
hsBool ccrSendToAllPlayers = false;
#ifndef PLASMA_EXTERNAL_RELEASE
if ( AmCCR() )
{
ccrSendToAllPlayers = msg->HasBCastFlag( plMessage::kCCRSendToAllPlayers );
if ( ccrSendToAllPlayers )
netMsgWrap->SetBit( plNetMessage::kRouteToAllPlayers );
}
#endif
//
// check for inter-age routing. if set, online rcvrs not in current age will receive
// this msg courtesy of pls routing.
//
if ( !ccrSendToAllPlayers )
{
hsBool allowInterAge = msg->HasBCastFlag( plMessage::kNetAllowInterAge );
if ( allowInterAge )
netMsgWrap->SetBit(plNetMessage::kInterAgeRouting);
}
// check for reliable send
if (msg->HasBCastFlag(plMessage::kNetSendUnreliable) &&
!(synchedObj && (synchedObj->GetSynchFlags() & plSynchedObject::kSendReliably)) )
netMsgWrap->SetBit(plNetMessage::kNeedsReliableSend, 0); // clear reliable net send bit
#ifdef HS_DEBUGGING
Int16 type=*(Int16*)netMsgWrap->StreamInfo()->GetStreamBuf();
hsAssert(type>=0 && type<plCreatableIndex::plNumClassIndices, "garbage type out");
#endif
netMsgWrap->SetPlayerID(GetPlayerID());
netMsgWrap->SetNetProtocol(kNetProtocolCli2Game);
int ret = SendMsg(netMsgWrap);
if (plNetObjectDebugger::GetInstance()->IsDebugObject(msg->GetSender() ? msg->GetSender()->ObjectIsLoaded() : nil))
{
#if 0
hsLogEntry(plNetObjectDebugger::GetInstance()->LogMsg(
xtl::format("<SND> object:%s, rcvr %s %s",
msg->GetSender(),
msg->GetNumReceivers() ? msg->GetReceiver(0)->GetName() : "?",
netMsgWrap->AsStdString().c_str()).c_str()));
#endif
}
delete netMsgWrap;
return ret;
}
//
// Send a net msg. Delivers to transport mgr who sends p2p or to server
//
int plNetClientMgr::SendMsg(plNetMessage* msg)
{
if (GetFlagsBit(kDisabled))
return hsOK;
if (!CanSendMsg(msg))
return hsOK;
// If we're recording messages, set an identifying flag and echo the message back to ourselves
if (fMsgRecorder && fMsgRecorder->IsRecordableMsg(msg))
{
msg->SetBit(plNetMessage::kEchoBackToSender, true);
}
msg->SetTimeSent(plUnifiedTime::GetCurrentTime());
int channel = IPrepMsg(msg);
// hsLogEntry( DebugMsg( "<SND> %s %s", msg->ClassName(), msg->AsStdString().c_str()) );
int ret=fTransport.SendMsg(channel, msg);
// Debug
if (plNetMsgVoice::ConvertNoRef(msg))
SetFlagsBit(kSendingVoice);
if (plNetMsgGameMessage::ConvertNoRef(msg))
SetFlagsBit(kSendingActions);
plCheckNetMgrResult_ValReturn(ret,(char*)xtl::format("Failed to send %s, NC ret=%d",
msg->ClassName(), ret).c_str());
return ret;
}
void plNetClientMgr::StoreSDLState(const plStateDataRecord* sdRec, const plUoid& uoid,
UInt32 sendFlags, UInt32 writeOptions)
{
// send to server
plNetMsgSDLState* msg = sdRec->PrepNetMsg(0, writeOptions);
msg->SetNetProtocol(kNetProtocolCli2Game);
msg->ObjectInfo()->SetUoid(uoid);
if (sendFlags & plSynchedObject::kNewState)
msg->SetBit(plNetMessage::kNewSDLState);
if (sendFlags & plSynchedObject::kUseRelevanceRegions)
msg->SetBit(plNetMessage::kUseRelevanceRegions);
if (sendFlags & plSynchedObject::kDontPersistOnServer)
msg->SetPersistOnServer(false);
if (sendFlags & plSynchedObject::kIsAvatarState)
msg->SetIsAvatarState(true);
bool broadcast = (sendFlags & plSynchedObject::kBCastToClients) != 0;
if (broadcast && plNetClientApp::GetInstance())
{
msg->SetPlayerID(plNetClientApp::GetInstance()->GetPlayerID());
}
SendMsg(msg);
DEL(msg);
}
/*==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==*/
#include "hsTimer.h"
#include "hsResMgr.h"
#include "plNetClientMgr.h"
#include "plCreatableIndex.h"
#include "plNetObjectDebugger.h"
#include "plNetClientMsgScreener.h"
#include "pnNetCommon/plSynchedObject.h"
#include "pnNetCommon/plSDLTypes.h"
#include "pnMessage/plCameraMsg.h"
#include "plNetClientRecorder/plNetClientRecorder.h"
#include "plMessage/plLoadCloneMsg.h"
#include "plMessage/plLoadAvatarMsg.h"
#include "plAvatar/plAvatarClothing.h"
#include "plAvatar/plArmatureMod.h"
#include "plAvatar/plAvatarMgr.h"
#include "plNetMessage/plNetMessage.h"
#include "plMessage/plCCRMsg.h"
#include "plVault/plVault.h"
#include "plContainer/plConfigInfo.h"
#include "plDrawable/plMorphSequence.h"
#include "plParticleSystem/plParticleSystem.h"
#include "plParticleSystem/plParticleSDLMod.h"
#include "plResMgr/plLocalization.h"
#include "pfMessage/pfKIMsg.h" // TMP
#include "plNetGameLib/plNetGameLib.h"
#include "plSDL/plSDL.h"
//
// request members list from server
//
int plNetClientMgr::ISendMembersListRequest()
{
plNetMsgMembersListReq msg;
msg.SetNetProtocol(kNetProtocolCli2Game);
return SendMsg(&msg);
}
//
// reset paged in rooms list on server
//
int plNetClientMgr::ISendRoomsReset()
{
plNetMsgPagingRoom msg;
msg.SetPageFlags(plNetMsgPagingRoom::kResetList);
msg.SetNetProtocol(kNetProtocolCli2Game);
return SendMsg(&msg);
}
//
// Make sure all dirty objects save their state.
// Mark those objects as clean and clear the dirty list.
//
int plNetClientMgr::ISendDirtyState(double secs)
{
std::vector<plSynchedObject::StateDefn> carryOvers;
Int32 num=plSynchedObject::GetNumDirtyStates();
#if 0
if (num)
{
DebugMsg("%d dirty sdl state msgs queued, t=%f", num, secs);
}
#endif
Int32 i;
for(i=0;i<num;i++)
{
plSynchedObject::StateDefn* state=plSynchedObject::GetDirtyState(i);
plSynchedObject* obj=state->GetObject();
if (!obj)
continue; // could add to carryOvers
if (!(state->fSendFlags & plSynchedObject::kSkipLocalOwnershipCheck))
{
int localOwned=obj->IsLocallyOwned();
if (localOwned==plSynchedObject::kNo)
{
DebugMsg("Late rejection of queued SDL state, obj %s, sdl %s",
state->fObjKey->GetName(), state->fSDLName.c_str());
continue;
}
}
obj->CallDirtyNotifiers();
obj->SendSDLStateMsg(state->fSDLName.c_str(), state->fSendFlags);
}
plSynchedObject::ClearDirtyState(carryOvers);
return hsOK;
}
//
// Given a plasma petition msg, send a petition text node to the vault
// vault will detect and fwd to CCR system.
//
void plNetClientMgr::ISendCCRPetition(plCCRPetitionMsg* petMsg)
{
// petition msg info
UInt8 type = petMsg->GetType();
const char* title = petMsg->GetTitle();
const char* note = petMsg->GetNote();
std::string work = note;
std::replace( work.begin(), work.end(), '\n', '\t' );
note = work.c_str();
// stuff petition info fields into a config info object
plConfigInfo info;
info.AddValue( "Petition", "Type", type );
info.AddValue( "Petition", "Content", note );
info.AddValue( "Petition", "Title", title );
info.AddValue( "Petition", "Language", plLocalization::GetLanguageName( plLocalization::GetLanguage() ) );
info.AddValue( "Petition", "AcctName", NetCommGetAccount()->accountNameAnsi );
char buffy[20];
sprintf( buffy, "%lu", GetPlayerID() );
info.AddValue( "Petition", "PlayerID", buffy );
info.AddValue( "Petition", "PlayerName", GetPlayerName() );
// write config info formatted like an ini file to a buffer
hsRAMStream ram;
info.WriteTo( &plIniStreamConfigSource( &ram ) );
int size = ram.GetPosition();
ram.Rewind();
std::string buf;
buf.resize( size );
ram.CopyToMem( (void*)buf.data() );
wchar * wStr = StrDupToUnicode(buf.c_str());
NetCliAuthSendCCRPetition(wStr);
FREE(wStr);
}
//
// send a msg to reset the camera in a new age
//
void plNetClientMgr::ISendCameraReset(hsBool bEnteringAge)
{
plCameraMsg* pCamMsg = TRACKED_NEW plCameraMsg;
if (bEnteringAge)
pCamMsg->SetCmd(plCameraMsg::kResetOnEnter);
else
pCamMsg->SetCmd(plCameraMsg::kResetOnExit);
pCamMsg->SetBCastFlag(plMessage::kBCastByExactType, false);
plUoid U2(kVirtualCamera1_KEY);
plKey pCamKey = hsgResMgr::ResMgr()->FindKey(U2);
if (pCamKey)
pCamMsg->AddReceiver(pCamKey);
pCamMsg->Send();
}
//
// When we link in to a new age, we need to send our avatar state up to the gameserver
//
void plNetClientMgr::SendLocalPlayerAvatarCustomizations()
{
plSynchEnabler ps(true); // make sure synching is enabled, since this happens during load
const plArmatureMod * avMod = plAvatarMgr::GetInstance()->GetLocalAvatar();
hsAssert(avMod,"Failed to get local avatar armature modifier.");
avMod->GetClothingOutfit()->DirtySynchState(kSDLClothing, plSynchedObject::kBCastToClients | plSynchedObject::kForceFullSend);
plSceneObject* pObj = (const_cast<plArmatureMod*>(avMod))->GetFollowerParticleSystemSO();
if (pObj)
{
const plParticleSystem* sys = plParticleSystem::ConvertNoRef(pObj->GetModifierByType(plParticleSystem::Index()));
if (sys)
(const_cast<plParticleSystem*>(sys))->GetSDLMod()->SendState(plSynchedObject::kBCastToClients | plSynchedObject::kForceFullSend);
}
// may want to do this all the time, but for now stealthmode is the only extra avatar state we care about
// don't bcast this to other clients, the invis level is contained in the linkIn msg which will synch other clients
if (avMod->IsInStealthMode() && avMod->GetTarget(0))
avMod->GetTarget(0)->DirtySynchState(kSDLAvatar, plSynchedObject::kForceFullSend);
hsTArray<const plMorphSequence*> morphs;
plMorphSequence::FindMorphMods(avMod->GetTarget(0), morphs);
int i;
for (i = 0; i < morphs.GetCount(); i++)
if (morphs[i]->GetTarget(0))
morphs[i]->GetTarget(0)->DirtySynchState(kSDLMorphSequence, plSynchedObject::kBCastToClients);
}
//
// Called to send a plasma msg out over the network. Called by the dispatcher.
// return hsOK if ok
//
int plNetClientMgr::ISendGameMessage(plMessage* msg)
{
if (GetFlagsBit(kDisabled))
return hsOK;
static plNetClientMsgScreener screener; // make static so that there's only 1 log per session
if (!screener.AllowMessage(msg))
{
if (GetFlagsBit(kScreenMessages))
return hsOK; // filter out illegal messages
}
// TEMP
if (GetFlagsBit(kSilencePlayer))
{
pfKIMsg* kiMsg = pfKIMsg::ConvertNoRef(msg);
if (kiMsg && kiMsg->GetCommand()==pfKIMsg::kHACKChatMsg)
return hsOK;
}
plNetPlayerIDList* dstIDs = msg->GetNetReceivers();
#ifdef HS_DEBUGGING
if ( dstIDs )
{
DebugMsg( "Preparing to send %s to specific players.", msg->ClassName() );
}
#endif
// get sender object
plSynchedObject* synchedObj = msg->GetSender() ? plSynchedObject::ConvertNoRef(msg->GetSender()->ObjectIsLoaded()) : nil;
// if sender is flagged as localOnly, he shouldn't talk to the network
if (synchedObj && !synchedObj->IsNetSynched() )
return hsOK;
// choose appropriate type of net game msg wrapper
plNetMsgGameMessage* netMsgWrap=nil;
plLoadCloneMsg* loadClone = plLoadCloneMsg::ConvertNoRef(msg);
if (loadClone)
{
plLoadAvatarMsg* lam=plLoadAvatarMsg::ConvertNoRef(msg);
netMsgWrap = TRACKED_NEW plNetMsgLoadClone;
plNetMsgLoadClone* netLoadClone=plNetMsgLoadClone::ConvertNoRef(netMsgWrap);
netLoadClone->SetIsPlayer(lam && lam->GetIsPlayer());
netLoadClone->SetIsLoading(loadClone->GetIsLoading()!=0);
netLoadClone->ObjectInfo()->SetFromKey(loadClone->GetCloneKey());
}
else
if (dstIDs)
{
netMsgWrap = TRACKED_NEW plNetMsgGameMessageDirected;
int i;
for(i=0;i<dstIDs->size();i++)
{
UInt32 playerID = (*dstIDs)[i];
if (playerID == NetCommGetPlayer()->playerInt)
continue;
hsLogEntry( DebugMsg( "\tAdding receiver: %lu" , playerID ) );
((plNetMsgGameMessageDirected*)netMsgWrap)->Receivers()->AddReceiverPlayerID( playerID );
}
}
else
netMsgWrap = TRACKED_NEW plNetMsgGameMessage;
// check delivery timestamp
if (msg->GetTimeStamp()<=hsTimer::GetSysSeconds())
msg->SetTimeStamp(0);
else
netMsgWrap->GetDeliveryTime().SetFromGameTime(msg->GetTimeStamp(), hsTimer::GetSysSeconds());
// write message (and label) to ram stream
hsRAMStream stream;
hsgResMgr::ResMgr()->WriteCreatable(&stream, msg);
// put stream in net msg wrapper
netMsgWrap->StreamInfo()->CopyStream(&stream);
// hsLogEntry( DebugMsg(plDispatchLog::GetInstance()->MakeMsgInfoString(msg, "\tActionMsg:",0)) );
// check if this msg uses direct communication (sent to specific rcvrs)
// if so the server can filter it
hsBool bCast = msg->HasBCastFlag(plMessage::kBCastByExactType) ||
msg->HasBCastFlag(plMessage::kBCastByType);
hsBool directCom = msg->GetNumReceivers()>0;
if( directCom )
{
// It's direct if we have receivers AND any of them are in non-virtual locations
int i;
for( i = 0, directCom = false; i < msg->GetNumReceivers(); i++ )
{
if( !msg->GetReceiver( i )->GetUoid().GetLocation().IsVirtual() &&
!msg->GetReceiver( i )->GetUoid().GetLocation().IsReserved()
// && !IsBuiltIn
)
{
directCom = true;
break;
}
}
if (!directCom)
bCast = true;
}
if (!directCom && !bCast && !dstIDs)
WarningMsg("Msg %s has no rcvrs or bcast instructions?", msg->ClassName());
hsAssert(!(directCom && bCast), "msg has both rcvrs and bcast instructions, rcvrs ignored");
if (directCom && !bCast)
{
netMsgWrap->SetBit(plNetMessage::kHasGameMsgRcvrs); // for quick server filtering
netMsgWrap->StreamInfo()->SetCompressionType(plNetMessage::kCompressionDont);
}
//
// check for net propagated plasma msgs which should be filtered by relevance regions.
// currently only avatar control messages.
//
if (msg->HasBCastFlag(plMessage::kNetUseRelevanceRegions))
{
netMsgWrap->SetBit(plNetMessage::kUseRelevanceRegions);
}
//
// CCRs can route a plMessage to all online players.
//
hsBool ccrSendToAllPlayers = false;
#ifndef PLASMA_EXTERNAL_RELEASE
if ( AmCCR() )
{
ccrSendToAllPlayers = msg->HasBCastFlag( plMessage::kCCRSendToAllPlayers );
if ( ccrSendToAllPlayers )
netMsgWrap->SetBit( plNetMessage::kRouteToAllPlayers );
}
#endif
//
// check for inter-age routing. if set, online rcvrs not in current age will receive
// this msg courtesy of pls routing.
//
if ( !ccrSendToAllPlayers )
{
hsBool allowInterAge = msg->HasBCastFlag( plMessage::kNetAllowInterAge );
if ( allowInterAge )
netMsgWrap->SetBit(plNetMessage::kInterAgeRouting);
}
// check for reliable send
if (msg->HasBCastFlag(plMessage::kNetSendUnreliable) &&
!(synchedObj && (synchedObj->GetSynchFlags() & plSynchedObject::kSendReliably)) )
netMsgWrap->SetBit(plNetMessage::kNeedsReliableSend, 0); // clear reliable net send bit
#ifdef HS_DEBUGGING
Int16 type=*(Int16*)netMsgWrap->StreamInfo()->GetStreamBuf();
hsAssert(type>=0 && type<plCreatableIndex::plNumClassIndices, "garbage type out");
#endif
netMsgWrap->SetPlayerID(GetPlayerID());
netMsgWrap->SetNetProtocol(kNetProtocolCli2Game);
int ret = SendMsg(netMsgWrap);
if (plNetObjectDebugger::GetInstance()->IsDebugObject(msg->GetSender() ? msg->GetSender()->ObjectIsLoaded() : nil))
{
#if 0
hsLogEntry(plNetObjectDebugger::GetInstance()->LogMsg(
xtl::format("<SND> object:%s, rcvr %s %s",
msg->GetSender(),
msg->GetNumReceivers() ? msg->GetReceiver(0)->GetName() : "?",
netMsgWrap->AsStdString().c_str()).c_str()));
#endif
}
delete netMsgWrap;
return ret;
}
//
// Send a net msg. Delivers to transport mgr who sends p2p or to server
//
int plNetClientMgr::SendMsg(plNetMessage* msg)
{
if (GetFlagsBit(kDisabled))
return hsOK;
if (!CanSendMsg(msg))
return hsOK;
// If we're recording messages, set an identifying flag and echo the message back to ourselves
if (fMsgRecorder && fMsgRecorder->IsRecordableMsg(msg))
{
msg->SetBit(plNetMessage::kEchoBackToSender, true);
}
msg->SetTimeSent(plUnifiedTime::GetCurrentTime());
int channel = IPrepMsg(msg);
// hsLogEntry( DebugMsg( "<SND> %s %s", msg->ClassName(), msg->AsStdString().c_str()) );
int ret=fTransport.SendMsg(channel, msg);
// Debug
if (plNetMsgVoice::ConvertNoRef(msg))
SetFlagsBit(kSendingVoice);
if (plNetMsgGameMessage::ConvertNoRef(msg))
SetFlagsBit(kSendingActions);
plCheckNetMgrResult_ValReturn(ret,(char*)xtl::format("Failed to send %s, NC ret=%d",
msg->ClassName(), ret).c_str());
return ret;
}
void plNetClientMgr::StoreSDLState(const plStateDataRecord* sdRec, const plUoid& uoid,
UInt32 sendFlags, UInt32 writeOptions)
{
// send to server
plNetMsgSDLState* msg = sdRec->PrepNetMsg(0, writeOptions);
msg->SetNetProtocol(kNetProtocolCli2Game);
msg->ObjectInfo()->SetUoid(uoid);
if (sendFlags & plSynchedObject::kNewState)
msg->SetBit(plNetMessage::kNewSDLState);
if (sendFlags & plSynchedObject::kUseRelevanceRegions)
msg->SetBit(plNetMessage::kUseRelevanceRegions);
if (sendFlags & plSynchedObject::kDontPersistOnServer)
msg->SetPersistOnServer(false);
if (sendFlags & plSynchedObject::kIsAvatarState)
msg->SetIsAvatarState(true);
bool broadcast = (sendFlags & plSynchedObject::kBCastToClients) != 0;
if (broadcast && plNetClientApp::GetInstance())
{
msg->SetPlayerID(plNetClientApp::GetInstance()->GetPlayerID());
}
SendMsg(msg);
DEL(msg);
}

View File

@ -1,375 +1,375 @@
/*==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==*/
#include "plNetClientMgr.h"
#include "plNetLinkingMgr.h"
#include "pnSceneObject/plSceneObject.h"
#include "plPipeline/plPlates.h"
#include "plPipeline/plDebugText.h"
#include "plNetTransport/plNetTransportMember.h"
#include "plAvatar/plArmatureMod.h"
#include "plScene/plRelevanceMgr.h"
//
// Code which displays stuff on the screen
//
//
// show lists of members, listenList, and talkList
//
void plNetClientMgr::IShowLists()
{
plNetLinkingMgr * lm = plNetLinkingMgr::GetInstance();
plDebugText &txt = plDebugText::Instance();
int y,x,i;
const int yOff=10, xOff=300, startY=70, startX=10;
char str[256];
// My player info
x=startX;
y=startY;
plSceneObject *player = plSceneObject::ConvertNoRef(GetLocalPlayer());
hsPoint3 pos = (player ? player->GetLocalToWorld() * hsPoint3(0, 0, 0) : hsPoint3(0, 0, 0));
sprintf(str, "%s%s PlyrName=%s PlyrID=%d AcctID=%d P2P=%d Join#=%d Peers=%d %.1f,%.1f,%.1f",
GetFlagsBit(kSendingVoice) ? "V" : " ",
GetFlagsBit(kSendingActions) ? "A" : " ",
GetPlayerName(), GetPlayerID(), 0,
IsPeerToPeer(), GetJoinOrder(), 0,
pos.fX, pos.fY, pos.fZ);
txt.DrawString(x,y,str,255,255,255,255);
SetFlagsBit(kSendingVoice, 0);
SetFlagsBit(kSendingActions, 0);
y+=yOff;
sprintf(str, " Server=%s ILIAS=%d", "foo",
IsLoadingInitialAgeState());
txt.DrawString(x,y,str,255,255,255,255);
// MEMBERS
y+=yOff;
int baseY=y;
txt.DrawString(x,y," Members",255,255,255,255,plDebugText::kStyleBold);
y+=yOff;
plNetTransportMember** members=nil;
fTransport.GetMemberListDistSorted(members);
for(i=0;i<fTransport.GetNumMembers();i++)
{
plNetTransportMember* mbr=members[i];
hsAssert(mbr, "ShowLists: nil member?");
if (mbr->IsServer())
continue;
player = (mbr->GetAvatarKey() ? plSceneObject::ConvertNoRef(mbr->GetAvatarKey()->ObjectIsLoaded()) : nil);
sprintf(str, "%s%s %s p2p=%d dist=%.1f",
mbr->GetTransportFlags() & plNetTransportMember::kSendingVoice ? "V" : " ",
mbr->GetTransportFlags() & plNetTransportMember::kSendingActions ? "A" : " ",
mbr->AsStdString().c_str(),
mbr->IsPeerToPeer(),
mbr->GetDistSq() != hsScalarMax ? hsSquareRoot(mbr->GetDistSq()) :-1.f);
txt.DrawString(x,y,str);
y+=yOff;
mbr->SetTransportFlags(mbr->GetTransportFlags() &
~(plNetTransportMember::kSendingVoice|plNetTransportMember::kSendingActions));
}
delete [] members;
// LISTENLIST
x+=xOff;
y=baseY;
txt.DrawString(x,y,"ListenList",255,255,255,255,plDebugText::kStyleBold);
y+=yOff;
for(i=0;i<GetListenList()->GetNumMembers();i++)
{
sprintf(str, "name=%s", GetListenList()->GetMember(i)->AsStdString().c_str());
txt.DrawString(x,y,str);
y+=yOff;
}
// TALKLIST
x+=xOff;
y=baseY;
txt.DrawString(x,y,"TalkList",255,255,255,255,plDebugText::kStyleBold);
y+=yOff;
for(i=0;i<GetTalkList()->GetNumMembers();i++)
{
sprintf(str, "name=%s", GetTalkList()->GetMember(i)->AsStdString().c_str());
txt.DrawString(x,y,str);
y+=yOff;
}
}
//
// show lists of members, listenList, and talkList
//
void plNetClientMgr::IShowRooms()
{
plDebugText &txt = plDebugText::Instance();
int y,x;
const int yOff=10, xOff=300, startY=70, startX=10;
char str[256];
// OWNEDLIST
x=startX;
y=startY;
txt.DrawString(x,y,"RoomsOwned",255,255,255,255,plDebugText::kStyleBold);
y+=yOff;
std::set<plNetClientGroups::OwnedGroup>::iterator it=GetNetGroups()->fGroups.begin();
for(;it != GetNetGroups()->fGroups.end(); it++)
{
if ((*it).fOwnIt)
{
sprintf(str, "%s", (*it).fGroup.GetDesc());
txt.DrawString(x,y,str);
y+=yOff;
}
}
// NOTOWNEDLIST
x+=xOff;
y=startY;
txt.DrawString(x,y,"RoomsNotOwned",255,255,255,255,plDebugText::kStyleBold);
y+=yOff;
it=GetNetGroups()->fGroups.begin();
for(;it != GetNetGroups()->fGroups.end(); it++)
{
if (!(*it).fOwnIt)
{
sprintf(str, "%s", (*it).fGroup.GetDesc());
txt.DrawString(x,y,str);
y+=yOff;
}
}
}
UInt32 IPrintRelRegion(const hsBitVector& region, int x, int y, const hsBitVector* cmpRegion)
{
char buf[256];
int maxBits = 255;
UInt32 num = plRelevanceMgr::Instance()->GetNumRegions();
if (num > maxBits)
num = maxBits;
bool orTrue = false;
int i;
for (i = 0; i < num; i++)
{
buf[i] = (region.IsBitSet(i) ? '1' : '0');
if (cmpRegion && cmpRegion->IsBitSet(i) && region.IsBitSet(i))
orTrue = true;
}
buf[i] = '\0';
plDebugText& txt = plDebugText::Instance() ;
if (orTrue)
txt.DrawString(x, y, buf, 0, 255, 0);
else
txt.DrawString(x, y, buf);
return txt.CalcStringWidth(buf);
}
void plNetClientMgr::IShowRelevanceRegions()
{
plDebugText& txt = plDebugText::Instance();
const int yOff = 12, xOff = 20, startY=70, startX=10;
int x = startX, y = startY;
const char* title = "Name / In / Care";
txt.DrawString(x, y - yOff, title, 255, 255, 255, 255, plDebugText::kStyleBold);
plNetTransportMember** members = nil;
fTransport.GetMemberListDistSorted(members);
//
// Print out the player names in the first column
//
UInt32 maxPlayerName = 0;
txt.DrawString(x, y, GetPlayerName());
maxPlayerName = hsMaximum(maxPlayerName, txt.CalcStringWidth(GetPlayerName()));
y += yOff;
int i;
for (i = 0; i < fTransport.GetNumMembers(); i++)
{
plNetTransportMember* mbr = members[i];
hsAssert(mbr, "ShowLists: nil member?");
if (mbr->IsServer())
continue;
const char* name = mbr->GetPlayerName();
txt.DrawString(x, y, name);
maxPlayerName = hsMaximum(maxPlayerName, txt.CalcStringWidth(name));
y += yOff;
}
x = startX + maxPlayerName + xOff;
y = startY;
//
// Print out the regions
//
const hsBitVector* ourCare = nil;
const hsBitVector* ourIn = nil;
plSceneObject* player = plSceneObject::ConvertNoRef(GetLocalPlayer());
if (player)
{
const plArmatureMod *avMod = plArmatureMod::ConvertNoRef(player->GetModifierByType(plArmatureMod::Index()));
if (avMod)
{
ourIn = &avMod->GetRelRegionImIn();
UInt32 width = IPrintRelRegion(*ourIn, x, y, nil);
ourCare = &avMod->GetRelRegionCareAbout();
IPrintRelRegion(*ourCare, x + width + xOff, y, nil);
y += yOff;
}
}
for (i = 0; i < fTransport.GetNumMembers(); i++)
{
plNetTransportMember* mbr = members[i];
if (mbr->IsServer())
continue;
player = (mbr->GetAvatarKey() ? plSceneObject::ConvertNoRef(mbr->GetAvatarKey()->ObjectIsLoaded()) : nil);
if (player)
{
const plArmatureMod* avMod = plArmatureMod::ConvertNoRef(player->GetModifierByType(plArmatureMod::Index()));
if (avMod)
{
const hsBitVector& in = avMod->GetRelRegionImIn();
UInt32 width = IPrintRelRegion(in, x, y, ourCare);
const hsBitVector& care = avMod->GetRelRegionCareAbout();
IPrintRelRegion(care, x + width + xOff, y, ourIn);
y += yOff;
}
}
}
delete [] members;
}
void plNetClientMgr::IShowAvatars()
{
plDebugText &txt = plDebugText::Instance();
txt.SetFont( "Courier New", 6 );
int y,x,i;
const int yOff=10, xOff=285, startY=100, startX=10;
char str[256];
// Me
x=startX;
y=startY-yOff*3;
plSceneObject *player = plSceneObject::ConvertNoRef(GetLocalPlayer());
hsPoint3 pos = (player ? player->GetLocalToWorld() * hsPoint3(0, 0, 0) : hsPoint3(0, 0, 0));
hsVector3 ori = (player ? player->GetLocalToWorld() * hsVector3(0, -1, 0) : hsVector3(0, 0, 0));
sprintf(str, "%s: pos(%.2f, %.2f, %.2f) ori(%.2f, %.2f, %.2f)",
GetPlayerName(), pos.fX, pos.fY, pos.fZ, ori.fX, ori.fY, ori.fZ);
txt.DrawString(x,y,str,255,255,255,255);
if (player)
{
const plArmatureMod *avMod = plArmatureMod::ConvertNoRef(player->GetModifierByType(plArmatureMod::Index()));
if (avMod)
{
plArmatureMod* pNonConstArm = const_cast<plArmatureMod*>(avMod);
plSceneObject* pObj = pNonConstArm->GetFollowerParticleSystemSO();
if (pObj)
{
y+=yOff;
y+=yOff;
hsPoint3 pos = (pObj ? pObj->GetLocalToWorld() * hsPoint3(0, 0, 0) : hsPoint3(0, 0, 0));
hsVector3 ori = (pObj ? pObj->GetLocalToWorld() * hsVector3(0, -1, 0) : hsVector3(0, 0, 0));
sprintf(str, "%s: pos(%.2f, %.2f, %.2f) ori(%.2f, %.2f, %.2f)",
pObj->GetKeyName(), pos.fX, pos.fY, pos.fZ, ori.fX, ori.fY, ori.fZ);
txt.DrawString(x,y,str,255,255,255,255);
}
}
}
// Others
y=startY;
x=startX;
plNetTransportMember** members=nil;
fTransport.GetMemberListDistSorted(members);
for(i=0;i<fTransport.GetNumMembers();i++)
{
plNetTransportMember* mbr=members[i];
hsAssert(mbr, "ShowLists: nil member?");
if (mbr->IsServer())
continue;
player = (mbr->GetAvatarKey() ? plSceneObject::ConvertNoRef(mbr->GetAvatarKey()->ObjectIsLoaded()) : nil);
pos = (player ? player->GetLocalToWorld() * hsPoint3(0, 0, 0) : hsPoint3(0, 0, 0));
ori = (player ? player->GetLocalToWorld() * hsVector3(0, -1, 0) : hsVector3(0, 0, 0));
sprintf(str, "%s: pos(%.2f, %.2f, %.2f) ori(%.2f, %.2f, %.2f)",
mbr->AsStdString().c_str(), pos.fX, pos.fY, pos.fZ, ori.fX, ori.fY, ori.fZ);
txt.DrawString(x,y,str);
y+=yOff;
if (player)
{
const plArmatureMod *avMod = plArmatureMod::ConvertNoRef(player->GetModifierByType(plArmatureMod::Index()));
if (avMod)
{
plArmatureMod* pNonConstArm = const_cast<plArmatureMod*>(avMod);
plSceneObject* pObj = pNonConstArm->GetFollowerParticleSystemSO();
if (pObj)
{
y+=yOff;
y+=yOff;
hsPoint3 pos = (pObj ? pObj->GetLocalToWorld() * hsPoint3(0, 0, 0) : hsPoint3(0, 0, 0));
hsVector3 ori = (pObj ? pObj->GetLocalToWorld() * hsVector3(0, -1, 0) : hsVector3(0, 0, 0));
sprintf(str, "%s: pos(%.2f, %.2f, %.2f) ori(%.2f, %.2f, %.2f)",
pObj->GetKeyName(), pos.fX, pos.fY, pos.fZ, ori.fX, ori.fY, ori.fZ);
txt.DrawString(x,y,str,255,255,255,255);
}
}
}
}
delete [] members;
txt.SetFont( "Courier New", 8 );
}
/*==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==*/
#include "plNetClientMgr.h"
#include "plNetLinkingMgr.h"
#include "pnSceneObject/plSceneObject.h"
#include "plPipeline/plPlates.h"
#include "plPipeline/plDebugText.h"
#include "plNetTransport/plNetTransportMember.h"
#include "plAvatar/plArmatureMod.h"
#include "plScene/plRelevanceMgr.h"
//
// Code which displays stuff on the screen
//
//
// show lists of members, listenList, and talkList
//
void plNetClientMgr::IShowLists()
{
plNetLinkingMgr * lm = plNetLinkingMgr::GetInstance();
plDebugText &txt = plDebugText::Instance();
int y,x,i;
const int yOff=10, xOff=300, startY=70, startX=10;
char str[256];
// My player info
x=startX;
y=startY;
plSceneObject *player = plSceneObject::ConvertNoRef(GetLocalPlayer());
hsPoint3 pos = (player ? player->GetLocalToWorld() * hsPoint3(0, 0, 0) : hsPoint3(0, 0, 0));
sprintf(str, "%s%s PlyrName=%s PlyrID=%d AcctID=%d P2P=%d Join#=%d Peers=%d %.1f,%.1f,%.1f",
GetFlagsBit(kSendingVoice) ? "V" : " ",
GetFlagsBit(kSendingActions) ? "A" : " ",
GetPlayerName(), GetPlayerID(), 0,
IsPeerToPeer(), GetJoinOrder(), 0,
pos.fX, pos.fY, pos.fZ);
txt.DrawString(x,y,str,255,255,255,255);
SetFlagsBit(kSendingVoice, 0);
SetFlagsBit(kSendingActions, 0);
y+=yOff;
sprintf(str, " Server=%s ILIAS=%d", "foo",
IsLoadingInitialAgeState());
txt.DrawString(x,y,str,255,255,255,255);
// MEMBERS
y+=yOff;
int baseY=y;
txt.DrawString(x,y," Members",255,255,255,255,plDebugText::kStyleBold);
y+=yOff;
plNetTransportMember** members=nil;
fTransport.GetMemberListDistSorted(members);
for(i=0;i<fTransport.GetNumMembers();i++)
{
plNetTransportMember* mbr=members[i];
hsAssert(mbr, "ShowLists: nil member?");
if (mbr->IsServer())
continue;
player = (mbr->GetAvatarKey() ? plSceneObject::ConvertNoRef(mbr->GetAvatarKey()->ObjectIsLoaded()) : nil);
sprintf(str, "%s%s %s p2p=%d dist=%.1f",
mbr->GetTransportFlags() & plNetTransportMember::kSendingVoice ? "V" : " ",
mbr->GetTransportFlags() & plNetTransportMember::kSendingActions ? "A" : " ",
mbr->AsStdString().c_str(),
mbr->IsPeerToPeer(),
mbr->GetDistSq() != hsScalarMax ? hsSquareRoot(mbr->GetDistSq()) :-1.f);
txt.DrawString(x,y,str);
y+=yOff;
mbr->SetTransportFlags(mbr->GetTransportFlags() &
~(plNetTransportMember::kSendingVoice|plNetTransportMember::kSendingActions));
}
delete [] members;
// LISTENLIST
x+=xOff;
y=baseY;
txt.DrawString(x,y,"ListenList",255,255,255,255,plDebugText::kStyleBold);
y+=yOff;
for(i=0;i<GetListenList()->GetNumMembers();i++)
{
sprintf(str, "name=%s", GetListenList()->GetMember(i)->AsStdString().c_str());
txt.DrawString(x,y,str);
y+=yOff;
}
// TALKLIST
x+=xOff;
y=baseY;
txt.DrawString(x,y,"TalkList",255,255,255,255,plDebugText::kStyleBold);
y+=yOff;
for(i=0;i<GetTalkList()->GetNumMembers();i++)
{
sprintf(str, "name=%s", GetTalkList()->GetMember(i)->AsStdString().c_str());
txt.DrawString(x,y,str);
y+=yOff;
}
}
//
// show lists of members, listenList, and talkList
//
void plNetClientMgr::IShowRooms()
{
plDebugText &txt = plDebugText::Instance();
int y,x;
const int yOff=10, xOff=300, startY=70, startX=10;
char str[256];
// OWNEDLIST
x=startX;
y=startY;
txt.DrawString(x,y,"RoomsOwned",255,255,255,255,plDebugText::kStyleBold);
y+=yOff;
std::set<plNetClientGroups::OwnedGroup>::iterator it=GetNetGroups()->fGroups.begin();
for(;it != GetNetGroups()->fGroups.end(); it++)
{
if ((*it).fOwnIt)
{
sprintf(str, "%s", (*it).fGroup.GetDesc());
txt.DrawString(x,y,str);
y+=yOff;
}
}
// NOTOWNEDLIST
x+=xOff;
y=startY;
txt.DrawString(x,y,"RoomsNotOwned",255,255,255,255,plDebugText::kStyleBold);
y+=yOff;
it=GetNetGroups()->fGroups.begin();
for(;it != GetNetGroups()->fGroups.end(); it++)
{
if (!(*it).fOwnIt)
{
sprintf(str, "%s", (*it).fGroup.GetDesc());
txt.DrawString(x,y,str);
y+=yOff;
}
}
}
UInt32 IPrintRelRegion(const hsBitVector& region, int x, int y, const hsBitVector* cmpRegion)
{
char buf[256];
int maxBits = 255;
UInt32 num = plRelevanceMgr::Instance()->GetNumRegions();
if (num > maxBits)
num = maxBits;
bool orTrue = false;
int i;
for (i = 0; i < num; i++)
{
buf[i] = (region.IsBitSet(i) ? '1' : '0');
if (cmpRegion && cmpRegion->IsBitSet(i) && region.IsBitSet(i))
orTrue = true;
}
buf[i] = '\0';
plDebugText& txt = plDebugText::Instance() ;
if (orTrue)
txt.DrawString(x, y, buf, 0, 255, 0);
else
txt.DrawString(x, y, buf);
return txt.CalcStringWidth(buf);
}
void plNetClientMgr::IShowRelevanceRegions()
{
plDebugText& txt = plDebugText::Instance();
const int yOff = 12, xOff = 20, startY=70, startX=10;
int x = startX, y = startY;
const char* title = "Name / In / Care";
txt.DrawString(x, y - yOff, title, 255, 255, 255, 255, plDebugText::kStyleBold);
plNetTransportMember** members = nil;
fTransport.GetMemberListDistSorted(members);
//
// Print out the player names in the first column
//
UInt32 maxPlayerName = 0;
txt.DrawString(x, y, GetPlayerName());
maxPlayerName = hsMaximum(maxPlayerName, txt.CalcStringWidth(GetPlayerName()));
y += yOff;
int i;
for (i = 0; i < fTransport.GetNumMembers(); i++)
{
plNetTransportMember* mbr = members[i];
hsAssert(mbr, "ShowLists: nil member?");
if (mbr->IsServer())
continue;
const char* name = mbr->GetPlayerName();
txt.DrawString(x, y, name);
maxPlayerName = hsMaximum(maxPlayerName, txt.CalcStringWidth(name));
y += yOff;
}
x = startX + maxPlayerName + xOff;
y = startY;
//
// Print out the regions
//
const hsBitVector* ourCare = nil;
const hsBitVector* ourIn = nil;
plSceneObject* player = plSceneObject::ConvertNoRef(GetLocalPlayer());
if (player)
{
const plArmatureMod *avMod = plArmatureMod::ConvertNoRef(player->GetModifierByType(plArmatureMod::Index()));
if (avMod)
{
ourIn = &avMod->GetRelRegionImIn();
UInt32 width = IPrintRelRegion(*ourIn, x, y, nil);
ourCare = &avMod->GetRelRegionCareAbout();
IPrintRelRegion(*ourCare, x + width + xOff, y, nil);
y += yOff;
}
}
for (i = 0; i < fTransport.GetNumMembers(); i++)
{
plNetTransportMember* mbr = members[i];
if (mbr->IsServer())
continue;
player = (mbr->GetAvatarKey() ? plSceneObject::ConvertNoRef(mbr->GetAvatarKey()->ObjectIsLoaded()) : nil);
if (player)
{
const plArmatureMod* avMod = plArmatureMod::ConvertNoRef(player->GetModifierByType(plArmatureMod::Index()));
if (avMod)
{
const hsBitVector& in = avMod->GetRelRegionImIn();
UInt32 width = IPrintRelRegion(in, x, y, ourCare);
const hsBitVector& care = avMod->GetRelRegionCareAbout();
IPrintRelRegion(care, x + width + xOff, y, ourIn);
y += yOff;
}
}
}
delete [] members;
}
void plNetClientMgr::IShowAvatars()
{
plDebugText &txt = plDebugText::Instance();
txt.SetFont( "Courier New", 6 );
int y,x,i;
const int yOff=10, xOff=285, startY=100, startX=10;
char str[256];
// Me
x=startX;
y=startY-yOff*3;
plSceneObject *player = plSceneObject::ConvertNoRef(GetLocalPlayer());
hsPoint3 pos = (player ? player->GetLocalToWorld() * hsPoint3(0, 0, 0) : hsPoint3(0, 0, 0));
hsVector3 ori = (player ? player->GetLocalToWorld() * hsVector3(0, -1, 0) : hsVector3(0, 0, 0));
sprintf(str, "%s: pos(%.2f, %.2f, %.2f) ori(%.2f, %.2f, %.2f)",
GetPlayerName(), pos.fX, pos.fY, pos.fZ, ori.fX, ori.fY, ori.fZ);
txt.DrawString(x,y,str,255,255,255,255);
if (player)
{
const plArmatureMod *avMod = plArmatureMod::ConvertNoRef(player->GetModifierByType(plArmatureMod::Index()));
if (avMod)
{
plArmatureMod* pNonConstArm = const_cast<plArmatureMod*>(avMod);
plSceneObject* pObj = pNonConstArm->GetFollowerParticleSystemSO();
if (pObj)
{
y+=yOff;
y+=yOff;
hsPoint3 pos = (pObj ? pObj->GetLocalToWorld() * hsPoint3(0, 0, 0) : hsPoint3(0, 0, 0));
hsVector3 ori = (pObj ? pObj->GetLocalToWorld() * hsVector3(0, -1, 0) : hsVector3(0, 0, 0));
sprintf(str, "%s: pos(%.2f, %.2f, %.2f) ori(%.2f, %.2f, %.2f)",
pObj->GetKeyName(), pos.fX, pos.fY, pos.fZ, ori.fX, ori.fY, ori.fZ);
txt.DrawString(x,y,str,255,255,255,255);
}
}
}
// Others
y=startY;
x=startX;
plNetTransportMember** members=nil;
fTransport.GetMemberListDistSorted(members);
for(i=0;i<fTransport.GetNumMembers();i++)
{
plNetTransportMember* mbr=members[i];
hsAssert(mbr, "ShowLists: nil member?");
if (mbr->IsServer())
continue;
player = (mbr->GetAvatarKey() ? plSceneObject::ConvertNoRef(mbr->GetAvatarKey()->ObjectIsLoaded()) : nil);
pos = (player ? player->GetLocalToWorld() * hsPoint3(0, 0, 0) : hsPoint3(0, 0, 0));
ori = (player ? player->GetLocalToWorld() * hsVector3(0, -1, 0) : hsVector3(0, 0, 0));
sprintf(str, "%s: pos(%.2f, %.2f, %.2f) ori(%.2f, %.2f, %.2f)",
mbr->AsStdString().c_str(), pos.fX, pos.fY, pos.fZ, ori.fX, ori.fY, ori.fZ);
txt.DrawString(x,y,str);
y+=yOff;
if (player)
{
const plArmatureMod *avMod = plArmatureMod::ConvertNoRef(player->GetModifierByType(plArmatureMod::Index()));
if (avMod)
{
plArmatureMod* pNonConstArm = const_cast<plArmatureMod*>(avMod);
plSceneObject* pObj = pNonConstArm->GetFollowerParticleSystemSO();
if (pObj)
{
y+=yOff;
y+=yOff;
hsPoint3 pos = (pObj ? pObj->GetLocalToWorld() * hsPoint3(0, 0, 0) : hsPoint3(0, 0, 0));
hsVector3 ori = (pObj ? pObj->GetLocalToWorld() * hsVector3(0, -1, 0) : hsVector3(0, 0, 0));
sprintf(str, "%s: pos(%.2f, %.2f, %.2f) ori(%.2f, %.2f, %.2f)",
pObj->GetKeyName(), pos.fX, pos.fY, pos.fZ, ori.fX, ori.fY, ori.fZ);
txt.DrawString(x,y,str,255,255,255,255);
}
}
}
}
delete [] members;
txt.SetFont( "Courier New", 8 );
}

View File

@ -1,25 +1,25 @@
/*==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==*/
/*==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==*/

View File

@ -1,25 +1,25 @@
/*==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==*/
/*==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==*/

View File

@ -1,394 +1,394 @@
/*==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==*/
#include <algorithm>
#include "hsMatrix44.h"
#include "hsGeometry3.h"
#include "plNetClientMgr.h"
#include "plNetMessage/plNetMessage.h"
#include "pnNetCommon/plNetServers.h"
#include "pnSceneObject/plSceneObject.h"
#include "pnSceneObject/plCoordinateInterface.h"
#include "pnKeyedObject/plKey.h"
#include "plNetTransport/plNetTransportMember.h"
#include "plMessage/plMemberUpdateMsg.h"
#include "plMessage/plNetVoiceListMsg.h"
#include "plStatusLog/plStatusLog.h"
#include "plVault/plVault.h"
#define SAME_TALK_AND_LISTEN
struct DistSqInfo
{
plNetTransportMember* fMbr;
float fDistSq;
DistSqInfo(plNetTransportMember* m, float d) : fMbr(m),fDistSq(d) {}
};
bool lessComp(DistSqInfo a, DistSqInfo b)
{
return (a.fDistSq<b.fDistSq);
}
//
// see if new listen list differs from current one
// apply new list if there's a difference
// send listenList update msgs to old and new members in the list
// return true if the new list is different
//
hsBool plNetClientMgr::IApplyNewListenList(std::vector<DistSqInfo>& newListenList, hsBool forceSynch)
{
hsBool changed=false;
int i;
// see if new listen list differs from current one
if (forceSynch || newListenList.size() != GetListenList()->GetNumMembers())
changed=true;
else
{
for(i=0;i<newListenList.size(); i++)
{
if (GetListenList()->FindMember(newListenList[i].fMbr)==-1)
{
changed=true;
break;
}
}
}
// set as new listen list
if (changed)
{
DebugMsg("ListenList changed, forceSynch=%d\n", forceSynch);
plNetMsgListenListUpdate llu;
llu.SetPlayerID(GetPlayerID());
llu.SetNetProtocol(kNetProtocolCli2Game);
//
// for each client in the old list, if not in the new list, send a ListenList remove msg
//
llu.Receivers()->Clear();
llu.SetAdding(false);
for(i=0;i<GetListenList()->GetNumMembers(); i++)
{
hsBool found=false;
if (!forceSynch)
{
int j;
for(j=0;j<newListenList.size(); j++)
{
if (newListenList[j].fMbr==GetListenList()->GetMember(i))
{
found=true;
break;
}
}
}
if (found==false)
{
llu.Receivers()->AddReceiverPlayerID(GetListenList()->GetMember(i)->GetPlayerID());
}
}
#ifndef SAME_TALK_AND_LISTEN
if (llu.Receivers()->GetNumReceivers())
{
// DEBUGGING
int i;
for(i=0;i<llu.Receivers()->GetNumReceivers(); i++)
{
int idx=fTransport.FindMember(llu.Receivers()->GetReceiverClientNum(i));
plNetTransportMember* mbr=fTransport.GetMember(idx);
DebugMsg("<SEND %s> ListenListUpdate msg, adding=%d\n",
mbr->AsStdString().c_str(), llu.GetAdding());
}
SendMsg(&llu);
}
#endif
//
// for each client in the new list, [if not in the old list,] send a ListenList add msg
//
llu.Receivers()->Clear();
llu.SetAdding(true);
for(i=0;i<newListenList.size(); i++)
{
if (forceSynch || GetListenList()->FindMember(newListenList[i].fMbr)==-1)
{
// if not in the old list, send a ListenList add msg
llu.Receivers()->AddReceiverPlayerID(newListenList[i].fMbr->GetPlayerID());
}
}
#ifndef SAME_TALK_AND_LISTEN
if (llu.Receivers()->GetNumReceivers())
{
// DEBUGGING
int i;
for(i=0;i<llu.Receivers()->GetNumReceivers(); i++)
{
int cNum=llu.Receivers()->GetReceiverClientNum(i);
int idx=fTransport.FindMember(cNum);
plNetTransportMember* mbr=fTransport.GetMember(idx);
DebugMsg("<SEND %s> ListenListUpdate msg, adding=%d, cNum=%d\n",
mbr->AsStdString().c_str(), llu.GetAdding(), cNum);
}
SendMsg(&llu);
}
#endif
//
// set as new listen list
//
GetListenList()->Clear();
#ifdef HS_DEBUGGING
DebugMsg("New ListenList, size=%d\n", newListenList.size());
#endif
for(i=0;i<newListenList.size(); i++)
{
GetListenList()->AddMember(newListenList[i].fMbr);
#ifdef HS_DEBUGGING
DebugMsg("\tLL Member %d, name=%s, cNum=%d, dist=%f\n",
i, newListenList[i].fMbr->AsStdString().c_str(),
newListenList[i].fMbr->GetPlayerID(), newListenList[i].fDistSq);
#endif
}
}
return changed;
}
//
// Periodically updates the list of what remote players I'm listening to.
// Used to filter voice streams.
// Returns true if the listenList was changed.
// Note: Updates distSq to each member. Other things rely on this so we must do it even if p2p is disabled.
//
hsBool plNetClientMgr::IUpdateListenList(double secs)
{
if (GetFlagsBit(kDisabled))
return false;
if (!fLocalPlayerKey || !fLocalPlayerKey->ObjectIsLoaded())
return false;
hsBool changed = false;
if (secs - GetListenList()->GetLastUpdateTime()>plNetListenList::kUpdateInterval)
{
GetListenList()->SetLastUpdateTime(secs);
std::vector<DistSqInfo> newListenList;
switch (fListenListMode)
{
case kListenList_Forced:
{
#ifdef SAME_TALK_AND_LISTEN
SynchTalkList();
#endif
}
return true;
case kListenList_Distance:
{
// Finds the 3 closest players to our local player
// Search is unoptimized for now...
// compute our players pos
plSceneObject* locPlayer = plSceneObject::ConvertNoRef(fLocalPlayerKey->ObjectIsLoaded());
hsAssert(locPlayer, "local player is not a sceneObject?");
hsAssert(locPlayer->GetCoordinateInterface(), "locPlayer has no coordInterface");
hsMatrix44 l2w=locPlayer->GetCoordinateInterface()->GetLocalToWorld();
hsPoint3 locPlayerPos=l2w.GetTranslate();
int i;
for(i=0;i<fTransport.GetNumMembers();i++)
{
fTransport.GetMember(i)->SetDistSq(hsScalarMax);
if (fTransport.GetMember(i)->IsServer())
continue;
if(VaultAmIgnoringPlayer(fTransport.GetMember(i)->GetPlayerID()))
{
continue;
}
plKey k=fTransport.GetMember(i)->GetAvatarKey();
#if 0
if (!k)
{
DebugMsg("UpdateListenList: Nil avatar key on member %s\n",
fTransport.GetMember(i)->AsStdString().c_str());
}
#endif
plSceneObject* obj=plSceneObject::ConvertNoRef(k ? k->ObjectIsLoaded() : nil);
if (obj && obj->GetCoordinateInterface())
{
#if 1
// compute distSq to me
l2w=obj->GetCoordinateInterface()->GetLocalToWorld();
hsPoint3 pos=l2w.GetTranslate();
float distSq = hsVector3(&pos, &locPlayerPos).MagnitudeSquared();
fTransport.GetMember(i)->SetDistSq(distSq);
// I can't listen to players that are more than 50 ft away
if (distSq>plNetListenList::kMaxListenDistSq)
continue;
// if we are p2p and member isn't, skip them.
if ( IsPeerToPeer() && !fTransport.GetMember(i)->IsPeerToPeer() )
continue;
// otherwise, we aren't p2p so just update the listen list
// normally so it will update in the gui as distance changes.
#else
float distSq=1;
#endif
// if we have < 3 elements in the list, grow the list, or,
// if obj is closer than item 3, add it to the list.
// keep the list (3) elements sorted.
if (plNetListenList::kMaxListenListSize==-1 ||
newListenList.size()<plNetListenList::kMaxListenListSize ||
(distSq<newListenList[plNetListenList::kMaxListenListSize-1].fDistSq) )
{
DistSqInfo dsi(fTransport.GetMember(i), distSq);
if (plNetListenList::kMaxListenListSize==-1 ||
newListenList.size()<plNetListenList::kMaxListenListSize)
{
newListenList.push_back(dsi);
}
else
{
newListenList[plNetListenList::kMaxListenListSize-1]=dsi;
}
if (plNetListenList::kMaxListenListSize!=-1) // don't need to sort every time in this case
{
std::sort(newListenList.begin(), newListenList.end(), lessComp);
}
}
}
if (plNetListenList::kMaxListenListSize==-1 && newListenList.size())
{
std::sort(newListenList.begin(), newListenList.end(), lessComp);
}
}
}
break;
default:
break;
}
hsAssert(plNetListenList::kMaxListenListSize==-1 || newListenList.size()<=plNetListenList::kMaxListenListSize,
"illegal new listenlist size");
changed = IApplyNewListenList(newListenList,
#ifdef SAME_TALK_AND_LISTEN
false
#else
GetListenList()->CheckForceSynch()
#endif
);
}
// update talkList based on listenList
if (changed)
{
#ifdef SAME_TALK_AND_LISTEN
SynchTalkList();
#endif
// notify KI, member distances have been updated
plMemberUpdateMsg* mu = TRACKED_NEW plMemberUpdateMsg;
mu->Send();
}
return changed;
}
void plNetClientMgr::SynchTalkList()
{
GetTalkList()->Clear();
int i;
for(i=0;i<GetListenList()->GetNumMembers(); i++)
GetTalkList()->AddMember(GetListenList()->GetMember(i));
}
void plNetClientMgr::SetListenListMode(int i)
{
// set new mode, clear list and force update
fListenListMode = i;
GetListenList()->Clear();
GetListenList()->SetLastUpdateTime(0.f);
}
void plNetClientMgr::IHandleNetVoiceListMsg(plNetVoiceListMsg* msg)
{
if (msg->GetCmd() == plNetVoiceListMsg::kForcedListenerMode)
{
// first make sure this message applies to us:
int i;
bool included = false;
for (i = 0; i < msg->GetClientList()->Count(); i++)
{
if (msg->GetClientList()->AcquireArray()[i] == NetCommGetPlayer()->playerInt)
{
included = true;
break;
}
}
if (!included)
return;
SetListenListMode(kListenList_Forced);
// add in the members we receive from python
for (i = 0; i < msg->GetClientList()->Count(); i++)
{
plNetTransportMember **members = nil;
plNetClientMgr::GetInstance()->TransportMgr().GetMemberListDistSorted( members );
if( members != nil)
{
for(int j= 0; j < plNetClientMgr::GetInstance()->TransportMgr().GetNumMembers(); j++ )
{
plNetTransportMember *mbr = members[ j ];
if( mbr != nil && mbr->GetAvatarKey() != nil && mbr->GetPlayerID() == msg->GetClientList()->AcquireArray()[i])
{
plNetClientMgr::GetInstance()->GetListenList()->AddMember(mbr);
}
}
}
delete [] members;
}
}
else
if (msg->GetCmd() == plNetVoiceListMsg::kDistanceMode)
{
// again, see that it is us that we care about:
if (msg->GetRemovedKey() == GetLocalPlayerKey())
SetListenListMode(kListenList_Distance);
}
}
/*==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==*/
#include <algorithm>
#include "hsMatrix44.h"
#include "hsGeometry3.h"
#include "plNetClientMgr.h"
#include "plNetMessage/plNetMessage.h"
#include "pnNetCommon/plNetServers.h"
#include "pnSceneObject/plSceneObject.h"
#include "pnSceneObject/plCoordinateInterface.h"
#include "pnKeyedObject/plKey.h"
#include "plNetTransport/plNetTransportMember.h"
#include "plMessage/plMemberUpdateMsg.h"
#include "plMessage/plNetVoiceListMsg.h"
#include "plStatusLog/plStatusLog.h"
#include "plVault/plVault.h"
#define SAME_TALK_AND_LISTEN
struct DistSqInfo
{
plNetTransportMember* fMbr;
float fDistSq;
DistSqInfo(plNetTransportMember* m, float d) : fMbr(m),fDistSq(d) {}
};
bool lessComp(DistSqInfo a, DistSqInfo b)
{
return (a.fDistSq<b.fDistSq);
}
//
// see if new listen list differs from current one
// apply new list if there's a difference
// send listenList update msgs to old and new members in the list
// return true if the new list is different
//
hsBool plNetClientMgr::IApplyNewListenList(std::vector<DistSqInfo>& newListenList, hsBool forceSynch)
{
hsBool changed=false;
int i;
// see if new listen list differs from current one
if (forceSynch || newListenList.size() != GetListenList()->GetNumMembers())
changed=true;
else
{
for(i=0;i<newListenList.size(); i++)
{
if (GetListenList()->FindMember(newListenList[i].fMbr)==-1)
{
changed=true;
break;
}
}
}
// set as new listen list
if (changed)
{
DebugMsg("ListenList changed, forceSynch=%d\n", forceSynch);
plNetMsgListenListUpdate llu;
llu.SetPlayerID(GetPlayerID());
llu.SetNetProtocol(kNetProtocolCli2Game);
//
// for each client in the old list, if not in the new list, send a ListenList remove msg
//
llu.Receivers()->Clear();
llu.SetAdding(false);
for(i=0;i<GetListenList()->GetNumMembers(); i++)
{
hsBool found=false;
if (!forceSynch)
{
int j;
for(j=0;j<newListenList.size(); j++)
{
if (newListenList[j].fMbr==GetListenList()->GetMember(i))
{
found=true;
break;
}
}
}
if (found==false)
{
llu.Receivers()->AddReceiverPlayerID(GetListenList()->GetMember(i)->GetPlayerID());
}
}
#ifndef SAME_TALK_AND_LISTEN
if (llu.Receivers()->GetNumReceivers())
{
// DEBUGGING
int i;
for(i=0;i<llu.Receivers()->GetNumReceivers(); i++)
{
int idx=fTransport.FindMember(llu.Receivers()->GetReceiverClientNum(i));
plNetTransportMember* mbr=fTransport.GetMember(idx);
DebugMsg("<SEND %s> ListenListUpdate msg, adding=%d\n",
mbr->AsStdString().c_str(), llu.GetAdding());
}
SendMsg(&llu);
}
#endif
//
// for each client in the new list, [if not in the old list,] send a ListenList add msg
//
llu.Receivers()->Clear();
llu.SetAdding(true);
for(i=0;i<newListenList.size(); i++)
{
if (forceSynch || GetListenList()->FindMember(newListenList[i].fMbr)==-1)
{
// if not in the old list, send a ListenList add msg
llu.Receivers()->AddReceiverPlayerID(newListenList[i].fMbr->GetPlayerID());
}
}
#ifndef SAME_TALK_AND_LISTEN
if (llu.Receivers()->GetNumReceivers())
{
// DEBUGGING
int i;
for(i=0;i<llu.Receivers()->GetNumReceivers(); i++)
{
int cNum=llu.Receivers()->GetReceiverClientNum(i);
int idx=fTransport.FindMember(cNum);
plNetTransportMember* mbr=fTransport.GetMember(idx);
DebugMsg("<SEND %s> ListenListUpdate msg, adding=%d, cNum=%d\n",
mbr->AsStdString().c_str(), llu.GetAdding(), cNum);
}
SendMsg(&llu);
}
#endif
//
// set as new listen list
//
GetListenList()->Clear();
#ifdef HS_DEBUGGING
DebugMsg("New ListenList, size=%d\n", newListenList.size());
#endif
for(i=0;i<newListenList.size(); i++)
{
GetListenList()->AddMember(newListenList[i].fMbr);
#ifdef HS_DEBUGGING
DebugMsg("\tLL Member %d, name=%s, cNum=%d, dist=%f\n",
i, newListenList[i].fMbr->AsStdString().c_str(),
newListenList[i].fMbr->GetPlayerID(), newListenList[i].fDistSq);
#endif
}
}
return changed;
}
//
// Periodically updates the list of what remote players I'm listening to.
// Used to filter voice streams.
// Returns true if the listenList was changed.
// Note: Updates distSq to each member. Other things rely on this so we must do it even if p2p is disabled.
//
hsBool plNetClientMgr::IUpdateListenList(double secs)
{
if (GetFlagsBit(kDisabled))
return false;
if (!fLocalPlayerKey || !fLocalPlayerKey->ObjectIsLoaded())
return false;
hsBool changed = false;
if (secs - GetListenList()->GetLastUpdateTime()>plNetListenList::kUpdateInterval)
{
GetListenList()->SetLastUpdateTime(secs);
std::vector<DistSqInfo> newListenList;
switch (fListenListMode)
{
case kListenList_Forced:
{
#ifdef SAME_TALK_AND_LISTEN
SynchTalkList();
#endif
}
return true;
case kListenList_Distance:
{
// Finds the 3 closest players to our local player
// Search is unoptimized for now...
// compute our players pos
plSceneObject* locPlayer = plSceneObject::ConvertNoRef(fLocalPlayerKey->ObjectIsLoaded());
hsAssert(locPlayer, "local player is not a sceneObject?");
hsAssert(locPlayer->GetCoordinateInterface(), "locPlayer has no coordInterface");
hsMatrix44 l2w=locPlayer->GetCoordinateInterface()->GetLocalToWorld();
hsPoint3 locPlayerPos=l2w.GetTranslate();
int i;
for(i=0;i<fTransport.GetNumMembers();i++)
{
fTransport.GetMember(i)->SetDistSq(hsScalarMax);
if (fTransport.GetMember(i)->IsServer())
continue;
if(VaultAmIgnoringPlayer(fTransport.GetMember(i)->GetPlayerID()))
{
continue;
}
plKey k=fTransport.GetMember(i)->GetAvatarKey();
#if 0
if (!k)
{
DebugMsg("UpdateListenList: Nil avatar key on member %s\n",
fTransport.GetMember(i)->AsStdString().c_str());
}
#endif
plSceneObject* obj=plSceneObject::ConvertNoRef(k ? k->ObjectIsLoaded() : nil);
if (obj && obj->GetCoordinateInterface())
{
#if 1
// compute distSq to me
l2w=obj->GetCoordinateInterface()->GetLocalToWorld();
hsPoint3 pos=l2w.GetTranslate();
float distSq = hsVector3(&pos, &locPlayerPos).MagnitudeSquared();
fTransport.GetMember(i)->SetDistSq(distSq);
// I can't listen to players that are more than 50 ft away
if (distSq>plNetListenList::kMaxListenDistSq)
continue;
// if we are p2p and member isn't, skip them.
if ( IsPeerToPeer() && !fTransport.GetMember(i)->IsPeerToPeer() )
continue;
// otherwise, we aren't p2p so just update the listen list
// normally so it will update in the gui as distance changes.
#else
float distSq=1;
#endif
// if we have < 3 elements in the list, grow the list, or,
// if obj is closer than item 3, add it to the list.
// keep the list (3) elements sorted.
if (plNetListenList::kMaxListenListSize==-1 ||
newListenList.size()<plNetListenList::kMaxListenListSize ||
(distSq<newListenList[plNetListenList::kMaxListenListSize-1].fDistSq) )
{
DistSqInfo dsi(fTransport.GetMember(i), distSq);
if (plNetListenList::kMaxListenListSize==-1 ||
newListenList.size()<plNetListenList::kMaxListenListSize)
{
newListenList.push_back(dsi);
}
else
{
newListenList[plNetListenList::kMaxListenListSize-1]=dsi;
}
if (plNetListenList::kMaxListenListSize!=-1) // don't need to sort every time in this case
{
std::sort(newListenList.begin(), newListenList.end(), lessComp);
}
}
}
if (plNetListenList::kMaxListenListSize==-1 && newListenList.size())
{
std::sort(newListenList.begin(), newListenList.end(), lessComp);
}
}
}
break;
default:
break;
}
hsAssert(plNetListenList::kMaxListenListSize==-1 || newListenList.size()<=plNetListenList::kMaxListenListSize,
"illegal new listenlist size");
changed = IApplyNewListenList(newListenList,
#ifdef SAME_TALK_AND_LISTEN
false
#else
GetListenList()->CheckForceSynch()
#endif
);
}
// update talkList based on listenList
if (changed)
{
#ifdef SAME_TALK_AND_LISTEN
SynchTalkList();
#endif
// notify KI, member distances have been updated
plMemberUpdateMsg* mu = TRACKED_NEW plMemberUpdateMsg;
mu->Send();
}
return changed;
}
void plNetClientMgr::SynchTalkList()
{
GetTalkList()->Clear();
int i;
for(i=0;i<GetListenList()->GetNumMembers(); i++)
GetTalkList()->AddMember(GetListenList()->GetMember(i));
}
void plNetClientMgr::SetListenListMode(int i)
{
// set new mode, clear list and force update
fListenListMode = i;
GetListenList()->Clear();
GetListenList()->SetLastUpdateTime(0.f);
}
void plNetClientMgr::IHandleNetVoiceListMsg(plNetVoiceListMsg* msg)
{
if (msg->GetCmd() == plNetVoiceListMsg::kForcedListenerMode)
{
// first make sure this message applies to us:
int i;
bool included = false;
for (i = 0; i < msg->GetClientList()->Count(); i++)
{
if (msg->GetClientList()->AcquireArray()[i] == NetCommGetPlayer()->playerInt)
{
included = true;
break;
}
}
if (!included)
return;
SetListenListMode(kListenList_Forced);
// add in the members we receive from python
for (i = 0; i < msg->GetClientList()->Count(); i++)
{
plNetTransportMember **members = nil;
plNetClientMgr::GetInstance()->TransportMgr().GetMemberListDistSorted( members );
if( members != nil)
{
for(int j= 0; j < plNetClientMgr::GetInstance()->TransportMgr().GetNumMembers(); j++ )
{
plNetTransportMember *mbr = members[ j ];
if( mbr != nil && mbr->GetAvatarKey() != nil && mbr->GetPlayerID() == msg->GetClientList()->AcquireArray()[i])
{
plNetClientMgr::GetInstance()->GetListenList()->AddMember(mbr);
}
}
}
delete [] members;
}
}
else
if (msg->GetCmd() == plNetVoiceListMsg::kDistanceMode)
{
// again, see that it is us that we care about:
if (msg->GetRemovedKey() == GetLocalPlayerKey())
SetListenListMode(kListenList_Distance);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,72 +1,72 @@
/*==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==*/
#ifndef plNetClientMsgHandler_inc
#define plNetClientMsgHandler_inc
#include "plNetCommon/plNetMsgHandler.h"
#include "hsStlUtils.h"
///////////////////////////////////////////////////////////////////
//
// define msg handler fxn for netClient msgs
//
class plNetClientMgr;
class plNetMsgMemberInfoHelper;
class plNetTransportMember;
///////////////////////////////////////////////////////////////////
class plNetClientMsgHandler : public plNetMsgHandler
{
//protected:
enum // SendOrTimeOut return values and meanings
{
kTimedOutNoRetry = -1,
kDoNothing = 0,
kSend = 1,
};
plNetClientMgr * IGetNetClientMgr();
void IFillInTransportMember(const plNetMsgMemberInfoHelper* mbi, plNetTransportMember* mbr);
public:
plNetClientMsgHandler(plNetClientMgr * mgr);
~plNetClientMsgHandler();
int ReceiveMsg(plNetMessage *& netMsg);
int PeekMsg(plNetMessage * netMsg); // return msgsize on success. -1 on error.
MSG_HANDLER_DECL(plNetMsgTerminated)
MSG_HANDLER_DECL(plNetMsgGroupOwner)
MSG_HANDLER_DECL(plNetMsgSDLState)
MSG_HANDLER_DECL(plNetMsgGameMessage)
MSG_HANDLER_DECL(plNetMsgVoice)
MSG_HANDLER_DECL(plNetMsgMembersList)
MSG_HANDLER_DECL(plNetMsgMemberUpdate)
MSG_HANDLER_DECL(plNetMsgListenListUpdate)
MSG_HANDLER_DECL(plNetMsgInitialAgeStateSent)
};
#endif // plNetClientMsgHandler_inc
/*==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==*/
#ifndef plNetClientMsgHandler_inc
#define plNetClientMsgHandler_inc
#include "plNetCommon/plNetMsgHandler.h"
#include "hsStlUtils.h"
///////////////////////////////////////////////////////////////////
//
// define msg handler fxn for netClient msgs
//
class plNetClientMgr;
class plNetMsgMemberInfoHelper;
class plNetTransportMember;
///////////////////////////////////////////////////////////////////
class plNetClientMsgHandler : public plNetMsgHandler
{
//protected:
enum // SendOrTimeOut return values and meanings
{
kTimedOutNoRetry = -1,
kDoNothing = 0,
kSend = 1,
};
plNetClientMgr * IGetNetClientMgr();
void IFillInTransportMember(const plNetMsgMemberInfoHelper* mbi, plNetTransportMember* mbr);
public:
plNetClientMsgHandler(plNetClientMgr * mgr);
~plNetClientMsgHandler();
int ReceiveMsg(plNetMessage *& netMsg);
int PeekMsg(plNetMessage * netMsg); // return msgsize on success. -1 on error.
MSG_HANDLER_DECL(plNetMsgTerminated)
MSG_HANDLER_DECL(plNetMsgGroupOwner)
MSG_HANDLER_DECL(plNetMsgSDLState)
MSG_HANDLER_DECL(plNetMsgGameMessage)
MSG_HANDLER_DECL(plNetMsgVoice)
MSG_HANDLER_DECL(plNetMsgMembersList)
MSG_HANDLER_DECL(plNetMsgMemberUpdate)
MSG_HANDLER_DECL(plNetMsgListenListUpdate)
MSG_HANDLER_DECL(plNetMsgInitialAgeStateSent)
};
#endif // plNetClientMsgHandler_inc

View File

@ -1,109 +1,109 @@
/*==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==*/
#include "plNetClientMsgScreener.h"
#include "plNetLinkingMgr.h"
#include "pnNetCommon/plNetApp.h"
#include "pnMessage/plMessage.h"
#include "plStatusLog/plStatusLog.h"
#include "plAvatar/plAvatarMgr.h"
#include "plAvatar/plArmatureMod.h"
///////////////////////////////////////////////////////////////
// CLIENT Version
///////////////////////////////////////////////////////////////
plNetClientMsgScreener::plNetClientMsgScreener()
{
DebugMsg("created");
}
//
// For plLoggable base
//
void plNetClientMsgScreener::ICreateStatusLog() const
{
fStatusLog = plStatusLogMgr::GetInstance().CreateStatusLog(40, "NetScreener.log",
plStatusLog::kTimestamp | plStatusLog::kFilledBackground | plStatusLog::kAlignToTop);
}
//
// return cur age name
//
const char* plNetClientMsgScreener::IGetAgeName() const
{
plNetLinkingMgr *lm = plNetLinkingMgr::GetInstance();
return lm && lm->GetAgeLink()->GetAgeInfo() ? lm->GetAgeLink()->GetAgeInfo()->GetAgeFilename() : "?";
}
//
// Check if key is local avatar
//
bool plNetClientMsgScreener::IIsLocalAvatarKey(plKey key, const plNetGameMember* gm) const
{
return (!key || key==plNetClientApp::GetInstance()->GetLocalPlayerKey());
}
bool plNetClientMsgScreener::IIsLocalArmatureModKey(plKey key, const plNetGameMember* gm) const
{
plKey playerKey = plNetClientApp::GetInstance()->GetLocalPlayerKey();
plArmatureMod* aMod = playerKey ? plAvatarMgr::GetInstance()->FindAvatar(playerKey) : nil;
return (!key || key==(aMod ? aMod->GetKey() : nil));
}
//
// Check if CCR
//
bool plNetClientMsgScreener::IIsSenderCCR(const plNetGameMember* gm) const
{
return plNetClientApp::GetInstance()->AmCCR();
}
//
// return true if msg is allowed/accepted as a net msg
//
bool plNetClientMsgScreener::AllowMessage(const plMessage* msg) const
{
if (!msg)
return false;
Answer ans=IAllowMessageType(msg->ClassIndex());
if (ans==kYes)
return true;
if (ans==kNo)
{
// WarningMsg("Quick-reject net propagated msg %s", msg->ClassName());
return false;
}
if (!IValidateMessage(msg))
{
// WarningMsg("Validation failed. Blocking net propagated msg %s", msg->ClassName());
return false;
}
return true;
}
/*==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==*/
#include "plNetClientMsgScreener.h"
#include "plNetLinkingMgr.h"
#include "pnNetCommon/plNetApp.h"
#include "pnMessage/plMessage.h"
#include "plStatusLog/plStatusLog.h"
#include "plAvatar/plAvatarMgr.h"
#include "plAvatar/plArmatureMod.h"
///////////////////////////////////////////////////////////////
// CLIENT Version
///////////////////////////////////////////////////////////////
plNetClientMsgScreener::plNetClientMsgScreener()
{
DebugMsg("created");
}
//
// For plLoggable base
//
void plNetClientMsgScreener::ICreateStatusLog() const
{
fStatusLog = plStatusLogMgr::GetInstance().CreateStatusLog(40, "NetScreener.log",
plStatusLog::kTimestamp | plStatusLog::kFilledBackground | plStatusLog::kAlignToTop);
}
//
// return cur age name
//
const char* plNetClientMsgScreener::IGetAgeName() const
{
plNetLinkingMgr *lm = plNetLinkingMgr::GetInstance();
return lm && lm->GetAgeLink()->GetAgeInfo() ? lm->GetAgeLink()->GetAgeInfo()->GetAgeFilename() : "?";
}
//
// Check if key is local avatar
//
bool plNetClientMsgScreener::IIsLocalAvatarKey(plKey key, const plNetGameMember* gm) const
{
return (!key || key==plNetClientApp::GetInstance()->GetLocalPlayerKey());
}
bool plNetClientMsgScreener::IIsLocalArmatureModKey(plKey key, const plNetGameMember* gm) const
{
plKey playerKey = plNetClientApp::GetInstance()->GetLocalPlayerKey();
plArmatureMod* aMod = playerKey ? plAvatarMgr::GetInstance()->FindAvatar(playerKey) : nil;
return (!key || key==(aMod ? aMod->GetKey() : nil));
}
//
// Check if CCR
//
bool plNetClientMsgScreener::IIsSenderCCR(const plNetGameMember* gm) const
{
return plNetClientApp::GetInstance()->AmCCR();
}
//
// return true if msg is allowed/accepted as a net msg
//
bool plNetClientMsgScreener::AllowMessage(const plMessage* msg) const
{
if (!msg)
return false;
Answer ans=IAllowMessageType(msg->ClassIndex());
if (ans==kYes)
return true;
if (ans==kNo)
{
// WarningMsg("Quick-reject net propagated msg %s", msg->ClassName());
return false;
}
if (!IValidateMessage(msg))
{
// WarningMsg("Validation failed. Blocking net propagated msg %s", msg->ClassName());
return false;
}
return true;
}

View File

@ -1,52 +1,52 @@
/*==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==*/
#ifndef plNetClientMsgScreener_h
#define plNetClientMsgScreener_h
#include "plNetCommon/plNetMsgScreener.h"
//
// Client-side version
//
class plNetClientMsgScreener : public plNetMsgScreener
{
protected:
void ICreateStatusLog() const;
const char* IGetSenderName(const plNetGameMember* gm) const { return "local"; }
const char* IGetAgeName() const;
bool IIsLocalAvatarKey(plKey key, const plNetGameMember* gm) const;
bool IIsLocalArmatureModKey(plKey key, const plNetGameMember* gm) const;
bool IIsSenderCCR(const plNetGameMember* gm=nil) const;
bool IAmClient() const { return true; }
public:
plNetClientMsgScreener();
bool AllowMessage(const plMessage* msg) const;
};
#endif // plNetClientMsgScreener_h
/*==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==*/
#ifndef plNetClientMsgScreener_h
#define plNetClientMsgScreener_h
#include "plNetCommon/plNetMsgScreener.h"
//
// Client-side version
//
class plNetClientMsgScreener : public plNetMsgScreener
{
protected:
void ICreateStatusLog() const;
const char* IGetSenderName(const plNetGameMember* gm) const { return "local"; }
const char* IGetAgeName() const;
bool IIsLocalAvatarKey(plKey key, const plNetGameMember* gm) const;
bool IIsLocalArmatureModKey(plKey key, const plNetGameMember* gm) const;
bool IIsSenderCCR(const plNetGameMember* gm=nil) const;
bool IAmClient() const { return true; }
public:
plNetClientMsgScreener();
bool AllowMessage(const plMessage* msg) const;
};
#endif // plNetClientMsgScreener_h

View File

@ -1,91 +1,91 @@
/*==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==*/
#include "plNetClientStats.h"
#include "plNetClientMgr.h"
#include "hsTimer.h"
plNetClientStats::plNetClientStats() :
fNumVaultMsgsSent(0),
fNumVaultMsgsRcvd(0),
fVaultMsgSentBytes(0),
fVaultMsgRcvdBytes(0),
fAgeStatsULBits(0),
fAgeStatsDLBits(0),
fAgeStatsLinkInTime(0)
{
}
//
// return the avg UL bps used so far in this age
//
float plNetClientStats::GetAgeStatsULBitsPerSec() const
{
double elapsedAgeTime = hsTimer::GetSeconds() - fAgeStatsLinkInTime;
return (float)(fAgeStatsULBits/elapsedAgeTime);
}
//
// return the acks that were conpressed so far
//
UInt32 plNetClientStats::GetRecvdMultipleAcks() const
{
return fRecvdMultipleAcks;
}
//
// return the avg DL bps used so far in this age
//
float plNetClientStats::GetAgeStatsDLBitsPerSec() const
{
double elapsedAgeTime = hsTimer::GetSeconds() - fAgeStatsLinkInTime;
return (float)(fAgeStatsDLBits/elapsedAgeTime);
}
//
// Accumulate the UL/DL bits & acks used from the netCore state
//
void plNetClientStats::UpdateAgeStats()
{
plNetClientMgr* nc=plNetClientMgr::GetInstance();
#if 0
fAgeStatsDLBits += nc->GetNetCore()->GetStats()->GetDLBits();
fAgeStatsULBits += nc->GetNetCore()->GetStats()->GetULBits();
fRecvdMultipleAcks += nc->GetNetCore()->GetStats()->GetRecvdMultipleAcks();
#endif
}
//
// Call when you join an age
//
void plNetClientStats::ResetAgeStats()
{
fAgeStatsDLBits = fAgeStatsULBits = 0;
fRecvdMultipleAcks = 0;
fAgeStatsLinkInTime = hsTimer::GetSeconds();
/*==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==*/
#include "plNetClientStats.h"
#include "plNetClientMgr.h"
#include "hsTimer.h"
plNetClientStats::plNetClientStats() :
fNumVaultMsgsSent(0),
fNumVaultMsgsRcvd(0),
fVaultMsgSentBytes(0),
fVaultMsgRcvdBytes(0),
fAgeStatsULBits(0),
fAgeStatsDLBits(0),
fAgeStatsLinkInTime(0)
{
}
//
// return the avg UL bps used so far in this age
//
float plNetClientStats::GetAgeStatsULBitsPerSec() const
{
double elapsedAgeTime = hsTimer::GetSeconds() - fAgeStatsLinkInTime;
return (float)(fAgeStatsULBits/elapsedAgeTime);
}
//
// return the acks that were conpressed so far
//
UInt32 plNetClientStats::GetRecvdMultipleAcks() const
{
return fRecvdMultipleAcks;
}
//
// return the avg DL bps used so far in this age
//
float plNetClientStats::GetAgeStatsDLBitsPerSec() const
{
double elapsedAgeTime = hsTimer::GetSeconds() - fAgeStatsLinkInTime;
return (float)(fAgeStatsDLBits/elapsedAgeTime);
}
//
// Accumulate the UL/DL bits & acks used from the netCore state
//
void plNetClientStats::UpdateAgeStats()
{
plNetClientMgr* nc=plNetClientMgr::GetInstance();
#if 0
fAgeStatsDLBits += nc->GetNetCore()->GetStats()->GetDLBits();
fAgeStatsULBits += nc->GetNetCore()->GetStats()->GetULBits();
fRecvdMultipleAcks += nc->GetNetCore()->GetStats()->GetRecvdMultipleAcks();
#endif
}
//
// Call when you join an age
//
void plNetClientStats::ResetAgeStats()
{
fAgeStatsDLBits = fAgeStatsULBits = 0;
fRecvdMultipleAcks = 0;
fAgeStatsLinkInTime = hsTimer::GetSeconds();
}

View File

@ -1,76 +1,76 @@
/*==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==*/
#ifndef plNetClientStats_h
#define plNetClientStats_h
#include "hsTypes.h"
//
// Holds stats counters used by the Net Client
//
class plNetClientStats
{
public:
plNetClientStats();
//
// Vault Stats
//
private:
// Vault msg counters
UInt32 fNumVaultMsgsSent;
UInt32 fNumVaultMsgsRcvd;
UInt32 fVaultMsgSentBytes;
UInt32 fVaultMsgRcvdBytes;
public:
// msg counters
UInt32 GetNumVaultMsgsSent() const { return fNumVaultMsgsSent; }
UInt32 GetNumVaultMsgsRcvd() const { return fNumVaultMsgsRcvd; }
UInt32 GetVaultMsgSentBytes() const { return fVaultMsgSentBytes; }
UInt32 GetVaultMsgRcvdBytes() const { return fVaultMsgRcvdBytes; }
void TallyVaultMsgSent( int size ) { fNumVaultMsgsSent++; fVaultMsgSentBytes+=size; }
void TallyVaultMsgRcvd( int size ) { fNumVaultMsgsRcvd++; fVaultMsgRcvdBytes+=size; }
void ResetVaultMsgCounters() { fNumVaultMsgsSent=fNumVaultMsgsRcvd=fVaultMsgSentBytes=fVaultMsgRcvdBytes=0; }
//
// NetClient BW Stats, kept per age
//
private:
int fAgeStatsULBits, fAgeStatsDLBits;
UInt32 fRecvdMultipleAcks;
double fAgeStatsLinkInTime;
public:
void UpdateAgeStats();
void ResetAgeStats();
float GetAgeStatsULBitsPerSec() const;
float GetAgeStatsDLBitsPerSec() const;
UInt32 GetRecvdMultipleAcks() const;
};
#endif // plNetClientStats_h
/*==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==*/
#ifndef plNetClientStats_h
#define plNetClientStats_h
#include "hsTypes.h"
//
// Holds stats counters used by the Net Client
//
class plNetClientStats
{
public:
plNetClientStats();
//
// Vault Stats
//
private:
// Vault msg counters
UInt32 fNumVaultMsgsSent;
UInt32 fNumVaultMsgsRcvd;
UInt32 fVaultMsgSentBytes;
UInt32 fVaultMsgRcvdBytes;
public:
// msg counters
UInt32 GetNumVaultMsgsSent() const { return fNumVaultMsgsSent; }
UInt32 GetNumVaultMsgsRcvd() const { return fNumVaultMsgsRcvd; }
UInt32 GetVaultMsgSentBytes() const { return fVaultMsgSentBytes; }
UInt32 GetVaultMsgRcvdBytes() const { return fVaultMsgRcvdBytes; }
void TallyVaultMsgSent( int size ) { fNumVaultMsgsSent++; fVaultMsgSentBytes+=size; }
void TallyVaultMsgRcvd( int size ) { fNumVaultMsgsRcvd++; fVaultMsgRcvdBytes+=size; }
void ResetVaultMsgCounters() { fNumVaultMsgsSent=fNumVaultMsgsRcvd=fVaultMsgSentBytes=fVaultMsgRcvdBytes=0; }
//
// NetClient BW Stats, kept per age
//
private:
int fAgeStatsULBits, fAgeStatsDLBits;
UInt32 fRecvdMultipleAcks;
double fAgeStatsLinkInTime;
public:
void UpdateAgeStats();
void ResetAgeStats();
float GetAgeStatsULBitsPerSec() const;
float GetAgeStatsDLBitsPerSec() const;
UInt32 GetRecvdMultipleAcks() const;
};
#endif // plNetClientStats_h

View File

@ -1,164 +1,164 @@
/*==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==*/
#include "plNetClientMgr.h"
#include "plNetClientVNodeMgr.h"
#include "../plNetMessage/plNetMessage.h"
#include "../plGImage/plMipmap.h"
#include "../plJPEG/plJPEG.h"
#include "../plVault/plVault.h"
#include "hsResMgr.h"
#include "../pnMessage/plRefMsg.h"
#include "../plVault/plDniCoordinateInfo.h"
#include "../plVault/plAgeInfoSource.h"
#include "plNetLinkingMgr.h"
#include "../plStatusLog/plStatusLog.h"
#include "../plClientState/plClientStateMgr.h"
#include "../plSDL/plSDL.h"
#include "../plAgeLoader/plAgeLoader.h"
#include "../../FeatureLib/pfMessage/pfKIMsg.h"
////////////////////////////////////////////////////////////////////
class plNetClientAgeInfoSource : public plAgeInfoSource
{
plDniCoordinateInfo fNilCoords; // TEMPORARY
public:
const plDniCoordinateInfo * GetAgeCoords( void ) const
{
return &fNilCoords; // tmp
}
const plUnifiedTime * GetAgeTime( void ) const
{
static plUnifiedTime ut;
ut.SetSecsDouble(plNetClientMgr::GetInstance()->GetCurrentAgeElapsedSeconds());
return &ut;
}
const char * GetAgeName( void ) const
{
return plNetLinkingMgr::GetInstance()->GetAgeLink()->GetAgeInfo()->GetAgeInstanceName();
}
const plUUID * GetAgeGuid( void ) const
{
return plNetLinkingMgr::GetInstance()->GetAgeLink()->GetAgeInfo()->GetAgeInstanceGuid();
}
static plNetClientAgeInfoSource * GetInstance( void )
{
static plNetClientAgeInfoSource Me;
return &Me;
}
};
//// Image/Mipmap Conversion //////////////////////////////////////////////////
hsBool StuffImageIntoNode( plMipmap * src, RelVaultNode * dst )
{
VaultImageNode image(dst);
hsRAMStream ramStream;
// Create our JPEG stream
plJPEG::Instance().SetWriteQuality( 30 ); // In percent quality
if( !plJPEG::Instance().WriteToStream( &ramStream, src ) )
return false;
unsigned bytes = ramStream.GetEOF();
byte * buffer = (byte *)ALLOC(bytes);
ramStream.CopyToMem(buffer);
image.SetImageData(buffer, bytes);
image.SetImageType( VaultImageNode::kJPEG );
// possibly make a plKey for the mipmap.
return ExtractImageFromNode( dst );
}
hsBool ExtractImageFromNode( RelVaultNode * src)
{
// no id? exit now. we will be called again when element is given an id.
if ( src->nodeId == 0 )
return false;
VaultCliImageNode image(src);
// already have a mipmap and it has a key? release it
if ( image.fMipmap && image.fMipmap->GetKey()!=nil )
{
plNetClientMgr::GetInstance()->GetKey()->Release( image.fMipmap->GetKey() );
image.fMipmap = nil;
}
// convert image data to a plMipmap
switch( image.imgType )
{
case VaultImageNode::kJPEG:
{
// Copy to a RAM stream so the JPEG class is happy
hsRAMStream ramStream;
ramStream.Write( image.imgDataLen, image.imgData );
ramStream.Rewind();
// create mipmap from image data
image.fMipmap = plJPEG::Instance().ReadFromStream( &ramStream );
}
break;
default:
{
hsAssert( false, "ExtractImageFromNode: Invalid image type" );
return false; // Invalid image type
}
}
if ( !image.fMipmap )
{
hsAssert( false, "ExtractImageFromNode failed" );
return false;
}
// we now have a mipmap, but it doesn't have a key. make a key for it
static int UniqueIdentifier = 0;
char keyName[512];
sprintf( keyName, "VaultImage_%lu_%d", src->nodeId, UniqueIdentifier++ );
// create a key for the mipmap
plKey imageKey = hsgResMgr::ResMgr()->NewKey( keyName, image.fMipmap, plLocation::kGlobalFixedLoc );
// ref the image key
hsgResMgr::ResMgr()->AddViaNotify( imageKey, TRACKED_NEW plGenRefMsg(
plNetClientMgr::GetInstance()->GetKey(), plRefMsg::kOnCreate, 0, plNetClientMgr::kVaultImage ),
plRefFlags::kActiveRef );
return ( image.fMipmap->GetKey()!=nil );
}
////////////////////////////////////////////////////////////////////
// End.
/*==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==*/
#include "plNetClientMgr.h"
#include "plNetClientVNodeMgr.h"
#include "../plNetMessage/plNetMessage.h"
#include "../plGImage/plMipmap.h"
#include "../plJPEG/plJPEG.h"
#include "../plVault/plVault.h"
#include "hsResMgr.h"
#include "../pnMessage/plRefMsg.h"
#include "../plVault/plDniCoordinateInfo.h"
#include "../plVault/plAgeInfoSource.h"
#include "plNetLinkingMgr.h"
#include "../plStatusLog/plStatusLog.h"
#include "../plClientState/plClientStateMgr.h"
#include "../plSDL/plSDL.h"
#include "../plAgeLoader/plAgeLoader.h"
#include "../../FeatureLib/pfMessage/pfKIMsg.h"
////////////////////////////////////////////////////////////////////
class plNetClientAgeInfoSource : public plAgeInfoSource
{
plDniCoordinateInfo fNilCoords; // TEMPORARY
public:
const plDniCoordinateInfo * GetAgeCoords( void ) const
{
return &fNilCoords; // tmp
}
const plUnifiedTime * GetAgeTime( void ) const
{
static plUnifiedTime ut;
ut.SetSecsDouble(plNetClientMgr::GetInstance()->GetCurrentAgeElapsedSeconds());
return &ut;
}
const char * GetAgeName( void ) const
{
return plNetLinkingMgr::GetInstance()->GetAgeLink()->GetAgeInfo()->GetAgeInstanceName();
}
const plUUID * GetAgeGuid( void ) const
{
return plNetLinkingMgr::GetInstance()->GetAgeLink()->GetAgeInfo()->GetAgeInstanceGuid();
}
static plNetClientAgeInfoSource * GetInstance( void )
{
static plNetClientAgeInfoSource Me;
return &Me;
}
};
//// Image/Mipmap Conversion //////////////////////////////////////////////////
hsBool StuffImageIntoNode( plMipmap * src, RelVaultNode * dst )
{
VaultImageNode image(dst);
hsRAMStream ramStream;
// Create our JPEG stream
plJPEG::Instance().SetWriteQuality( 30 ); // In percent quality
if( !plJPEG::Instance().WriteToStream( &ramStream, src ) )
return false;
unsigned bytes = ramStream.GetEOF();
byte * buffer = (byte *)ALLOC(bytes);
ramStream.CopyToMem(buffer);
image.SetImageData(buffer, bytes);
image.SetImageType( VaultImageNode::kJPEG );
// possibly make a plKey for the mipmap.
return ExtractImageFromNode( dst );
}
hsBool ExtractImageFromNode( RelVaultNode * src)
{
// no id? exit now. we will be called again when element is given an id.
if ( src->nodeId == 0 )
return false;
VaultCliImageNode image(src);
// already have a mipmap and it has a key? release it
if ( image.fMipmap && image.fMipmap->GetKey()!=nil )
{
plNetClientMgr::GetInstance()->GetKey()->Release( image.fMipmap->GetKey() );
image.fMipmap = nil;
}
// convert image data to a plMipmap
switch( image.imgType )
{
case VaultImageNode::kJPEG:
{
// Copy to a RAM stream so the JPEG class is happy
hsRAMStream ramStream;
ramStream.Write( image.imgDataLen, image.imgData );
ramStream.Rewind();
// create mipmap from image data
image.fMipmap = plJPEG::Instance().ReadFromStream( &ramStream );
}
break;
default:
{
hsAssert( false, "ExtractImageFromNode: Invalid image type" );
return false; // Invalid image type
}
}
if ( !image.fMipmap )
{
hsAssert( false, "ExtractImageFromNode failed" );
return false;
}
// we now have a mipmap, but it doesn't have a key. make a key for it
static int UniqueIdentifier = 0;
char keyName[512];
sprintf( keyName, "VaultImage_%lu_%d", src->nodeId, UniqueIdentifier++ );
// create a key for the mipmap
plKey imageKey = hsgResMgr::ResMgr()->NewKey( keyName, image.fMipmap, plLocation::kGlobalFixedLoc );
// ref the image key
hsgResMgr::ResMgr()->AddViaNotify( imageKey, TRACKED_NEW plGenRefMsg(
plNetClientMgr::GetInstance()->GetKey(), plRefMsg::kOnCreate, 0, plNetClientMgr::kVaultImage ),
plRefFlags::kActiveRef );
return ( image.fMipmap->GetKey()!=nil );
}
////////////////////////////////////////////////////////////////////
// End.

View File

@ -1,234 +1,234 @@
/*==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==*/
#include "plNetClientMgr.h"
#include "plNetClientVault.h"
#include "../pnNetCommon/plNetMsg.h"
#include "../plGImage/plMipmap.h"
#include "../plJPEG/plJPEG.h"
#include "../plVault/plVaultTasks.h"
#include "hsResMgr.h"
#include "../pnMessage/plRefMsg.h"
#include "../plVault/plDniCoordinateInfo.h"
#include "../plVault/plAgeInfoSource.h"
////////////////////////////////////////////////////////////////////
class plNetClientAgeInfoSource : public plAgeInfoSource
{
plDniCoordinateInfo fNilCoords; // TEMPORARY
public:
const plDniCoordinateInfo * GetAgeCoords( void ) const
{
return &fNilCoords; // tmp
}
const plUnifiedTime * GetAgeTime( void ) const
{
static plUnifiedTime ut;
ut.SetSecsDouble(plNetClientMgr::GetInstance()->GetCurrentAgeElapsedSeconds());
return &ut;
}
const char * GetAgeName( void ) const
{
return plNetClientMgr::GetInstance()->GetAgeName();
}
const plServerGuid * GetAgeGuid( void ) const
{
return plNetClientMgr::GetInstance()->GetCurrSessionInfo()->GetServerGuid();
}
static plNetClientAgeInfoSource * GetInstance( void )
{
static plNetClientAgeInfoSource Me;
return &Me;
}
};
////////////////////////////////////////////////////////////////////
plNetClientVault::plNetClientVault()
{
}
plNetApp * plNetClientVault::GetNetApp( void ) const
{
return plNetClientMgr::GetInstance();
}
plAgeInfoSource * plNetClientVault::GetAgeInfo( void ) const
{
return plNetClientAgeInfoSource::GetInstance();
}
void plNetClientVault::IInitNode( plVaultNode * node )
{
plVaultImageNode * IMG = plVaultImageNode::ConvertNoRef( node );
if ( IMG )
{
plNetClientVault::ExtractImageFromNode( IMG );
}
}
void plNetClientVault::IFiniNode( plVaultNode * node )
{
plVaultImageNode * IMG = plVaultImageNode::ConvertNoRef( node );
if ( IMG && IMG->GetMipmap() )
{
plNetClientMgr::GetInstance()->GetKey()->Release( IMG->GetMipmap()->GetKey() );
IMG->ISetMipmap( nil );
}
}
int plNetClientVault::ISendNetMsg( plNetMsgVault * msg, UInt32 sendFlags )
{
return plNetClientMgr::GetInstance()->SendMsg( msg, sendFlags );
}
void plNetClientVault::IOnTaskTimedOut( plVaultTask * task )
{
std::string msg;
xtl::format( msg, "KI task timed out: %s", task->ClassName() );
plNetClientMgr::GetInstance()->OnNetFailure( msg.c_str(), true );
}
bool plNetClientVault::IAmOnline( void ) const
{
return plNetClientMgr::GetInstance()->IsEnabled()!=0;
}
//// Image/Mipmap Conversion //////////////////////////////////////////////////
hsBool plNetClientVault::StuffImageIntoNode( plMipmap * src, plVaultImageNode * dst )
{
hsRAMStream ramStream;
// Create our JPEG stream
plJPEG::Instance().SetWriteQuality( 50 ); // In percent quality
if( !plJPEG::Instance().WriteToStream( &ramStream, src ) )
return false;
// Copy the stream to the image element now
void * buffer = dst->AllocBuffer( ramStream.GetEOF() );
if( buffer == nil )
return false;
ramStream.CopyToMem( buffer );
dst->SetImageType( plVaultImageNode::kJPEG );
// possibly make a plKey for the mipmap.
return plNetClientVault::ExtractImageFromNode( dst );
}
hsBool plNetClientVault::ExtractImageFromNode( plVaultImageNode * src)
{
// no id? exit now. we will be called again when element is given an id.
if ( src->GetID()==0 )
return false;
// already have a mipmap and it has a key? release it
if ( src->GetMipmap() && src->GetMipmap()->GetKey()!=nil )
{
plNetClientMgr::GetInstance()->GetKey()->Release( src->GetMipmap()->GetKey() );
src->ISetMipmap( nil );
}
// convert image data to a plMipmap
switch( src->GetImageType() )
{
case plVaultImageNode::kJPEG:
{
// Copy to a RAM stream so the JPEG class is happy
hsRAMStream ramStream;
ramStream.Write( src->GetBufSize(), src->GetBuffer() );
ramStream.Rewind();
// create mipmap from image data
src->ISetMipmap( plJPEG::Instance().ReadFromStream( &ramStream ) );
}
break;
default:
{
hsAssert( false, "ExtractImageFromNode: Invalid image type" );
return false; // Invalid image type
}
}
if ( !src->GetMipmap() )
{
hsAssert( false, "ExtractImageFromNode failed" );
return false;
}
// we now have a mipmap, but it doesn't have a key. make a key for it
static int UniqueIdentifier = 0;
char keyName[512];
sprintf( keyName, "VaultImage_%lu_%d", src->GetID(), UniqueIdentifier++ );
// create a key for the mipmap
plKey imageKey = hsgResMgr::ResMgr()->NewKey( keyName, src->IGetMipmap(),
plLocation::kGlobalFixedLoc );
// ref the image key
hsgResMgr::ResMgr()->AddViaNotify( imageKey, new plGenRefMsg(
plNetClientMgr::GetInstance()->GetKey(), plRefMsg::kOnCreate, 0, 0 ),
plRefFlags::kActiveRef );
return ( src->GetMipmap()->GetKey()!=nil );
}
////////////////////////////////////////////////////////////////////
plNetPlayerVault::plNetPlayerVault()
{
}
bool plNetPlayerVault::IIsThisMe( plVaultPlayerInfoNode * node ) const
{
return GetPlayer()->GetPlayerInfo()->GetID()==node->GetID();
}
plVaultPlayerNode * plNetPlayerVault::GetPlayer( void ) const
{
return plVaultPlayerNode::ConvertNoRef( GetRootNode() );
}
void plNetPlayerVault::IFillOutConnectFields( plNetMsgVault * msg ) const
{
msg->AddInt( plVault::kArg_VaultClientType, plVault::kNodeType_VaultPlayer );
msg->AddInt( plVault::kArg_VaultClientID, plNetClientMgr::GetInstance()->GetDesiredPlayerID() );
}
bool plNetPlayerVault::IIsThisMsgMine( plNetMsgVault * msg ) const
{
if ( plVaultClient::IIsThisMsgMine( msg ) )
return true;
return ( msg->GetInt( plVault::kArg_VaultClientID )==plNetClientMgr::GetInstance()->GetDesiredPlayerID() );
}
////////////////////////////////////////////////////////////////////
// End.
/*==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==*/
#include "plNetClientMgr.h"
#include "plNetClientVault.h"
#include "../pnNetCommon/plNetMsg.h"
#include "../plGImage/plMipmap.h"
#include "../plJPEG/plJPEG.h"
#include "../plVault/plVaultTasks.h"
#include "hsResMgr.h"
#include "../pnMessage/plRefMsg.h"
#include "../plVault/plDniCoordinateInfo.h"
#include "../plVault/plAgeInfoSource.h"
////////////////////////////////////////////////////////////////////
class plNetClientAgeInfoSource : public plAgeInfoSource
{
plDniCoordinateInfo fNilCoords; // TEMPORARY
public:
const plDniCoordinateInfo * GetAgeCoords( void ) const
{
return &fNilCoords; // tmp
}
const plUnifiedTime * GetAgeTime( void ) const
{
static plUnifiedTime ut;
ut.SetSecsDouble(plNetClientMgr::GetInstance()->GetCurrentAgeElapsedSeconds());
return &ut;
}
const char * GetAgeName( void ) const
{
return plNetClientMgr::GetInstance()->GetAgeName();
}
const plServerGuid * GetAgeGuid( void ) const
{
return plNetClientMgr::GetInstance()->GetCurrSessionInfo()->GetServerGuid();
}
static plNetClientAgeInfoSource * GetInstance( void )
{
static plNetClientAgeInfoSource Me;
return &Me;
}
};
////////////////////////////////////////////////////////////////////
plNetClientVault::plNetClientVault()
{
}
plNetApp * plNetClientVault::GetNetApp( void ) const
{
return plNetClientMgr::GetInstance();
}
plAgeInfoSource * plNetClientVault::GetAgeInfo( void ) const
{
return plNetClientAgeInfoSource::GetInstance();
}
void plNetClientVault::IInitNode( plVaultNode * node )
{
plVaultImageNode * IMG = plVaultImageNode::ConvertNoRef( node );
if ( IMG )
{
plNetClientVault::ExtractImageFromNode( IMG );
}
}
void plNetClientVault::IFiniNode( plVaultNode * node )
{
plVaultImageNode * IMG = plVaultImageNode::ConvertNoRef( node );
if ( IMG && IMG->GetMipmap() )
{
plNetClientMgr::GetInstance()->GetKey()->Release( IMG->GetMipmap()->GetKey() );
IMG->ISetMipmap( nil );
}
}
int plNetClientVault::ISendNetMsg( plNetMsgVault * msg, UInt32 sendFlags )
{
return plNetClientMgr::GetInstance()->SendMsg( msg, sendFlags );
}
void plNetClientVault::IOnTaskTimedOut( plVaultTask * task )
{
std::string msg;
xtl::format( msg, "KI task timed out: %s", task->ClassName() );
plNetClientMgr::GetInstance()->OnNetFailure( msg.c_str(), true );
}
bool plNetClientVault::IAmOnline( void ) const
{
return plNetClientMgr::GetInstance()->IsEnabled()!=0;
}
//// Image/Mipmap Conversion //////////////////////////////////////////////////
hsBool plNetClientVault::StuffImageIntoNode( plMipmap * src, plVaultImageNode * dst )
{
hsRAMStream ramStream;
// Create our JPEG stream
plJPEG::Instance().SetWriteQuality( 50 ); // In percent quality
if( !plJPEG::Instance().WriteToStream( &ramStream, src ) )
return false;
// Copy the stream to the image element now
void * buffer = dst->AllocBuffer( ramStream.GetEOF() );
if( buffer == nil )
return false;
ramStream.CopyToMem( buffer );
dst->SetImageType( plVaultImageNode::kJPEG );
// possibly make a plKey for the mipmap.
return plNetClientVault::ExtractImageFromNode( dst );
}
hsBool plNetClientVault::ExtractImageFromNode( plVaultImageNode * src)
{
// no id? exit now. we will be called again when element is given an id.
if ( src->GetID()==0 )
return false;
// already have a mipmap and it has a key? release it
if ( src->GetMipmap() && src->GetMipmap()->GetKey()!=nil )
{
plNetClientMgr::GetInstance()->GetKey()->Release( src->GetMipmap()->GetKey() );
src->ISetMipmap( nil );
}
// convert image data to a plMipmap
switch( src->GetImageType() )
{
case plVaultImageNode::kJPEG:
{
// Copy to a RAM stream so the JPEG class is happy
hsRAMStream ramStream;
ramStream.Write( src->GetBufSize(), src->GetBuffer() );
ramStream.Rewind();
// create mipmap from image data
src->ISetMipmap( plJPEG::Instance().ReadFromStream( &ramStream ) );
}
break;
default:
{
hsAssert( false, "ExtractImageFromNode: Invalid image type" );
return false; // Invalid image type
}
}
if ( !src->GetMipmap() )
{
hsAssert( false, "ExtractImageFromNode failed" );
return false;
}
// we now have a mipmap, but it doesn't have a key. make a key for it
static int UniqueIdentifier = 0;
char keyName[512];
sprintf( keyName, "VaultImage_%lu_%d", src->GetID(), UniqueIdentifier++ );
// create a key for the mipmap
plKey imageKey = hsgResMgr::ResMgr()->NewKey( keyName, src->IGetMipmap(),
plLocation::kGlobalFixedLoc );
// ref the image key
hsgResMgr::ResMgr()->AddViaNotify( imageKey, new plGenRefMsg(
plNetClientMgr::GetInstance()->GetKey(), plRefMsg::kOnCreate, 0, 0 ),
plRefFlags::kActiveRef );
return ( src->GetMipmap()->GetKey()!=nil );
}
////////////////////////////////////////////////////////////////////
plNetPlayerVault::plNetPlayerVault()
{
}
bool plNetPlayerVault::IIsThisMe( plVaultPlayerInfoNode * node ) const
{
return GetPlayer()->GetPlayerInfo()->GetID()==node->GetID();
}
plVaultPlayerNode * plNetPlayerVault::GetPlayer( void ) const
{
return plVaultPlayerNode::ConvertNoRef( GetRootNode() );
}
void plNetPlayerVault::IFillOutConnectFields( plNetMsgVault * msg ) const
{
msg->AddInt( plVault::kArg_VaultClientType, plVault::kNodeType_VaultPlayer );
msg->AddInt( plVault::kArg_VaultClientID, plNetClientMgr::GetInstance()->GetDesiredPlayerID() );
}
bool plNetPlayerVault::IIsThisMsgMine( plNetMsgVault * msg ) const
{
if ( plVaultClient::IIsThisMsgMine( msg ) )
return true;
return ( msg->GetInt( plVault::kArg_VaultClientID )==plNetClientMgr::GetInstance()->GetDesiredPlayerID() );
}
////////////////////////////////////////////////////////////////////
// End.

View File

@ -1,71 +1,71 @@
/*==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==*/
#ifndef plNetClientVault_h_inc
#define plNetClientVault_h_inc
#include "../plVault/plVaultClient.h"
class plMipmap;
class plVaultImageNode;
////////////////////////////////////////////////////////////////////
class plNetClientVault : public plVaultClient
{
protected:
void IInitNode( plVaultNode * node );
void IFiniNode( plVaultNode * node );
int ISendNetMsg( plNetMsgVault * msg, UInt32 sendFlags=0 );
void IOnTaskTimedOut( plVaultTask * task );
bool IAmOnline( void ) const;
public:
plNetClientVault();
plNetApp * GetNetApp( void ) const;
plAgeInfoSource * GetAgeInfo( void ) const;
// static helpers to convert between plMipmap and plVaultImageNode
static hsBool StuffImageIntoNode( plMipmap * src, plVaultImageNode * dst );
static hsBool ExtractImageFromNode( plVaultImageNode * src );
};
////////////////////////////////////////////////////////////////////
class plNetPlayerVault : public plNetClientVault
{
protected:
bool IIsThisMe( plVaultPlayerInfoNode * node ) const;
void IFillOutConnectFields( plNetMsgVault * msg ) const;
bool IIsThisMsgMine( plNetMsgVault * msg ) const;
public:
plNetPlayerVault();
plVaultPlayerNode * GetPlayer( void ) const;
};
#endif // plNetClientVault_h_inc
/*==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==*/
#ifndef plNetClientVault_h_inc
#define plNetClientVault_h_inc
#include "../plVault/plVaultClient.h"
class plMipmap;
class plVaultImageNode;
////////////////////////////////////////////////////////////////////
class plNetClientVault : public plVaultClient
{
protected:
void IInitNode( plVaultNode * node );
void IFiniNode( plVaultNode * node );
int ISendNetMsg( plNetMsgVault * msg, UInt32 sendFlags=0 );
void IOnTaskTimedOut( plVaultTask * task );
bool IAmOnline( void ) const;
public:
plNetClientVault();
plNetApp * GetNetApp( void ) const;
plAgeInfoSource * GetAgeInfo( void ) const;
// static helpers to convert between plMipmap and plVaultImageNode
static hsBool StuffImageIntoNode( plMipmap * src, plVaultImageNode * dst );
static hsBool ExtractImageFromNode( plVaultImageNode * src );
};
////////////////////////////////////////////////////////////////////
class plNetPlayerVault : public plNetClientVault
{
protected:
bool IIsThisMe( plVaultPlayerInfoNode * node ) const;
void IFillOutConnectFields( plNetMsgVault * msg ) const;
bool IIsThisMsgMine( plNetMsgVault * msg ) const;
public:
plNetPlayerVault();
plVaultPlayerNode * GetPlayer( void ) const;
};
#endif // plNetClientVault_h_inc

File diff suppressed because it is too large Load Diff

View File

@ -1,148 +1,148 @@
/*==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==*/
#ifndef plNetLinkingMgr_h_inc
#define plNetLinkingMgr_h_inc
#include "hsTypes.h"
#include "hsStlUtils.h"
#include "hsBitVector.h"
#include "plNetCommon/plNetServerSessionInfo.h"
#include "plNetCommon/plNetCommon.h"
#include "plMessage/plLinkToAgeMsg.h"
class plMessage;
struct plNCAgeJoiner;
struct plNCAgeLeaver;
class plNetLinkingMgr
{
static void NCAgeJoinerCallback (
plNCAgeJoiner * joiner,
unsigned type,
void * notify,
void * userState
);
static void NCAgeLeaverCallback (
plNCAgeLeaver * leaver,
unsigned type,
void * notify,
void * userState
);
friend struct NCAgeJoinerCallback;
friend struct NCAgeLeaverCallback;
static void ExecNextOp ();
plNetLinkingMgr();
plNetLinkingMgr(const plNetLinkingMgr &);
enum Cmds
{
kNilCmd,
// Sent to a player to have them call us back with info for linking to their age.
kLinkPlayerHere,
// Offer link to player.
kOfferLinkToPlayer,
// Offer link to another player from a public linking book (to my instance of the age w/out going through personal age)
kOfferLinkFromPublicBook,
// Sent to a player to have them link to their last age
kLinkPlayerToPrevAge
};
bool IPreProcessLink( void );
void IPostProcessLink( void );
bool IProcessLinkingMgrMsg( plLinkingMgrMsg * msg );
bool IProcessLinkToAgeMsg( plLinkToAgeMsg * msg );
bool IDispatchMsg( plMessage * msg, UInt32 playerID );
public:
static plNetLinkingMgr * GetInstance();
hsBool MsgReceive( plMessage *msg ); // TODO: Make this a hsKeyedObject so we can really handle messages.
void Update();
bool IsEnabled( void ) const { return fLinkingEnabled;}
void SetEnabled( bool b );
bool LinkedIn () const { return fLinkedIn && fLinkingEnabled; }
bool Linking () const { return !fLinkedIn && !fLinkingEnabled; }
// Link to an age.
void LinkToAge( plAgeLinkStruct * link, UInt32 playerID=kInvalidPlayerID );
void LinkToAge( plAgeLinkStruct * link, const char* linkAnim, UInt32 playerID=kInvalidPlayerID );
// Link to my last age.
void LinkToPrevAge( UInt32 playerID=kInvalidPlayerID );
// Link to my Personal Age
void LinkToMyPersonalAge( UInt32 playerID=kInvalidPlayerID );
// Link to my Neighborhood Age
void LinkToMyNeighborhoodAge( UInt32 playerID=kInvalidPlayerID );
// Link a player here.
void LinkPlayerHere( UInt32 playerID );
// Link player to specified age
void LinkPlayerToAge( plAgeLinkStruct * link, UInt32 playerID );
// Link player back to his last age
void LinkPlayerToPrevAge( UInt32 playerID );
// Link us to a players age.
void LinkToPlayersAge( UInt32 playerID );
// Offer a link to player.
void OfferLinkToPlayer( const plAgeLinkStruct * info, UInt32 playerID, plKey replyKey );
void OfferLinkToPlayer( const plAgeInfoStruct * info, UInt32 playerID );
void OfferLinkToPlayer( const plAgeLinkStruct * info, UInt32 playerID );
// Leave the current age
void LeaveAge (bool quitting);
// link info
plAgeLinkStruct * GetAgeLink() { return &fAgeLink; }
plAgeLinkStruct * GetPrevAgeLink() { return &fPrevAgeLink; }
// lobby info
void SetLobbyAddr( const char * ipaddr ) { fLobbyInfo.SetServerAddr( ipaddr );}
void SetLobbyPort( int port ) { fLobbyInfo.SetServerPort( port );}
const plNetServerSessionInfo * GetLobbyServerInfo( void ) const { return &fLobbyInfo;}
// helpers
static std::string GetProperAgeName( const char * ageName ); // attempt to fix wrong case age name.
private:
bool fLinkingEnabled;
bool fLinkedIn;
// The age we are either joining or are joined with.
plAgeLinkStruct fAgeLink;
// The age we just left.
plAgeLinkStruct fPrevAgeLink;
// The lobby we want to talk to.
plNetServerSessionInfo fLobbyInfo;
};
#endif // plNetLinkingMgr_h_inc
/*==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==*/
#ifndef plNetLinkingMgr_h_inc
#define plNetLinkingMgr_h_inc
#include "hsTypes.h"
#include "hsStlUtils.h"
#include "hsBitVector.h"
#include "plNetCommon/plNetServerSessionInfo.h"
#include "plNetCommon/plNetCommon.h"
#include "plMessage/plLinkToAgeMsg.h"
class plMessage;
struct plNCAgeJoiner;
struct plNCAgeLeaver;
class plNetLinkingMgr
{
static void NCAgeJoinerCallback (
plNCAgeJoiner * joiner,
unsigned type,
void * notify,
void * userState
);
static void NCAgeLeaverCallback (
plNCAgeLeaver * leaver,
unsigned type,
void * notify,
void * userState
);
friend struct NCAgeJoinerCallback;
friend struct NCAgeLeaverCallback;
static void ExecNextOp ();
plNetLinkingMgr();
plNetLinkingMgr(const plNetLinkingMgr &);
enum Cmds
{
kNilCmd,
// Sent to a player to have them call us back with info for linking to their age.
kLinkPlayerHere,
// Offer link to player.
kOfferLinkToPlayer,
// Offer link to another player from a public linking book (to my instance of the age w/out going through personal age)
kOfferLinkFromPublicBook,
// Sent to a player to have them link to their last age
kLinkPlayerToPrevAge
};
bool IPreProcessLink( void );
void IPostProcessLink( void );
bool IProcessLinkingMgrMsg( plLinkingMgrMsg * msg );
bool IProcessLinkToAgeMsg( plLinkToAgeMsg * msg );
bool IDispatchMsg( plMessage * msg, UInt32 playerID );
public:
static plNetLinkingMgr * GetInstance();
hsBool MsgReceive( plMessage *msg ); // TODO: Make this a hsKeyedObject so we can really handle messages.
void Update();
bool IsEnabled( void ) const { return fLinkingEnabled;}
void SetEnabled( bool b );
bool LinkedIn () const { return fLinkedIn && fLinkingEnabled; }
bool Linking () const { return !fLinkedIn && !fLinkingEnabled; }
// Link to an age.
void LinkToAge( plAgeLinkStruct * link, UInt32 playerID=kInvalidPlayerID );
void LinkToAge( plAgeLinkStruct * link, const char* linkAnim, UInt32 playerID=kInvalidPlayerID );
// Link to my last age.
void LinkToPrevAge( UInt32 playerID=kInvalidPlayerID );
// Link to my Personal Age
void LinkToMyPersonalAge( UInt32 playerID=kInvalidPlayerID );
// Link to my Neighborhood Age
void LinkToMyNeighborhoodAge( UInt32 playerID=kInvalidPlayerID );
// Link a player here.
void LinkPlayerHere( UInt32 playerID );
// Link player to specified age
void LinkPlayerToAge( plAgeLinkStruct * link, UInt32 playerID );
// Link player back to his last age
void LinkPlayerToPrevAge( UInt32 playerID );
// Link us to a players age.
void LinkToPlayersAge( UInt32 playerID );
// Offer a link to player.
void OfferLinkToPlayer( const plAgeLinkStruct * info, UInt32 playerID, plKey replyKey );
void OfferLinkToPlayer( const plAgeInfoStruct * info, UInt32 playerID );
void OfferLinkToPlayer( const plAgeLinkStruct * info, UInt32 playerID );
// Leave the current age
void LeaveAge (bool quitting);
// link info
plAgeLinkStruct * GetAgeLink() { return &fAgeLink; }
plAgeLinkStruct * GetPrevAgeLink() { return &fPrevAgeLink; }
// lobby info
void SetLobbyAddr( const char * ipaddr ) { fLobbyInfo.SetServerAddr( ipaddr );}
void SetLobbyPort( int port ) { fLobbyInfo.SetServerPort( port );}
const plNetServerSessionInfo * GetLobbyServerInfo( void ) const { return &fLobbyInfo;}
// helpers
static std::string GetProperAgeName( const char * ageName ); // attempt to fix wrong case age name.
private:
bool fLinkingEnabled;
bool fLinkedIn;
// The age we are either joining or are joined with.
plAgeLinkStruct fAgeLink;
// The age we just left.
plAgeLinkStruct fPrevAgeLink;
// The lobby we want to talk to.
plNetServerSessionInfo fLobbyInfo;
};
#endif // plNetLinkingMgr_h_inc

View File

@ -1,306 +1,306 @@
/*==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==*/
#include "plNetObjectDebugger.h"
#include "hsResMgr.h"
#include "hsTemplates.h"
#include "pnUtils/pnUtils.h"
#include "pnKeyedObject/hsKeyedObject.h"
#include "plStatusLog/plStatusLog.h"
#include "plResMgr/plKeyFinder.h"
#include "plNetClient/plNetClientMgr.h"
#include "plAgeLoader/plAgeLoader.h"
plNetObjectDebugger::DebugObject::DebugObject(const char* objName, plLocation& loc, UInt32 flags) :
fLoc(loc),
fFlags(flags)
{
std::string tmp = objName;
hsStrLower((char*)tmp.c_str());
fObjName = tmp;
}
//
// return true if string matches objName according to flags
//
bool plNetObjectDebugger::DebugObject::StringMatches(const char* str) const
{
if (!str)
return false;
if (fFlags & kExactStringMatch)
return !stricmp(str, fObjName.c_str());
if (fFlags & kEndStringMatch)
{
int len=strlen(str);
if (len>fObjName.size())
return false;
return !stricmp(str, fObjName.c_str()+fObjName.size()-len);
}
if (fFlags & kStartStringMatch)
{
int len=strlen(str);
if (len>fObjName.size())
return false;
return !strnicmp(str, fObjName.c_str(), strlen(str));
}
if (fFlags & kSubStringMatch)
{
std::string tmp = str;
hsStrLower((char*)tmp.c_str());
return (strstr(tmp.c_str(), fObjName.c_str()) != nil);
}
hsAssert(false, "missing flags");
return false;
}
//
// if both objName and pageName are provided, and this object has page info,
// return true if object matches both string and location.
// else just return true if object matches string
//
bool plNetObjectDebugger::DebugObject::ObjectMatches(const char* objName, const char* pageName)
{
if (!objName)
return false;
if (!pageName || (fFlags & kPageMatch)==0)
{
// only have enough info to match by objName
return StringMatches(objName);
}
plLocation loc;
loc = plKeyFinder::Instance().FindLocation(NetCommGetAge()->ageDatasetName, pageName);
return (StringMatches(objName) && loc==fLoc);
}
//
// try to match by plLocation
//
bool plNetObjectDebugger::DebugObject::ObjectMatches(const hsKeyedObject* obj)
{
if (!obj || !obj->GetKey())
return false;
if ((fFlags & kPageMatch)==0)
{
// match based on object name only
return StringMatches(obj->GetKeyName());
}
return (obj->GetKey()->GetUoid().GetLocation()==fLoc);
}
/////////////////////////////////////////////////////////////////
// plNetObjectDebugger
/////////////////////////////////////////////////////////////////
plNetObjectDebugger::plNetObjectDebugger() : fStatusLog(nil), fDebugging(false)
{
}
plNetObjectDebugger::~plNetObjectDebugger()
{
ClearAllDebugObjects();
delete fStatusLog;
}
//
// STATIC
//
plNetObjectDebugger* plNetObjectDebugger::GetInstance()
{
static plNetObjectDebugger gNetObjectDebugger;
if (plNetObjectDebuggerBase::GetInstance()==nil)
plNetObjectDebuggerBase::SetInstance(&gNetObjectDebugger);
return &gNetObjectDebugger;
}
//
// create StatusLog if necessary
//
void plNetObjectDebugger::ICreateStatusLog() const
{
if (!fStatusLog)
{
fStatusLog = plStatusLogMgr::GetInstance().CreateStatusLog(40, "NetObject.log",
plStatusLog::kFilledBackground | plStatusLog::kAlignToTop | plStatusLog::kTimestamp );
}
}
bool plNetObjectDebugger::AddDebugObject(const char* objName, const char* pageName)
{
if (!objName)
return false;
int size=strlen(objName)+1;
hsTempArray<char> tmpObjName(size);
memset(tmpObjName, 0, size);
//
// set string matching flags
//
int len = strlen(objName);
UInt32 flags=0;
if (objName[0]=='*')
{
if (objName[len-1]=='*')
{
flags = kSubStringMatch; // *foo*
strncpy(tmpObjName, objName+1, strlen(objName)-2);
}
else
{
flags = kEndStringMatch; // *foo
strncpy(tmpObjName, objName+1, strlen(objName)-1);
}
}
if (!flags && objName[len-1]=='*')
{
flags = kStartStringMatch; // foo*
strncpy(tmpObjName, objName, strlen(objName)-1);
}
if (!flags)
{
flags = kExactStringMatch;
strcpy(tmpObjName, objName);
}
//
// set plLocation
//
plLocation loc;
if (pageName)
{
loc = plKeyFinder::Instance().FindLocation(NetCommGetAge()->ageDatasetName, pageName);
flags |= kPageMatch;
}
fDebugObjects.push_back(TRACKED_NEW DebugObject(tmpObjName, loc, flags));
ICreateStatusLog();
return true;
}
bool plNetObjectDebugger::RemoveDebugObject(const char* objName, const char* pageName)
{
bool didIt=false;
if (!pageName)
{
DebugObjectList::iterator it =fDebugObjects.begin();
for( ; it != fDebugObjects.end(); )
{
if ( (*it) && (*it)->ObjectMatches(objName, pageName))
{
delete *it;
it = fDebugObjects.erase(it);
didIt=true;
}
else
it++;
}
}
return didIt;
}
void plNetObjectDebugger::ClearAllDebugObjects()
{
DebugObjectList::iterator it =fDebugObjects.begin();
for( ; it != fDebugObjects.end(); it++)
{
delete *it;
}
fDebugObjects.clear();
}
//
// write to status log if there's a string match
//
void plNetObjectDebugger::LogMsgIfMatch(const char* msg) const
{
if (GetNumDebugObjects()==0 || !msg)
return;
// extract object name from msg, expects '...object:foo,...'
std::string tmp = msg;
hsStrLower((char*)tmp.c_str());
std::string objTag="object";
const char* c=strstr(tmp.c_str(), objTag.c_str());
if (c && c != tmp.c_str())
{
c+=objTag.size();
// move past spaces
while ( *c || *c==' ' )
c++;
char objName[128];
int i=0;
// copy objName token
while(*c && *c != ',' && *c != ' ' && i<127)
objName[i++] = *c++;
objName[i]=0;
DebugObjectList::const_iterator it = fDebugObjects.begin();
for( objName[0]; it != fDebugObjects.end(); it++)
{
if ((*it) && (*it)->StringMatches(objName))
{
LogMsg(msg);
break;
}
}
}
}
void plNetObjectDebugger::LogMsg(const char* msg) const
{
DEBUG_MSG(msg);
}
bool plNetObjectDebugger::IsDebugObject(const hsKeyedObject* obj) const
{
DebugObjectList::const_iterator it =fDebugObjects.begin();
for( ; it != fDebugObjects.end(); it++)
if ((*it) && (*it)->ObjectMatches(obj))
{
return true;
}
return false;
}
/*==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==*/
#include "plNetObjectDebugger.h"
#include "hsResMgr.h"
#include "hsTemplates.h"
#include "pnUtils/pnUtils.h"
#include "pnKeyedObject/hsKeyedObject.h"
#include "plStatusLog/plStatusLog.h"
#include "plResMgr/plKeyFinder.h"
#include "plNetClient/plNetClientMgr.h"
#include "plAgeLoader/plAgeLoader.h"
plNetObjectDebugger::DebugObject::DebugObject(const char* objName, plLocation& loc, UInt32 flags) :
fLoc(loc),
fFlags(flags)
{
std::string tmp = objName;
hsStrLower((char*)tmp.c_str());
fObjName = tmp;
}
//
// return true if string matches objName according to flags
//
bool plNetObjectDebugger::DebugObject::StringMatches(const char* str) const
{
if (!str)
return false;
if (fFlags & kExactStringMatch)
return !stricmp(str, fObjName.c_str());
if (fFlags & kEndStringMatch)
{
int len=strlen(str);
if (len>fObjName.size())
return false;
return !stricmp(str, fObjName.c_str()+fObjName.size()-len);
}
if (fFlags & kStartStringMatch)
{
int len=strlen(str);
if (len>fObjName.size())
return false;
return !strnicmp(str, fObjName.c_str(), strlen(str));
}
if (fFlags & kSubStringMatch)
{
std::string tmp = str;
hsStrLower((char*)tmp.c_str());
return (strstr(tmp.c_str(), fObjName.c_str()) != nil);
}
hsAssert(false, "missing flags");
return false;
}
//
// if both objName and pageName are provided, and this object has page info,
// return true if object matches both string and location.
// else just return true if object matches string
//
bool plNetObjectDebugger::DebugObject::ObjectMatches(const char* objName, const char* pageName)
{
if (!objName)
return false;
if (!pageName || (fFlags & kPageMatch)==0)
{
// only have enough info to match by objName
return StringMatches(objName);
}
plLocation loc;
loc = plKeyFinder::Instance().FindLocation(NetCommGetAge()->ageDatasetName, pageName);
return (StringMatches(objName) && loc==fLoc);
}
//
// try to match by plLocation
//
bool plNetObjectDebugger::DebugObject::ObjectMatches(const hsKeyedObject* obj)
{
if (!obj || !obj->GetKey())
return false;
if ((fFlags & kPageMatch)==0)
{
// match based on object name only
return StringMatches(obj->GetKeyName());
}
return (obj->GetKey()->GetUoid().GetLocation()==fLoc);
}
/////////////////////////////////////////////////////////////////
// plNetObjectDebugger
/////////////////////////////////////////////////////////////////
plNetObjectDebugger::plNetObjectDebugger() : fStatusLog(nil), fDebugging(false)
{
}
plNetObjectDebugger::~plNetObjectDebugger()
{
ClearAllDebugObjects();
delete fStatusLog;
}
//
// STATIC
//
plNetObjectDebugger* plNetObjectDebugger::GetInstance()
{
static plNetObjectDebugger gNetObjectDebugger;
if (plNetObjectDebuggerBase::GetInstance()==nil)
plNetObjectDebuggerBase::SetInstance(&gNetObjectDebugger);
return &gNetObjectDebugger;
}
//
// create StatusLog if necessary
//
void plNetObjectDebugger::ICreateStatusLog() const
{
if (!fStatusLog)
{
fStatusLog = plStatusLogMgr::GetInstance().CreateStatusLog(40, "NetObject.log",
plStatusLog::kFilledBackground | plStatusLog::kAlignToTop | plStatusLog::kTimestamp );
}
}
bool plNetObjectDebugger::AddDebugObject(const char* objName, const char* pageName)
{
if (!objName)
return false;
int size=strlen(objName)+1;
hsTempArray<char> tmpObjName(size);
memset(tmpObjName, 0, size);
//
// set string matching flags
//
int len = strlen(objName);
UInt32 flags=0;
if (objName[0]=='*')
{
if (objName[len-1]=='*')
{
flags = kSubStringMatch; // *foo*
strncpy(tmpObjName, objName+1, strlen(objName)-2);
}
else
{
flags = kEndStringMatch; // *foo
strncpy(tmpObjName, objName+1, strlen(objName)-1);
}
}
if (!flags && objName[len-1]=='*')
{
flags = kStartStringMatch; // foo*
strncpy(tmpObjName, objName, strlen(objName)-1);
}
if (!flags)
{
flags = kExactStringMatch;
strcpy(tmpObjName, objName);
}
//
// set plLocation
//
plLocation loc;
if (pageName)
{
loc = plKeyFinder::Instance().FindLocation(NetCommGetAge()->ageDatasetName, pageName);
flags |= kPageMatch;
}
fDebugObjects.push_back(TRACKED_NEW DebugObject(tmpObjName, loc, flags));
ICreateStatusLog();
return true;
}
bool plNetObjectDebugger::RemoveDebugObject(const char* objName, const char* pageName)
{
bool didIt=false;
if (!pageName)
{
DebugObjectList::iterator it =fDebugObjects.begin();
for( ; it != fDebugObjects.end(); )
{
if ( (*it) && (*it)->ObjectMatches(objName, pageName))
{
delete *it;
it = fDebugObjects.erase(it);
didIt=true;
}
else
it++;
}
}
return didIt;
}
void plNetObjectDebugger::ClearAllDebugObjects()
{
DebugObjectList::iterator it =fDebugObjects.begin();
for( ; it != fDebugObjects.end(); it++)
{
delete *it;
}
fDebugObjects.clear();
}
//
// write to status log if there's a string match
//
void plNetObjectDebugger::LogMsgIfMatch(const char* msg) const
{
if (GetNumDebugObjects()==0 || !msg)
return;
// extract object name from msg, expects '...object:foo,...'
std::string tmp = msg;
hsStrLower((char*)tmp.c_str());
std::string objTag="object";
const char* c=strstr(tmp.c_str(), objTag.c_str());
if (c && c != tmp.c_str())
{
c+=objTag.size();
// move past spaces
while ( *c || *c==' ' )
c++;
char objName[128];
int i=0;
// copy objName token
while(*c && *c != ',' && *c != ' ' && i<127)
objName[i++] = *c++;
objName[i]=0;
DebugObjectList::const_iterator it = fDebugObjects.begin();
for( objName[0]; it != fDebugObjects.end(); it++)
{
if ((*it) && (*it)->StringMatches(objName))
{
LogMsg(msg);
break;
}
}
}
}
void plNetObjectDebugger::LogMsg(const char* msg) const
{
DEBUG_MSG(msg);
}
bool plNetObjectDebugger::IsDebugObject(const hsKeyedObject* obj) const
{
DebugObjectList::const_iterator it =fDebugObjects.begin();
for( ; it != fDebugObjects.end(); it++)
if ((*it) && (*it)->ObjectMatches(obj))
{
return true;
}
return false;
}

View File

@ -1,85 +1,85 @@
/*==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==*/
#ifndef plNetObjectDebugger_inc
#define plNetObjectDebugger_inc
#include "hsTypes.h"
#include "hsStlUtils.h"
#include "pnKeyedObject/plUoid.h"
#include "pnNetCommon/plNetApp.h"
class hsKeyedObject;
class plStatusLog;
class plNetObjectDebugger : public plNetObjectDebuggerBase
{
public:
enum Flags
{
kExactStringMatch = 0x1,
kEndStringMatch = 0x2,
kStartStringMatch = 0x4,
kSubStringMatch = 0x8,
kPageMatch = 0x10 // has page info specified
};
private:
struct DebugObject
{
std::string fObjName;
plLocation fLoc;
UInt32 fFlags;
bool StringMatches(const char* str) const; // return true if string matches objName according to flags
bool ObjectMatches(const hsKeyedObject* obj);
bool ObjectMatches(const char* objName, const char* pageName);
DebugObject(const char* objName, plLocation& loc, UInt32 flags);
};
typedef std::vector<DebugObject*> DebugObjectList;
DebugObjectList fDebugObjects;
mutable plStatusLog* fStatusLog;
bool fDebugging;
void ICreateStatusLog() const;
public:
plNetObjectDebugger();
~plNetObjectDebugger();
static plNetObjectDebugger* GetInstance();
bool GetDebugging() const { return fDebugging; }
void SetDebugging(bool b) { fDebugging=b; }
// object fxns
bool AddDebugObject(const char* objName, const char* pageName=nil);
bool RemoveDebugObject(const char* objName, const char* pageName=nil);
void ClearAllDebugObjects();
int GetNumDebugObjects() const { return fDebugObjects.size(); }
bool IsDebugObject(const hsKeyedObject* obj) const;
void LogMsgIfMatch(const char* msg) const; // write to status log if there's a string match
void LogMsg(const char* msg) const;
};
#endif // plNetObjectDebugger_inc
/*==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==*/
#ifndef plNetObjectDebugger_inc
#define plNetObjectDebugger_inc
#include "hsTypes.h"
#include "hsStlUtils.h"
#include "pnKeyedObject/plUoid.h"
#include "pnNetCommon/plNetApp.h"
class hsKeyedObject;
class plStatusLog;
class plNetObjectDebugger : public plNetObjectDebuggerBase
{
public:
enum Flags
{
kExactStringMatch = 0x1,
kEndStringMatch = 0x2,
kStartStringMatch = 0x4,
kSubStringMatch = 0x8,
kPageMatch = 0x10 // has page info specified
};
private:
struct DebugObject
{
std::string fObjName;
plLocation fLoc;
UInt32 fFlags;
bool StringMatches(const char* str) const; // return true if string matches objName according to flags
bool ObjectMatches(const hsKeyedObject* obj);
bool ObjectMatches(const char* objName, const char* pageName);
DebugObject(const char* objName, plLocation& loc, UInt32 flags);
};
typedef std::vector<DebugObject*> DebugObjectList;
DebugObjectList fDebugObjects;
mutable plStatusLog* fStatusLog;
bool fDebugging;
void ICreateStatusLog() const;
public:
plNetObjectDebugger();
~plNetObjectDebugger();
static plNetObjectDebugger* GetInstance();
bool GetDebugging() const { return fDebugging; }
void SetDebugging(bool b) { fDebugging=b; }
// object fxns
bool AddDebugObject(const char* objName, const char* pageName=nil);
bool RemoveDebugObject(const char* objName, const char* pageName=nil);
void ClearAllDebugObjects();
int GetNumDebugObjects() const { return fDebugObjects.size(); }
bool IsDebugObject(const hsKeyedObject* obj) const;
void LogMsgIfMatch(const char* msg) const; // write to status log if there's a string match
void LogMsg(const char* msg) const;
};
#endif // plNetObjectDebugger_inc

View File

@ -1,145 +1,145 @@
/*==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==*/
#include <algorithm>
#include "plgDispatch.h"
#include "plNetClientMgr.h"
#include "plNetVoiceList.h"
#include "plNetTransport/plNetTransportMember.h"
#include "pnMessage/plSoundMsg.h"
#include "pnKeyedObject/plKey.h"
#include "plStatusLog/plStatusLog.h"
// statics
float plNetListenList::kUpdateInterval=0.5f;
int plNetListenList::kMaxListenListSize=-1; // -1 is unlimited
float plNetListenList::kMaxListenDistSq=75.0f*75.0f;
int plNetVoiceList::FindMember(plNetTransportMember* e)
{
VoiceListType::iterator result = std::find(fMembers.begin(), fMembers.end(), e);
return result!=fMembers.end() ? result-fMembers.begin() : -1;
}
/*****************************************************************************
*
* plNetTalkList
*
***/
void plNetTalkList::UpdateTransportGroup(plNetClientMgr* nc)
{
if (fFlags & kDirty)
{
nc->fTransport.ClearChannelGrp(plNetClientMgr::kNetChanVoice);
if (nc->IsPeerToPeer())
{
int i;
for(i=0;i<GetNumMembers();i++)
{
if (GetMember(i)->IsPeerToPeer())
nc->fTransport.SubscribeToChannelGrp(GetMember(i), plNetClientMgr::kNetChanVoice);
}
}
fFlags &= ~kDirty;
}
}
void plNetTalkList::AddMember(plNetTransportMember* e)
{
if (FindMember(e)==-1)
{
plStatusLog::AddLineS("voice.log", "Adding %s to talk list", e->AsStdString().c_str());
fMembers.push_back(e);
}
fFlags |= kDirty;
}
void plNetTalkList::RemoveMember(plNetTransportMember* e)
{
int idx=FindMember(e);
if (idx!=-1)
{
plStatusLog::AddLineS("voice.log", "Removing %s from talklist", e->AsStdString().c_str());
fMembers.erase(fMembers.begin()+idx);
}
fFlags |= kDirty;
}
void plNetTalkList::Clear()
{
plNetVoiceList::Clear();
fFlags |= kDirty;
}
/*****************************************************************************
*
* plNetListenList
*
***/
void plNetListenList::AddMember(plNetTransportMember* e)
{
if (FindMember(e)==-1)
{
plStatusLog::AddLineS("voice.log", "Adding %s to listen list ", e->AsStdString().c_str());
fMembers.push_back(e);
#if 0
// call the new member's win audible and set talk icon parameters
plSoundMsg* pMsg = TRACKED_NEW plSoundMsg;
plArmatureMod* pMod = plArmatureMod::ConvertNoRef(e->GetAvatarKey()->GetObjectPtr());
if (pMod)
pMsg->AddReceiver(pMod->GetTarget(0)->GetKey());
pMsg->SetCmd(plSoundMsg::kSetTalkIcon);
pMsg->fIndex = GetNumMembers();
pMsg->fNameStr = (UInt32)e->GetName();
plgDispatch::MsgSend(pMsg);
#endif
}
}
void plNetListenList::RemoveMember(plNetTransportMember* e)
{
int idx=FindMember(e);
if (idx!=-1)
{
fMembers.erase(fMembers.begin()+idx);
plStatusLog::AddLineS("voice.log", "Removing %s from listen list", e->AsStdString().c_str());
#if 0
// call the new member's win audible and set talk icon parameters
plSoundMsg* pMsg = TRACKED_NEW plSoundMsg;
plArmatureMod* pMod = plArmatureMod::ConvertNoRef(e->GetAvatarKey()->GetObjectPtr());
if (pMod)
pMsg->AddReceiver(pMod->GetTarget(0)->GetKey());
pMsg->SetCmd(plSoundMsg::kClearTalkIcon);
plgDispatch::MsgSend(pMsg);
#endif
}
}
/*==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==*/
#include <algorithm>
#include "plgDispatch.h"
#include "plNetClientMgr.h"
#include "plNetVoiceList.h"
#include "plNetTransport/plNetTransportMember.h"
#include "pnMessage/plSoundMsg.h"
#include "pnKeyedObject/plKey.h"
#include "plStatusLog/plStatusLog.h"
// statics
float plNetListenList::kUpdateInterval=0.5f;
int plNetListenList::kMaxListenListSize=-1; // -1 is unlimited
float plNetListenList::kMaxListenDistSq=75.0f*75.0f;
int plNetVoiceList::FindMember(plNetTransportMember* e)
{
VoiceListType::iterator result = std::find(fMembers.begin(), fMembers.end(), e);
return result!=fMembers.end() ? result-fMembers.begin() : -1;
}
/*****************************************************************************
*
* plNetTalkList
*
***/
void plNetTalkList::UpdateTransportGroup(plNetClientMgr* nc)
{
if (fFlags & kDirty)
{
nc->fTransport.ClearChannelGrp(plNetClientMgr::kNetChanVoice);
if (nc->IsPeerToPeer())
{
int i;
for(i=0;i<GetNumMembers();i++)
{
if (GetMember(i)->IsPeerToPeer())
nc->fTransport.SubscribeToChannelGrp(GetMember(i), plNetClientMgr::kNetChanVoice);
}
}
fFlags &= ~kDirty;
}
}
void plNetTalkList::AddMember(plNetTransportMember* e)
{
if (FindMember(e)==-1)
{
plStatusLog::AddLineS("voice.log", "Adding %s to talk list", e->AsStdString().c_str());
fMembers.push_back(e);
}
fFlags |= kDirty;
}
void plNetTalkList::RemoveMember(plNetTransportMember* e)
{
int idx=FindMember(e);
if (idx!=-1)
{
plStatusLog::AddLineS("voice.log", "Removing %s from talklist", e->AsStdString().c_str());
fMembers.erase(fMembers.begin()+idx);
}
fFlags |= kDirty;
}
void plNetTalkList::Clear()
{
plNetVoiceList::Clear();
fFlags |= kDirty;
}
/*****************************************************************************
*
* plNetListenList
*
***/
void plNetListenList::AddMember(plNetTransportMember* e)
{
if (FindMember(e)==-1)
{
plStatusLog::AddLineS("voice.log", "Adding %s to listen list ", e->AsStdString().c_str());
fMembers.push_back(e);
#if 0
// call the new member's win audible and set talk icon parameters
plSoundMsg* pMsg = TRACKED_NEW plSoundMsg;
plArmatureMod* pMod = plArmatureMod::ConvertNoRef(e->GetAvatarKey()->GetObjectPtr());
if (pMod)
pMsg->AddReceiver(pMod->GetTarget(0)->GetKey());
pMsg->SetCmd(plSoundMsg::kSetTalkIcon);
pMsg->fIndex = GetNumMembers();
pMsg->fNameStr = (UInt32)e->GetName();
plgDispatch::MsgSend(pMsg);
#endif
}
}
void plNetListenList::RemoveMember(plNetTransportMember* e)
{
int idx=FindMember(e);
if (idx!=-1)
{
fMembers.erase(fMembers.begin()+idx);
plStatusLog::AddLineS("voice.log", "Removing %s from listen list", e->AsStdString().c_str());
#if 0
// call the new member's win audible and set talk icon parameters
plSoundMsg* pMsg = TRACKED_NEW plSoundMsg;
plArmatureMod* pMod = plArmatureMod::ConvertNoRef(e->GetAvatarKey()->GetObjectPtr());
if (pMod)
pMsg->AddReceiver(pMod->GetTarget(0)->GetKey());
pMsg->SetCmd(plSoundMsg::kClearTalkIcon);
plgDispatch::MsgSend(pMsg);
#endif
}
}

View File

@ -1,107 +1,107 @@
/*==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==*/
#ifndef plNetVoiceList_h
#define plNetVoiceList_h
#include "hsTypes.h"
#include "hsStlUtils.h"
//
// a simple class used by the net client code to hold listenLists and talkLists
// for voice filtering.
//
class plNetTransportMember;
class plNetVoiceList
{
protected:
typedef std::vector<plNetTransportMember*> VoiceListType;
protected:
VoiceListType fMembers;
public:
plNetVoiceList() {}
virtual ~plNetVoiceList() {}
int GetNumMembers() const { return fMembers.size(); }
plNetTransportMember* GetMember(int i) const { return fMembers[i]; }
virtual void AddMember(plNetTransportMember* e) = 0;
virtual void RemoveMember(plNetTransportMember* e) = 0;
virtual void Clear() { fMembers.clear(); }
int FindMember(plNetTransportMember* e); // return index or -1
};
//
// Specialized version for listen list
// a list of other player I am listening to
//
class plNetListenList : public plNetVoiceList
{
private:
double fLastUpdateTime;
int fNumUpdates;
public:
plNetListenList() : fNumUpdates(0) {}
~plNetListenList() {}
static float kUpdateInterval;
static int kMaxListenListSize;
static float kMaxListenDistSq;
void SetLastUpdateTime(double t) { fLastUpdateTime=t; fNumUpdates++; }
double GetLastUpdateTime() { return fLastUpdateTime; }
hsBool CheckForceSynch() { if (fNumUpdates>10) { fNumUpdates=0; return true;} return false; }
virtual void AddMember(plNetTransportMember* e);
virtual void RemoveMember(plNetTransportMember* e);
};
//
// Specialized version for talk list
// a list of other players I am talking to
//
class plNetClientMgr;
class plNetTalkList : public plNetVoiceList
{
private:
enum
{
kDirty = 0x1
};
UInt32 fFlags;
public:
plNetTalkList() : fFlags(0) {}
~plNetTalkList() {}
void UpdateTransportGroup(plNetClientMgr* nc);
void AddMember(plNetTransportMember* e);
void RemoveMember(plNetTransportMember* e);
void Clear();
};
#endif // plNetVoiceList_h
/*==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==*/
#ifndef plNetVoiceList_h
#define plNetVoiceList_h
#include "hsTypes.h"
#include "hsStlUtils.h"
//
// a simple class used by the net client code to hold listenLists and talkLists
// for voice filtering.
//
class plNetTransportMember;
class plNetVoiceList
{
protected:
typedef std::vector<plNetTransportMember*> VoiceListType;
protected:
VoiceListType fMembers;
public:
plNetVoiceList() {}
virtual ~plNetVoiceList() {}
int GetNumMembers() const { return fMembers.size(); }
plNetTransportMember* GetMember(int i) const { return fMembers[i]; }
virtual void AddMember(plNetTransportMember* e) = 0;
virtual void RemoveMember(plNetTransportMember* e) = 0;
virtual void Clear() { fMembers.clear(); }
int FindMember(plNetTransportMember* e); // return index or -1
};
//
// Specialized version for listen list
// a list of other player I am listening to
//
class plNetListenList : public plNetVoiceList
{
private:
double fLastUpdateTime;
int fNumUpdates;
public:
plNetListenList() : fNumUpdates(0) {}
~plNetListenList() {}
static float kUpdateInterval;
static int kMaxListenListSize;
static float kMaxListenDistSq;
void SetLastUpdateTime(double t) { fLastUpdateTime=t; fNumUpdates++; }
double GetLastUpdateTime() { return fLastUpdateTime; }
hsBool CheckForceSynch() { if (fNumUpdates>10) { fNumUpdates=0; return true;} return false; }
virtual void AddMember(plNetTransportMember* e);
virtual void RemoveMember(plNetTransportMember* e);
};
//
// Specialized version for talk list
// a list of other players I am talking to
//
class plNetClientMgr;
class plNetTalkList : public plNetVoiceList
{
private:
enum
{
kDirty = 0x1
};
UInt32 fFlags;
public:
plNetTalkList() : fFlags(0) {}
~plNetTalkList() {}
void UpdateTransportGroup(plNetClientMgr* nc);
void AddMember(plNetTransportMember* e);
void RemoveMember(plNetTransportMember* e);
void Clear();
};
#endif // plNetVoiceList_h