2
3
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-14 02:27:40 -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,26 +1,26 @@
include_directories("../../CoreLib")
include_directories("../../FeatureLib")
include_directories("../../NucleusLib/inc")
include_directories("../../NucleusLib")
include_directories("../../PubUtilLib")
include_directories(${OPENSSL_INCLUDE_DIR})
set(plAgeLoader_SOURCES
plAgeLoader.cpp
plAgeLoaderPaging.cpp
plBackgroundDownloader.cpp
plResPatcher.cpp
)
set(plAgeLoader_HEADERS
plAgeLoader.h
plAgeLoaderCreatable.h
plBackgroundDownloader.h
plResPatcher.h
)
add_library(plAgeLoader STATIC ${plAgeLoader_SOURCES} ${plAgeLoader_HEADERS})
source_group("Source Files" FILES ${plAgeLoader_SOURCES})
source_group("Header Files" FILES ${plAgeLoader_HEADERS})
include_directories("../../CoreLib")
include_directories("../../FeatureLib")
include_directories("../../NucleusLib/inc")
include_directories("../../NucleusLib")
include_directories("../../PubUtilLib")
include_directories(${OPENSSL_INCLUDE_DIR})
set(plAgeLoader_SOURCES
plAgeLoader.cpp
plAgeLoaderPaging.cpp
plBackgroundDownloader.cpp
plResPatcher.cpp
)
set(plAgeLoader_HEADERS
plAgeLoader.h
plAgeLoaderCreatable.h
plBackgroundDownloader.h
plResPatcher.h
)
add_library(plAgeLoader STATIC ${plAgeLoader_SOURCES} ${plAgeLoader_HEADERS})
source_group("Source Files" FILES ${plAgeLoader_SOURCES})
source_group("Header Files" FILES ${plAgeLoader_HEADERS})

View File

@ -1,455 +1,455 @@
/*==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 "plAgeLoader.h"
#include "hsStream.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//#include "hsTimer.h"
#include "plResPatcher.h"
#include "plBackgroundDownloader.h"
#include "process.h" // for getpid()
#include "pnProduct/pnProduct.h"
#include "pnKeyedObject/plKey.h"
#include "pnKeyedObject/plFixedKey.h"
#include "pnSceneObject/plSceneObject.h"
#include "pnMessage/plClientMsg.h"
#include "pnNetCommon/plNetApp.h"
#include "plScene/plRelevanceMgr.h"
#include "plResMgr/plKeyFinder.h"
#include "plAgeDescription/plAgeDescription.h"
#include "plSDL/plSDL.h"
#include "plNetClient/plNetClientMgr.h"
#include "plResMgr/plRegistryHelpers.h"
#include "plResMgr/plRegistryNode.h"
#include "plResMgr/plResManager.h"
#include "plFile/plEncryptedStream.h"
/// TEMP HACK TO LOAD CONSOLE INIT FILES ON AGE LOAD
#include "plMessage/plConsoleMsg.h"
#include "plMessage/plLoadAvatarMsg.h"
#include "plMessage/plAgeLoadedMsg.h"
extern hsBool gDataServerLocal;
extern hsBool gUseBackgroundDownloader;
// static
plAgeLoader* plAgeLoader::fInstance=nil;
//
// CONSTRUCT
//
plAgeLoader::plAgeLoader() :
fInitialAgeState(nil),
fFlags(0)
{
}
//
// DESTRUCT
//
plAgeLoader::~plAgeLoader()
{
delete fInitialAgeState;
fInitialAgeState=nil;
if ( PendingAgeFniFiles().size() )
plNetClientApp::StaticErrorMsg( "~plAgeLoader(): %d pending age fni files", PendingAgeFniFiles().size() );
if ( PendingPageOuts().size() )
plNetClientApp::StaticErrorMsg( "~plAgeLoader(): %d pending page outs", PendingPageOuts().size() );
ClearPageExcludeList(); // Clear our debugging exclude list, just to be tidy
if (fInstance==this)
SetInstance(nil);
}
void plAgeLoader::Shutdown()
{
}
void plAgeLoader::Init()
{
RegisterAs( kAgeLoader_KEY );
plgDispatch::Dispatch()->RegisterForExactType(plInitialAgeStateLoadedMsg::Index(), GetKey());
plgDispatch::Dispatch()->RegisterForExactType(plClientMsg::Index(), GetKey());
if (!gDataServerLocal && gUseBackgroundDownloader)
plBackgroundDownloader::StartThread();
}
//
// STATIC
//
plAgeLoader* plAgeLoader::GetInstance()
{
return fInstance;
}
//
// STATIC
//
void plAgeLoader::SetInstance(plAgeLoader* inst)
{
fInstance=inst;
}
//
// Plasma Msg Handler
//
hsBool plAgeLoader::MsgReceive(plMessage* msg)
{
plInitialAgeStateLoadedMsg *stateMsg = plInitialAgeStateLoadedMsg::ConvertNoRef( msg );
if( stateMsg != nil )
{
// done receiving the initial state of the age from the server
return true;
}
plClientMsg* clientMsg = plClientMsg::ConvertNoRef(msg);
if (clientMsg && clientMsg->GetClientMsgFlag()==plClientMsg::kInitComplete)
{
ExecPendingAgeFniFiles(); // exec age-specific fni files
return true;
}
return plReceiver::MsgReceive(msg);
}
//
// read in the age desc file and page in/out the rooms belonging to the specified age.
// return false on error
//
//============================================================================
bool plAgeLoader::LoadAge(const char ageName[])
{
return ILoadAge(ageName);
}
//============================================================================
bool plAgeLoader::UpdateAge(const char ageName[])
{
bool result = true;
if (!gDataServerLocal)
{
plResPatcher myPatcher(ageName);
result = myPatcher.Update();
}
return result;
}
//============================================================================
void plAgeLoader::NotifyAgeLoaded( bool loaded )
{
if ( loaded )
fFlags &= ~kLoadingAge;
else
fFlags &= ~kUnLoadingAge;
plAgeLoadedMsg * msg = TRACKED_NEW plAgeLoadedMsg;
msg->fLoaded = loaded;
msg->Send();
}
//// ILoadAge ////////////////////////////////////////////////////////////////
// Does the loading-specific stuff for queueing an age to load
bool plAgeLoader::ILoadAge(const char ageName[])
{
plNetClientApp* nc = plNetClientApp::GetInstance();
ASSERT(!nc->GetFlagsBit(plNetClientApp::kPlayingGame));
StrCopy(fAgeName, ageName, arrsize(fAgeName));
nc->DebugMsg( "Net: Loading age %s", fAgeName);
if ((fFlags & kLoadMask) != 0)
ErrorFatal(__LINE__, __FILE__, "Fatal Error:\nAlready loading or unloading an age.\n%S will now exit.", ProductShortName());
fFlags |= kLoadingAge;
plAgeBeginLoadingMsg* ageBeginLoading = TRACKED_NEW plAgeBeginLoadingMsg();
ageBeginLoading->Send();
///////////////////////////////////////////////////////
/// Step 1: Update all of the dat files for this age
/*
UpdateAge(fAgeName);
*/
/// Step 2: Load the keys for this age, so we can find sceneNodes for them
// exec age .fni file when data is done loading
char consoleIniName[ 256 ];
sprintf( consoleIniName, "dat\\%s.fni", fAgeName);
fPendingAgeFniFiles.push_back( consoleIniName );
char csvName[256];
sprintf(csvName, "dat\\%s.csv", fAgeName);
fPendingAgeCsvFiles.push_back(csvName);
plSynchEnabler p( false ); // turn off dirty tracking while in this function
hsStream* stream=GetAgeDescFileStream(fAgeName);
if (!stream)
{
nc->ErrorMsg("Failed loading age. Age desc file %s has nil stream", fAgeName);
fFlags &= ~kLoadingAge;
return false;
}
plAgeDescription ad;
ad.Read(stream);
ad.SetAgeName(fAgeName);
stream->Close();
delete stream;
ad.SeekFirstPage();
plAgePage *page;
plKey clientKey = hsgResMgr::ResMgr()->FindKey( kClient_KEY );
// Copy, exclude pages we want excluded, and collect our scene nodes
fCurAgeDescription.CopyFrom(ad);
while( ( page = ad.GetNextPage() ) != nil )
{
if( IsPageExcluded( page, fAgeName) )
continue;
plKey roomKey = plKeyFinder::Instance().FindSceneNodeKey( fAgeName, page->GetName() );
if( roomKey != nil )
AddPendingPageInRoomKey( roomKey );
}
ad.SeekFirstPage();
// Tell the client to load-and-hold all the keys for this age, to make the loading process work better
plClientMsg *loadAgeKeysMsg = TRACKED_NEW plClientMsg( plClientMsg::kLoadAgeKeys );
loadAgeKeysMsg->SetAgeName( fAgeName);
loadAgeKeysMsg->Send( clientKey );
//
// Load the Age's SDL Hook object (and it's python modifier)
//
plUoid oid=nc->GetAgeSDLObjectUoid(fAgeName);
plKey ageSDLObjectKey = hsgResMgr::ResMgr()->FindKey(oid);
if (ageSDLObjectKey)
hsgResMgr::ResMgr()->AddViaNotify(ageSDLObjectKey, TRACKED_NEW plGenRefMsg(nc->GetKey(), plRefMsg::kOnCreate, -1,
plNetClientMgr::kAgeSDLHook), plRefFlags::kActiveRef);
int nPages = 0;
plClientMsg* pMsg1 = TRACKED_NEW plClientMsg(plClientMsg::kLoadRoom);
pMsg1->SetAgeName(fAgeName);
// Loop and ref!
while( ( page = ad.GetNextPage() ) != nil )
{
if( IsPageExcluded( page, fAgeName) )
{
nc->DebugMsg( "\tExcluding page %s\n", page->GetName() );
continue;
}
nPages++;
pMsg1->AddRoomLoc(ad.CalcPageLocation(page->GetName()));
nc->DebugMsg("\tPaging in room %s\n", page->GetName());
}
pMsg1->Send(clientKey);
// Send the client a message to let go of the extra keys it was holding on to
plClientMsg *dumpAgeKeys = TRACKED_NEW plClientMsg( plClientMsg::kReleaseAgeKeys );
dumpAgeKeys->SetAgeName( fAgeName);
dumpAgeKeys->Send( clientKey );
if ( nPages==0 )
{
// age is done loading because it has no pages?
fFlags &= ~kLoadingAge;
}
return true;
}
//// plUnloadAgeCollector ////////////////////////////////////////////////////
// Registry page iterator to collect all the loaded pages of a given age
// Note: we have to do an IterateAllPages(), since we want to also catch
// pages that are partially loaded, which are skipped in the vanilla
// IteratePages() call.
class plUnloadAgeCollector : public plRegistryPageIterator
{
public:
hsTArray<plRegistryPageNode *> fPages;
const char *fAge;
plUnloadAgeCollector( const char *a ) : fAge( a ) {}
virtual hsBool EatPage( plRegistryPageNode *page )
{
if( fAge && stricmp( page->GetPageInfo().GetAge(), fAge ) == 0 )
{
fPages.Append( page );
}
return true;
}
};
//// IUnloadAge //////////////////////////////////////////////////////////////
// Does the UNloading-specific stuff for queueing an age to unload.
// Far simpler that ILoadAge :)
bool plAgeLoader::IUnloadAge()
{
plNetClientApp* nc = plNetClientApp::GetInstance();
nc->DebugMsg( "Net: Unloading age %s", fAgeName);
hsAssert( (fFlags & kLoadMask)==0, "already loading or unloading an age?");
fFlags |= kUnLoadingAge;
plAgeBeginLoadingMsg* msg = TRACKED_NEW plAgeBeginLoadingMsg();
msg->fLoading = false;
msg->Send();
// Note: instead of going from the .age file, we just want a list of what
// is REALLY paged in for this age. So ask the resMgr!
plUnloadAgeCollector collector( fAgeName);
// WARNING: unsafe cast here, but it's ok, until somebody is mean and makes a non-plResManager resMgr
( (plResManager *)hsgResMgr::ResMgr() )->IterateAllPages( &collector );
// Dat was easy...
plKey clientKey = hsgResMgr::ResMgr()->FindKey( kClient_KEY );
// Build up a list of all the rooms we're going to page out
plKeyVec newPageOuts;
int i;
for( i = 0; i < collector.fPages.GetCount(); i++ )
{
plRegistryPageNode *page = collector.fPages[ i ];
plKey roomKey = plKeyFinder::Instance().FindSceneNodeKey( page->GetPageInfo().GetLocation() );
if( roomKey != nil && roomKey->ObjectIsLoaded() )
{
nc->DebugMsg( "\tPaging out room %s\n", page->GetPageInfo().GetPage() );
newPageOuts.push_back(roomKey);
}
}
// Put them in our pending page outs
for( i = 0; i < newPageOuts.size(); i++ )
fPendingPageOuts.push_back(newPageOuts[i]);
// ...then send the unload messages. That way we ensure the list is complete
// before any messages get processed
for( i = 0; i < newPageOuts.size(); i++ )
{
plClientMsg *pMsg1 = TRACKED_NEW plClientMsg( plClientMsg::kUnloadRoom );
pMsg1->AddRoomLoc(newPageOuts[i]->GetUoid().GetLocation());
pMsg1->Send( clientKey );
}
if ( newPageOuts.size()==0 )
{
// age is done unloading because it has no pages?
NotifyAgeLoaded( false );
}
return true;
}
void plAgeLoader::ExecPendingAgeFniFiles()
{
int i;
for (i=0;i<PendingAgeFniFiles().size(); i++)
{
plConsoleMsg *cMsg = TRACKED_NEW plConsoleMsg( plConsoleMsg::kExecuteFile, fPendingAgeFniFiles[i].c_str() );
plgDispatch::MsgSend( cMsg );
}
fPendingAgeFniFiles.clear();
}
void plAgeLoader::ExecPendingAgeCsvFiles()
{
int i;
for (i=0;i<PendingAgeCsvFiles().size(); i++)
{
hsStream* stream = plEncryptedStream::OpenEncryptedFile(fPendingAgeCsvFiles[i].c_str());
if (stream)
{
plRelevanceMgr::Instance()->ParseCsvInput(stream);
stream->Close();
delete stream;
}
}
fPendingAgeCsvFiles.clear();
}
//
// return alloced stream or nil
// static
//
hsStream* plAgeLoader::GetAgeDescFileStream(const char* ageName)
{
if (!ageName)
return nil;
char ageDescFileName[256];
sprintf(ageDescFileName, "dat\\%s.age", ageName);
hsStream* stream = plEncryptedStream::OpenEncryptedFile(ageDescFileName);
if (!stream)
{
char str[256];
sprintf(str, "Can't find age desc file %s", ageDescFileName);
hsAssert(false, str);
return nil;
}
return stream;
}
//
// sent from server with joinAck
//
void plAgeLoader::ISetInitialAgeState(plStateDataRecord* s)
{
hsAssert(fInitialAgeState != s, "duplicate initial age state");
delete fInitialAgeState;
fInitialAgeState=s;
}
/*==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 "plAgeLoader.h"
#include "hsStream.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//#include "hsTimer.h"
#include "plResPatcher.h"
#include "plBackgroundDownloader.h"
#include "process.h" // for getpid()
#include "pnProduct/pnProduct.h"
#include "pnKeyedObject/plKey.h"
#include "pnKeyedObject/plFixedKey.h"
#include "pnSceneObject/plSceneObject.h"
#include "pnMessage/plClientMsg.h"
#include "pnNetCommon/plNetApp.h"
#include "plScene/plRelevanceMgr.h"
#include "plResMgr/plKeyFinder.h"
#include "plAgeDescription/plAgeDescription.h"
#include "plSDL/plSDL.h"
#include "plNetClient/plNetClientMgr.h"
#include "plResMgr/plRegistryHelpers.h"
#include "plResMgr/plRegistryNode.h"
#include "plResMgr/plResManager.h"
#include "plFile/plEncryptedStream.h"
/// TEMP HACK TO LOAD CONSOLE INIT FILES ON AGE LOAD
#include "plMessage/plConsoleMsg.h"
#include "plMessage/plLoadAvatarMsg.h"
#include "plMessage/plAgeLoadedMsg.h"
extern hsBool gDataServerLocal;
extern hsBool gUseBackgroundDownloader;
// static
plAgeLoader* plAgeLoader::fInstance=nil;
//
// CONSTRUCT
//
plAgeLoader::plAgeLoader() :
fInitialAgeState(nil),
fFlags(0)
{
}
//
// DESTRUCT
//
plAgeLoader::~plAgeLoader()
{
delete fInitialAgeState;
fInitialAgeState=nil;
if ( PendingAgeFniFiles().size() )
plNetClientApp::StaticErrorMsg( "~plAgeLoader(): %d pending age fni files", PendingAgeFniFiles().size() );
if ( PendingPageOuts().size() )
plNetClientApp::StaticErrorMsg( "~plAgeLoader(): %d pending page outs", PendingPageOuts().size() );
ClearPageExcludeList(); // Clear our debugging exclude list, just to be tidy
if (fInstance==this)
SetInstance(nil);
}
void plAgeLoader::Shutdown()
{
}
void plAgeLoader::Init()
{
RegisterAs( kAgeLoader_KEY );
plgDispatch::Dispatch()->RegisterForExactType(plInitialAgeStateLoadedMsg::Index(), GetKey());
plgDispatch::Dispatch()->RegisterForExactType(plClientMsg::Index(), GetKey());
if (!gDataServerLocal && gUseBackgroundDownloader)
plBackgroundDownloader::StartThread();
}
//
// STATIC
//
plAgeLoader* plAgeLoader::GetInstance()
{
return fInstance;
}
//
// STATIC
//
void plAgeLoader::SetInstance(plAgeLoader* inst)
{
fInstance=inst;
}
//
// Plasma Msg Handler
//
hsBool plAgeLoader::MsgReceive(plMessage* msg)
{
plInitialAgeStateLoadedMsg *stateMsg = plInitialAgeStateLoadedMsg::ConvertNoRef( msg );
if( stateMsg != nil )
{
// done receiving the initial state of the age from the server
return true;
}
plClientMsg* clientMsg = plClientMsg::ConvertNoRef(msg);
if (clientMsg && clientMsg->GetClientMsgFlag()==plClientMsg::kInitComplete)
{
ExecPendingAgeFniFiles(); // exec age-specific fni files
return true;
}
return plReceiver::MsgReceive(msg);
}
//
// read in the age desc file and page in/out the rooms belonging to the specified age.
// return false on error
//
//============================================================================
bool plAgeLoader::LoadAge(const char ageName[])
{
return ILoadAge(ageName);
}
//============================================================================
bool plAgeLoader::UpdateAge(const char ageName[])
{
bool result = true;
if (!gDataServerLocal)
{
plResPatcher myPatcher(ageName);
result = myPatcher.Update();
}
return result;
}
//============================================================================
void plAgeLoader::NotifyAgeLoaded( bool loaded )
{
if ( loaded )
fFlags &= ~kLoadingAge;
else
fFlags &= ~kUnLoadingAge;
plAgeLoadedMsg * msg = TRACKED_NEW plAgeLoadedMsg;
msg->fLoaded = loaded;
msg->Send();
}
//// ILoadAge ////////////////////////////////////////////////////////////////
// Does the loading-specific stuff for queueing an age to load
bool plAgeLoader::ILoadAge(const char ageName[])
{
plNetClientApp* nc = plNetClientApp::GetInstance();
ASSERT(!nc->GetFlagsBit(plNetClientApp::kPlayingGame));
StrCopy(fAgeName, ageName, arrsize(fAgeName));
nc->DebugMsg( "Net: Loading age %s", fAgeName);
if ((fFlags & kLoadMask) != 0)
ErrorFatal(__LINE__, __FILE__, "Fatal Error:\nAlready loading or unloading an age.\n%S will now exit.", ProductShortName());
fFlags |= kLoadingAge;
plAgeBeginLoadingMsg* ageBeginLoading = TRACKED_NEW plAgeBeginLoadingMsg();
ageBeginLoading->Send();
///////////////////////////////////////////////////////
/// Step 1: Update all of the dat files for this age
/*
UpdateAge(fAgeName);
*/
/// Step 2: Load the keys for this age, so we can find sceneNodes for them
// exec age .fni file when data is done loading
char consoleIniName[ 256 ];
sprintf( consoleIniName, "dat\\%s.fni", fAgeName);
fPendingAgeFniFiles.push_back( consoleIniName );
char csvName[256];
sprintf(csvName, "dat\\%s.csv", fAgeName);
fPendingAgeCsvFiles.push_back(csvName);
plSynchEnabler p( false ); // turn off dirty tracking while in this function
hsStream* stream=GetAgeDescFileStream(fAgeName);
if (!stream)
{
nc->ErrorMsg("Failed loading age. Age desc file %s has nil stream", fAgeName);
fFlags &= ~kLoadingAge;
return false;
}
plAgeDescription ad;
ad.Read(stream);
ad.SetAgeName(fAgeName);
stream->Close();
delete stream;
ad.SeekFirstPage();
plAgePage *page;
plKey clientKey = hsgResMgr::ResMgr()->FindKey( kClient_KEY );
// Copy, exclude pages we want excluded, and collect our scene nodes
fCurAgeDescription.CopyFrom(ad);
while( ( page = ad.GetNextPage() ) != nil )
{
if( IsPageExcluded( page, fAgeName) )
continue;
plKey roomKey = plKeyFinder::Instance().FindSceneNodeKey( fAgeName, page->GetName() );
if( roomKey != nil )
AddPendingPageInRoomKey( roomKey );
}
ad.SeekFirstPage();
// Tell the client to load-and-hold all the keys for this age, to make the loading process work better
plClientMsg *loadAgeKeysMsg = TRACKED_NEW plClientMsg( plClientMsg::kLoadAgeKeys );
loadAgeKeysMsg->SetAgeName( fAgeName);
loadAgeKeysMsg->Send( clientKey );
//
// Load the Age's SDL Hook object (and it's python modifier)
//
plUoid oid=nc->GetAgeSDLObjectUoid(fAgeName);
plKey ageSDLObjectKey = hsgResMgr::ResMgr()->FindKey(oid);
if (ageSDLObjectKey)
hsgResMgr::ResMgr()->AddViaNotify(ageSDLObjectKey, TRACKED_NEW plGenRefMsg(nc->GetKey(), plRefMsg::kOnCreate, -1,
plNetClientMgr::kAgeSDLHook), plRefFlags::kActiveRef);
int nPages = 0;
plClientMsg* pMsg1 = TRACKED_NEW plClientMsg(plClientMsg::kLoadRoom);
pMsg1->SetAgeName(fAgeName);
// Loop and ref!
while( ( page = ad.GetNextPage() ) != nil )
{
if( IsPageExcluded( page, fAgeName) )
{
nc->DebugMsg( "\tExcluding page %s\n", page->GetName() );
continue;
}
nPages++;
pMsg1->AddRoomLoc(ad.CalcPageLocation(page->GetName()));
nc->DebugMsg("\tPaging in room %s\n", page->GetName());
}
pMsg1->Send(clientKey);
// Send the client a message to let go of the extra keys it was holding on to
plClientMsg *dumpAgeKeys = TRACKED_NEW plClientMsg( plClientMsg::kReleaseAgeKeys );
dumpAgeKeys->SetAgeName( fAgeName);
dumpAgeKeys->Send( clientKey );
if ( nPages==0 )
{
// age is done loading because it has no pages?
fFlags &= ~kLoadingAge;
}
return true;
}
//// plUnloadAgeCollector ////////////////////////////////////////////////////
// Registry page iterator to collect all the loaded pages of a given age
// Note: we have to do an IterateAllPages(), since we want to also catch
// pages that are partially loaded, which are skipped in the vanilla
// IteratePages() call.
class plUnloadAgeCollector : public plRegistryPageIterator
{
public:
hsTArray<plRegistryPageNode *> fPages;
const char *fAge;
plUnloadAgeCollector( const char *a ) : fAge( a ) {}
virtual hsBool EatPage( plRegistryPageNode *page )
{
if( fAge && stricmp( page->GetPageInfo().GetAge(), fAge ) == 0 )
{
fPages.Append( page );
}
return true;
}
};
//// IUnloadAge //////////////////////////////////////////////////////////////
// Does the UNloading-specific stuff for queueing an age to unload.
// Far simpler that ILoadAge :)
bool plAgeLoader::IUnloadAge()
{
plNetClientApp* nc = plNetClientApp::GetInstance();
nc->DebugMsg( "Net: Unloading age %s", fAgeName);
hsAssert( (fFlags & kLoadMask)==0, "already loading or unloading an age?");
fFlags |= kUnLoadingAge;
plAgeBeginLoadingMsg* msg = TRACKED_NEW plAgeBeginLoadingMsg();
msg->fLoading = false;
msg->Send();
// Note: instead of going from the .age file, we just want a list of what
// is REALLY paged in for this age. So ask the resMgr!
plUnloadAgeCollector collector( fAgeName);
// WARNING: unsafe cast here, but it's ok, until somebody is mean and makes a non-plResManager resMgr
( (plResManager *)hsgResMgr::ResMgr() )->IterateAllPages( &collector );
// Dat was easy...
plKey clientKey = hsgResMgr::ResMgr()->FindKey( kClient_KEY );
// Build up a list of all the rooms we're going to page out
plKeyVec newPageOuts;
int i;
for( i = 0; i < collector.fPages.GetCount(); i++ )
{
plRegistryPageNode *page = collector.fPages[ i ];
plKey roomKey = plKeyFinder::Instance().FindSceneNodeKey( page->GetPageInfo().GetLocation() );
if( roomKey != nil && roomKey->ObjectIsLoaded() )
{
nc->DebugMsg( "\tPaging out room %s\n", page->GetPageInfo().GetPage() );
newPageOuts.push_back(roomKey);
}
}
// Put them in our pending page outs
for( i = 0; i < newPageOuts.size(); i++ )
fPendingPageOuts.push_back(newPageOuts[i]);
// ...then send the unload messages. That way we ensure the list is complete
// before any messages get processed
for( i = 0; i < newPageOuts.size(); i++ )
{
plClientMsg *pMsg1 = TRACKED_NEW plClientMsg( plClientMsg::kUnloadRoom );
pMsg1->AddRoomLoc(newPageOuts[i]->GetUoid().GetLocation());
pMsg1->Send( clientKey );
}
if ( newPageOuts.size()==0 )
{
// age is done unloading because it has no pages?
NotifyAgeLoaded( false );
}
return true;
}
void plAgeLoader::ExecPendingAgeFniFiles()
{
int i;
for (i=0;i<PendingAgeFniFiles().size(); i++)
{
plConsoleMsg *cMsg = TRACKED_NEW plConsoleMsg( plConsoleMsg::kExecuteFile, fPendingAgeFniFiles[i].c_str() );
plgDispatch::MsgSend( cMsg );
}
fPendingAgeFniFiles.clear();
}
void plAgeLoader::ExecPendingAgeCsvFiles()
{
int i;
for (i=0;i<PendingAgeCsvFiles().size(); i++)
{
hsStream* stream = plEncryptedStream::OpenEncryptedFile(fPendingAgeCsvFiles[i].c_str());
if (stream)
{
plRelevanceMgr::Instance()->ParseCsvInput(stream);
stream->Close();
delete stream;
}
}
fPendingAgeCsvFiles.clear();
}
//
// return alloced stream or nil
// static
//
hsStream* plAgeLoader::GetAgeDescFileStream(const char* ageName)
{
if (!ageName)
return nil;
char ageDescFileName[256];
sprintf(ageDescFileName, "dat\\%s.age", ageName);
hsStream* stream = plEncryptedStream::OpenEncryptedFile(ageDescFileName);
if (!stream)
{
char str[256];
sprintf(str, "Can't find age desc file %s", ageDescFileName);
hsAssert(false, str);
return nil;
}
return stream;
}
//
// sent from server with joinAck
//
void plAgeLoader::ISetInitialAgeState(plStateDataRecord* s)
{
hsAssert(fInitialAgeState != s, "duplicate initial age state");
delete fInitialAgeState;
fInitialAgeState=s;
}

View File

@ -1,129 +1,129 @@
/*==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 plAgeLoader_h
#define plAgeLoader_h
#include "hsTypes.h"
#include "hsStlUtils.h"
#include "pnUtils/pnUtils.h"
#include "pnNetBase/pnNetBase.h"
#include "pnKeyedObject/hsKeyedObject.h"
#include "pnKeyedObject/plKey.h"
#include "plAgeDescription/plAgeDescription.h"
#include "plUUID/plUUID.h"
//
// A singleton class which manages loading and unloading ages and operations associated with that
//
// fwd decls
class plStateDataRecord;
class plMessage;
class plOperationProgress;
class plAgeLoader : public hsKeyedObject
{
friend class plNetClientMsgHandler;
friend class plNetClientJoinTask;
private:
typedef std::vector<plKey> plKeyVec;
typedef std::vector<std::string> plStringVec;
enum Flags
{
kLoadingAge = 0x1,
kUnLoadingAge = 0x2,
kLoadMask = (kLoadingAge | kUnLoadingAge)
};
static plAgeLoader* fInstance;
UInt32 fFlags;
plStringVec fPendingAgeFniFiles; // list of age .fni files to be parsed
plStringVec fPendingAgeCsvFiles; // list of age .csv files to be parsed
plKeyVec fPendingPageIns; // keys of rooms which are currently being paged in.
plKeyVec fPendingPageOuts; // keys of rooms which are currently being paged out.
plAgeDescription fCurAgeDescription;
plStateDataRecord* fInitialAgeState;
char fAgeName[kMaxAgeNameLength];
bool ILoadAge(const char ageName[]);
bool IUnloadAge();
void ISetInitialAgeState(plStateDataRecord* s); // sent from server with joinAck
const plStateDataRecord* IGetInitialAgeState() const { return fInitialAgeState; }
public:
plAgeLoader();
~plAgeLoader();
CLASSNAME_REGISTER( plAgeLoader);
GETINTERFACE_ANY( plAgeLoader, hsKeyedObject);
static plAgeLoader* GetInstance();
static void SetInstance(plAgeLoader* inst);
static hsStream* GetAgeDescFileStream(const char* ageName);
void Init();
void Shutdown();
hsBool MsgReceive(plMessage* msg);
bool LoadAge(const char ageName[]);
bool UnloadAge() { return IUnloadAge(); }
bool UpdateAge(const char ageName[]);
void NotifyAgeLoaded( bool loaded );
const plKeyVec& PendingPageOuts() const { return fPendingPageOuts; }
const plKeyVec& PendingPageIns() const { return fPendingPageIns; }
const plStringVec& PendingAgeCsvFiles() const { return fPendingAgeCsvFiles; }
const plStringVec& PendingAgeFniFiles() const { return fPendingAgeFniFiles; }
void AddPendingPageInRoomKey(plKey r);
bool RemovePendingPageInRoomKey(plKey r);
bool IsPendingPageInRoomKey(plKey p, int* idx=nil);
void ExecPendingAgeFniFiles();
void ExecPendingAgeCsvFiles();
// Fun debugging exclude commands (to prevent certain pages from loading)
void ClearPageExcludeList( void );
void AddExcludedPage( const char *pageName, const char *ageName = nil );
bool IsPageExcluded( const plAgePage *page, const char *ageName = nil );
const plAgeDescription &GetCurrAgeDesc( void ) const { return fCurAgeDescription; }
// paging
void FinishedPagingInRoom(plKey* rmKey, int numRms); // call when finished paging in/out a room
void StartPagingOutRoom(plKey* rmKey, int numRms); // call when starting to page in/out a room
void FinishedPagingOutRoom(plKey* rmKey, int numRms);
// Called on page-in-hold rooms, since we don't want them actually paging out in the NCM (i.e. sending info to the server)
void IgnorePagingOutRoom(plKey* rmKey, int numRms);
bool IsLoadingAge(){ return (fFlags & (kUnLoadingAge | kLoadingAge)); }
};
#endif // plAgeLoader_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 plAgeLoader_h
#define plAgeLoader_h
#include "hsTypes.h"
#include "hsStlUtils.h"
#include "pnUtils/pnUtils.h"
#include "pnNetBase/pnNetBase.h"
#include "pnKeyedObject/hsKeyedObject.h"
#include "pnKeyedObject/plKey.h"
#include "plAgeDescription/plAgeDescription.h"
#include "plUUID/plUUID.h"
//
// A singleton class which manages loading and unloading ages and operations associated with that
//
// fwd decls
class plStateDataRecord;
class plMessage;
class plOperationProgress;
class plAgeLoader : public hsKeyedObject
{
friend class plNetClientMsgHandler;
friend class plNetClientJoinTask;
private:
typedef std::vector<plKey> plKeyVec;
typedef std::vector<std::string> plStringVec;
enum Flags
{
kLoadingAge = 0x1,
kUnLoadingAge = 0x2,
kLoadMask = (kLoadingAge | kUnLoadingAge)
};
static plAgeLoader* fInstance;
UInt32 fFlags;
plStringVec fPendingAgeFniFiles; // list of age .fni files to be parsed
plStringVec fPendingAgeCsvFiles; // list of age .csv files to be parsed
plKeyVec fPendingPageIns; // keys of rooms which are currently being paged in.
plKeyVec fPendingPageOuts; // keys of rooms which are currently being paged out.
plAgeDescription fCurAgeDescription;
plStateDataRecord* fInitialAgeState;
char fAgeName[kMaxAgeNameLength];
bool ILoadAge(const char ageName[]);
bool IUnloadAge();
void ISetInitialAgeState(plStateDataRecord* s); // sent from server with joinAck
const plStateDataRecord* IGetInitialAgeState() const { return fInitialAgeState; }
public:
plAgeLoader();
~plAgeLoader();
CLASSNAME_REGISTER( plAgeLoader);
GETINTERFACE_ANY( plAgeLoader, hsKeyedObject);
static plAgeLoader* GetInstance();
static void SetInstance(plAgeLoader* inst);
static hsStream* GetAgeDescFileStream(const char* ageName);
void Init();
void Shutdown();
hsBool MsgReceive(plMessage* msg);
bool LoadAge(const char ageName[]);
bool UnloadAge() { return IUnloadAge(); }
bool UpdateAge(const char ageName[]);
void NotifyAgeLoaded( bool loaded );
const plKeyVec& PendingPageOuts() const { return fPendingPageOuts; }
const plKeyVec& PendingPageIns() const { return fPendingPageIns; }
const plStringVec& PendingAgeCsvFiles() const { return fPendingAgeCsvFiles; }
const plStringVec& PendingAgeFniFiles() const { return fPendingAgeFniFiles; }
void AddPendingPageInRoomKey(plKey r);
bool RemovePendingPageInRoomKey(plKey r);
bool IsPendingPageInRoomKey(plKey p, int* idx=nil);
void ExecPendingAgeFniFiles();
void ExecPendingAgeCsvFiles();
// Fun debugging exclude commands (to prevent certain pages from loading)
void ClearPageExcludeList( void );
void AddExcludedPage( const char *pageName, const char *ageName = nil );
bool IsPageExcluded( const plAgePage *page, const char *ageName = nil );
const plAgeDescription &GetCurrAgeDesc( void ) const { return fCurAgeDescription; }
// paging
void FinishedPagingInRoom(plKey* rmKey, int numRms); // call when finished paging in/out a room
void StartPagingOutRoom(plKey* rmKey, int numRms); // call when starting to page in/out a room
void FinishedPagingOutRoom(plKey* rmKey, int numRms);
// Called on page-in-hold rooms, since we don't want them actually paging out in the NCM (i.e. sending info to the server)
void IgnorePagingOutRoom(plKey* rmKey, int numRms);
bool IsLoadingAge(){ return (fFlags & (kUnLoadingAge | kLoadingAge)); }
};
#endif // plAgeLoader_h

View File

@ -1,34 +1,34 @@
/*==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 plAgeLoaderCreatable_inc
#define plAgeLoaderCreatable_inc
#include "pnFactory/plCreator.h"
#include "plAgeLoader.h"
REGISTER_CREATABLE( plAgeLoader);
#endif // plAgeLoaderCreatable_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 plAgeLoaderCreatable_inc
#define plAgeLoaderCreatable_inc
#include "pnFactory/plCreator.h"
#include "plAgeLoader.h"
REGISTER_CREATABLE( plAgeLoader);
#endif // plAgeLoaderCreatable_inc

View File

@ -1,321 +1,321 @@
/*==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 "plAgeLoader.h"
#include "hsTimer.h"
#include "hsResMgr.h"
#include "plgDispatch.h"
#include <algorithm>
#include "pnNetCommon/plNetApp.h"
#include "pnKeyedObject/plKey.h"
#include "plMessage/plAgeLoadedMsg.h"
#include "plNetMessage/plNetMessage.h"
#include "plProgressMgr/plProgressMgr.h"
#include "plSDL/plSDL.h"
#include "pnDispatch/plDispatch.h"
#include "plResMgr/plResManager.h"
#include "plNetClient/plNetClientMgr.h"
//
// if room is reserved or for animations, don't report it to the server.
// the server only cares about rooms which have real, networked objects in them.
// The server already assigns a global room to everyone for things like avatar and builtin state .
//
bool ReportRoomToServer(const plKey &key)
{
plLocation keyLoc=key->GetUoid().GetLocation();
bool skip=(keyLoc.IsReserved() || keyLoc.IsVirtual() ||
// HACK ALERT - replace with new uoid type flags
(key->GetName() &&
(!strnicmp(key->GetName(), "global", 6) ||
strstr(key->GetName(), "_Male") ||
strstr(key->GetName(), "_Female")
)
)
);
if (skip)
hsLogEntry(plNetApp::StaticDebugMsg("Not reporting room %s to server, reserved=%d, virtual=%d",
key->GetName(), keyLoc.IsReserved(), keyLoc.IsVirtual()));
return !skip;
}
//
// call when finished paging in a room.
//
void plAgeLoader::FinishedPagingInRoom(plKey* rmKey, int numRms)
{
if (numRms==0)
return;
unsigned pendingPageIns = PendingPageIns().size();
plNetClientApp* nc = plNetClientApp::GetInstance();
// Send a msg to the server indicating that we have this room paged in
plNetMsgPagingRoom * pagingMsg = TRACKED_NEW plNetMsgPagingRoom;
pagingMsg->SetNetProtocol(kNetProtocolCli2Game);
int i;
for(i=0;i<numRms;i++)
{
plKey key=rmKey[i];
if (!RemovePendingPageInRoomKey(key)) // room is done paging in
continue; // we didn't queue this room
if (!ReportRoomToServer(key))
continue;
pagingMsg->AddRoom(key);
hsLogEntry(nc->DebugMsg("\tSending PageIn/RequestState msg, room=%s\n", key->GetName()));
}
if( pagingMsg->GetNumRooms() > 0 ) // all rooms were reserved
{
plNetClientMgr * mgr = plNetClientMgr::GetInstance();
mgr->AddPendingPagingRoomMsg( pagingMsg );
}
else
delete pagingMsg;
// If any of these rooms were queued for load by us, then we may be done loading the age.
if (pendingPageIns != PendingPageIns().size())
{
bool ageLoaded = (PendingPageIns().size()==0) && (fFlags & kLoadingAge);
if (ageLoaded)
{
plAgeLoaded2Msg * msg = TRACKED_NEW plAgeLoaded2Msg;
msg->Send();
// join task will call NotifyAgeLoaded for us later
}
}
}
//
// called by the client when a room is finished paging out
//
void plAgeLoader::FinishedPagingOutRoom(plKey* rmKey, int numRms)
{
plNetClientApp* nc = plNetClientApp::GetInstance();
nc->StayAlive(hsTimer::GetSysSeconds()); // alive
int i;
for(i=0;i<numRms;i++)
{
plKeyVec::iterator found = std::find( fPendingPageOuts.begin(), fPendingPageOuts.end(), rmKey[ i ] );
if( found != fPendingPageOuts.end() )
{
fPendingPageOuts.erase( found );
nc->DebugMsg("Finished paging out room %s", rmKey[i]->GetName());
}
}
if (PendingPageOuts().size() == 0 && (fFlags & kUnLoadingAge))
{
NotifyAgeLoaded( false );
}
}
//
// call when starting to page out a room.
// allows server to transfer ownership of room objects to someone else.
//
void plAgeLoader::StartPagingOutRoom(plKey* rmKey, int numRms)
{
plNetClientApp* nc = plNetClientApp::GetInstance();
plNetMsgPagingRoom pagingMsg;
pagingMsg.SetNetProtocol(kNetProtocolCli2Game);
pagingMsg.SetPagingOut(true);
int i;
for(i=0;i<numRms;i++)
{
plKey key=rmKey[i];
if (!ReportRoomToServer(key))
continue;
pagingMsg.AddRoom(rmKey[i]);
nc->DebugMsg("\tSending PageOut msg, room=%s", rmKey[i]->GetName());
}
if (!pagingMsg.GetNumRooms()) // all rooms were reserved
return;
nc->SendMsg(&pagingMsg);
}
// Client telling us that this page isn't going to get the start/finish combo
// on page out, most likely because it was a load-and-hold, not a load. So take
// it from our pending list but don't actually process it
// Note: right now it's just a dup of FinishPagingOutRoom(), but since the latter
// might change later, we go ahead and dup to avoid unnecessary bugs later
void plAgeLoader::IgnorePagingOutRoom(plKey* rmKey, int numRms)
{
plNetClientApp* nc = plNetClientApp::GetInstance();
nc->StayAlive(hsTimer::GetSysSeconds()); // alive
int i;
for(i=0;i<numRms;i++)
{
plKeyVec::iterator found = std::find( fPendingPageOuts.begin(), fPendingPageOuts.end(), rmKey[ i ] );
if( found != fPendingPageOuts.end() )
{
fPendingPageOuts.erase( found );
nc->DebugMsg("Ignoring paged out room %s", rmKey[i]->GetName());
}
}
if (PendingPageOuts().size() == 0 && (fFlags & kUnLoadingAge))
{
NotifyAgeLoaded( false );
}
}
///////////////////////////////////
bool plAgeLoader::IsPendingPageInRoomKey(plKey pKey, int *idx)
{
if (pKey)
{
plKeyVec::iterator result=std::find(fPendingPageIns.begin(), fPendingPageIns.end(), pKey);
bool found = result!=fPendingPageIns.end();
if (idx)
*idx = found ? result-fPendingPageIns.begin() : -1;
return found;
}
return false;
}
void plAgeLoader::AddPendingPageInRoomKey(plKey pKey)
{
if (!IsPendingPageInRoomKey(pKey))
{
fPendingPageIns.push_back(pKey);
}
}
bool plAgeLoader::RemovePendingPageInRoomKey(plKey pKey)
{
int idx;
if (IsPendingPageInRoomKey(pKey, &idx))
{
fPendingPageIns.erase(fPendingPageIns.begin()+idx); // remove key from list
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////////
//// Page Exclusion //////////////////////////////////////////////////////////
// //
// Fun debugging exclude commands (to prevent certain pages from loading) //
// //
//////////////////////////////////////////////////////////////////////////////
class plExcludePage
{
public:
char *fPageName;
char *fAgeName;
plExcludePage() { fPageName = nil; fAgeName = nil; }
plExcludePage( char *p, char *a )
{
fPageName = p;
fAgeName = a;
}
};
static hsTArray<plExcludePage> sExcludeList;
void plAgeLoader::ClearPageExcludeList( void )
{
int i;
for( i = 0; i < sExcludeList.GetCount(); i++ )
{
delete [] sExcludeList[ i ].fPageName;
delete [] sExcludeList[ i ].fAgeName;
}
}
void plAgeLoader::AddExcludedPage( const char *pageName, const char *ageName )
{
char *p = hsStrcpy( pageName );
char *a = nil;
if( ageName != nil )
a = hsStrcpy( ageName );
sExcludeList.Append( plExcludePage( p, a ) );
}
bool plAgeLoader::IsPageExcluded( const plAgePage *page, const char *ageName )
{
// check page flags
if (page->GetFlags() & plAgePage::kPreventAutoLoad)
return true;
// check exclude list
const char* pageName = page->GetName();
int i;
for( i = 0; i < sExcludeList.GetCount(); i++ )
{
if( stricmp( pageName, sExcludeList[ i ].fPageName ) == 0 )
{
if( ageName == nil || sExcludeList[ i ].fAgeName == nil ||
stricmp( ageName, sExcludeList[ i ].fAgeName ) == 0 )
{
return true;
}
}
}
// Check if pages are excluded due to age SDL vars
if (page->GetFlags() & plAgePage::kLoadIfSDLPresent)
{
if (IGetInitialAgeState())
{
plSimpleStateVariable* sdVar = IGetInitialAgeState()->FindVar(pageName);
if (!sdVar)
return true; // no sdl var, exclude
bool value;
sdVar->Get(&value);
return value ? false : true; // exclude if var is false
}
else
return true; // no age state, exclude
}
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 "plAgeLoader.h"
#include "hsTimer.h"
#include "hsResMgr.h"
#include "plgDispatch.h"
#include <algorithm>
#include "pnNetCommon/plNetApp.h"
#include "pnKeyedObject/plKey.h"
#include "plMessage/plAgeLoadedMsg.h"
#include "plNetMessage/plNetMessage.h"
#include "plProgressMgr/plProgressMgr.h"
#include "plSDL/plSDL.h"
#include "pnDispatch/plDispatch.h"
#include "plResMgr/plResManager.h"
#include "plNetClient/plNetClientMgr.h"
//
// if room is reserved or for animations, don't report it to the server.
// the server only cares about rooms which have real, networked objects in them.
// The server already assigns a global room to everyone for things like avatar and builtin state .
//
bool ReportRoomToServer(const plKey &key)
{
plLocation keyLoc=key->GetUoid().GetLocation();
bool skip=(keyLoc.IsReserved() || keyLoc.IsVirtual() ||
// HACK ALERT - replace with new uoid type flags
(key->GetName() &&
(!strnicmp(key->GetName(), "global", 6) ||
strstr(key->GetName(), "_Male") ||
strstr(key->GetName(), "_Female")
)
)
);
if (skip)
hsLogEntry(plNetApp::StaticDebugMsg("Not reporting room %s to server, reserved=%d, virtual=%d",
key->GetName(), keyLoc.IsReserved(), keyLoc.IsVirtual()));
return !skip;
}
//
// call when finished paging in a room.
//
void plAgeLoader::FinishedPagingInRoom(plKey* rmKey, int numRms)
{
if (numRms==0)
return;
unsigned pendingPageIns = PendingPageIns().size();
plNetClientApp* nc = plNetClientApp::GetInstance();
// Send a msg to the server indicating that we have this room paged in
plNetMsgPagingRoom * pagingMsg = TRACKED_NEW plNetMsgPagingRoom;
pagingMsg->SetNetProtocol(kNetProtocolCli2Game);
int i;
for(i=0;i<numRms;i++)
{
plKey key=rmKey[i];
if (!RemovePendingPageInRoomKey(key)) // room is done paging in
continue; // we didn't queue this room
if (!ReportRoomToServer(key))
continue;
pagingMsg->AddRoom(key);
hsLogEntry(nc->DebugMsg("\tSending PageIn/RequestState msg, room=%s\n", key->GetName()));
}
if( pagingMsg->GetNumRooms() > 0 ) // all rooms were reserved
{
plNetClientMgr * mgr = plNetClientMgr::GetInstance();
mgr->AddPendingPagingRoomMsg( pagingMsg );
}
else
delete pagingMsg;
// If any of these rooms were queued for load by us, then we may be done loading the age.
if (pendingPageIns != PendingPageIns().size())
{
bool ageLoaded = (PendingPageIns().size()==0) && (fFlags & kLoadingAge);
if (ageLoaded)
{
plAgeLoaded2Msg * msg = TRACKED_NEW plAgeLoaded2Msg;
msg->Send();
// join task will call NotifyAgeLoaded for us later
}
}
}
//
// called by the client when a room is finished paging out
//
void plAgeLoader::FinishedPagingOutRoom(plKey* rmKey, int numRms)
{
plNetClientApp* nc = plNetClientApp::GetInstance();
nc->StayAlive(hsTimer::GetSysSeconds()); // alive
int i;
for(i=0;i<numRms;i++)
{
plKeyVec::iterator found = std::find( fPendingPageOuts.begin(), fPendingPageOuts.end(), rmKey[ i ] );
if( found != fPendingPageOuts.end() )
{
fPendingPageOuts.erase( found );
nc->DebugMsg("Finished paging out room %s", rmKey[i]->GetName());
}
}
if (PendingPageOuts().size() == 0 && (fFlags & kUnLoadingAge))
{
NotifyAgeLoaded( false );
}
}
//
// call when starting to page out a room.
// allows server to transfer ownership of room objects to someone else.
//
void plAgeLoader::StartPagingOutRoom(plKey* rmKey, int numRms)
{
plNetClientApp* nc = plNetClientApp::GetInstance();
plNetMsgPagingRoom pagingMsg;
pagingMsg.SetNetProtocol(kNetProtocolCli2Game);
pagingMsg.SetPagingOut(true);
int i;
for(i=0;i<numRms;i++)
{
plKey key=rmKey[i];
if (!ReportRoomToServer(key))
continue;
pagingMsg.AddRoom(rmKey[i]);
nc->DebugMsg("\tSending PageOut msg, room=%s", rmKey[i]->GetName());
}
if (!pagingMsg.GetNumRooms()) // all rooms were reserved
return;
nc->SendMsg(&pagingMsg);
}
// Client telling us that this page isn't going to get the start/finish combo
// on page out, most likely because it was a load-and-hold, not a load. So take
// it from our pending list but don't actually process it
// Note: right now it's just a dup of FinishPagingOutRoom(), but since the latter
// might change later, we go ahead and dup to avoid unnecessary bugs later
void plAgeLoader::IgnorePagingOutRoom(plKey* rmKey, int numRms)
{
plNetClientApp* nc = plNetClientApp::GetInstance();
nc->StayAlive(hsTimer::GetSysSeconds()); // alive
int i;
for(i=0;i<numRms;i++)
{
plKeyVec::iterator found = std::find( fPendingPageOuts.begin(), fPendingPageOuts.end(), rmKey[ i ] );
if( found != fPendingPageOuts.end() )
{
fPendingPageOuts.erase( found );
nc->DebugMsg("Ignoring paged out room %s", rmKey[i]->GetName());
}
}
if (PendingPageOuts().size() == 0 && (fFlags & kUnLoadingAge))
{
NotifyAgeLoaded( false );
}
}
///////////////////////////////////
bool plAgeLoader::IsPendingPageInRoomKey(plKey pKey, int *idx)
{
if (pKey)
{
plKeyVec::iterator result=std::find(fPendingPageIns.begin(), fPendingPageIns.end(), pKey);
bool found = result!=fPendingPageIns.end();
if (idx)
*idx = found ? result-fPendingPageIns.begin() : -1;
return found;
}
return false;
}
void plAgeLoader::AddPendingPageInRoomKey(plKey pKey)
{
if (!IsPendingPageInRoomKey(pKey))
{
fPendingPageIns.push_back(pKey);
}
}
bool plAgeLoader::RemovePendingPageInRoomKey(plKey pKey)
{
int idx;
if (IsPendingPageInRoomKey(pKey, &idx))
{
fPendingPageIns.erase(fPendingPageIns.begin()+idx); // remove key from list
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////////
//// Page Exclusion //////////////////////////////////////////////////////////
// //
// Fun debugging exclude commands (to prevent certain pages from loading) //
// //
//////////////////////////////////////////////////////////////////////////////
class plExcludePage
{
public:
char *fPageName;
char *fAgeName;
plExcludePage() { fPageName = nil; fAgeName = nil; }
plExcludePage( char *p, char *a )
{
fPageName = p;
fAgeName = a;
}
};
static hsTArray<plExcludePage> sExcludeList;
void plAgeLoader::ClearPageExcludeList( void )
{
int i;
for( i = 0; i < sExcludeList.GetCount(); i++ )
{
delete [] sExcludeList[ i ].fPageName;
delete [] sExcludeList[ i ].fAgeName;
}
}
void plAgeLoader::AddExcludedPage( const char *pageName, const char *ageName )
{
char *p = hsStrcpy( pageName );
char *a = nil;
if( ageName != nil )
a = hsStrcpy( ageName );
sExcludeList.Append( plExcludePage( p, a ) );
}
bool plAgeLoader::IsPageExcluded( const plAgePage *page, const char *ageName )
{
// check page flags
if (page->GetFlags() & plAgePage::kPreventAutoLoad)
return true;
// check exclude list
const char* pageName = page->GetName();
int i;
for( i = 0; i < sExcludeList.GetCount(); i++ )
{
if( stricmp( pageName, sExcludeList[ i ].fPageName ) == 0 )
{
if( ageName == nil || sExcludeList[ i ].fAgeName == nil ||
stricmp( ageName, sExcludeList[ i ].fAgeName ) == 0 )
{
return true;
}
}
}
// Check if pages are excluded due to age SDL vars
if (page->GetFlags() & plAgePage::kLoadIfSDLPresent)
{
if (IGetInitialAgeState())
{
plSimpleStateVariable* sdVar = IGetInitialAgeState()->FindVar(pageName);
if (!sdVar)
return true; // no sdl var, exclude
bool value;
sdVar->Get(&value);
return value ? false : true; // exclude if var is false
}
else
return true; // no age state, exclude
}
return false;
}

View File

@ -1,82 +1,82 @@
/*==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 plBackgroundDownloader_h_inc
#define plBackgroundDownloader_h_inc
#include <vector>
#include "hsTypes.h"
class plManifestFile;
struct NetCliFileManifestEntry;
class plBackgroundDownloader
{
protected:
static plBackgroundDownloader* fInstance;
static void Init();
static void Shutdown();
static void ThreadMain(void * param);
plBackgroundDownloader();
~plBackgroundDownloader();
HANDLE fBGDownloaderRun;
HANDLE fBGDownloaderIsPaused;
enum FileType {kFail, kPrp, kOther};
typedef std::vector<plManifestFile*> MfsFileVec;
MfsFileVec fMfsVec;
public:
bool fDoneWithFile;
bool fSuccess;
bool IGetDataManifest();
FileType IGetFile(const plManifestFile* mfsFile);
UInt32 IGetDownloadSize();
bool IDecompressSound(plManifestFile* mfsFile, bool noOverwrite = false);
public:
static plBackgroundDownloader* GetInstance();
static void StartThread();
bool Run();
void CleanUp();
void Pause();
void UnPause();
static bool CheckFreeSpace(UInt32 bytesNeeded);
// called by download callbacks to tell it we are done with the current file
void DoneWithFile(bool success);
void DoneWithManifest(bool success, const NetCliFileManifestEntry manifestEntires[], unsigned entryCount);
};
/*==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 plBackgroundDownloader_h_inc
#define plBackgroundDownloader_h_inc
#include <vector>
#include "hsTypes.h"
class plManifestFile;
struct NetCliFileManifestEntry;
class plBackgroundDownloader
{
protected:
static plBackgroundDownloader* fInstance;
static void Init();
static void Shutdown();
static void ThreadMain(void * param);
plBackgroundDownloader();
~plBackgroundDownloader();
HANDLE fBGDownloaderRun;
HANDLE fBGDownloaderIsPaused;
enum FileType {kFail, kPrp, kOther};
typedef std::vector<plManifestFile*> MfsFileVec;
MfsFileVec fMfsVec;
public:
bool fDoneWithFile;
bool fSuccess;
bool IGetDataManifest();
FileType IGetFile(const plManifestFile* mfsFile);
UInt32 IGetDownloadSize();
bool IDecompressSound(plManifestFile* mfsFile, bool noOverwrite = false);
public:
static plBackgroundDownloader* GetInstance();
static void StartThread();
bool Run();
void CleanUp();
void Pause();
void UnPause();
static bool CheckFreeSpace(UInt32 bytesNeeded);
// called by download callbacks to tell it we are done with the current file
void DoneWithFile(bool success);
void DoneWithManifest(bool success, const NetCliFileManifestEntry manifestEntires[], unsigned entryCount);
};
#endif //plBackgroundDownloader_h_inc

File diff suppressed because it is too large Load Diff

View File

@ -1,87 +1,87 @@
/*==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 plResPatcher_h_inc
#define plResPatcher_h_inc
#include "hsStlUtils.h"
#include "pnUtils/pnUtils.h"
#include "pnNetBase/pnNetBase.h"
#include "plEncryption/plChecksum.h"
class plManifest;
class plManifestFile;
class plOperationProgress;
struct NetCliFileManifestEntry;
class plResPatcher
{
protected:
enum FileType {kFail, kPrp, kOther};
std::string fAgeToPatch;
typedef std::vector<plManifestFile*> MfsFileVec;
MfsFileVec fMfsVec;
bool fDoneWithFile;
bool fSuccess;
bool fAlwaysShowAgeName;
void IInit();
static void ILog(UInt32 type, const char* format, ...);
FileType IGetFile(const plManifestFile* mfsFile, plOperationProgress* progressBar);
bool IGetAgeManifest();
UInt32 IGetDownloadSize();
bool IDecompressSound(plManifestFile* mfsFile, bool noOverwrite = false);
public:
plResPatcher(const char* ageToPatch, bool showAgeName = false);
~plResPatcher();
bool Update();
static bool CheckFreeSpace(UInt32 bytesNeeded);
// called by download callbacks to tell it we are done with the current file
void DoneWithFile(bool success) {fDoneWithFile = true; fSuccess = success;}
void DoneWithManifest(bool success, const NetCliFileManifestEntry manifestEntires[], unsigned entryCount);
};
enum PatcherLogType
{
kHeader,
kInfo,
kMajorStatus,
kStatus,
kError,
};
void PatcherLog(PatcherLogType type, const char* format, ...);
#endif // _plResPatcher_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 plResPatcher_h_inc
#define plResPatcher_h_inc
#include "hsStlUtils.h"
#include "pnUtils/pnUtils.h"
#include "pnNetBase/pnNetBase.h"
#include "plEncryption/plChecksum.h"
class plManifest;
class plManifestFile;
class plOperationProgress;
struct NetCliFileManifestEntry;
class plResPatcher
{
protected:
enum FileType {kFail, kPrp, kOther};
std::string fAgeToPatch;
typedef std::vector<plManifestFile*> MfsFileVec;
MfsFileVec fMfsVec;
bool fDoneWithFile;
bool fSuccess;
bool fAlwaysShowAgeName;
void IInit();
static void ILog(UInt32 type, const char* format, ...);
FileType IGetFile(const plManifestFile* mfsFile, plOperationProgress* progressBar);
bool IGetAgeManifest();
UInt32 IGetDownloadSize();
bool IDecompressSound(plManifestFile* mfsFile, bool noOverwrite = false);
public:
plResPatcher(const char* ageToPatch, bool showAgeName = false);
~plResPatcher();
bool Update();
static bool CheckFreeSpace(UInt32 bytesNeeded);
// called by download callbacks to tell it we are done with the current file
void DoneWithFile(bool success) {fDoneWithFile = true; fSuccess = success;}
void DoneWithManifest(bool success, const NetCliFileManifestEntry manifestEntires[], unsigned entryCount);
};
enum PatcherLogType
{
kHeader,
kInfo,
kMajorStatus,
kStatus,
kError,
};
void PatcherLog(PatcherLogType type, const char* format, ...);
#endif // _plResPatcher_h