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:
@ -1,39 +1,39 @@
|
||||
include_directories("../../CoreLib")
|
||||
include_directories("../../NucleusLib/inc")
|
||||
include_directories("../../NucleusLib")
|
||||
include_directories("../../PubUtilLib")
|
||||
|
||||
set(plResMgr_SOURCES
|
||||
plBSDiffBuffer.cpp
|
||||
plDiffBuffer.cpp
|
||||
plKeyFinder.cpp
|
||||
plLocalization.cpp
|
||||
plPageInfo.cpp
|
||||
plRegistryHelpers.cpp
|
||||
plRegistryKeyList.cpp
|
||||
plRegistryNode.cpp
|
||||
plResManager.cpp
|
||||
plResManagerHelper.cpp
|
||||
plVersion.cpp
|
||||
)
|
||||
|
||||
set(plResMgr_HEADERS
|
||||
plBSDiffBuffer.h
|
||||
plDiffBuffer.h
|
||||
plKeyFinder.h
|
||||
plLocalization.h
|
||||
plPageInfo.h
|
||||
plRegistryHelpers.h
|
||||
plRegistryKeyList.h
|
||||
plRegistryNode.h
|
||||
plResManager.h
|
||||
plResManagerHelper.h
|
||||
plResMgrCreatable.h
|
||||
plResMgrSettings.h
|
||||
plVersion.h
|
||||
)
|
||||
|
||||
add_library(plResMgr STATIC ${plResMgr_SOURCES} ${plResMgr_HEADERS})
|
||||
|
||||
source_group("Source Files" FILES ${plResMgr_SOURCES})
|
||||
source_group("Header Files" FILES ${plResMgr_HEADERS})
|
||||
include_directories("../../CoreLib")
|
||||
include_directories("../../NucleusLib/inc")
|
||||
include_directories("../../NucleusLib")
|
||||
include_directories("../../PubUtilLib")
|
||||
|
||||
set(plResMgr_SOURCES
|
||||
plBSDiffBuffer.cpp
|
||||
plDiffBuffer.cpp
|
||||
plKeyFinder.cpp
|
||||
plLocalization.cpp
|
||||
plPageInfo.cpp
|
||||
plRegistryHelpers.cpp
|
||||
plRegistryKeyList.cpp
|
||||
plRegistryNode.cpp
|
||||
plResManager.cpp
|
||||
plResManagerHelper.cpp
|
||||
plVersion.cpp
|
||||
)
|
||||
|
||||
set(plResMgr_HEADERS
|
||||
plBSDiffBuffer.h
|
||||
plDiffBuffer.h
|
||||
plKeyFinder.h
|
||||
plLocalization.h
|
||||
plPageInfo.h
|
||||
plRegistryHelpers.h
|
||||
plRegistryKeyList.h
|
||||
plRegistryNode.h
|
||||
plResManager.h
|
||||
plResManagerHelper.h
|
||||
plResMgrCreatable.h
|
||||
plResMgrSettings.h
|
||||
plVersion.h
|
||||
)
|
||||
|
||||
add_library(plResMgr STATIC ${plResMgr_SOURCES} ${plResMgr_HEADERS})
|
||||
|
||||
source_group("Source Files" FILES ${plResMgr_SOURCES})
|
||||
source_group("Header Files" FILES ${plResMgr_HEADERS})
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,111 +1,111 @@
|
||||
/*==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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// plBSDiffBuffer - A utility class for writing and applying a difference
|
||||
// buffer--i.e. a buffer containing a series of modifications
|
||||
// that will modify an old data buffer to match a new one.
|
||||
// It's a useful utility class when doing binary file
|
||||
// patching, for example, as you can write out the changes
|
||||
// to this class, get back a data buffer suitable for writing,
|
||||
// then use this class again later to reconstruct the new buffer.
|
||||
//
|
||||
// This class is copied in structure (not substance) from
|
||||
// plDiffBuffer. It is based on bsdiff-4.1 from BSD
|
||||
// Linux (http://www.daemonology.org/bsdiff). It's *extremely*
|
||||
// hard to read code (written by a PhD), but it works well. The
|
||||
// original BSD code has been modified to have the bzip2 pipes
|
||||
// it used to compress data removed. It has also been converted
|
||||
// to work a C++ utility class.
|
||||
//
|
||||
// There isn't really an Add or Copy command in bsdiff. It just
|
||||
// uses three control numbers and two diff/data buffers.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plBSDiffBuffer_h
|
||||
#define _plBSDiffBuffer_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsStream.h"
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class hsRAMStream;
|
||||
class plBSDiffBuffer
|
||||
{
|
||||
protected:
|
||||
|
||||
hsBool fWriting;
|
||||
UInt32 fNewLength, fPatchLength;
|
||||
unsigned char* fPatchBuffer;
|
||||
|
||||
public:
|
||||
|
||||
plBSDiffBuffer( UInt32 newLength, UInt32 oldLength = 0 ); // Constructor for writing new buffers. oldLength isn't required but helpful for optimizations
|
||||
plBSDiffBuffer( void *buffer, UInt32 length ); // Constructor for applying a given diff set
|
||||
// to an old buffer
|
||||
virtual ~plBSDiffBuffer();
|
||||
|
||||
|
||||
/// Creation/write functions
|
||||
|
||||
// Diff() creates the diff buffer from the new and old.
|
||||
UInt32 Diff( UInt32 oldLength, void *oldBuffer, UInt32 newLength, void *newBuffer );
|
||||
|
||||
// GetBuffer() will copy the diff stream into a new buffer and return it. You are responsible for freeing the buffer.
|
||||
void GetBuffer( UInt32 &length, void *&bufferPtr );
|
||||
|
||||
|
||||
/// Apply functions
|
||||
|
||||
// Apply() is another way to call Patch().
|
||||
UInt32 Apply( UInt32 oldLength, void *oldBuffer, UInt32 &newLength, void *&newBuffer )
|
||||
{ return Patch(oldLength, oldBuffer, newLength, newBuffer); };
|
||||
|
||||
// Patch() will take this diff buffer and apply it to the given old buffer,
|
||||
// allocating and producing a new buffer. You are responsible for freeing the new buffer.
|
||||
UInt32 Patch( UInt32 oldLength, void *oldBuffer, UInt32 &newLength, void *&newBuffer );
|
||||
|
||||
private:
|
||||
|
||||
UInt32 IReadUnsignedInt8(unsigned char *buf);
|
||||
void IWriteUnsignedInt8(UInt32 x,unsigned char *buf);
|
||||
void ISafeMemcpy(unsigned char *dest, unsigned char *src, size_t nbytes,
|
||||
unsigned char *destend, unsigned char *srcend);
|
||||
void ISplit(Int32 *I,Int32 *V,UInt32 start,UInt32 len,UInt32 h);
|
||||
void IQSuffixSort(Int32 *I,Int32 *V,unsigned char *old,UInt32 oldsize);
|
||||
UInt32 IMatchLen( unsigned char *oldBuffer, UInt32 oldLength,
|
||||
unsigned char *newBuffer, UInt32 newLength);
|
||||
UInt32 ISearch( Int32 *I,
|
||||
unsigned char *oldBuffer, UInt32 oldLength,
|
||||
unsigned char *newBuffer, UInt32 newLength,
|
||||
UInt32 st, UInt32 en, Int32 *pos);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // _plBSDiffBuffer_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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// plBSDiffBuffer - A utility class for writing and applying a difference
|
||||
// buffer--i.e. a buffer containing a series of modifications
|
||||
// that will modify an old data buffer to match a new one.
|
||||
// It's a useful utility class when doing binary file
|
||||
// patching, for example, as you can write out the changes
|
||||
// to this class, get back a data buffer suitable for writing,
|
||||
// then use this class again later to reconstruct the new buffer.
|
||||
//
|
||||
// This class is copied in structure (not substance) from
|
||||
// plDiffBuffer. It is based on bsdiff-4.1 from BSD
|
||||
// Linux (http://www.daemonology.org/bsdiff). It's *extremely*
|
||||
// hard to read code (written by a PhD), but it works well. The
|
||||
// original BSD code has been modified to have the bzip2 pipes
|
||||
// it used to compress data removed. It has also been converted
|
||||
// to work a C++ utility class.
|
||||
//
|
||||
// There isn't really an Add or Copy command in bsdiff. It just
|
||||
// uses three control numbers and two diff/data buffers.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plBSDiffBuffer_h
|
||||
#define _plBSDiffBuffer_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsStream.h"
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class hsRAMStream;
|
||||
class plBSDiffBuffer
|
||||
{
|
||||
protected:
|
||||
|
||||
hsBool fWriting;
|
||||
UInt32 fNewLength, fPatchLength;
|
||||
unsigned char* fPatchBuffer;
|
||||
|
||||
public:
|
||||
|
||||
plBSDiffBuffer( UInt32 newLength, UInt32 oldLength = 0 ); // Constructor for writing new buffers. oldLength isn't required but helpful for optimizations
|
||||
plBSDiffBuffer( void *buffer, UInt32 length ); // Constructor for applying a given diff set
|
||||
// to an old buffer
|
||||
virtual ~plBSDiffBuffer();
|
||||
|
||||
|
||||
/// Creation/write functions
|
||||
|
||||
// Diff() creates the diff buffer from the new and old.
|
||||
UInt32 Diff( UInt32 oldLength, void *oldBuffer, UInt32 newLength, void *newBuffer );
|
||||
|
||||
// GetBuffer() will copy the diff stream into a new buffer and return it. You are responsible for freeing the buffer.
|
||||
void GetBuffer( UInt32 &length, void *&bufferPtr );
|
||||
|
||||
|
||||
/// Apply functions
|
||||
|
||||
// Apply() is another way to call Patch().
|
||||
UInt32 Apply( UInt32 oldLength, void *oldBuffer, UInt32 &newLength, void *&newBuffer )
|
||||
{ return Patch(oldLength, oldBuffer, newLength, newBuffer); };
|
||||
|
||||
// Patch() will take this diff buffer and apply it to the given old buffer,
|
||||
// allocating and producing a new buffer. You are responsible for freeing the new buffer.
|
||||
UInt32 Patch( UInt32 oldLength, void *oldBuffer, UInt32 &newLength, void *&newBuffer );
|
||||
|
||||
private:
|
||||
|
||||
UInt32 IReadUnsignedInt8(unsigned char *buf);
|
||||
void IWriteUnsignedInt8(UInt32 x,unsigned char *buf);
|
||||
void ISafeMemcpy(unsigned char *dest, unsigned char *src, size_t nbytes,
|
||||
unsigned char *destend, unsigned char *srcend);
|
||||
void ISplit(Int32 *I,Int32 *V,UInt32 start,UInt32 len,UInt32 h);
|
||||
void IQSuffixSort(Int32 *I,Int32 *V,unsigned char *old,UInt32 oldsize);
|
||||
UInt32 IMatchLen( unsigned char *oldBuffer, UInt32 oldLength,
|
||||
unsigned char *newBuffer, UInt32 newLength);
|
||||
UInt32 ISearch( Int32 *I,
|
||||
unsigned char *oldBuffer, UInt32 oldLength,
|
||||
unsigned char *newBuffer, UInt32 newLength,
|
||||
UInt32 st, UInt32 en, Int32 *pos);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // _plBSDiffBuffer_h
|
||||
|
@ -1,250 +1,250 @@
|
||||
/*==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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// plDiffBuffer - A utility class for writing and applying a difference
|
||||
// buffer--i.e. a buffer containing a series of modifications
|
||||
// (specifically, adds and copys) that will modify an old
|
||||
// data buffer to match a new one. It's a useful utility
|
||||
// class when doing binary file patching, for example, as you
|
||||
// can write out the changes to this class, get back a data
|
||||
// buffer suitable for writing, then use this class again
|
||||
// later to reconstruct the new buffer.
|
||||
//
|
||||
//// History /////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 7.24.2002 mcn - Created (Happy late b-day to me!)
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plDiffBuffer.h"
|
||||
#include "plBSDiffBuffer.h"
|
||||
#include "hsUtils.h"
|
||||
#include "hsStream.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Constructor/Destructors /////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//// Creation Constructor ////////////////////////////////////////////////////
|
||||
// Use this constructor when creating a new diff buffer. Pass in the length
|
||||
// of the final new buffer. You don't need to pass in the length of the old
|
||||
// buffer, but if you do, it'll help this class do some internal space
|
||||
// optimization.
|
||||
|
||||
plDiffBuffer::plDiffBuffer( UInt32 newLength, UInt32 oldLength )
|
||||
: fBSDiffBuffer( nil )
|
||||
, fIsBSDiff( false )
|
||||
{
|
||||
// Basically, if the new and old lengths can both fit into 16 bits
|
||||
// (not including a potential negation), then we can store all the
|
||||
// segment info as 16-bit values instead of 32.
|
||||
if( oldLength > 0 && oldLength < 32767 && newLength < 32767 )
|
||||
f16BitMode = true;
|
||||
else
|
||||
f16BitMode = false;
|
||||
|
||||
fNewLength = newLength;
|
||||
fStream = TRACKED_NEW hsRAMStream();
|
||||
fStream->WriteSwap32( fNewLength );
|
||||
fStream->WriteBool( f16BitMode );
|
||||
fWriting = true;
|
||||
}
|
||||
|
||||
//// Application Constructor /////////////////////////////////////////////////
|
||||
// Use this constructor when taking a diff buffer and applying it to an old
|
||||
// buffer. Pass in a pointer to the diff buffer and its length. The buffer
|
||||
// will be copied, so you don't need to keep it around after you construct
|
||||
// this object.
|
||||
|
||||
plDiffBuffer::plDiffBuffer( void *buffer, UInt32 length )
|
||||
: fBSDiffBuffer( nil )
|
||||
, fStream( nil )
|
||||
, fIsBSDiff( false )
|
||||
, fWriting( false )
|
||||
{
|
||||
// Check to see if this uses the newer BSDiff format
|
||||
if ( buffer && length > 32 &&
|
||||
memcmp(buffer,"BSDIFF40",8)==0 )
|
||||
{
|
||||
// This is a bsdiff buffer. Use plBSDiffBuffer to handle it.
|
||||
fBSDiffBuffer = TRACKED_NEW plBSDiffBuffer(buffer, length);
|
||||
fIsBSDiff = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fStream = TRACKED_NEW hsRAMStream();
|
||||
fStream->Write( length, buffer );
|
||||
fStream->Rewind();
|
||||
|
||||
fNewLength = fStream->ReadSwap32();
|
||||
f16BitMode = fStream->ReadBool();
|
||||
}
|
||||
}
|
||||
|
||||
plDiffBuffer::~plDiffBuffer()
|
||||
{
|
||||
if (fStream)
|
||||
delete fStream;
|
||||
if (fBSDiffBuffer)
|
||||
delete fBSDiffBuffer;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Creation/Write Functions ////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//// Add /////////////////////////////////////////////////////////////////////
|
||||
// Add() appends an Add-New-Data operation to the diff buffer. The data
|
||||
// supplied will be copied internally, so you can discard it after you call
|
||||
// this function.
|
||||
|
||||
void plDiffBuffer::Add( Int32 length, void *newData )
|
||||
{
|
||||
hsAssert( fWriting, "Trying to Add() to a difference buffer that's reading" );
|
||||
|
||||
// We flag our two different op types by the sign of the length. Negative
|
||||
// lengths are an add operation, positive ones are copy ops.
|
||||
if( f16BitMode )
|
||||
fStream->WriteSwap16( -( (Int16)length ) );
|
||||
else
|
||||
fStream->WriteSwap32( -length );
|
||||
fStream->Write( length, newData );
|
||||
}
|
||||
|
||||
//// Copy ////////////////////////////////////////////////////////////////////
|
||||
// Copy() appends a Copy-Data-From-Old operation to the diff buffer.
|
||||
|
||||
void plDiffBuffer::Copy( Int32 length, UInt32 oldOffset )
|
||||
{
|
||||
hsAssert( fWriting, "Trying to Copy() to a difference buffer that's reading" );
|
||||
|
||||
// We flag our two different op types by the sign of the length. Negative
|
||||
// lengths are an add operation, positive ones are copy ops.
|
||||
if( f16BitMode )
|
||||
{
|
||||
fStream->WriteSwap16( (Int16)length );
|
||||
fStream->WriteSwap16( (UInt16)oldOffset );
|
||||
}
|
||||
else
|
||||
{
|
||||
fStream->WriteSwap32( length );
|
||||
fStream->WriteSwap32( oldOffset );
|
||||
}
|
||||
}
|
||||
|
||||
//// GetBuffer ///////////////////////////////////////////////////////////////
|
||||
// GetBuffer() will copy the diff stream into a new buffer and return it.
|
||||
// You are responsible for freeing the buffer. Call this once you're done
|
||||
// adding ops and want the raw data to write out somewhere. Note: this
|
||||
// function will rewind the diff stream, so once you call it, you can't do
|
||||
// anything else on the object.
|
||||
|
||||
void plDiffBuffer::GetBuffer( UInt32 &length, void *&bufferPtr )
|
||||
{
|
||||
hsAssert( fWriting, "Trying to GetBuffer() on a difference buffer that's reading" );
|
||||
|
||||
length = fStream->GetPosition();
|
||||
bufferPtr = (void *)TRACKED_NEW UInt8[ length ];
|
||||
|
||||
fStream->Rewind();
|
||||
fStream->Read( length, bufferPtr );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Application Functions ///////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//// Apply ///////////////////////////////////////////////////////////////////
|
||||
// Apply() will take this diff buffer and apply it to the given old buffer,
|
||||
// allocating and producing a new buffer. You are responsible for freeing
|
||||
// the new buffer.
|
||||
|
||||
#define hsAssertAndBreak( cond, msg ) { if( cond ) { hsAssert( false, msg ); break; } }
|
||||
|
||||
void plDiffBuffer::Apply( UInt32 oldLength, void *oldBuffer, UInt32 &newLength, void *&newBuffer )
|
||||
{
|
||||
hsAssert( !fWriting, "Trying to Apply() a difference buffer that's writing" );
|
||||
|
||||
// Is this is a BSDiff patch, use plBSDiffBuffer and return.
|
||||
if (fIsBSDiff)
|
||||
{
|
||||
fBSDiffBuffer->Apply(oldLength, oldBuffer, newLength, newBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
/// Step 1: Allocate the new buffer
|
||||
newLength = fNewLength;
|
||||
UInt8 *new8Buffer = TRACKED_NEW UInt8[ newLength ];
|
||||
UInt8 *old8Buffer = (UInt8 *)oldBuffer;
|
||||
newBuffer = (void *)new8Buffer;
|
||||
|
||||
|
||||
/// Step 2: Loop through the difference stream
|
||||
Int32 opLength;
|
||||
UInt32 newBufferPos = 0;
|
||||
while( newBufferPos < newLength )
|
||||
{
|
||||
// Read in the op length
|
||||
if( f16BitMode )
|
||||
{
|
||||
Int16 opLen16 = fStream->ReadSwap16();
|
||||
if( opLen16 < 0 )
|
||||
opLength = -( (Int32)( -opLen16 ) );
|
||||
else
|
||||
opLength = (UInt32)opLen16;
|
||||
}
|
||||
else
|
||||
opLength = fStream->ReadSwap32();
|
||||
|
||||
// As defined, negative ops are add ops, positive ones are copys
|
||||
if( opLength < 0 )
|
||||
{
|
||||
hsAssertAndBreak( newBufferPos - opLength > newLength, "Destination buffer offset in plDiffBuffer() is out of range!" );
|
||||
|
||||
// Add op, read in the added data
|
||||
fStream->Read( -opLength, &new8Buffer[ newBufferPos ] );
|
||||
newBufferPos += -opLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy op, so get the old offset and copy from there
|
||||
UInt32 oldOffset = f16BitMode ? fStream->ReadSwap16() : fStream->ReadSwap32();
|
||||
|
||||
hsAssertAndBreak( newBufferPos + opLength > newLength, "Destination buffer offset in plDiffBuffer() is out of range!" );
|
||||
hsAssertAndBreak( oldOffset + opLength > oldLength, "Difference buffer offset in plDiffBuffer() is out of range of the old buffer!" );
|
||||
|
||||
memcpy( &new8Buffer[ newBufferPos ], old8Buffer + oldOffset, opLength );
|
||||
newBufferPos += opLength;
|
||||
}
|
||||
}
|
||||
|
||||
hsAssert( newBufferPos == newLength, "Invalid sequence of difference ops in plDiffBuffer::Apply()" );
|
||||
}
|
||||
/*==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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// plDiffBuffer - A utility class for writing and applying a difference
|
||||
// buffer--i.e. a buffer containing a series of modifications
|
||||
// (specifically, adds and copys) that will modify an old
|
||||
// data buffer to match a new one. It's a useful utility
|
||||
// class when doing binary file patching, for example, as you
|
||||
// can write out the changes to this class, get back a data
|
||||
// buffer suitable for writing, then use this class again
|
||||
// later to reconstruct the new buffer.
|
||||
//
|
||||
//// History /////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 7.24.2002 mcn - Created (Happy late b-day to me!)
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plDiffBuffer.h"
|
||||
#include "plBSDiffBuffer.h"
|
||||
#include "hsUtils.h"
|
||||
#include "hsStream.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Constructor/Destructors /////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//// Creation Constructor ////////////////////////////////////////////////////
|
||||
// Use this constructor when creating a new diff buffer. Pass in the length
|
||||
// of the final new buffer. You don't need to pass in the length of the old
|
||||
// buffer, but if you do, it'll help this class do some internal space
|
||||
// optimization.
|
||||
|
||||
plDiffBuffer::plDiffBuffer( UInt32 newLength, UInt32 oldLength )
|
||||
: fBSDiffBuffer( nil )
|
||||
, fIsBSDiff( false )
|
||||
{
|
||||
// Basically, if the new and old lengths can both fit into 16 bits
|
||||
// (not including a potential negation), then we can store all the
|
||||
// segment info as 16-bit values instead of 32.
|
||||
if( oldLength > 0 && oldLength < 32767 && newLength < 32767 )
|
||||
f16BitMode = true;
|
||||
else
|
||||
f16BitMode = false;
|
||||
|
||||
fNewLength = newLength;
|
||||
fStream = TRACKED_NEW hsRAMStream();
|
||||
fStream->WriteSwap32( fNewLength );
|
||||
fStream->WriteBool( f16BitMode );
|
||||
fWriting = true;
|
||||
}
|
||||
|
||||
//// Application Constructor /////////////////////////////////////////////////
|
||||
// Use this constructor when taking a diff buffer and applying it to an old
|
||||
// buffer. Pass in a pointer to the diff buffer and its length. The buffer
|
||||
// will be copied, so you don't need to keep it around after you construct
|
||||
// this object.
|
||||
|
||||
plDiffBuffer::plDiffBuffer( void *buffer, UInt32 length )
|
||||
: fBSDiffBuffer( nil )
|
||||
, fStream( nil )
|
||||
, fIsBSDiff( false )
|
||||
, fWriting( false )
|
||||
{
|
||||
// Check to see if this uses the newer BSDiff format
|
||||
if ( buffer && length > 32 &&
|
||||
memcmp(buffer,"BSDIFF40",8)==0 )
|
||||
{
|
||||
// This is a bsdiff buffer. Use plBSDiffBuffer to handle it.
|
||||
fBSDiffBuffer = TRACKED_NEW plBSDiffBuffer(buffer, length);
|
||||
fIsBSDiff = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fStream = TRACKED_NEW hsRAMStream();
|
||||
fStream->Write( length, buffer );
|
||||
fStream->Rewind();
|
||||
|
||||
fNewLength = fStream->ReadSwap32();
|
||||
f16BitMode = fStream->ReadBool();
|
||||
}
|
||||
}
|
||||
|
||||
plDiffBuffer::~plDiffBuffer()
|
||||
{
|
||||
if (fStream)
|
||||
delete fStream;
|
||||
if (fBSDiffBuffer)
|
||||
delete fBSDiffBuffer;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Creation/Write Functions ////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//// Add /////////////////////////////////////////////////////////////////////
|
||||
// Add() appends an Add-New-Data operation to the diff buffer. The data
|
||||
// supplied will be copied internally, so you can discard it after you call
|
||||
// this function.
|
||||
|
||||
void plDiffBuffer::Add( Int32 length, void *newData )
|
||||
{
|
||||
hsAssert( fWriting, "Trying to Add() to a difference buffer that's reading" );
|
||||
|
||||
// We flag our two different op types by the sign of the length. Negative
|
||||
// lengths are an add operation, positive ones are copy ops.
|
||||
if( f16BitMode )
|
||||
fStream->WriteSwap16( -( (Int16)length ) );
|
||||
else
|
||||
fStream->WriteSwap32( -length );
|
||||
fStream->Write( length, newData );
|
||||
}
|
||||
|
||||
//// Copy ////////////////////////////////////////////////////////////////////
|
||||
// Copy() appends a Copy-Data-From-Old operation to the diff buffer.
|
||||
|
||||
void plDiffBuffer::Copy( Int32 length, UInt32 oldOffset )
|
||||
{
|
||||
hsAssert( fWriting, "Trying to Copy() to a difference buffer that's reading" );
|
||||
|
||||
// We flag our two different op types by the sign of the length. Negative
|
||||
// lengths are an add operation, positive ones are copy ops.
|
||||
if( f16BitMode )
|
||||
{
|
||||
fStream->WriteSwap16( (Int16)length );
|
||||
fStream->WriteSwap16( (UInt16)oldOffset );
|
||||
}
|
||||
else
|
||||
{
|
||||
fStream->WriteSwap32( length );
|
||||
fStream->WriteSwap32( oldOffset );
|
||||
}
|
||||
}
|
||||
|
||||
//// GetBuffer ///////////////////////////////////////////////////////////////
|
||||
// GetBuffer() will copy the diff stream into a new buffer and return it.
|
||||
// You are responsible for freeing the buffer. Call this once you're done
|
||||
// adding ops and want the raw data to write out somewhere. Note: this
|
||||
// function will rewind the diff stream, so once you call it, you can't do
|
||||
// anything else on the object.
|
||||
|
||||
void plDiffBuffer::GetBuffer( UInt32 &length, void *&bufferPtr )
|
||||
{
|
||||
hsAssert( fWriting, "Trying to GetBuffer() on a difference buffer that's reading" );
|
||||
|
||||
length = fStream->GetPosition();
|
||||
bufferPtr = (void *)TRACKED_NEW UInt8[ length ];
|
||||
|
||||
fStream->Rewind();
|
||||
fStream->Read( length, bufferPtr );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Application Functions ///////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//// Apply ///////////////////////////////////////////////////////////////////
|
||||
// Apply() will take this diff buffer and apply it to the given old buffer,
|
||||
// allocating and producing a new buffer. You are responsible for freeing
|
||||
// the new buffer.
|
||||
|
||||
#define hsAssertAndBreak( cond, msg ) { if( cond ) { hsAssert( false, msg ); break; } }
|
||||
|
||||
void plDiffBuffer::Apply( UInt32 oldLength, void *oldBuffer, UInt32 &newLength, void *&newBuffer )
|
||||
{
|
||||
hsAssert( !fWriting, "Trying to Apply() a difference buffer that's writing" );
|
||||
|
||||
// Is this is a BSDiff patch, use plBSDiffBuffer and return.
|
||||
if (fIsBSDiff)
|
||||
{
|
||||
fBSDiffBuffer->Apply(oldLength, oldBuffer, newLength, newBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
/// Step 1: Allocate the new buffer
|
||||
newLength = fNewLength;
|
||||
UInt8 *new8Buffer = TRACKED_NEW UInt8[ newLength ];
|
||||
UInt8 *old8Buffer = (UInt8 *)oldBuffer;
|
||||
newBuffer = (void *)new8Buffer;
|
||||
|
||||
|
||||
/// Step 2: Loop through the difference stream
|
||||
Int32 opLength;
|
||||
UInt32 newBufferPos = 0;
|
||||
while( newBufferPos < newLength )
|
||||
{
|
||||
// Read in the op length
|
||||
if( f16BitMode )
|
||||
{
|
||||
Int16 opLen16 = fStream->ReadSwap16();
|
||||
if( opLen16 < 0 )
|
||||
opLength = -( (Int32)( -opLen16 ) );
|
||||
else
|
||||
opLength = (UInt32)opLen16;
|
||||
}
|
||||
else
|
||||
opLength = fStream->ReadSwap32();
|
||||
|
||||
// As defined, negative ops are add ops, positive ones are copys
|
||||
if( opLength < 0 )
|
||||
{
|
||||
hsAssertAndBreak( newBufferPos - opLength > newLength, "Destination buffer offset in plDiffBuffer() is out of range!" );
|
||||
|
||||
// Add op, read in the added data
|
||||
fStream->Read( -opLength, &new8Buffer[ newBufferPos ] );
|
||||
newBufferPos += -opLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy op, so get the old offset and copy from there
|
||||
UInt32 oldOffset = f16BitMode ? fStream->ReadSwap16() : fStream->ReadSwap32();
|
||||
|
||||
hsAssertAndBreak( newBufferPos + opLength > newLength, "Destination buffer offset in plDiffBuffer() is out of range!" );
|
||||
hsAssertAndBreak( oldOffset + opLength > oldLength, "Difference buffer offset in plDiffBuffer() is out of range of the old buffer!" );
|
||||
|
||||
memcpy( &new8Buffer[ newBufferPos ], old8Buffer + oldOffset, opLength );
|
||||
newBufferPos += opLength;
|
||||
}
|
||||
}
|
||||
|
||||
hsAssert( newBufferPos == newLength, "Invalid sequence of difference ops in plDiffBuffer::Apply()" );
|
||||
}
|
||||
|
@ -1,103 +1,103 @@
|
||||
/*==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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// plDiffBuffer - A utility class for writing and applying a difference
|
||||
// buffer--i.e. a buffer containing a series of modifications
|
||||
// (specifically, adds and copys) that will modify an old
|
||||
// data buffer to match a new one. It's a useful utility
|
||||
// class when doing binary file patching, for example, as you
|
||||
// can write out the changes to this class, get back a data
|
||||
// buffer suitable for writing, then use this class again
|
||||
// later to reconstruct the new buffer.
|
||||
//
|
||||
// This class is meant to construct diff buffers using two
|
||||
// ops: add and copy. Basically, the syntax is defined so
|
||||
// that to reconstruct the new buffer, you run through the
|
||||
// list of ops sequentially, each one defining the next
|
||||
// chunk of data in the new buffer. Add ops will add new data
|
||||
// to the buffer that didn't exist in the old buffer, and
|
||||
// copy ops will copy data that existed in the old buffer
|
||||
// (from an arbitrary offset, to facilitate encoding data
|
||||
// shuffling). Delete ops are implicit, as they simply aren't
|
||||
// defined in the stream of ops.
|
||||
//
|
||||
//// History /////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 7.24.2002 mcn - Created (Happy late b-day to me!)
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plDiffBuffer_h
|
||||
#define _plDiffBuffer_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsStream.h"
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class hsRAMStream;
|
||||
class plBSDiffBuffer;
|
||||
class plDiffBuffer
|
||||
{
|
||||
protected:
|
||||
|
||||
hsBool fWriting, f16BitMode;
|
||||
UInt32 fNewLength;
|
||||
hsRAMStream *fStream;
|
||||
|
||||
// Support for BSDiff patch buffers (Patching only)
|
||||
plBSDiffBuffer *fBSDiffBuffer;
|
||||
hsBool fIsBSDiff;
|
||||
|
||||
public:
|
||||
|
||||
plDiffBuffer( UInt32 newLength, UInt32 oldLength = 0 ); // Constructor for writing new buffers. oldLength isn't required but helpful for optimizations
|
||||
plDiffBuffer( void *buffer, UInt32 length ); // Constructor for applying a given diff set
|
||||
// to an old buffer
|
||||
virtual ~plDiffBuffer();
|
||||
|
||||
|
||||
/// Creation/write functions
|
||||
|
||||
// Add() appends an Add-New-Data operation to the diff buffer. The data supplied will be copied internally.
|
||||
void Add( Int32 length, void *newData );
|
||||
|
||||
// Copy() appends a Copy-Data-From-Old operation to the diff buffer
|
||||
void Copy( Int32 length, UInt32 oldOffset );
|
||||
|
||||
// GetBuffer() will copy the diff stream into a new buffer and return it. You are responsible for freeing the buffer.
|
||||
void GetBuffer( UInt32 &length, void *&bufferPtr );
|
||||
|
||||
|
||||
/// Apply functions
|
||||
|
||||
// Apply() will take this diff buffer and apply it to the given old buffer, allocating and producing a new buffer. You are responsible for freeing the new buffer.
|
||||
void Apply( UInt32 oldLength, void *oldBuffer, UInt32 &newLength, void *&newBuffer );
|
||||
|
||||
};
|
||||
|
||||
#endif // _plDiffBuffer_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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// plDiffBuffer - A utility class for writing and applying a difference
|
||||
// buffer--i.e. a buffer containing a series of modifications
|
||||
// (specifically, adds and copys) that will modify an old
|
||||
// data buffer to match a new one. It's a useful utility
|
||||
// class when doing binary file patching, for example, as you
|
||||
// can write out the changes to this class, get back a data
|
||||
// buffer suitable for writing, then use this class again
|
||||
// later to reconstruct the new buffer.
|
||||
//
|
||||
// This class is meant to construct diff buffers using two
|
||||
// ops: add and copy. Basically, the syntax is defined so
|
||||
// that to reconstruct the new buffer, you run through the
|
||||
// list of ops sequentially, each one defining the next
|
||||
// chunk of data in the new buffer. Add ops will add new data
|
||||
// to the buffer that didn't exist in the old buffer, and
|
||||
// copy ops will copy data that existed in the old buffer
|
||||
// (from an arbitrary offset, to facilitate encoding data
|
||||
// shuffling). Delete ops are implicit, as they simply aren't
|
||||
// defined in the stream of ops.
|
||||
//
|
||||
//// History /////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 7.24.2002 mcn - Created (Happy late b-day to me!)
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plDiffBuffer_h
|
||||
#define _plDiffBuffer_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsStream.h"
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class hsRAMStream;
|
||||
class plBSDiffBuffer;
|
||||
class plDiffBuffer
|
||||
{
|
||||
protected:
|
||||
|
||||
hsBool fWriting, f16BitMode;
|
||||
UInt32 fNewLength;
|
||||
hsRAMStream *fStream;
|
||||
|
||||
// Support for BSDiff patch buffers (Patching only)
|
||||
plBSDiffBuffer *fBSDiffBuffer;
|
||||
hsBool fIsBSDiff;
|
||||
|
||||
public:
|
||||
|
||||
plDiffBuffer( UInt32 newLength, UInt32 oldLength = 0 ); // Constructor for writing new buffers. oldLength isn't required but helpful for optimizations
|
||||
plDiffBuffer( void *buffer, UInt32 length ); // Constructor for applying a given diff set
|
||||
// to an old buffer
|
||||
virtual ~plDiffBuffer();
|
||||
|
||||
|
||||
/// Creation/write functions
|
||||
|
||||
// Add() appends an Add-New-Data operation to the diff buffer. The data supplied will be copied internally.
|
||||
void Add( Int32 length, void *newData );
|
||||
|
||||
// Copy() appends a Copy-Data-From-Old operation to the diff buffer
|
||||
void Copy( Int32 length, UInt32 oldOffset );
|
||||
|
||||
// GetBuffer() will copy the diff stream into a new buffer and return it. You are responsible for freeing the buffer.
|
||||
void GetBuffer( UInt32 &length, void *&bufferPtr );
|
||||
|
||||
|
||||
/// Apply functions
|
||||
|
||||
// Apply() will take this diff buffer and apply it to the given old buffer, allocating and producing a new buffer. You are responsible for freeing the new buffer.
|
||||
void Apply( UInt32 oldLength, void *oldBuffer, UInt32 &newLength, void *&newBuffer );
|
||||
|
||||
};
|
||||
|
||||
#endif // _plDiffBuffer_h
|
||||
|
@ -1,195 +1,195 @@
|
||||
/*==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==*/
|
||||
#define plIndexFile_cpp // for version numbers in plVersion.h
|
||||
|
||||
#include "plIndexFile.h"
|
||||
#include "hsStream.h"
|
||||
#include "plVersion.h"
|
||||
|
||||
//--------------------
|
||||
// plIndexFileHeader
|
||||
//--------------------
|
||||
|
||||
plIndexFileHeader::plIndexFileHeader()
|
||||
{
|
||||
fTimeStamp[ 0 ] = fTimeStamp[ 1 ] = 0;
|
||||
fStrTblStartPos = 0;
|
||||
fStrTblKnt = 0;
|
||||
fMajorVersion = plVersion::GetMajorVersion();
|
||||
fMinorVersion = plVersion::GetMinorVersion();
|
||||
fExportLocal = 0;
|
||||
}
|
||||
|
||||
void plIndexFileHeader::Write(hsStream *s)
|
||||
{
|
||||
s->WriteSwap32(2,fTimeStamp);
|
||||
s->WriteSwap32(fStrTblStartPos);
|
||||
s->WriteSwap16(fStrTblKnt);
|
||||
s->WriteSwap16(fMajorVersion);
|
||||
s->WriteSwap16(fMinorVersion);
|
||||
s->WriteSwap16(fExportLocal);
|
||||
}
|
||||
void plIndexFileHeader::Read(hsStream *s)
|
||||
{
|
||||
s->ReadSwap32(2,fTimeStamp);
|
||||
fStrTblStartPos = s->ReadSwap32();
|
||||
fStrTblKnt = s->ReadSwap16();
|
||||
fMajorVersion = s->ReadSwap16();
|
||||
fMinorVersion = s->ReadSwap16();
|
||||
fExportLocal = s->ReadSwap16();
|
||||
}
|
||||
|
||||
//--------------------
|
||||
// plIndexFileRoom
|
||||
//--------------------
|
||||
|
||||
void plIndexFileRoom::Write(hsStream *s)
|
||||
{
|
||||
fRmUoid.Write(s);
|
||||
s->WriteSwap32(fTypesInRoom);
|
||||
s->WriteSwap16(fFiller1_16);
|
||||
s->WriteSwap32(fFiller2_32);
|
||||
s->WriteSwap32(fFiller3_32);
|
||||
}
|
||||
void plIndexFileRoom::Read(hsStream *s)
|
||||
{
|
||||
fRmUoid.Read(s);
|
||||
fTypesInRoom = s->ReadSwap32();
|
||||
s->ReadSwap16();
|
||||
s->ReadSwap32();
|
||||
s->ReadSwap32();
|
||||
}
|
||||
//--------------------
|
||||
// plIndexFileType
|
||||
//--------------------
|
||||
|
||||
|
||||
void plIndexFileType::Write(hsStream *s)
|
||||
{
|
||||
fTypeUoid.Write(s);
|
||||
s->WriteSwap32(fNumKeys);
|
||||
s->WriteSwap32(fFiller1_32);
|
||||
s->WriteSwap32(fFiller2_32);
|
||||
}
|
||||
|
||||
void plIndexFileType::Read(hsStream *s)
|
||||
{
|
||||
fTypeUoid.Read(s);
|
||||
fNumKeys = s->ReadSwap32();
|
||||
s->ReadSwap32();
|
||||
s->ReadSwap32();
|
||||
}
|
||||
//--------------------
|
||||
// plIndexFileKey
|
||||
//--------------------
|
||||
|
||||
|
||||
void plIndexFileKey::Write(hsStream *s)
|
||||
{
|
||||
fKeyUoid.Write(s);
|
||||
s->WriteSwap32(fStartPos);
|
||||
s->WriteSwap32(fDataLen);
|
||||
s->WriteSwap16(fNameIx);
|
||||
s->WriteSwap16(fFiller1_16);
|
||||
}
|
||||
|
||||
|
||||
void plIndexFileKey::Read(hsStream *s)
|
||||
{
|
||||
fKeyUoid.Read(s);
|
||||
fStartPos = s->ReadSwap32();
|
||||
fDataLen = s->ReadSwap32();
|
||||
fNameIx = s->ReadSwap16();
|
||||
s->ReadSwap16();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------
|
||||
// plIxStrTbl
|
||||
//--------------------
|
||||
|
||||
plIxStrTbl::~plIxStrTbl()
|
||||
{
|
||||
if (fpStrings) delete []fpStrings; // if strings came from elsewhere, not our responsibility
|
||||
}
|
||||
|
||||
UInt16 plIxStrTbl::AddString(const char *p)
|
||||
{ Int16 ix = FindString(p);
|
||||
if (ix != -1)
|
||||
return ix; // duplicate
|
||||
fStringTbl.push_back(p); return fStringTbl.size() - 1;
|
||||
}
|
||||
|
||||
Int16 plIxStrTbl::FindString(const char *p)
|
||||
{
|
||||
for (int i=0; i < fStringTbl.size(); i++)
|
||||
{
|
||||
if (!_stricmp(p,fStringTbl[i]))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void plIxStrTbl::Write(hsStream *s)
|
||||
{
|
||||
for (int i=0; i < fStringTbl.size(); i++)
|
||||
{ Int32 len= fStringTbl[i] ? strlen(fStringTbl[i]) : 0;
|
||||
hsAssert(len < 256,"Name string too long");
|
||||
UInt8 l = (UInt8) len;
|
||||
s->WriteByte(l); // FUTURE, don't really need length!
|
||||
if (len)
|
||||
{
|
||||
s->Write(len, fStringTbl[i]);
|
||||
}
|
||||
s->WriteByte(0); // Null terminate
|
||||
}
|
||||
}
|
||||
|
||||
void plIxStrTbl::Read(hsStream *s)
|
||||
{ UInt32 pos = s->GetPosition();
|
||||
s->FastFwd();
|
||||
fTabSize = s->GetPosition() - pos; // Get size of table
|
||||
s->SetPosition(pos);
|
||||
fpStrings = new char[fTabSize];
|
||||
hsAssert(fpStrings,"new failed");
|
||||
s->Read(fTabSize,fpStrings); // Read all the string in
|
||||
|
||||
char *p = fpStrings;
|
||||
while (p < fpStrings + fTabSize)
|
||||
{
|
||||
UInt8 len = *p;
|
||||
p++;
|
||||
hsAssert(p < fpStrings + fTabSize,"String Index error");
|
||||
fStringTbl.push_back(p);
|
||||
p += len + 1; // past len and NULL
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*==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==*/
|
||||
#define plIndexFile_cpp // for version numbers in plVersion.h
|
||||
|
||||
#include "plIndexFile.h"
|
||||
#include "hsStream.h"
|
||||
#include "plVersion.h"
|
||||
|
||||
//--------------------
|
||||
// plIndexFileHeader
|
||||
//--------------------
|
||||
|
||||
plIndexFileHeader::plIndexFileHeader()
|
||||
{
|
||||
fTimeStamp[ 0 ] = fTimeStamp[ 1 ] = 0;
|
||||
fStrTblStartPos = 0;
|
||||
fStrTblKnt = 0;
|
||||
fMajorVersion = plVersion::GetMajorVersion();
|
||||
fMinorVersion = plVersion::GetMinorVersion();
|
||||
fExportLocal = 0;
|
||||
}
|
||||
|
||||
void plIndexFileHeader::Write(hsStream *s)
|
||||
{
|
||||
s->WriteSwap32(2,fTimeStamp);
|
||||
s->WriteSwap32(fStrTblStartPos);
|
||||
s->WriteSwap16(fStrTblKnt);
|
||||
s->WriteSwap16(fMajorVersion);
|
||||
s->WriteSwap16(fMinorVersion);
|
||||
s->WriteSwap16(fExportLocal);
|
||||
}
|
||||
void plIndexFileHeader::Read(hsStream *s)
|
||||
{
|
||||
s->ReadSwap32(2,fTimeStamp);
|
||||
fStrTblStartPos = s->ReadSwap32();
|
||||
fStrTblKnt = s->ReadSwap16();
|
||||
fMajorVersion = s->ReadSwap16();
|
||||
fMinorVersion = s->ReadSwap16();
|
||||
fExportLocal = s->ReadSwap16();
|
||||
}
|
||||
|
||||
//--------------------
|
||||
// plIndexFileRoom
|
||||
//--------------------
|
||||
|
||||
void plIndexFileRoom::Write(hsStream *s)
|
||||
{
|
||||
fRmUoid.Write(s);
|
||||
s->WriteSwap32(fTypesInRoom);
|
||||
s->WriteSwap16(fFiller1_16);
|
||||
s->WriteSwap32(fFiller2_32);
|
||||
s->WriteSwap32(fFiller3_32);
|
||||
}
|
||||
void plIndexFileRoom::Read(hsStream *s)
|
||||
{
|
||||
fRmUoid.Read(s);
|
||||
fTypesInRoom = s->ReadSwap32();
|
||||
s->ReadSwap16();
|
||||
s->ReadSwap32();
|
||||
s->ReadSwap32();
|
||||
}
|
||||
//--------------------
|
||||
// plIndexFileType
|
||||
//--------------------
|
||||
|
||||
|
||||
void plIndexFileType::Write(hsStream *s)
|
||||
{
|
||||
fTypeUoid.Write(s);
|
||||
s->WriteSwap32(fNumKeys);
|
||||
s->WriteSwap32(fFiller1_32);
|
||||
s->WriteSwap32(fFiller2_32);
|
||||
}
|
||||
|
||||
void plIndexFileType::Read(hsStream *s)
|
||||
{
|
||||
fTypeUoid.Read(s);
|
||||
fNumKeys = s->ReadSwap32();
|
||||
s->ReadSwap32();
|
||||
s->ReadSwap32();
|
||||
}
|
||||
//--------------------
|
||||
// plIndexFileKey
|
||||
//--------------------
|
||||
|
||||
|
||||
void plIndexFileKey::Write(hsStream *s)
|
||||
{
|
||||
fKeyUoid.Write(s);
|
||||
s->WriteSwap32(fStartPos);
|
||||
s->WriteSwap32(fDataLen);
|
||||
s->WriteSwap16(fNameIx);
|
||||
s->WriteSwap16(fFiller1_16);
|
||||
}
|
||||
|
||||
|
||||
void plIndexFileKey::Read(hsStream *s)
|
||||
{
|
||||
fKeyUoid.Read(s);
|
||||
fStartPos = s->ReadSwap32();
|
||||
fDataLen = s->ReadSwap32();
|
||||
fNameIx = s->ReadSwap16();
|
||||
s->ReadSwap16();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------
|
||||
// plIxStrTbl
|
||||
//--------------------
|
||||
|
||||
plIxStrTbl::~plIxStrTbl()
|
||||
{
|
||||
if (fpStrings) delete []fpStrings; // if strings came from elsewhere, not our responsibility
|
||||
}
|
||||
|
||||
UInt16 plIxStrTbl::AddString(const char *p)
|
||||
{ Int16 ix = FindString(p);
|
||||
if (ix != -1)
|
||||
return ix; // duplicate
|
||||
fStringTbl.push_back(p); return fStringTbl.size() - 1;
|
||||
}
|
||||
|
||||
Int16 plIxStrTbl::FindString(const char *p)
|
||||
{
|
||||
for (int i=0; i < fStringTbl.size(); i++)
|
||||
{
|
||||
if (!_stricmp(p,fStringTbl[i]))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void plIxStrTbl::Write(hsStream *s)
|
||||
{
|
||||
for (int i=0; i < fStringTbl.size(); i++)
|
||||
{ Int32 len= fStringTbl[i] ? strlen(fStringTbl[i]) : 0;
|
||||
hsAssert(len < 256,"Name string too long");
|
||||
UInt8 l = (UInt8) len;
|
||||
s->WriteByte(l); // FUTURE, don't really need length!
|
||||
if (len)
|
||||
{
|
||||
s->Write(len, fStringTbl[i]);
|
||||
}
|
||||
s->WriteByte(0); // Null terminate
|
||||
}
|
||||
}
|
||||
|
||||
void plIxStrTbl::Read(hsStream *s)
|
||||
{ UInt32 pos = s->GetPosition();
|
||||
s->FastFwd();
|
||||
fTabSize = s->GetPosition() - pos; // Get size of table
|
||||
s->SetPosition(pos);
|
||||
fpStrings = new char[fTabSize];
|
||||
hsAssert(fpStrings,"new failed");
|
||||
s->Read(fTabSize,fpStrings); // Read all the string in
|
||||
|
||||
char *p = fpStrings;
|
||||
while (p < fpStrings + fTabSize)
|
||||
{
|
||||
UInt8 len = *p;
|
||||
p++;
|
||||
hsAssert(p < fpStrings + fTabSize,"String Index error");
|
||||
fStringTbl.push_back(p);
|
||||
p += len + 1; // past len and NULL
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,152 +1,152 @@
|
||||
/*==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 PLINDEXFILE_H
|
||||
#define PLINDEXFILE_H
|
||||
|
||||
#include "../pnKeyedObject/plUoid.h"
|
||||
#include <vector>
|
||||
//---------------------------------------------------------------
|
||||
// These Classes are used to Read and Write the Index file for the Database
|
||||
// Records are kept the same size Currently 20 Bytes
|
||||
// At the End of the file, the Strings are stored
|
||||
// plIxStrTbl is used to Read and Write the String section of the Index
|
||||
//---------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Main header Entry, One per Index file
|
||||
//---------------------------------------------------------------
|
||||
class plIndexFileHeader
|
||||
{
|
||||
public:
|
||||
plIndexFileHeader(); // I buried Paul
|
||||
~plIndexFileHeader(){}
|
||||
|
||||
UInt32 fTimeStamp[2];
|
||||
UInt32 fStrTblStartPos; // where the String table starts in the Index file
|
||||
UInt16 fStrTblKnt; // how many strings in the string table
|
||||
UInt16 fMajorVersion;
|
||||
UInt16 fMinorVersion;
|
||||
UInt16 fExportLocal; // was this file exported locally or downloaded from server?
|
||||
|
||||
void Write(hsStream *s);
|
||||
void Read(hsStream *s);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Room Entry One Entry per Room
|
||||
//---------------------------------------------------------------
|
||||
class plIndexFileRoom
|
||||
{
|
||||
public:
|
||||
plIndexFileRoom() { memset(this,1,sizeof(this)); } // no virtuals...relax
|
||||
~plIndexFileRoom(){}
|
||||
|
||||
plUoid fRmUoid;
|
||||
UInt16 fTypesInRoom;
|
||||
UInt16 fFiller1_16;
|
||||
UInt32 fFiller2_32;
|
||||
UInt32 fFiller3_32;
|
||||
|
||||
void Write(hsStream *s);
|
||||
void Read(hsStream *s);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Type Entry One Entry per Type in each Room
|
||||
//---------------------------------------------------------------
|
||||
|
||||
class plIndexFileType
|
||||
{
|
||||
public:
|
||||
plIndexFileType() { memset(this,1,sizeof(this)); } // no virtuals...relax
|
||||
~plIndexFileType(){}
|
||||
|
||||
plUoid fTypeUoid;
|
||||
UInt16 fNumKeys;
|
||||
UInt32 fFiller1_32;
|
||||
UInt32 fFiller2_32;
|
||||
|
||||
void Write(hsStream *s);
|
||||
void Read(hsStream *s);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Key Entry One Entry per Type in each Room
|
||||
//---------------------------------------------------------------
|
||||
|
||||
class plIndexFileKey
|
||||
{
|
||||
public:
|
||||
plIndexFileKey() { memset(this,1,sizeof(this)); } // no virtuals...relax
|
||||
~plIndexFileKey(){}
|
||||
|
||||
|
||||
plUoid fKeyUoid;
|
||||
UInt32 fStartPos;
|
||||
UInt32 fDataLen;
|
||||
UInt16 fNameIx; // Index into string table of name
|
||||
UInt16 fFiller1_16;
|
||||
|
||||
void Write(hsStream *s) ;
|
||||
void Read(hsStream *s);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// String Table, Lives at the end of the Index File
|
||||
//---------------------------------------------------------------
|
||||
class plIxStrTbl
|
||||
{
|
||||
std::vector<const char *>fStringTbl;
|
||||
char *fpStrings;
|
||||
UInt32 fTabSize; // buffer size for strings
|
||||
|
||||
public:
|
||||
|
||||
plIxStrTbl() :fpStrings(nil), fTabSize(0){}
|
||||
~plIxStrTbl();
|
||||
|
||||
Int16 FindString(const char *p); // returns -1 if not found, otherwise the index from zero
|
||||
UInt16 AddString(const char *p);
|
||||
UInt16 NumStrings() { return fStringTbl.size(); }
|
||||
const char * GetString(UInt16 x) { return fStringTbl[x]; }
|
||||
|
||||
void Write(hsStream *s);
|
||||
void Read(hsStream *s);
|
||||
};
|
||||
|
||||
class plLinkRecord
|
||||
{
|
||||
public:
|
||||
plLinkRecord(UInt16 a, UInt16 d, UInt16 r) : fAgeIx(a), fDistIx(d), fRoomIx(r){}
|
||||
~plLinkRecord(){}
|
||||
|
||||
UInt16 fAgeIx; // Index into string table
|
||||
UInt16 fDistIx;
|
||||
UInt16 fRoomIx;
|
||||
UInt32 fTimeStamp[2];
|
||||
};
|
||||
|
||||
#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==*/
|
||||
#ifndef PLINDEXFILE_H
|
||||
#define PLINDEXFILE_H
|
||||
|
||||
#include "../pnKeyedObject/plUoid.h"
|
||||
#include <vector>
|
||||
//---------------------------------------------------------------
|
||||
// These Classes are used to Read and Write the Index file for the Database
|
||||
// Records are kept the same size Currently 20 Bytes
|
||||
// At the End of the file, the Strings are stored
|
||||
// plIxStrTbl is used to Read and Write the String section of the Index
|
||||
//---------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Main header Entry, One per Index file
|
||||
//---------------------------------------------------------------
|
||||
class plIndexFileHeader
|
||||
{
|
||||
public:
|
||||
plIndexFileHeader(); // I buried Paul
|
||||
~plIndexFileHeader(){}
|
||||
|
||||
UInt32 fTimeStamp[2];
|
||||
UInt32 fStrTblStartPos; // where the String table starts in the Index file
|
||||
UInt16 fStrTblKnt; // how many strings in the string table
|
||||
UInt16 fMajorVersion;
|
||||
UInt16 fMinorVersion;
|
||||
UInt16 fExportLocal; // was this file exported locally or downloaded from server?
|
||||
|
||||
void Write(hsStream *s);
|
||||
void Read(hsStream *s);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Room Entry One Entry per Room
|
||||
//---------------------------------------------------------------
|
||||
class plIndexFileRoom
|
||||
{
|
||||
public:
|
||||
plIndexFileRoom() { memset(this,1,sizeof(this)); } // no virtuals...relax
|
||||
~plIndexFileRoom(){}
|
||||
|
||||
plUoid fRmUoid;
|
||||
UInt16 fTypesInRoom;
|
||||
UInt16 fFiller1_16;
|
||||
UInt32 fFiller2_32;
|
||||
UInt32 fFiller3_32;
|
||||
|
||||
void Write(hsStream *s);
|
||||
void Read(hsStream *s);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Type Entry One Entry per Type in each Room
|
||||
//---------------------------------------------------------------
|
||||
|
||||
class plIndexFileType
|
||||
{
|
||||
public:
|
||||
plIndexFileType() { memset(this,1,sizeof(this)); } // no virtuals...relax
|
||||
~plIndexFileType(){}
|
||||
|
||||
plUoid fTypeUoid;
|
||||
UInt16 fNumKeys;
|
||||
UInt32 fFiller1_32;
|
||||
UInt32 fFiller2_32;
|
||||
|
||||
void Write(hsStream *s);
|
||||
void Read(hsStream *s);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Key Entry One Entry per Type in each Room
|
||||
//---------------------------------------------------------------
|
||||
|
||||
class plIndexFileKey
|
||||
{
|
||||
public:
|
||||
plIndexFileKey() { memset(this,1,sizeof(this)); } // no virtuals...relax
|
||||
~plIndexFileKey(){}
|
||||
|
||||
|
||||
plUoid fKeyUoid;
|
||||
UInt32 fStartPos;
|
||||
UInt32 fDataLen;
|
||||
UInt16 fNameIx; // Index into string table of name
|
||||
UInt16 fFiller1_16;
|
||||
|
||||
void Write(hsStream *s) ;
|
||||
void Read(hsStream *s);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// String Table, Lives at the end of the Index File
|
||||
//---------------------------------------------------------------
|
||||
class plIxStrTbl
|
||||
{
|
||||
std::vector<const char *>fStringTbl;
|
||||
char *fpStrings;
|
||||
UInt32 fTabSize; // buffer size for strings
|
||||
|
||||
public:
|
||||
|
||||
plIxStrTbl() :fpStrings(nil), fTabSize(0){}
|
||||
~plIxStrTbl();
|
||||
|
||||
Int16 FindString(const char *p); // returns -1 if not found, otherwise the index from zero
|
||||
UInt16 AddString(const char *p);
|
||||
UInt16 NumStrings() { return fStringTbl.size(); }
|
||||
const char * GetString(UInt16 x) { return fStringTbl[x]; }
|
||||
|
||||
void Write(hsStream *s);
|
||||
void Read(hsStream *s);
|
||||
};
|
||||
|
||||
class plLinkRecord
|
||||
{
|
||||
public:
|
||||
plLinkRecord(UInt16 a, UInt16 d, UInt16 r) : fAgeIx(a), fDistIx(d), fRoomIx(r){}
|
||||
~plLinkRecord(){}
|
||||
|
||||
UInt16 fAgeIx; // Index into string table
|
||||
UInt16 fDistIx;
|
||||
UInt16 fRoomIx;
|
||||
UInt32 fTimeStamp[2];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,498 +1,498 @@
|
||||
/*==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 "plKeyFinder.h"
|
||||
|
||||
#include "hsTemplates.h"
|
||||
#include "hsStlUtils.h"
|
||||
|
||||
#include "hsResMgr.h"
|
||||
#include "plResManager.h"
|
||||
|
||||
#include "plRegistryHelpers.h"
|
||||
#include "plRegistryNode.h"
|
||||
#include "plRegistryKeyList.h"
|
||||
#include "plPageInfo.h"
|
||||
#include "pnFactory/plFactory.h"
|
||||
#include "hsUtils.h"
|
||||
#include "plCreatableIndex.h"
|
||||
|
||||
plResManager* IGetResMgr() { return (plResManager*)hsgResMgr::ResMgr(); }
|
||||
|
||||
plKeyFinder& plKeyFinder::Instance()
|
||||
{
|
||||
static plKeyFinder theInstance;
|
||||
return theInstance;
|
||||
}
|
||||
|
||||
const char* plKeyFinder::GetLastErrorString() // For Console display
|
||||
{
|
||||
// For Console display
|
||||
static const char* KeyFinderErrors[] =
|
||||
{
|
||||
"Ok",
|
||||
"Age not found",
|
||||
"Page not found",
|
||||
"Invalid class",
|
||||
"None of those classes in this page",
|
||||
"Object not found"
|
||||
};
|
||||
return KeyFinderErrors[fLastError];
|
||||
}
|
||||
|
||||
//
|
||||
// Does name string compare with potentially mangled (ie. [1 0 0]foo) names
|
||||
//
|
||||
hsBool NameMatches(const char* obName, const char* pKName, hsBool subString)
|
||||
{
|
||||
if (!obName || !pKName)
|
||||
return false;
|
||||
|
||||
const char *o = obName;
|
||||
const char *p = pKName;
|
||||
|
||||
// If names are mangled, unmangle
|
||||
if (*o != '[' || *p != '[')
|
||||
{
|
||||
// skip past ']' in both names in case mangled
|
||||
while (*o && *o != ']')
|
||||
o++;
|
||||
o = (*o==']') ? o+1 : obName;
|
||||
|
||||
while (*p && *p != ']')
|
||||
p++;
|
||||
p = (*p==']') ? p+1 : pKName;
|
||||
}
|
||||
|
||||
if (!subString)
|
||||
{
|
||||
if (!_stricmp(o, p))
|
||||
return true; // FOUND IT!!!!!!!!!!!!!!!!!!!
|
||||
}
|
||||
else
|
||||
{
|
||||
char oCopy[256], pCopy[256];
|
||||
strcpy(oCopy, o);
|
||||
strcpy(pCopy, p);
|
||||
hsStrLower(oCopy);
|
||||
hsStrLower(pCopy);
|
||||
if (strstr(pCopy, oCopy))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
plKey plKeyFinder::StupidSearch(const char * age, const char * rm,
|
||||
const char *className, const char *obName, hsBool subString)
|
||||
{
|
||||
UInt16 ty = plFactory::FindClassIndex(className);
|
||||
return StupidSearch(age, rm, ty, obName, subString);
|
||||
}
|
||||
|
||||
class plKeyFinderIter : public plRegistryKeyIterator, public plRegistryPageIterator
|
||||
{
|
||||
protected:
|
||||
UInt16 fClassType;
|
||||
const char *fObjName;
|
||||
hsBool fSubstr;
|
||||
plKey fFoundKey;
|
||||
const char *fAgeName;
|
||||
|
||||
public:
|
||||
plKey GetFoundKey( void ) const { return fFoundKey; }
|
||||
|
||||
plKeyFinderIter( UInt16 classType, const char *obName, hsBool substr )
|
||||
: fFoundKey( nil ), fClassType( classType ), fObjName( obName ), fSubstr( substr ) { }
|
||||
|
||||
plKeyFinderIter( UInt16 classType, const char *obName, hsBool substr, const char *ageName )
|
||||
: fFoundKey( nil ), fClassType( classType ), fObjName( obName ), fSubstr( substr ),
|
||||
fAgeName( ageName ) {}
|
||||
|
||||
virtual hsBool EatKey( const plKey& key )
|
||||
{
|
||||
if( key->GetUoid().GetClassType() == fClassType &&
|
||||
NameMatches( fObjName, key->GetUoid().GetObjectName(), fSubstr ) )
|
||||
{
|
||||
fFoundKey = key;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual hsBool EatPage( plRegistryPageNode *pageNode )
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
try
|
||||
{
|
||||
#endif
|
||||
if( stricmp( pageNode->GetPageInfo().GetAge(), fAgeName ) == 0 )
|
||||
{
|
||||
// Try loading and searching thru this page
|
||||
hsTArray<plKey> keyRefs;
|
||||
|
||||
IGetResMgr()->LoadPageKeys( pageNode );
|
||||
plKeyCollector coll( keyRefs );
|
||||
pageNode->IterateKeys( &coll );
|
||||
|
||||
if( !pageNode->IterateKeys( this ) )
|
||||
return false;
|
||||
}
|
||||
#ifndef _DEBUG
|
||||
} catch (...)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
plKey plKeyFinder::StupidSearch(const char * age, const char * rm,
|
||||
UInt16 classType, const char *obName, hsBool subString)
|
||||
{
|
||||
if (!obName)
|
||||
return nil;
|
||||
|
||||
plUoid newOid;
|
||||
|
||||
fLastError = kOk;
|
||||
|
||||
UInt16 maxClasses = plFactory::GetNumClasses();
|
||||
|
||||
UInt16 ty = classType;
|
||||
if (ty == maxClasses) // error
|
||||
{ fLastError = kInvalidClass;
|
||||
return nil;
|
||||
}
|
||||
|
||||
if( age != nil && rm != nil )
|
||||
{
|
||||
const plLocation &loc = IGetResMgr()->FindLocation( age, rm );
|
||||
if( !loc.IsValid() )
|
||||
{
|
||||
fLastError = kPageNotFound;
|
||||
return nil;
|
||||
}
|
||||
|
||||
plKeyFinderIter keyFinder( classType, obName, subString );
|
||||
|
||||
if( !IGetResMgr()->IterateKeys( &keyFinder, loc ) )
|
||||
// Return value of false means it stopped somewhere, i.e. found something
|
||||
return keyFinder.GetFoundKey();
|
||||
}
|
||||
else if( age != nil )
|
||||
{
|
||||
plKeyFinderIter keyFinder(classType, obName, subString, age);
|
||||
|
||||
if( !IGetResMgr()->IterateAllPages( &keyFinder ) )
|
||||
return keyFinder.GetFoundKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
plKeyFinderIter keyFinder( classType, obName, subString );
|
||||
|
||||
if( !IGetResMgr()->IterateKeys( &keyFinder ) )
|
||||
// Return value of false means it stopped somewhere, i.e. found something
|
||||
return keyFinder.GetFoundKey();
|
||||
}
|
||||
|
||||
fLastError = kObjectNotFound;
|
||||
return nil;
|
||||
}
|
||||
|
||||
void plKeyFinder::ReallyStupidResponderSearch(const char *name, std::vector<plKey>& foundKeys, const plLocation &hintLocation )
|
||||
{
|
||||
ReallyStupidSubstringSearch(name, CLASS_INDEX_SCOPED(plResponderModifier), foundKeys, hintLocation);
|
||||
}
|
||||
|
||||
void plKeyFinder::ReallyStupidActivatorSearch(const char *name, std::vector<plKey>& foundKeys, const plLocation &hintLocation)
|
||||
{
|
||||
// use the createable macro so we don't have to pull in all of Python
|
||||
ReallyStupidSubstringSearch(name, CLASS_INDEX_SCOPED(plLogicModifier), foundKeys, hintLocation);
|
||||
ReallyStupidSubstringSearch(name, CLASS_INDEX_SCOPED(plPythonFileMod), foundKeys, hintLocation);
|
||||
ReallyStupidSubstringSearch(name, CLASS_INDEX_SCOPED(plSittingModifier), foundKeys, hintLocation);
|
||||
}
|
||||
|
||||
void plKeyFinder::IGetNames(std::vector<std::string>& names, const char* searchName, int index)
|
||||
{
|
||||
// Not really searching for any particular key, just need all the logic mods
|
||||
std::vector<plKey> keys;
|
||||
ReallyStupidSubstringSearch(searchName, index, keys);
|
||||
|
||||
for (int i = 0; i < keys.size(); i++)
|
||||
{
|
||||
// Only allow loaded ones to cut down on the crap
|
||||
plKey key = keys[i];
|
||||
if (key->ObjectIsLoaded())
|
||||
names.push_back(key->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
void plKeyFinder::GetResponderNames(std::vector<std::string>& names)
|
||||
{
|
||||
IGetNames(names, "", CLASS_INDEX_SCOPED(plResponderModifier));
|
||||
}
|
||||
|
||||
void plKeyFinder::GetActivatorNames(std::vector<std::string>& names)
|
||||
{
|
||||
IGetNames(names, "", CLASS_INDEX_SCOPED(plLogicModifier));
|
||||
}
|
||||
|
||||
class plKeyFinderIterator : public plRegistryKeyIterator, public plRegistryPageIterator
|
||||
{
|
||||
protected:
|
||||
|
||||
UInt16 fClassType;
|
||||
const char *fObjName;
|
||||
|
||||
std::vector<plKey> &fFoundKeys;
|
||||
|
||||
public:
|
||||
|
||||
plKeyFinderIterator( UInt16 classType, const char *obName, std::vector<plKey>& foundKeys )
|
||||
: fClassType( classType ), fObjName( obName ), fFoundKeys( foundKeys ) { }
|
||||
|
||||
virtual hsBool EatKey( const plKey& key )
|
||||
{
|
||||
if( key->GetUoid().IsValid() && key->GetUoid().GetClassType() == fClassType &&
|
||||
strstr( key->GetUoid().GetObjectName(), fObjName ) )
|
||||
{
|
||||
fFoundKeys.push_back( key );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual hsBool EatPage( plRegistryPageNode *page )
|
||||
{
|
||||
hsBool ret = page->IterateKeys( this );
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
void plKeyFinder::ReallyStupidSubstringSearch(const char *name, UInt16 objType, std::vector<plKey>& foundKeys, const plLocation &hintLocation )
|
||||
{
|
||||
if (!name)
|
||||
return;
|
||||
|
||||
plKeyFinderIterator collector( objType, name, foundKeys );
|
||||
if( hintLocation.IsValid() )
|
||||
{
|
||||
plRegistryPageNode *hintPage = IGetResMgr()->FindPage( hintLocation );
|
||||
if( hintPage != nil )
|
||||
{
|
||||
// Try all pages in the same age as that page
|
||||
IGetResMgr()->IteratePages( &collector, hintPage->GetPageInfo().GetAge() );
|
||||
}
|
||||
|
||||
if (foundKeys.size() > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//fpReg->IterateKeys( &collector );
|
||||
IGetResMgr()->IterateAllPages( &collector );
|
||||
}
|
||||
|
||||
//// Helper Class for FindSceneNodeKey ///////////////////////////////////////
|
||||
|
||||
class plPageFinder : public plRegistryPageIterator
|
||||
{
|
||||
protected:
|
||||
|
||||
plRegistryPageNode **fPagePtr;
|
||||
const char *fFindString, *fAgeString;
|
||||
|
||||
public:
|
||||
|
||||
plPageFinder( plRegistryPageNode **page, const char *find ) : fPagePtr( page ), fFindString( find ), fAgeString( nil )
|
||||
{ *fPagePtr = nil; }
|
||||
|
||||
plPageFinder( plRegistryPageNode **page, const char *ageS, const char *pageS ) : fPagePtr( page ), fFindString( pageS ), fAgeString( ageS )
|
||||
{ *fPagePtr = nil; }
|
||||
|
||||
virtual hsBool EatPage( plRegistryPageNode *node )
|
||||
{
|
||||
static char str[ 512 ];
|
||||
const plPageInfo &info = node->GetPageInfo();
|
||||
|
||||
// Are we searching by age/page?
|
||||
if( fAgeString != nil )
|
||||
{
|
||||
if( stricmp( info.GetAge(), fAgeString ) == 0 &&
|
||||
stricmp( info.GetPage(), fFindString ) == 0 )
|
||||
{
|
||||
*fPagePtr = node;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try for page only
|
||||
if( stricmp( info.GetPage(), fFindString ) == 0 )
|
||||
{
|
||||
*fPagePtr = node;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try for full location
|
||||
sprintf( str, "%s_%s_%s", info.GetAge(), info.GetPage() );
|
||||
if( stricmp( str, fFindString ) == 0 )
|
||||
{
|
||||
*fPagePtr = node;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true; // Keep searching
|
||||
}
|
||||
};
|
||||
|
||||
//// FindSceneNodeKey ////////////////////////////////////////////////////////
|
||||
// Given a string for either a page name or a fully qualified location name,
|
||||
// finds the page and then returns the key for the sceneNode in that page.
|
||||
// Note: in our case, we want to force the page's keys to load if necessary,
|
||||
// since the only time we call this function will be to actually load
|
||||
// the darned thing.
|
||||
|
||||
plKey plKeyFinder::FindSceneNodeKey( const char *pageOrFullLocName ) const
|
||||
{
|
||||
plRegistryPageNode *pageNode;
|
||||
plPageFinder pageFinder( &pageNode, pageOrFullLocName );
|
||||
|
||||
|
||||
// Use our own page finder, since we want to do nifty things like partial
|
||||
// matches, etc.
|
||||
if( IGetResMgr()->IterateAllPages( &pageFinder ) || pageNode == nil )
|
||||
return nil;
|
||||
|
||||
return IFindSceneNodeKey( pageNode );
|
||||
}
|
||||
|
||||
//// FindSceneNodeKey ////////////////////////////////////////////////////////
|
||||
// Age/page pair version
|
||||
|
||||
plKey plKeyFinder::FindSceneNodeKey( const char *ageName, const char *pageName ) const
|
||||
{
|
||||
plRegistryPageNode *pageNode;
|
||||
plPageFinder pageFinder( &pageNode, ageName, pageName );
|
||||
|
||||
// Use our own page finder, since we want to do nifty things like partial
|
||||
// matches, etc.
|
||||
if (IGetResMgr()->IterateAllPages(&pageFinder) || pageNode == nil)
|
||||
return nil;
|
||||
|
||||
return IFindSceneNodeKey( pageNode );
|
||||
}
|
||||
|
||||
//// FindSceneNodeKey ////////////////////////////////////////////////////////
|
||||
// plLocation version
|
||||
|
||||
plKey plKeyFinder::FindSceneNodeKey(const plLocation& location) const
|
||||
{
|
||||
plRegistryPageNode* pageNode = IGetResMgr()->FindPage(location);
|
||||
if (pageNode == nil)
|
||||
return nil;
|
||||
|
||||
return IFindSceneNodeKey(pageNode);
|
||||
}
|
||||
|
||||
//// IFindSceneNodeKey ///////////////////////////////////////////////////////
|
||||
|
||||
|
||||
plKey plKeyFinder::IFindSceneNodeKey(plRegistryPageNode* page) const
|
||||
{
|
||||
// Got the pageNode, try a find before loading
|
||||
plRegistryKeyList* keyList = page->IGetKeyList(CLASS_INDEX_SCOPED(plSceneNode));
|
||||
if (keyList)
|
||||
{
|
||||
if (keyList->fStaticKeys.size() == 1)
|
||||
{
|
||||
return plKey::Make((plKeyData*)keyList->fStaticKeys[0]);
|
||||
}
|
||||
else if (keyList->fDynamicKeys.size() == 1) // happens during export
|
||||
{
|
||||
plRegistryKeyList::DynSet::const_iterator it = keyList->fDynamicKeys.begin();
|
||||
plKeyImp* keyImp = *it;
|
||||
return plKey::Make(keyImp);
|
||||
}
|
||||
}
|
||||
|
||||
// Try loading and see if that helps
|
||||
if (page->IsFullyLoaded())
|
||||
return nil;
|
||||
|
||||
IGetResMgr()->LoadPageKeys(page);
|
||||
|
||||
// Get the list of all sceneNodes
|
||||
plKey retVal(nil);
|
||||
keyList = page->IGetKeyList(CLASS_INDEX_SCOPED(plSceneNode));
|
||||
if (keyList && keyList->fStaticKeys.size() == 1)
|
||||
{
|
||||
retVal = plKey::Make((plKeyData*)keyList->fStaticKeys[0]);
|
||||
}
|
||||
// If we just loaded up all the keys for this page, then we
|
||||
// may have a bunch of keys with a refcount of 0. For any of
|
||||
// these keys that nothing else refs (yes, we have unused objects
|
||||
// in the data), they don't get deleted because the refcount never
|
||||
// rises above zero or falls back to zero. So we'll go ahead and
|
||||
// ref and unref all of them. The ones in use stay put, the ones
|
||||
// not being used go away. This is less than ideal.
|
||||
IGetResMgr()->DumpUnusedKeys(page);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//// FindLocation ////////////////////////////////////////////////////////////
|
||||
|
||||
const plLocation &plKeyFinder::FindLocation( const char *age, const char *page ) const
|
||||
{
|
||||
if (age == nil)
|
||||
{
|
||||
static plLocation invalidLoc;
|
||||
plRegistryPageNode *pageNode;
|
||||
plPageFinder pageFinder( &pageNode, page );
|
||||
|
||||
if( IGetResMgr()->IterateAllPages( &pageFinder ) || pageNode == nil )
|
||||
return invalidLoc;
|
||||
|
||||
return pageNode->GetPageInfo().GetLocation();
|
||||
}
|
||||
|
||||
return IGetResMgr()->FindLocation( age, page );
|
||||
}
|
||||
|
||||
//// GetLocationInfo /////////////////////////////////////////////////////////
|
||||
|
||||
const plPageInfo* plKeyFinder::GetLocationInfo( const plLocation &loc ) const
|
||||
{
|
||||
plRegistryPageNode *node = IGetResMgr()->FindPage( loc );
|
||||
if (node)
|
||||
return &node->GetPageInfo();
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
/*==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 "plKeyFinder.h"
|
||||
|
||||
#include "hsTemplates.h"
|
||||
#include "hsStlUtils.h"
|
||||
|
||||
#include "hsResMgr.h"
|
||||
#include "plResManager.h"
|
||||
|
||||
#include "plRegistryHelpers.h"
|
||||
#include "plRegistryNode.h"
|
||||
#include "plRegistryKeyList.h"
|
||||
#include "plPageInfo.h"
|
||||
#include "pnFactory/plFactory.h"
|
||||
#include "hsUtils.h"
|
||||
#include "plCreatableIndex.h"
|
||||
|
||||
plResManager* IGetResMgr() { return (plResManager*)hsgResMgr::ResMgr(); }
|
||||
|
||||
plKeyFinder& plKeyFinder::Instance()
|
||||
{
|
||||
static plKeyFinder theInstance;
|
||||
return theInstance;
|
||||
}
|
||||
|
||||
const char* plKeyFinder::GetLastErrorString() // For Console display
|
||||
{
|
||||
// For Console display
|
||||
static const char* KeyFinderErrors[] =
|
||||
{
|
||||
"Ok",
|
||||
"Age not found",
|
||||
"Page not found",
|
||||
"Invalid class",
|
||||
"None of those classes in this page",
|
||||
"Object not found"
|
||||
};
|
||||
return KeyFinderErrors[fLastError];
|
||||
}
|
||||
|
||||
//
|
||||
// Does name string compare with potentially mangled (ie. [1 0 0]foo) names
|
||||
//
|
||||
hsBool NameMatches(const char* obName, const char* pKName, hsBool subString)
|
||||
{
|
||||
if (!obName || !pKName)
|
||||
return false;
|
||||
|
||||
const char *o = obName;
|
||||
const char *p = pKName;
|
||||
|
||||
// If names are mangled, unmangle
|
||||
if (*o != '[' || *p != '[')
|
||||
{
|
||||
// skip past ']' in both names in case mangled
|
||||
while (*o && *o != ']')
|
||||
o++;
|
||||
o = (*o==']') ? o+1 : obName;
|
||||
|
||||
while (*p && *p != ']')
|
||||
p++;
|
||||
p = (*p==']') ? p+1 : pKName;
|
||||
}
|
||||
|
||||
if (!subString)
|
||||
{
|
||||
if (!_stricmp(o, p))
|
||||
return true; // FOUND IT!!!!!!!!!!!!!!!!!!!
|
||||
}
|
||||
else
|
||||
{
|
||||
char oCopy[256], pCopy[256];
|
||||
strcpy(oCopy, o);
|
||||
strcpy(pCopy, p);
|
||||
hsStrLower(oCopy);
|
||||
hsStrLower(pCopy);
|
||||
if (strstr(pCopy, oCopy))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
plKey plKeyFinder::StupidSearch(const char * age, const char * rm,
|
||||
const char *className, const char *obName, hsBool subString)
|
||||
{
|
||||
UInt16 ty = plFactory::FindClassIndex(className);
|
||||
return StupidSearch(age, rm, ty, obName, subString);
|
||||
}
|
||||
|
||||
class plKeyFinderIter : public plRegistryKeyIterator, public plRegistryPageIterator
|
||||
{
|
||||
protected:
|
||||
UInt16 fClassType;
|
||||
const char *fObjName;
|
||||
hsBool fSubstr;
|
||||
plKey fFoundKey;
|
||||
const char *fAgeName;
|
||||
|
||||
public:
|
||||
plKey GetFoundKey( void ) const { return fFoundKey; }
|
||||
|
||||
plKeyFinderIter( UInt16 classType, const char *obName, hsBool substr )
|
||||
: fFoundKey( nil ), fClassType( classType ), fObjName( obName ), fSubstr( substr ) { }
|
||||
|
||||
plKeyFinderIter( UInt16 classType, const char *obName, hsBool substr, const char *ageName )
|
||||
: fFoundKey( nil ), fClassType( classType ), fObjName( obName ), fSubstr( substr ),
|
||||
fAgeName( ageName ) {}
|
||||
|
||||
virtual hsBool EatKey( const plKey& key )
|
||||
{
|
||||
if( key->GetUoid().GetClassType() == fClassType &&
|
||||
NameMatches( fObjName, key->GetUoid().GetObjectName(), fSubstr ) )
|
||||
{
|
||||
fFoundKey = key;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual hsBool EatPage( plRegistryPageNode *pageNode )
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
try
|
||||
{
|
||||
#endif
|
||||
if( stricmp( pageNode->GetPageInfo().GetAge(), fAgeName ) == 0 )
|
||||
{
|
||||
// Try loading and searching thru this page
|
||||
hsTArray<plKey> keyRefs;
|
||||
|
||||
IGetResMgr()->LoadPageKeys( pageNode );
|
||||
plKeyCollector coll( keyRefs );
|
||||
pageNode->IterateKeys( &coll );
|
||||
|
||||
if( !pageNode->IterateKeys( this ) )
|
||||
return false;
|
||||
}
|
||||
#ifndef _DEBUG
|
||||
} catch (...)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
plKey plKeyFinder::StupidSearch(const char * age, const char * rm,
|
||||
UInt16 classType, const char *obName, hsBool subString)
|
||||
{
|
||||
if (!obName)
|
||||
return nil;
|
||||
|
||||
plUoid newOid;
|
||||
|
||||
fLastError = kOk;
|
||||
|
||||
UInt16 maxClasses = plFactory::GetNumClasses();
|
||||
|
||||
UInt16 ty = classType;
|
||||
if (ty == maxClasses) // error
|
||||
{ fLastError = kInvalidClass;
|
||||
return nil;
|
||||
}
|
||||
|
||||
if( age != nil && rm != nil )
|
||||
{
|
||||
const plLocation &loc = IGetResMgr()->FindLocation( age, rm );
|
||||
if( !loc.IsValid() )
|
||||
{
|
||||
fLastError = kPageNotFound;
|
||||
return nil;
|
||||
}
|
||||
|
||||
plKeyFinderIter keyFinder( classType, obName, subString );
|
||||
|
||||
if( !IGetResMgr()->IterateKeys( &keyFinder, loc ) )
|
||||
// Return value of false means it stopped somewhere, i.e. found something
|
||||
return keyFinder.GetFoundKey();
|
||||
}
|
||||
else if( age != nil )
|
||||
{
|
||||
plKeyFinderIter keyFinder(classType, obName, subString, age);
|
||||
|
||||
if( !IGetResMgr()->IterateAllPages( &keyFinder ) )
|
||||
return keyFinder.GetFoundKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
plKeyFinderIter keyFinder( classType, obName, subString );
|
||||
|
||||
if( !IGetResMgr()->IterateKeys( &keyFinder ) )
|
||||
// Return value of false means it stopped somewhere, i.e. found something
|
||||
return keyFinder.GetFoundKey();
|
||||
}
|
||||
|
||||
fLastError = kObjectNotFound;
|
||||
return nil;
|
||||
}
|
||||
|
||||
void plKeyFinder::ReallyStupidResponderSearch(const char *name, std::vector<plKey>& foundKeys, const plLocation &hintLocation )
|
||||
{
|
||||
ReallyStupidSubstringSearch(name, CLASS_INDEX_SCOPED(plResponderModifier), foundKeys, hintLocation);
|
||||
}
|
||||
|
||||
void plKeyFinder::ReallyStupidActivatorSearch(const char *name, std::vector<plKey>& foundKeys, const plLocation &hintLocation)
|
||||
{
|
||||
// use the createable macro so we don't have to pull in all of Python
|
||||
ReallyStupidSubstringSearch(name, CLASS_INDEX_SCOPED(plLogicModifier), foundKeys, hintLocation);
|
||||
ReallyStupidSubstringSearch(name, CLASS_INDEX_SCOPED(plPythonFileMod), foundKeys, hintLocation);
|
||||
ReallyStupidSubstringSearch(name, CLASS_INDEX_SCOPED(plSittingModifier), foundKeys, hintLocation);
|
||||
}
|
||||
|
||||
void plKeyFinder::IGetNames(std::vector<std::string>& names, const char* searchName, int index)
|
||||
{
|
||||
// Not really searching for any particular key, just need all the logic mods
|
||||
std::vector<plKey> keys;
|
||||
ReallyStupidSubstringSearch(searchName, index, keys);
|
||||
|
||||
for (int i = 0; i < keys.size(); i++)
|
||||
{
|
||||
// Only allow loaded ones to cut down on the crap
|
||||
plKey key = keys[i];
|
||||
if (key->ObjectIsLoaded())
|
||||
names.push_back(key->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
void plKeyFinder::GetResponderNames(std::vector<std::string>& names)
|
||||
{
|
||||
IGetNames(names, "", CLASS_INDEX_SCOPED(plResponderModifier));
|
||||
}
|
||||
|
||||
void plKeyFinder::GetActivatorNames(std::vector<std::string>& names)
|
||||
{
|
||||
IGetNames(names, "", CLASS_INDEX_SCOPED(plLogicModifier));
|
||||
}
|
||||
|
||||
class plKeyFinderIterator : public plRegistryKeyIterator, public plRegistryPageIterator
|
||||
{
|
||||
protected:
|
||||
|
||||
UInt16 fClassType;
|
||||
const char *fObjName;
|
||||
|
||||
std::vector<plKey> &fFoundKeys;
|
||||
|
||||
public:
|
||||
|
||||
plKeyFinderIterator( UInt16 classType, const char *obName, std::vector<plKey>& foundKeys )
|
||||
: fClassType( classType ), fObjName( obName ), fFoundKeys( foundKeys ) { }
|
||||
|
||||
virtual hsBool EatKey( const plKey& key )
|
||||
{
|
||||
if( key->GetUoid().IsValid() && key->GetUoid().GetClassType() == fClassType &&
|
||||
strstr( key->GetUoid().GetObjectName(), fObjName ) )
|
||||
{
|
||||
fFoundKeys.push_back( key );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual hsBool EatPage( plRegistryPageNode *page )
|
||||
{
|
||||
hsBool ret = page->IterateKeys( this );
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
void plKeyFinder::ReallyStupidSubstringSearch(const char *name, UInt16 objType, std::vector<plKey>& foundKeys, const plLocation &hintLocation )
|
||||
{
|
||||
if (!name)
|
||||
return;
|
||||
|
||||
plKeyFinderIterator collector( objType, name, foundKeys );
|
||||
if( hintLocation.IsValid() )
|
||||
{
|
||||
plRegistryPageNode *hintPage = IGetResMgr()->FindPage( hintLocation );
|
||||
if( hintPage != nil )
|
||||
{
|
||||
// Try all pages in the same age as that page
|
||||
IGetResMgr()->IteratePages( &collector, hintPage->GetPageInfo().GetAge() );
|
||||
}
|
||||
|
||||
if (foundKeys.size() > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//fpReg->IterateKeys( &collector );
|
||||
IGetResMgr()->IterateAllPages( &collector );
|
||||
}
|
||||
|
||||
//// Helper Class for FindSceneNodeKey ///////////////////////////////////////
|
||||
|
||||
class plPageFinder : public plRegistryPageIterator
|
||||
{
|
||||
protected:
|
||||
|
||||
plRegistryPageNode **fPagePtr;
|
||||
const char *fFindString, *fAgeString;
|
||||
|
||||
public:
|
||||
|
||||
plPageFinder( plRegistryPageNode **page, const char *find ) : fPagePtr( page ), fFindString( find ), fAgeString( nil )
|
||||
{ *fPagePtr = nil; }
|
||||
|
||||
plPageFinder( plRegistryPageNode **page, const char *ageS, const char *pageS ) : fPagePtr( page ), fFindString( pageS ), fAgeString( ageS )
|
||||
{ *fPagePtr = nil; }
|
||||
|
||||
virtual hsBool EatPage( plRegistryPageNode *node )
|
||||
{
|
||||
static char str[ 512 ];
|
||||
const plPageInfo &info = node->GetPageInfo();
|
||||
|
||||
// Are we searching by age/page?
|
||||
if( fAgeString != nil )
|
||||
{
|
||||
if( stricmp( info.GetAge(), fAgeString ) == 0 &&
|
||||
stricmp( info.GetPage(), fFindString ) == 0 )
|
||||
{
|
||||
*fPagePtr = node;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try for page only
|
||||
if( stricmp( info.GetPage(), fFindString ) == 0 )
|
||||
{
|
||||
*fPagePtr = node;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try for full location
|
||||
sprintf( str, "%s_%s_%s", info.GetAge(), info.GetPage() );
|
||||
if( stricmp( str, fFindString ) == 0 )
|
||||
{
|
||||
*fPagePtr = node;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true; // Keep searching
|
||||
}
|
||||
};
|
||||
|
||||
//// FindSceneNodeKey ////////////////////////////////////////////////////////
|
||||
// Given a string for either a page name or a fully qualified location name,
|
||||
// finds the page and then returns the key for the sceneNode in that page.
|
||||
// Note: in our case, we want to force the page's keys to load if necessary,
|
||||
// since the only time we call this function will be to actually load
|
||||
// the darned thing.
|
||||
|
||||
plKey plKeyFinder::FindSceneNodeKey( const char *pageOrFullLocName ) const
|
||||
{
|
||||
plRegistryPageNode *pageNode;
|
||||
plPageFinder pageFinder( &pageNode, pageOrFullLocName );
|
||||
|
||||
|
||||
// Use our own page finder, since we want to do nifty things like partial
|
||||
// matches, etc.
|
||||
if( IGetResMgr()->IterateAllPages( &pageFinder ) || pageNode == nil )
|
||||
return nil;
|
||||
|
||||
return IFindSceneNodeKey( pageNode );
|
||||
}
|
||||
|
||||
//// FindSceneNodeKey ////////////////////////////////////////////////////////
|
||||
// Age/page pair version
|
||||
|
||||
plKey plKeyFinder::FindSceneNodeKey( const char *ageName, const char *pageName ) const
|
||||
{
|
||||
plRegistryPageNode *pageNode;
|
||||
plPageFinder pageFinder( &pageNode, ageName, pageName );
|
||||
|
||||
// Use our own page finder, since we want to do nifty things like partial
|
||||
// matches, etc.
|
||||
if (IGetResMgr()->IterateAllPages(&pageFinder) || pageNode == nil)
|
||||
return nil;
|
||||
|
||||
return IFindSceneNodeKey( pageNode );
|
||||
}
|
||||
|
||||
//// FindSceneNodeKey ////////////////////////////////////////////////////////
|
||||
// plLocation version
|
||||
|
||||
plKey plKeyFinder::FindSceneNodeKey(const plLocation& location) const
|
||||
{
|
||||
plRegistryPageNode* pageNode = IGetResMgr()->FindPage(location);
|
||||
if (pageNode == nil)
|
||||
return nil;
|
||||
|
||||
return IFindSceneNodeKey(pageNode);
|
||||
}
|
||||
|
||||
//// IFindSceneNodeKey ///////////////////////////////////////////////////////
|
||||
|
||||
|
||||
plKey plKeyFinder::IFindSceneNodeKey(plRegistryPageNode* page) const
|
||||
{
|
||||
// Got the pageNode, try a find before loading
|
||||
plRegistryKeyList* keyList = page->IGetKeyList(CLASS_INDEX_SCOPED(plSceneNode));
|
||||
if (keyList)
|
||||
{
|
||||
if (keyList->fStaticKeys.size() == 1)
|
||||
{
|
||||
return plKey::Make((plKeyData*)keyList->fStaticKeys[0]);
|
||||
}
|
||||
else if (keyList->fDynamicKeys.size() == 1) // happens during export
|
||||
{
|
||||
plRegistryKeyList::DynSet::const_iterator it = keyList->fDynamicKeys.begin();
|
||||
plKeyImp* keyImp = *it;
|
||||
return plKey::Make(keyImp);
|
||||
}
|
||||
}
|
||||
|
||||
// Try loading and see if that helps
|
||||
if (page->IsFullyLoaded())
|
||||
return nil;
|
||||
|
||||
IGetResMgr()->LoadPageKeys(page);
|
||||
|
||||
// Get the list of all sceneNodes
|
||||
plKey retVal(nil);
|
||||
keyList = page->IGetKeyList(CLASS_INDEX_SCOPED(plSceneNode));
|
||||
if (keyList && keyList->fStaticKeys.size() == 1)
|
||||
{
|
||||
retVal = plKey::Make((plKeyData*)keyList->fStaticKeys[0]);
|
||||
}
|
||||
// If we just loaded up all the keys for this page, then we
|
||||
// may have a bunch of keys with a refcount of 0. For any of
|
||||
// these keys that nothing else refs (yes, we have unused objects
|
||||
// in the data), they don't get deleted because the refcount never
|
||||
// rises above zero or falls back to zero. So we'll go ahead and
|
||||
// ref and unref all of them. The ones in use stay put, the ones
|
||||
// not being used go away. This is less than ideal.
|
||||
IGetResMgr()->DumpUnusedKeys(page);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//// FindLocation ////////////////////////////////////////////////////////////
|
||||
|
||||
const plLocation &plKeyFinder::FindLocation( const char *age, const char *page ) const
|
||||
{
|
||||
if (age == nil)
|
||||
{
|
||||
static plLocation invalidLoc;
|
||||
plRegistryPageNode *pageNode;
|
||||
plPageFinder pageFinder( &pageNode, page );
|
||||
|
||||
if( IGetResMgr()->IterateAllPages( &pageFinder ) || pageNode == nil )
|
||||
return invalidLoc;
|
||||
|
||||
return pageNode->GetPageInfo().GetLocation();
|
||||
}
|
||||
|
||||
return IGetResMgr()->FindLocation( age, page );
|
||||
}
|
||||
|
||||
//// GetLocationInfo /////////////////////////////////////////////////////////
|
||||
|
||||
const plPageInfo* plKeyFinder::GetLocationInfo( const plLocation &loc ) const
|
||||
{
|
||||
plRegistryPageNode *node = IGetResMgr()->FindPage( loc );
|
||||
if (node)
|
||||
return &node->GetPageInfo();
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
@ -1,106 +1,106 @@
|
||||
/*==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 plKeyFinder_h_inc
|
||||
#define plKeyFinder_h_inc
|
||||
|
||||
//----------------------------
|
||||
// plKeyFinder
|
||||
//----------------------------
|
||||
// provides a way to look up an object (via its plKey)
|
||||
// Using strings. The should only be used at Program Init time or console use (cause its not fast)
|
||||
// The error codes are remembered, and used for subsequent calls to GetLastErrorString(); which can
|
||||
// be display to tell the user where he screwed up the input.
|
||||
// If a key is not found it returns nil
|
||||
|
||||
//----------------------------
|
||||
// EXAMPLE OF USE:
|
||||
//----------------------------
|
||||
//
|
||||
// plKeyFinder *pFind = hsgResMgr::ResMgr()->GetKeyFinder();
|
||||
// plKey pKey = pFind->StupidSearch("Global", "Globalx", "1", "plSceneNode", "1");
|
||||
// if (!pKey)
|
||||
// hsStatusMessage(pFind->GetLastErrorString());
|
||||
// delete pFind;
|
||||
//
|
||||
//----------------------------
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "pnKeyedObject/plKey.h"
|
||||
#include "pnKeyedObject/plUoid.h"
|
||||
#include "hsStlUtils.h"
|
||||
#include <string>
|
||||
|
||||
class plLocation;
|
||||
class plRegistryPageNode;
|
||||
class plPageInfo;
|
||||
|
||||
class plKeyFinder
|
||||
{
|
||||
public:
|
||||
enum eErrCodes
|
||||
{
|
||||
kOk,
|
||||
kAgeNotFound,
|
||||
kPageNotFound,
|
||||
kInvalidClass,
|
||||
kNoClassesInPage,
|
||||
kObjectNotFound
|
||||
};
|
||||
|
||||
static plKeyFinder& Instance();
|
||||
|
||||
// These are Stupid search because they just do string searchs on the objects.
|
||||
plKey StupidSearch(const char * age, const char * rm, const char *className, const char *obName, hsBool subString=false);
|
||||
plKey StupidSearch(const char * age, const char * rm, UInt16 objType, const char *obName, hsBool subString=false);
|
||||
|
||||
eErrCodes GetLastErrorCode() { return fLastError; }
|
||||
const char* GetLastErrorString(); // For Console display
|
||||
|
||||
void ReallyStupidResponderSearch(const char* name, std::vector<plKey>& foundKeys, const plLocation& hintLocation = plLocation::kInvalidLoc);
|
||||
void ReallyStupidActivatorSearch(const char* name, std::vector<plKey>& foundKeys, const plLocation& hintLocation = plLocation::kInvalidLoc);
|
||||
|
||||
void ReallyStupidSubstringSearch(const char* name, UInt16 objType, std::vector<plKey>& foundKeys, const plLocation& hintLocation = plLocation::kInvalidLoc);
|
||||
|
||||
void GetActivatorNames(std::vector<std::string>& names);
|
||||
void GetResponderNames(std::vector<std::string>& names);
|
||||
|
||||
plKey FindSceneNodeKey(const char* pageOrFullLocName) const;
|
||||
plKey FindSceneNodeKey(const char* ageName, const char* pageName) const;
|
||||
plKey FindSceneNodeKey(const plLocation& location) const;
|
||||
|
||||
const plLocation& FindLocation(const char* age, const char* page) const;
|
||||
const plPageInfo* GetLocationInfo(const plLocation& loc) const;
|
||||
|
||||
protected:
|
||||
plKeyFinder() {}
|
||||
|
||||
void IGetNames(std::vector<std::string>& names, const char* name, int index);
|
||||
plKey IFindSceneNodeKey(plRegistryPageNode* page) const;
|
||||
|
||||
eErrCodes fLastError;
|
||||
};
|
||||
|
||||
#endif // plKeyFinder_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 plKeyFinder_h_inc
|
||||
#define plKeyFinder_h_inc
|
||||
|
||||
//----------------------------
|
||||
// plKeyFinder
|
||||
//----------------------------
|
||||
// provides a way to look up an object (via its plKey)
|
||||
// Using strings. The should only be used at Program Init time or console use (cause its not fast)
|
||||
// The error codes are remembered, and used for subsequent calls to GetLastErrorString(); which can
|
||||
// be display to tell the user where he screwed up the input.
|
||||
// If a key is not found it returns nil
|
||||
|
||||
//----------------------------
|
||||
// EXAMPLE OF USE:
|
||||
//----------------------------
|
||||
//
|
||||
// plKeyFinder *pFind = hsgResMgr::ResMgr()->GetKeyFinder();
|
||||
// plKey pKey = pFind->StupidSearch("Global", "Globalx", "1", "plSceneNode", "1");
|
||||
// if (!pKey)
|
||||
// hsStatusMessage(pFind->GetLastErrorString());
|
||||
// delete pFind;
|
||||
//
|
||||
//----------------------------
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "pnKeyedObject/plKey.h"
|
||||
#include "pnKeyedObject/plUoid.h"
|
||||
#include "hsStlUtils.h"
|
||||
#include <string>
|
||||
|
||||
class plLocation;
|
||||
class plRegistryPageNode;
|
||||
class plPageInfo;
|
||||
|
||||
class plKeyFinder
|
||||
{
|
||||
public:
|
||||
enum eErrCodes
|
||||
{
|
||||
kOk,
|
||||
kAgeNotFound,
|
||||
kPageNotFound,
|
||||
kInvalidClass,
|
||||
kNoClassesInPage,
|
||||
kObjectNotFound
|
||||
};
|
||||
|
||||
static plKeyFinder& Instance();
|
||||
|
||||
// These are Stupid search because they just do string searchs on the objects.
|
||||
plKey StupidSearch(const char * age, const char * rm, const char *className, const char *obName, hsBool subString=false);
|
||||
plKey StupidSearch(const char * age, const char * rm, UInt16 objType, const char *obName, hsBool subString=false);
|
||||
|
||||
eErrCodes GetLastErrorCode() { return fLastError; }
|
||||
const char* GetLastErrorString(); // For Console display
|
||||
|
||||
void ReallyStupidResponderSearch(const char* name, std::vector<plKey>& foundKeys, const plLocation& hintLocation = plLocation::kInvalidLoc);
|
||||
void ReallyStupidActivatorSearch(const char* name, std::vector<plKey>& foundKeys, const plLocation& hintLocation = plLocation::kInvalidLoc);
|
||||
|
||||
void ReallyStupidSubstringSearch(const char* name, UInt16 objType, std::vector<plKey>& foundKeys, const plLocation& hintLocation = plLocation::kInvalidLoc);
|
||||
|
||||
void GetActivatorNames(std::vector<std::string>& names);
|
||||
void GetResponderNames(std::vector<std::string>& names);
|
||||
|
||||
plKey FindSceneNodeKey(const char* pageOrFullLocName) const;
|
||||
plKey FindSceneNodeKey(const char* ageName, const char* pageName) const;
|
||||
plKey FindSceneNodeKey(const plLocation& location) const;
|
||||
|
||||
const plLocation& FindLocation(const char* age, const char* page) const;
|
||||
const plPageInfo* GetLocationInfo(const plLocation& loc) const;
|
||||
|
||||
protected:
|
||||
plKeyFinder() {}
|
||||
|
||||
void IGetNames(std::vector<std::string>& names, const char* name, int index);
|
||||
plKey IFindSceneNodeKey(plRegistryPageNode* page) const;
|
||||
|
||||
eErrCodes fLastError;
|
||||
};
|
||||
|
||||
#endif // plKeyFinder_h_inc
|
||||
|
@ -1,75 +1,75 @@
|
||||
/*==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 "plLoc.h"
|
||||
#include "../pnKeyedObject/hsKeyedObject.h"
|
||||
|
||||
|
||||
plLocFileParser::plLocFileParser(): fThrowBack(nil), fThrowBackLevel(0)
|
||||
{ fpFile = fopen(LOCTXTFILE,"rt"); // NEED to figure out where to put this
|
||||
}
|
||||
|
||||
int plLocFileParser::NextLine(char **pP)
|
||||
{
|
||||
|
||||
int levelKnt=0;
|
||||
*pP = 0;
|
||||
// If someone previously threwback a line...use it...
|
||||
if (ThrowBackAvailable())
|
||||
{ *pP = fThrowBack;
|
||||
int rtnLevel = fThrowBackLevel;
|
||||
ClearThrowBack();
|
||||
return rtnLevel;
|
||||
}
|
||||
// Get a New Line from the file
|
||||
char str[512];
|
||||
while(fgets(str,512 - 1,fpFile))
|
||||
{
|
||||
if (*str == '#') // indicates a missing file message, ignore
|
||||
continue;
|
||||
|
||||
int len = strlen(str);
|
||||
str[len - 1] = 0; // clobber new line
|
||||
//----------------------------------------------
|
||||
// If its the database file, remember the name, and skip it.
|
||||
//----------------------------------------------
|
||||
int i=0;
|
||||
while (str[i] == '\t')
|
||||
{ levelKnt++;
|
||||
i++;
|
||||
|
||||
}
|
||||
*pP = hsStrcpy(str + levelKnt); // Allocate a string copy, advance past TABS
|
||||
return levelKnt;
|
||||
}
|
||||
return LOC_EOF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*==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 "plLoc.h"
|
||||
#include "../pnKeyedObject/hsKeyedObject.h"
|
||||
|
||||
|
||||
plLocFileParser::plLocFileParser(): fThrowBack(nil), fThrowBackLevel(0)
|
||||
{ fpFile = fopen(LOCTXTFILE,"rt"); // NEED to figure out where to put this
|
||||
}
|
||||
|
||||
int plLocFileParser::NextLine(char **pP)
|
||||
{
|
||||
|
||||
int levelKnt=0;
|
||||
*pP = 0;
|
||||
// If someone previously threwback a line...use it...
|
||||
if (ThrowBackAvailable())
|
||||
{ *pP = fThrowBack;
|
||||
int rtnLevel = fThrowBackLevel;
|
||||
ClearThrowBack();
|
||||
return rtnLevel;
|
||||
}
|
||||
// Get a New Line from the file
|
||||
char str[512];
|
||||
while(fgets(str,512 - 1,fpFile))
|
||||
{
|
||||
if (*str == '#') // indicates a missing file message, ignore
|
||||
continue;
|
||||
|
||||
int len = strlen(str);
|
||||
str[len - 1] = 0; // clobber new line
|
||||
//----------------------------------------------
|
||||
// If its the database file, remember the name, and skip it.
|
||||
//----------------------------------------------
|
||||
int i=0;
|
||||
while (str[i] == '\t')
|
||||
{ levelKnt++;
|
||||
i++;
|
||||
|
||||
}
|
||||
*pP = hsStrcpy(str + levelKnt); // Allocate a string copy, advance past TABS
|
||||
return levelKnt;
|
||||
}
|
||||
return LOC_EOF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,64 +1,64 @@
|
||||
/*==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 PLLOC_H
|
||||
#define PLLOC_H
|
||||
|
||||
#include "HeadSpin.h"
|
||||
#include "hsUtils.h"
|
||||
|
||||
|
||||
// Values for UOID, such as AGE, District Room
|
||||
// Are kept in configuration file(s)
|
||||
// Levels are defined by the number of TABS in front of a string.
|
||||
const int LOC_EOF = -1;
|
||||
|
||||
// plLocFileParser Is a utility class used by plRegistry to Parse the Location.txt
|
||||
// configuration file.
|
||||
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
#define LOCTXTFILE "c:\\Location.txt"
|
||||
#else
|
||||
#define LOCTXTFILE "./Location.txt"
|
||||
#endif
|
||||
|
||||
class plLocFileParser
|
||||
{
|
||||
public:
|
||||
plLocFileParser();
|
||||
~plLocFileParser() { if (fpFile) fclose(fpFile); fpFile = 0; }
|
||||
void ThrowBack(char *p,UInt8 lev) { fThrowBack = p; fThrowBackLevel = lev; }
|
||||
void ClearThrowBack() { fThrowBack = NULL; fThrowBackLevel = 0; }
|
||||
bool ThrowBackAvailable() { return (fThrowBack == NULL) ? false: true; }
|
||||
int NextLine(char **pP); // returns an Allocated string in pP of next valid line, and Level #, or LOC_EOF
|
||||
hsBool8 Ready() { return fpFile ? true: false; }
|
||||
private:
|
||||
FILE * fpFile;
|
||||
char * fThrowBack; // If a line is not used, it can be thrown back...unget()
|
||||
int fThrowBackLevel;
|
||||
};
|
||||
|
||||
|
||||
#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==*/
|
||||
#ifndef PLLOC_H
|
||||
#define PLLOC_H
|
||||
|
||||
#include "HeadSpin.h"
|
||||
#include "hsUtils.h"
|
||||
|
||||
|
||||
// Values for UOID, such as AGE, District Room
|
||||
// Are kept in configuration file(s)
|
||||
// Levels are defined by the number of TABS in front of a string.
|
||||
const int LOC_EOF = -1;
|
||||
|
||||
// plLocFileParser Is a utility class used by plRegistry to Parse the Location.txt
|
||||
// configuration file.
|
||||
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
#define LOCTXTFILE "c:\\Location.txt"
|
||||
#else
|
||||
#define LOCTXTFILE "./Location.txt"
|
||||
#endif
|
||||
|
||||
class plLocFileParser
|
||||
{
|
||||
public:
|
||||
plLocFileParser();
|
||||
~plLocFileParser() { if (fpFile) fclose(fpFile); fpFile = 0; }
|
||||
void ThrowBack(char *p,UInt8 lev) { fThrowBack = p; fThrowBackLevel = lev; }
|
||||
void ClearThrowBack() { fThrowBack = NULL; fThrowBackLevel = 0; }
|
||||
bool ThrowBackAvailable() { return (fThrowBack == NULL) ? false: true; }
|
||||
int NextLine(char **pP); // returns an Allocated string in pP of next valid line, and Level #, or LOC_EOF
|
||||
hsBool8 Ready() { return fpFile ? true: false; }
|
||||
private:
|
||||
FILE * fpFile;
|
||||
char * fThrowBack; // If a line is not used, it can be thrown back...unget()
|
||||
int fThrowBackLevel;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,244 +1,244 @@
|
||||
/*==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 "hsTypes.h"
|
||||
#include "plLocalization.h"
|
||||
#include "plFile/plFileUtils.h"
|
||||
#include "hsUtils.h"
|
||||
|
||||
plLocalization::Language plLocalization::fLanguage = plLocalization::kEnglish;
|
||||
|
||||
char* plLocalization::fLangTags[] =
|
||||
{
|
||||
"_eng", // kEnglish
|
||||
"_fre", // kFrench
|
||||
"_ger", // kGerman
|
||||
"_spa", // kSpanish
|
||||
"_ita", // kItalian
|
||||
"_jpn" // kJapanese
|
||||
};
|
||||
const int kLangTagLen = 4;
|
||||
|
||||
char* plLocalization::fLangNames[] =
|
||||
{
|
||||
"English", // kEnglish
|
||||
"French", // kFrench
|
||||
"German", // kGerman
|
||||
"Spanish", // kSpanish
|
||||
"Italian", // kItalian
|
||||
"Japanese" // kJapanese
|
||||
};
|
||||
|
||||
bool plLocalization::fUsesUnicode[] =
|
||||
{
|
||||
false, // kEnglish
|
||||
false, // kFrench
|
||||
false, // kGerman
|
||||
false, // kSpanish
|
||||
false, // kItalian
|
||||
true // kJapanese
|
||||
};
|
||||
|
||||
plLocalization::encodingTypes plLocalization::fUnicodeEncoding[] =
|
||||
{
|
||||
Enc_Unencoded, // kEnglish
|
||||
Enc_Unencoded, // kFrench
|
||||
Enc_Unencoded, // kGerman
|
||||
Enc_Unencoded, // kSpanish
|
||||
Enc_Unencoded, // kItalian
|
||||
Enc_UTF8, // kJapanese
|
||||
};
|
||||
|
||||
hsBool plLocalization::IGetLocalized(const char* name, Language lang, char* localizedName)
|
||||
{
|
||||
const char* underscore = strrchr(name, '_');
|
||||
|
||||
if (underscore)
|
||||
{
|
||||
char langTag[kLangTagLen+1];
|
||||
strncpy(langTag,underscore,kLangTagLen);
|
||||
langTag[kLangTagLen] = '\0';
|
||||
|
||||
if (strncmp(langTag, fLangTags[kEnglish], kLangTagLen) == 0)
|
||||
{
|
||||
if (localizedName)
|
||||
{
|
||||
strcpy(localizedName, name);
|
||||
int underscorePos = underscore - name;
|
||||
memcpy(localizedName + underscorePos, fLangTags[lang], kLangTagLen);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
hsBool plLocalization::ExportGetLocalized(const char* name, int lang, char* localizedName)
|
||||
{
|
||||
return IGetLocalized(name, Language(lang+1), localizedName) &&
|
||||
plFileUtils::FileExists(localizedName);
|
||||
}
|
||||
|
||||
std::string plLocalization::LocalToString(const std::vector<std::string> & localizedText)
|
||||
{
|
||||
std::string retVal = "";
|
||||
for (int i=0; i<localizedText.size(); i++)
|
||||
{
|
||||
if (i > kNumLanguages-1)
|
||||
break;
|
||||
std::string langHeader = "$";
|
||||
std::string langName = GetLanguageName((Language)i);
|
||||
langHeader += langName.substr(0,2) + "$";
|
||||
retVal += langHeader + localizedText[i];
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
std::vector<std::string> plLocalization::StringToLocal(const std::string & localizedText)
|
||||
{
|
||||
std::vector<std::string> retVal;
|
||||
wchar_t *temp = hsStringToWString(localizedText.c_str());
|
||||
std::wstring wLocalizedText = temp;
|
||||
delete [] temp;
|
||||
|
||||
std::vector<std::wstring> wStringVector = StringToLocal(wLocalizedText);
|
||||
int i;
|
||||
for (i=0; i<wStringVector.size(); i++)
|
||||
{
|
||||
char *local = hsWStringToString(wStringVector[i].c_str());
|
||||
std::string val = local;
|
||||
delete [] local;
|
||||
retVal.push_back(val);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
std::vector<std::wstring> plLocalization::StringToLocal(const std::wstring & localizedText)
|
||||
{
|
||||
std::vector<std::wstring> tags;
|
||||
std::vector<int> tagLocs;
|
||||
std::vector<int> sortedTagLocs;
|
||||
std::vector<std::wstring> retVal;
|
||||
int i;
|
||||
for (i=0; i<kNumLanguages; i++)
|
||||
{
|
||||
std::wstring tag = L"$";
|
||||
std::string temp = GetLanguageName((Language)i);
|
||||
wchar_t *wTemp = hsStringToWString(temp.c_str());
|
||||
std::wstring langName = wTemp;
|
||||
delete [] wTemp;
|
||||
|
||||
tag += langName.substr(0,2) + L"$";
|
||||
tags.push_back(tag);
|
||||
tagLocs.push_back(localizedText.find(tag));
|
||||
sortedTagLocs.push_back(i);
|
||||
retVal.push_back(L"");
|
||||
}
|
||||
for (i=0; i<kNumLanguages-1; i++)
|
||||
{
|
||||
for (int j=i; j<kNumLanguages; j++)
|
||||
{
|
||||
if (tagLocs[sortedTagLocs[i]] > tagLocs[sortedTagLocs[j]])
|
||||
sortedTagLocs[i]^=sortedTagLocs[j]^=sortedTagLocs[i]^=sortedTagLocs[j]; // swap the contents (yes, it works)
|
||||
}
|
||||
}
|
||||
// now sortedTagLocs has the indexes of tagLocs sorted from smallest loc to highest loc
|
||||
hsBool noTags = true;
|
||||
for (i=0; i<kNumLanguages; i++)
|
||||
{
|
||||
int lang = sortedTagLocs[i]; // the language we are extracting
|
||||
if (tagLocs[lang] != -1)
|
||||
{
|
||||
noTags = false; // at least one tag was found in the text
|
||||
int startLoc = tagLocs[lang] + tags[lang].length();
|
||||
int endLoc;
|
||||
if (i+1 == kNumLanguages)
|
||||
endLoc = localizedText.length();
|
||||
else
|
||||
endLoc = tagLocs[sortedTagLocs[i+1]];
|
||||
retVal[lang] = localizedText.substr(startLoc,endLoc-startLoc);
|
||||
}
|
||||
}
|
||||
if (noTags)
|
||||
retVal[0] = localizedText; // if no tags were in the text, we assume it to be English
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#include "hsWindows.h"
|
||||
|
||||
void plLocalization::SetDefaultLanguage()
|
||||
{
|
||||
fLanguage = kEnglish;
|
||||
#if 0 // disable all languages
|
||||
#ifdef HS_BUILD_FOR_WIN32
|
||||
HKEY hLocalKey = NULL;
|
||||
HKEY hMSKey = NULL;
|
||||
HKEY hWindowsKey = NULL;
|
||||
HKEY hCurVerKey = NULL;
|
||||
HKEY hUninstKey = NULL;
|
||||
HKEY hUruKey = NULL;
|
||||
|
||||
#define RegOpen(key, retKey, subKeyName) RegOpenKeyEx(key, subKeyName, 0, KEY_READ, &retKey) == ERROR_SUCCESS
|
||||
|
||||
if (RegOpen(HKEY_LOCAL_MACHINE, hLocalKey, "software") &&
|
||||
RegOpen(hLocalKey, hMSKey, "microsoft") &&
|
||||
RegOpen(hMSKey, hWindowsKey, "windows") &&
|
||||
RegOpen(hWindowsKey, hCurVerKey, "currentversion") &&
|
||||
RegOpen(hCurVerKey, hUninstKey, "uninstall") &&
|
||||
RegOpen(hUninstKey, hUruKey, "Uru - Ages Beyond Myst"))
|
||||
{
|
||||
char value[20];
|
||||
DWORD bufsize = sizeof(value);
|
||||
if (RegQueryValueEx(hUruKey, "Lang", NULL, NULL, (LPBYTE)value, &bufsize) == ERROR_SUCCESS)
|
||||
{
|
||||
if (hsStrEQ(value, "en"))
|
||||
fLanguage = kEnglish;
|
||||
else if (hsStrEQ(value, "fr"))
|
||||
fLanguage = kFrench;
|
||||
else if (hsStrEQ(value, "de"))
|
||||
fLanguage = kGerman;
|
||||
else if (hsStrEQ(value, "es"))
|
||||
fLanguage = kSpanish;
|
||||
else if (hsStrEQ(value, "it"))
|
||||
fLanguage = kItalian;
|
||||
else if (hsStrEQ(value, "jp"))
|
||||
fLanguage = kJapanese;
|
||||
else
|
||||
fLanguage = kEnglish;
|
||||
}
|
||||
}
|
||||
|
||||
RegCloseKey(hLocalKey);
|
||||
RegCloseKey(hMSKey);
|
||||
RegCloseKey(hWindowsKey);
|
||||
RegCloseKey(hCurVerKey);
|
||||
RegCloseKey(hUninstKey);
|
||||
RegCloseKey(hUruKey);
|
||||
#endif // HS_BUILD_FOR_WIN32
|
||||
#endif // 0
|
||||
}
|
||||
/*==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 "hsTypes.h"
|
||||
#include "plLocalization.h"
|
||||
#include "plFile/plFileUtils.h"
|
||||
#include "hsUtils.h"
|
||||
|
||||
plLocalization::Language plLocalization::fLanguage = plLocalization::kEnglish;
|
||||
|
||||
char* plLocalization::fLangTags[] =
|
||||
{
|
||||
"_eng", // kEnglish
|
||||
"_fre", // kFrench
|
||||
"_ger", // kGerman
|
||||
"_spa", // kSpanish
|
||||
"_ita", // kItalian
|
||||
"_jpn" // kJapanese
|
||||
};
|
||||
const int kLangTagLen = 4;
|
||||
|
||||
char* plLocalization::fLangNames[] =
|
||||
{
|
||||
"English", // kEnglish
|
||||
"French", // kFrench
|
||||
"German", // kGerman
|
||||
"Spanish", // kSpanish
|
||||
"Italian", // kItalian
|
||||
"Japanese" // kJapanese
|
||||
};
|
||||
|
||||
bool plLocalization::fUsesUnicode[] =
|
||||
{
|
||||
false, // kEnglish
|
||||
false, // kFrench
|
||||
false, // kGerman
|
||||
false, // kSpanish
|
||||
false, // kItalian
|
||||
true // kJapanese
|
||||
};
|
||||
|
||||
plLocalization::encodingTypes plLocalization::fUnicodeEncoding[] =
|
||||
{
|
||||
Enc_Unencoded, // kEnglish
|
||||
Enc_Unencoded, // kFrench
|
||||
Enc_Unencoded, // kGerman
|
||||
Enc_Unencoded, // kSpanish
|
||||
Enc_Unencoded, // kItalian
|
||||
Enc_UTF8, // kJapanese
|
||||
};
|
||||
|
||||
hsBool plLocalization::IGetLocalized(const char* name, Language lang, char* localizedName)
|
||||
{
|
||||
const char* underscore = strrchr(name, '_');
|
||||
|
||||
if (underscore)
|
||||
{
|
||||
char langTag[kLangTagLen+1];
|
||||
strncpy(langTag,underscore,kLangTagLen);
|
||||
langTag[kLangTagLen] = '\0';
|
||||
|
||||
if (strncmp(langTag, fLangTags[kEnglish], kLangTagLen) == 0)
|
||||
{
|
||||
if (localizedName)
|
||||
{
|
||||
strcpy(localizedName, name);
|
||||
int underscorePos = underscore - name;
|
||||
memcpy(localizedName + underscorePos, fLangTags[lang], kLangTagLen);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
hsBool plLocalization::ExportGetLocalized(const char* name, int lang, char* localizedName)
|
||||
{
|
||||
return IGetLocalized(name, Language(lang+1), localizedName) &&
|
||||
plFileUtils::FileExists(localizedName);
|
||||
}
|
||||
|
||||
std::string plLocalization::LocalToString(const std::vector<std::string> & localizedText)
|
||||
{
|
||||
std::string retVal = "";
|
||||
for (int i=0; i<localizedText.size(); i++)
|
||||
{
|
||||
if (i > kNumLanguages-1)
|
||||
break;
|
||||
std::string langHeader = "$";
|
||||
std::string langName = GetLanguageName((Language)i);
|
||||
langHeader += langName.substr(0,2) + "$";
|
||||
retVal += langHeader + localizedText[i];
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
std::vector<std::string> plLocalization::StringToLocal(const std::string & localizedText)
|
||||
{
|
||||
std::vector<std::string> retVal;
|
||||
wchar_t *temp = hsStringToWString(localizedText.c_str());
|
||||
std::wstring wLocalizedText = temp;
|
||||
delete [] temp;
|
||||
|
||||
std::vector<std::wstring> wStringVector = StringToLocal(wLocalizedText);
|
||||
int i;
|
||||
for (i=0; i<wStringVector.size(); i++)
|
||||
{
|
||||
char *local = hsWStringToString(wStringVector[i].c_str());
|
||||
std::string val = local;
|
||||
delete [] local;
|
||||
retVal.push_back(val);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
std::vector<std::wstring> plLocalization::StringToLocal(const std::wstring & localizedText)
|
||||
{
|
||||
std::vector<std::wstring> tags;
|
||||
std::vector<int> tagLocs;
|
||||
std::vector<int> sortedTagLocs;
|
||||
std::vector<std::wstring> retVal;
|
||||
int i;
|
||||
for (i=0; i<kNumLanguages; i++)
|
||||
{
|
||||
std::wstring tag = L"$";
|
||||
std::string temp = GetLanguageName((Language)i);
|
||||
wchar_t *wTemp = hsStringToWString(temp.c_str());
|
||||
std::wstring langName = wTemp;
|
||||
delete [] wTemp;
|
||||
|
||||
tag += langName.substr(0,2) + L"$";
|
||||
tags.push_back(tag);
|
||||
tagLocs.push_back(localizedText.find(tag));
|
||||
sortedTagLocs.push_back(i);
|
||||
retVal.push_back(L"");
|
||||
}
|
||||
for (i=0; i<kNumLanguages-1; i++)
|
||||
{
|
||||
for (int j=i; j<kNumLanguages; j++)
|
||||
{
|
||||
if (tagLocs[sortedTagLocs[i]] > tagLocs[sortedTagLocs[j]])
|
||||
sortedTagLocs[i]^=sortedTagLocs[j]^=sortedTagLocs[i]^=sortedTagLocs[j]; // swap the contents (yes, it works)
|
||||
}
|
||||
}
|
||||
// now sortedTagLocs has the indexes of tagLocs sorted from smallest loc to highest loc
|
||||
hsBool noTags = true;
|
||||
for (i=0; i<kNumLanguages; i++)
|
||||
{
|
||||
int lang = sortedTagLocs[i]; // the language we are extracting
|
||||
if (tagLocs[lang] != -1)
|
||||
{
|
||||
noTags = false; // at least one tag was found in the text
|
||||
int startLoc = tagLocs[lang] + tags[lang].length();
|
||||
int endLoc;
|
||||
if (i+1 == kNumLanguages)
|
||||
endLoc = localizedText.length();
|
||||
else
|
||||
endLoc = tagLocs[sortedTagLocs[i+1]];
|
||||
retVal[lang] = localizedText.substr(startLoc,endLoc-startLoc);
|
||||
}
|
||||
}
|
||||
if (noTags)
|
||||
retVal[0] = localizedText; // if no tags were in the text, we assume it to be English
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#include "hsWindows.h"
|
||||
|
||||
void plLocalization::SetDefaultLanguage()
|
||||
{
|
||||
fLanguage = kEnglish;
|
||||
#if 0 // disable all languages
|
||||
#ifdef HS_BUILD_FOR_WIN32
|
||||
HKEY hLocalKey = NULL;
|
||||
HKEY hMSKey = NULL;
|
||||
HKEY hWindowsKey = NULL;
|
||||
HKEY hCurVerKey = NULL;
|
||||
HKEY hUninstKey = NULL;
|
||||
HKEY hUruKey = NULL;
|
||||
|
||||
#define RegOpen(key, retKey, subKeyName) RegOpenKeyEx(key, subKeyName, 0, KEY_READ, &retKey) == ERROR_SUCCESS
|
||||
|
||||
if (RegOpen(HKEY_LOCAL_MACHINE, hLocalKey, "software") &&
|
||||
RegOpen(hLocalKey, hMSKey, "microsoft") &&
|
||||
RegOpen(hMSKey, hWindowsKey, "windows") &&
|
||||
RegOpen(hWindowsKey, hCurVerKey, "currentversion") &&
|
||||
RegOpen(hCurVerKey, hUninstKey, "uninstall") &&
|
||||
RegOpen(hUninstKey, hUruKey, "Uru - Ages Beyond Myst"))
|
||||
{
|
||||
char value[20];
|
||||
DWORD bufsize = sizeof(value);
|
||||
if (RegQueryValueEx(hUruKey, "Lang", NULL, NULL, (LPBYTE)value, &bufsize) == ERROR_SUCCESS)
|
||||
{
|
||||
if (hsStrEQ(value, "en"))
|
||||
fLanguage = kEnglish;
|
||||
else if (hsStrEQ(value, "fr"))
|
||||
fLanguage = kFrench;
|
||||
else if (hsStrEQ(value, "de"))
|
||||
fLanguage = kGerman;
|
||||
else if (hsStrEQ(value, "es"))
|
||||
fLanguage = kSpanish;
|
||||
else if (hsStrEQ(value, "it"))
|
||||
fLanguage = kItalian;
|
||||
else if (hsStrEQ(value, "jp"))
|
||||
fLanguage = kJapanese;
|
||||
else
|
||||
fLanguage = kEnglish;
|
||||
}
|
||||
}
|
||||
|
||||
RegCloseKey(hLocalKey);
|
||||
RegCloseKey(hMSKey);
|
||||
RegCloseKey(hWindowsKey);
|
||||
RegCloseKey(hCurVerKey);
|
||||
RegCloseKey(hUninstKey);
|
||||
RegCloseKey(hUruKey);
|
||||
#endif // HS_BUILD_FOR_WIN32
|
||||
#endif // 0
|
||||
}
|
||||
|
@ -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==*/
|
||||
#ifndef plLocalization_h_inc
|
||||
#define plLocalization_h_inc
|
||||
|
||||
#include "hsStlUtils.h"
|
||||
|
||||
class plLocalization
|
||||
{
|
||||
public:
|
||||
enum Language
|
||||
{
|
||||
kEnglish,
|
||||
kFrench,
|
||||
kGerman,
|
||||
kSpanish,
|
||||
kItalian,
|
||||
kJapanese,
|
||||
|
||||
kNumLanguages,
|
||||
};
|
||||
|
||||
typedef enum encodingTypes
|
||||
{
|
||||
Enc_Unencoded, // This can also mean that python did the decoding for us and we don't need to tweak it on our end
|
||||
Enc_Split_String,
|
||||
Enc_Hybrid_Split_String,
|
||||
Enc_UTF8,
|
||||
Enc_UTF16,
|
||||
Enc_Unicode_Escape,
|
||||
Enc_Raw_Unicode_Escape,
|
||||
Enc_Latin_1,
|
||||
Enc_ASCII,
|
||||
Enc_MBCS
|
||||
};
|
||||
|
||||
protected:
|
||||
static Language fLanguage;
|
||||
static char* fLangTags[kNumLanguages];
|
||||
static char* fLangNames[kNumLanguages];
|
||||
static bool fUsesUnicode[kNumLanguages];
|
||||
static encodingTypes fUnicodeEncoding[kNumLanguages];
|
||||
|
||||
static hsBool IGetLocalized(const char* name, Language lang, char* localizedName);
|
||||
|
||||
public:
|
||||
// Sets the default language, as determined by the installer
|
||||
static void SetDefaultLanguage();
|
||||
|
||||
static void SetLanguage(Language lang) { fLanguage = lang; }
|
||||
static Language GetLanguage() { return fLanguage; }
|
||||
|
||||
static char* GetLanguageName(Language lang) { return fLangNames[lang]; }
|
||||
|
||||
static hsBool UsingUnicode() { return fUsesUnicode[fLanguage]; }
|
||||
static encodingTypes UnicodeEncoding() { return fUnicodeEncoding[fLanguage]; }
|
||||
|
||||
// Returns true if we're using localized assets. If it returns false, you
|
||||
// don't need to bother calling GetLocalized
|
||||
static hsBool IsLocalized() { return fLanguage != kEnglish; }
|
||||
|
||||
// Pass in a key name and this will give you the localized name
|
||||
// Returns false if the original keyname is not for a localized asset
|
||||
static hsBool GetLocalized(const char* name, char* localizedName) { return IGetLocalized(name, fLanguage, localizedName); }
|
||||
|
||||
//
|
||||
// Export only
|
||||
//
|
||||
// When you're exporting an asset that could be localized, you'll want to do
|
||||
// a loop something like this to try and find any localized versions.
|
||||
//
|
||||
// for (int i = 0; i < plLocalization::GetNumLocales(); i++)
|
||||
// {
|
||||
// char localName[MAX_PATH];
|
||||
// if (plLocalization::ExportGetLocalized(fileName, i, localName))
|
||||
// {
|
||||
// ...
|
||||
// }
|
||||
// }
|
||||
//
|
||||
static int GetNumLocales() { return kNumLanguages - 1; }
|
||||
static hsBool ExportGetLocalized(const char* name, int lang, char* localizedName);
|
||||
// Just tells us if this is localized, doesn't actually convert it for us
|
||||
static hsBool IsLocalizedName(const char* name) { return IGetLocalized(name, kEnglish, nil); }
|
||||
|
||||
// Converts a vector of translated strings to a encoded string that can be decoded by StringToLocal()
|
||||
// The index in the vector of a string is it's language
|
||||
static std::string LocalToString(const std::vector<std::string> & localizedText);
|
||||
// Converts a string encoded by LocalToString to a vector of translated strings
|
||||
static std::vector<std::string> StringToLocal(const std::string & localizedText);
|
||||
static std::vector<std::wstring> StringToLocal(const std::wstring & localizedText);
|
||||
};
|
||||
|
||||
/*==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 plLocalization_h_inc
|
||||
#define plLocalization_h_inc
|
||||
|
||||
#include "hsStlUtils.h"
|
||||
|
||||
class plLocalization
|
||||
{
|
||||
public:
|
||||
enum Language
|
||||
{
|
||||
kEnglish,
|
||||
kFrench,
|
||||
kGerman,
|
||||
kSpanish,
|
||||
kItalian,
|
||||
kJapanese,
|
||||
|
||||
kNumLanguages,
|
||||
};
|
||||
|
||||
typedef enum encodingTypes
|
||||
{
|
||||
Enc_Unencoded, // This can also mean that python did the decoding for us and we don't need to tweak it on our end
|
||||
Enc_Split_String,
|
||||
Enc_Hybrid_Split_String,
|
||||
Enc_UTF8,
|
||||
Enc_UTF16,
|
||||
Enc_Unicode_Escape,
|
||||
Enc_Raw_Unicode_Escape,
|
||||
Enc_Latin_1,
|
||||
Enc_ASCII,
|
||||
Enc_MBCS
|
||||
};
|
||||
|
||||
protected:
|
||||
static Language fLanguage;
|
||||
static char* fLangTags[kNumLanguages];
|
||||
static char* fLangNames[kNumLanguages];
|
||||
static bool fUsesUnicode[kNumLanguages];
|
||||
static encodingTypes fUnicodeEncoding[kNumLanguages];
|
||||
|
||||
static hsBool IGetLocalized(const char* name, Language lang, char* localizedName);
|
||||
|
||||
public:
|
||||
// Sets the default language, as determined by the installer
|
||||
static void SetDefaultLanguage();
|
||||
|
||||
static void SetLanguage(Language lang) { fLanguage = lang; }
|
||||
static Language GetLanguage() { return fLanguage; }
|
||||
|
||||
static char* GetLanguageName(Language lang) { return fLangNames[lang]; }
|
||||
|
||||
static hsBool UsingUnicode() { return fUsesUnicode[fLanguage]; }
|
||||
static encodingTypes UnicodeEncoding() { return fUnicodeEncoding[fLanguage]; }
|
||||
|
||||
// Returns true if we're using localized assets. If it returns false, you
|
||||
// don't need to bother calling GetLocalized
|
||||
static hsBool IsLocalized() { return fLanguage != kEnglish; }
|
||||
|
||||
// Pass in a key name and this will give you the localized name
|
||||
// Returns false if the original keyname is not for a localized asset
|
||||
static hsBool GetLocalized(const char* name, char* localizedName) { return IGetLocalized(name, fLanguage, localizedName); }
|
||||
|
||||
//
|
||||
// Export only
|
||||
//
|
||||
// When you're exporting an asset that could be localized, you'll want to do
|
||||
// a loop something like this to try and find any localized versions.
|
||||
//
|
||||
// for (int i = 0; i < plLocalization::GetNumLocales(); i++)
|
||||
// {
|
||||
// char localName[MAX_PATH];
|
||||
// if (plLocalization::ExportGetLocalized(fileName, i, localName))
|
||||
// {
|
||||
// ...
|
||||
// }
|
||||
// }
|
||||
//
|
||||
static int GetNumLocales() { return kNumLanguages - 1; }
|
||||
static hsBool ExportGetLocalized(const char* name, int lang, char* localizedName);
|
||||
// Just tells us if this is localized, doesn't actually convert it for us
|
||||
static hsBool IsLocalizedName(const char* name) { return IGetLocalized(name, kEnglish, nil); }
|
||||
|
||||
// Converts a vector of translated strings to a encoded string that can be decoded by StringToLocal()
|
||||
// The index in the vector of a string is it's language
|
||||
static std::string LocalToString(const std::vector<std::string> & localizedText);
|
||||
// Converts a string encoded by LocalToString to a vector of translated strings
|
||||
static std::vector<std::string> StringToLocal(const std::string & localizedText);
|
||||
static std::vector<std::wstring> StringToLocal(const std::wstring & localizedText);
|
||||
};
|
||||
|
||||
#endif // plLocalization_h_inc
|
@ -1,193 +1,193 @@
|
||||
/*==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 "plPageInfo.h"
|
||||
#include "hsUtils.h"
|
||||
#include "hsStream.h"
|
||||
#include "pnKeyedObject/plUoid.h"
|
||||
#include "plVersion.h"
|
||||
|
||||
static UInt32 sCurrPageInfoVersion = 6;
|
||||
|
||||
//// Constructor/Destructor //////////////////////////////////////////////////
|
||||
plPageInfo::plPageInfo()
|
||||
{
|
||||
IInit();
|
||||
}
|
||||
|
||||
plPageInfo::plPageInfo( const plLocation &loc )
|
||||
{
|
||||
IInit();
|
||||
fLocation = loc;
|
||||
}
|
||||
|
||||
void plPageInfo::IInit()
|
||||
{
|
||||
fAge = fPage = nil;
|
||||
fLocation.Invalidate();
|
||||
SetMajorVersion(plVersion::GetMajorVersion());
|
||||
fClassVersions.clear();
|
||||
fChecksum = 0;
|
||||
fDataStart = fIndexStart = 0;
|
||||
}
|
||||
|
||||
plPageInfo::~plPageInfo()
|
||||
{
|
||||
SetStrings( nil, nil );
|
||||
}
|
||||
|
||||
plPageInfo::plPageInfo( const plPageInfo &src )
|
||||
{
|
||||
IInit();
|
||||
ISetFrom( src );
|
||||
}
|
||||
|
||||
plPageInfo &plPageInfo::operator=( const plPageInfo &src )
|
||||
{
|
||||
ISetFrom( src );
|
||||
return *this;
|
||||
}
|
||||
|
||||
void plPageInfo::ISetFrom( const plPageInfo &src )
|
||||
{
|
||||
fLocation = src.fLocation;
|
||||
|
||||
SetStrings( src.fAge, src.fPage );
|
||||
fMajorVersion = src.fMajorVersion;
|
||||
fClassVersions = src.fClassVersions;
|
||||
fChecksum = src.fChecksum;
|
||||
fDataStart = src.fDataStart;
|
||||
fIndexStart = src.fIndexStart;
|
||||
}
|
||||
|
||||
void plPageInfo::SetStrings( const char *age, const char *page )
|
||||
{
|
||||
delete [] fAge;
|
||||
delete [] fPage;
|
||||
|
||||
fAge = ( age == nil ) ? nil : hsStrcpy( age );
|
||||
fPage = ( page == nil ) ? nil : hsStrcpy( page );
|
||||
}
|
||||
|
||||
void plPageInfo::SetLocation( const plLocation &loc )
|
||||
{
|
||||
fLocation = loc;
|
||||
}
|
||||
|
||||
void plPageInfo::AddClassVersion(UInt16 classIdx, UInt16 version)
|
||||
{
|
||||
ClassVersion cv;
|
||||
cv.Class = classIdx;
|
||||
cv.Version = version;
|
||||
fClassVersions.push_back(cv);
|
||||
}
|
||||
|
||||
const plLocation& plPageInfo::GetLocation() const
|
||||
{
|
||||
return fLocation;
|
||||
}
|
||||
|
||||
void plPageInfo::Read( hsStream *s )
|
||||
{
|
||||
delete [] fAge;
|
||||
delete [] fPage;
|
||||
|
||||
IInit();
|
||||
|
||||
// 5 is the earliest version since we began working again on the P20 codebase in Sep 2005,
|
||||
// after Uru's online component was cancelled in Feb 2004, so I've removed support for
|
||||
// anything prior to that to clean things up a bit.
|
||||
UInt32 version = s->ReadSwap32();
|
||||
if (version > sCurrPageInfoVersion || version < 5)
|
||||
{
|
||||
hsAssert( false, "Invalid header version in plPageInfo::Read()" );
|
||||
return;
|
||||
}
|
||||
if (version >= 5)
|
||||
{
|
||||
fLocation.Read( s );
|
||||
fAge = s->ReadSafeString();
|
||||
if (version < 6)
|
||||
delete s->ReadSafeString(); // fChapter was never used, and always "District".
|
||||
fPage = s->ReadSafeString();
|
||||
|
||||
s->ReadSwap( &fMajorVersion );
|
||||
|
||||
if (version < 6)
|
||||
{
|
||||
UInt16 unusedMinorVersion;
|
||||
s->ReadSwap(&unusedMinorVersion);
|
||||
Int32 unusedReleaseVersion;
|
||||
s->ReadSwap(&unusedReleaseVersion); // This was always zero... yanked.
|
||||
UInt32 unusedFlags;
|
||||
s->ReadSwap(&unusedFlags);
|
||||
}
|
||||
|
||||
s->ReadSwap( &fChecksum );
|
||||
s->ReadSwap( &fDataStart );
|
||||
s->ReadSwap( &fIndexStart );
|
||||
}
|
||||
|
||||
if (version >= 6)
|
||||
{
|
||||
UInt16 numClassVersions = s->ReadSwap16();
|
||||
fClassVersions.reserve(numClassVersions);
|
||||
for (UInt16 i = 0; i < numClassVersions; i++)
|
||||
{
|
||||
ClassVersion cv;
|
||||
cv.Class = s->ReadSwap16();
|
||||
cv.Version = s->ReadSwap16();
|
||||
fClassVersions.push_back(cv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plPageInfo::Write( hsStream *s )
|
||||
{
|
||||
s->WriteSwap32( sCurrPageInfoVersion );
|
||||
fLocation.Write( s );
|
||||
s->WriteSafeString( fAge );
|
||||
s->WriteSafeString( fPage );
|
||||
s->WriteSwap( fMajorVersion );
|
||||
s->WriteSwap( fChecksum );
|
||||
s->WriteSwap( fDataStart );
|
||||
s->WriteSwap( fIndexStart );
|
||||
UInt16 numClassVersions = UInt16(fClassVersions.size());
|
||||
s->WriteSwap16(numClassVersions);
|
||||
for (UInt16 i = 0; i < numClassVersions; i++)
|
||||
{
|
||||
ClassVersion& cv = fClassVersions[i];
|
||||
s->WriteSwap16(cv.Class);
|
||||
s->WriteSwap16(cv.Version);
|
||||
}
|
||||
}
|
||||
|
||||
//// IsValid /////////////////////////////////////////////////////////////////
|
||||
// Just a simple test for now.
|
||||
|
||||
hsBool plPageInfo::IsValid( void ) const
|
||||
{
|
||||
return fLocation.IsValid();
|
||||
}
|
||||
/*==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 "plPageInfo.h"
|
||||
#include "hsUtils.h"
|
||||
#include "hsStream.h"
|
||||
#include "pnKeyedObject/plUoid.h"
|
||||
#include "plVersion.h"
|
||||
|
||||
static UInt32 sCurrPageInfoVersion = 6;
|
||||
|
||||
//// Constructor/Destructor //////////////////////////////////////////////////
|
||||
plPageInfo::plPageInfo()
|
||||
{
|
||||
IInit();
|
||||
}
|
||||
|
||||
plPageInfo::plPageInfo( const plLocation &loc )
|
||||
{
|
||||
IInit();
|
||||
fLocation = loc;
|
||||
}
|
||||
|
||||
void plPageInfo::IInit()
|
||||
{
|
||||
fAge = fPage = nil;
|
||||
fLocation.Invalidate();
|
||||
SetMajorVersion(plVersion::GetMajorVersion());
|
||||
fClassVersions.clear();
|
||||
fChecksum = 0;
|
||||
fDataStart = fIndexStart = 0;
|
||||
}
|
||||
|
||||
plPageInfo::~plPageInfo()
|
||||
{
|
||||
SetStrings( nil, nil );
|
||||
}
|
||||
|
||||
plPageInfo::plPageInfo( const plPageInfo &src )
|
||||
{
|
||||
IInit();
|
||||
ISetFrom( src );
|
||||
}
|
||||
|
||||
plPageInfo &plPageInfo::operator=( const plPageInfo &src )
|
||||
{
|
||||
ISetFrom( src );
|
||||
return *this;
|
||||
}
|
||||
|
||||
void plPageInfo::ISetFrom( const plPageInfo &src )
|
||||
{
|
||||
fLocation = src.fLocation;
|
||||
|
||||
SetStrings( src.fAge, src.fPage );
|
||||
fMajorVersion = src.fMajorVersion;
|
||||
fClassVersions = src.fClassVersions;
|
||||
fChecksum = src.fChecksum;
|
||||
fDataStart = src.fDataStart;
|
||||
fIndexStart = src.fIndexStart;
|
||||
}
|
||||
|
||||
void plPageInfo::SetStrings( const char *age, const char *page )
|
||||
{
|
||||
delete [] fAge;
|
||||
delete [] fPage;
|
||||
|
||||
fAge = ( age == nil ) ? nil : hsStrcpy( age );
|
||||
fPage = ( page == nil ) ? nil : hsStrcpy( page );
|
||||
}
|
||||
|
||||
void plPageInfo::SetLocation( const plLocation &loc )
|
||||
{
|
||||
fLocation = loc;
|
||||
}
|
||||
|
||||
void plPageInfo::AddClassVersion(UInt16 classIdx, UInt16 version)
|
||||
{
|
||||
ClassVersion cv;
|
||||
cv.Class = classIdx;
|
||||
cv.Version = version;
|
||||
fClassVersions.push_back(cv);
|
||||
}
|
||||
|
||||
const plLocation& plPageInfo::GetLocation() const
|
||||
{
|
||||
return fLocation;
|
||||
}
|
||||
|
||||
void plPageInfo::Read( hsStream *s )
|
||||
{
|
||||
delete [] fAge;
|
||||
delete [] fPage;
|
||||
|
||||
IInit();
|
||||
|
||||
// 5 is the earliest version since we began working again on the P20 codebase in Sep 2005,
|
||||
// after Uru's online component was cancelled in Feb 2004, so I've removed support for
|
||||
// anything prior to that to clean things up a bit.
|
||||
UInt32 version = s->ReadSwap32();
|
||||
if (version > sCurrPageInfoVersion || version < 5)
|
||||
{
|
||||
hsAssert( false, "Invalid header version in plPageInfo::Read()" );
|
||||
return;
|
||||
}
|
||||
if (version >= 5)
|
||||
{
|
||||
fLocation.Read( s );
|
||||
fAge = s->ReadSafeString();
|
||||
if (version < 6)
|
||||
delete s->ReadSafeString(); // fChapter was never used, and always "District".
|
||||
fPage = s->ReadSafeString();
|
||||
|
||||
s->ReadSwap( &fMajorVersion );
|
||||
|
||||
if (version < 6)
|
||||
{
|
||||
UInt16 unusedMinorVersion;
|
||||
s->ReadSwap(&unusedMinorVersion);
|
||||
Int32 unusedReleaseVersion;
|
||||
s->ReadSwap(&unusedReleaseVersion); // This was always zero... yanked.
|
||||
UInt32 unusedFlags;
|
||||
s->ReadSwap(&unusedFlags);
|
||||
}
|
||||
|
||||
s->ReadSwap( &fChecksum );
|
||||
s->ReadSwap( &fDataStart );
|
||||
s->ReadSwap( &fIndexStart );
|
||||
}
|
||||
|
||||
if (version >= 6)
|
||||
{
|
||||
UInt16 numClassVersions = s->ReadSwap16();
|
||||
fClassVersions.reserve(numClassVersions);
|
||||
for (UInt16 i = 0; i < numClassVersions; i++)
|
||||
{
|
||||
ClassVersion cv;
|
||||
cv.Class = s->ReadSwap16();
|
||||
cv.Version = s->ReadSwap16();
|
||||
fClassVersions.push_back(cv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plPageInfo::Write( hsStream *s )
|
||||
{
|
||||
s->WriteSwap32( sCurrPageInfoVersion );
|
||||
fLocation.Write( s );
|
||||
s->WriteSafeString( fAge );
|
||||
s->WriteSafeString( fPage );
|
||||
s->WriteSwap( fMajorVersion );
|
||||
s->WriteSwap( fChecksum );
|
||||
s->WriteSwap( fDataStart );
|
||||
s->WriteSwap( fIndexStart );
|
||||
UInt16 numClassVersions = UInt16(fClassVersions.size());
|
||||
s->WriteSwap16(numClassVersions);
|
||||
for (UInt16 i = 0; i < numClassVersions; i++)
|
||||
{
|
||||
ClassVersion& cv = fClassVersions[i];
|
||||
s->WriteSwap16(cv.Class);
|
||||
s->WriteSwap16(cv.Version);
|
||||
}
|
||||
}
|
||||
|
||||
//// IsValid /////////////////////////////////////////////////////////////////
|
||||
// Just a simple test for now.
|
||||
|
||||
hsBool plPageInfo::IsValid( void ) const
|
||||
{
|
||||
return fLocation.IsValid();
|
||||
}
|
||||
|
@ -1,96 +1,96 @@
|
||||
/*==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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// plPageInfo - Pack of info about an individual page
|
||||
//
|
||||
|
||||
#ifndef _plPageInfo_h
|
||||
#define _plPageInfo_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "pnKeyedObject/plUoid.h"
|
||||
#include <vector>
|
||||
|
||||
class hsStream;
|
||||
class plLocation;
|
||||
class plPageInfo
|
||||
{
|
||||
public:
|
||||
struct ClassVersion { UInt16 Class; UInt16 Version; };
|
||||
typedef std::vector<ClassVersion> ClassVerVec;
|
||||
|
||||
protected:
|
||||
plLocation fLocation;
|
||||
char* fAge;
|
||||
char* fPage;
|
||||
UInt16 fMajorVersion;
|
||||
ClassVerVec fClassVersions;
|
||||
UInt32 fChecksum;
|
||||
UInt32 fDataStart, fIndexStart;
|
||||
|
||||
void IInit( void );
|
||||
void ISetFrom( const plPageInfo &src );
|
||||
|
||||
public:
|
||||
|
||||
plPageInfo();
|
||||
plPageInfo( const plLocation &loc );
|
||||
plPageInfo( const plPageInfo &src );
|
||||
virtual ~plPageInfo();
|
||||
|
||||
const char* GetAge() const { return fAge; }
|
||||
const char* GetPage() const { return fPage; }
|
||||
|
||||
plPageInfo &operator=( const plPageInfo &src );
|
||||
|
||||
void ClearClassVersions() { fClassVersions.clear(); }
|
||||
void AddClassVersion(UInt16 classIdx, UInt16 version);
|
||||
const ClassVerVec& GetClassVersions() const { return fClassVersions; }
|
||||
|
||||
void SetStrings( const char *age, const char *page );
|
||||
|
||||
void SetLocation(const plLocation& loc);
|
||||
const plLocation& GetLocation() const;
|
||||
|
||||
UInt16 GetMajorVersion() const { return fMajorVersion; }
|
||||
void SetMajorVersion(UInt16 major) { fMajorVersion = major; }
|
||||
|
||||
void SetChecksum( UInt32 c ) { fChecksum = c; }
|
||||
UInt32 GetChecksum( void ) const { return fChecksum; }
|
||||
|
||||
void Read( hsStream *s );
|
||||
void Write( hsStream *s );
|
||||
|
||||
hsBool IsValid( void ) const;
|
||||
|
||||
UInt32 GetDataStart( void ) const { return fDataStart; }
|
||||
void SetDataStart( UInt32 s ) { fDataStart = s; }
|
||||
|
||||
UInt32 GetIndexStart( void ) const { return fIndexStart; }
|
||||
void SetIndexStart( UInt32 s ) { fIndexStart = s; }
|
||||
};
|
||||
#endif // _plPageInfo_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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// plPageInfo - Pack of info about an individual page
|
||||
//
|
||||
|
||||
#ifndef _plPageInfo_h
|
||||
#define _plPageInfo_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "pnKeyedObject/plUoid.h"
|
||||
#include <vector>
|
||||
|
||||
class hsStream;
|
||||
class plLocation;
|
||||
class plPageInfo
|
||||
{
|
||||
public:
|
||||
struct ClassVersion { UInt16 Class; UInt16 Version; };
|
||||
typedef std::vector<ClassVersion> ClassVerVec;
|
||||
|
||||
protected:
|
||||
plLocation fLocation;
|
||||
char* fAge;
|
||||
char* fPage;
|
||||
UInt16 fMajorVersion;
|
||||
ClassVerVec fClassVersions;
|
||||
UInt32 fChecksum;
|
||||
UInt32 fDataStart, fIndexStart;
|
||||
|
||||
void IInit( void );
|
||||
void ISetFrom( const plPageInfo &src );
|
||||
|
||||
public:
|
||||
|
||||
plPageInfo();
|
||||
plPageInfo( const plLocation &loc );
|
||||
plPageInfo( const plPageInfo &src );
|
||||
virtual ~plPageInfo();
|
||||
|
||||
const char* GetAge() const { return fAge; }
|
||||
const char* GetPage() const { return fPage; }
|
||||
|
||||
plPageInfo &operator=( const plPageInfo &src );
|
||||
|
||||
void ClearClassVersions() { fClassVersions.clear(); }
|
||||
void AddClassVersion(UInt16 classIdx, UInt16 version);
|
||||
const ClassVerVec& GetClassVersions() const { return fClassVersions; }
|
||||
|
||||
void SetStrings( const char *age, const char *page );
|
||||
|
||||
void SetLocation(const plLocation& loc);
|
||||
const plLocation& GetLocation() const;
|
||||
|
||||
UInt16 GetMajorVersion() const { return fMajorVersion; }
|
||||
void SetMajorVersion(UInt16 major) { fMajorVersion = major; }
|
||||
|
||||
void SetChecksum( UInt32 c ) { fChecksum = c; }
|
||||
UInt32 GetChecksum( void ) const { return fChecksum; }
|
||||
|
||||
void Read( hsStream *s );
|
||||
void Write( hsStream *s );
|
||||
|
||||
hsBool IsValid( void ) const;
|
||||
|
||||
UInt32 GetDataStart( void ) const { return fDataStart; }
|
||||
void SetDataStart( UInt32 s ) { fDataStart = s; }
|
||||
|
||||
UInt32 GetIndexStart( void ) const { return fIndexStart; }
|
||||
void SetIndexStart( UInt32 s ) { fIndexStart = s; }
|
||||
};
|
||||
#endif // _plPageInfo_h
|
||||
|
@ -1,43 +1,43 @@
|
||||
/*==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 "plRegistryHelpers.h"
|
||||
#include "plRegistryNode.h"
|
||||
|
||||
plKeyCollector::plKeyCollector( hsTArray<plKey> &keys ) : fKeys( keys )
|
||||
{
|
||||
}
|
||||
|
||||
hsBool plKeyCollector::EatKey(const plKey& key)
|
||||
{
|
||||
fKeys.Append(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plIndirectUnloadIterator::EatPage(plRegistryPageNode* page)
|
||||
{
|
||||
page->IterateKeys(this);
|
||||
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 "plRegistryHelpers.h"
|
||||
#include "plRegistryNode.h"
|
||||
|
||||
plKeyCollector::plKeyCollector( hsTArray<plKey> &keys ) : fKeys( keys )
|
||||
{
|
||||
}
|
||||
|
||||
hsBool plKeyCollector::EatKey(const plKey& key)
|
||||
{
|
||||
fKeys.Append(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plIndirectUnloadIterator::EatPage(plRegistryPageNode* page)
|
||||
{
|
||||
page->IterateKeys(this);
|
||||
return true;
|
||||
}
|
@ -1,86 +1,86 @@
|
||||
/*==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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// plRegistryHelpers - Little helper classes for the registry and resManager
|
||||
//
|
||||
//// History /////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 3.25.2002 mcn - Created
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plRegistryHelpers_h
|
||||
#define _plRegistryHelpers_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsTemplates.h"
|
||||
#include "pnKeyedObject/plKey.h"
|
||||
|
||||
class plKey;
|
||||
class plRegistryPageNode;
|
||||
|
||||
//// Little Iterator Class Defs //////////////////////////////////////////////
|
||||
|
||||
class plRegistryKeyIterator
|
||||
{
|
||||
public:
|
||||
virtual ~plRegistryKeyIterator() {}
|
||||
virtual hsBool EatKey(const plKey& key) = 0;
|
||||
};
|
||||
|
||||
class plRegistryPageIterator
|
||||
{
|
||||
public:
|
||||
virtual ~plRegistryPageIterator() {}
|
||||
virtual hsBool EatPage(plRegistryPageNode* keyNode) = 0;
|
||||
};
|
||||
|
||||
|
||||
//// plKeyCollector //////////////////////////////////////////////////////////
|
||||
// Helper key iterator that collects the given keys into the given hsTArray
|
||||
class plKeyCollector : public plRegistryKeyIterator
|
||||
{
|
||||
protected:
|
||||
hsTArray<plKey> &fKeys;
|
||||
|
||||
public:
|
||||
plKeyCollector(hsTArray<plKey>& keys);
|
||||
virtual hsBool EatKey(const plKey& key);
|
||||
};
|
||||
|
||||
// If you loaded keys with another iterator, this will ensure that they're unloaded
|
||||
class plIndirectUnloadIterator : public plRegistryPageIterator, public plRegistryKeyIterator
|
||||
{
|
||||
public:
|
||||
plIndirectUnloadIterator() {}
|
||||
|
||||
hsBool EatKey(const plKey& key) { return true; }
|
||||
|
||||
hsBool EatPage(plRegistryPageNode* page);
|
||||
};
|
||||
|
||||
#endif // _plRegistryHelpers_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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// plRegistryHelpers - Little helper classes for the registry and resManager
|
||||
//
|
||||
//// History /////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 3.25.2002 mcn - Created
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plRegistryHelpers_h
|
||||
#define _plRegistryHelpers_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsTemplates.h"
|
||||
#include "pnKeyedObject/plKey.h"
|
||||
|
||||
class plKey;
|
||||
class plRegistryPageNode;
|
||||
|
||||
//// Little Iterator Class Defs //////////////////////////////////////////////
|
||||
|
||||
class plRegistryKeyIterator
|
||||
{
|
||||
public:
|
||||
virtual ~plRegistryKeyIterator() {}
|
||||
virtual hsBool EatKey(const plKey& key) = 0;
|
||||
};
|
||||
|
||||
class plRegistryPageIterator
|
||||
{
|
||||
public:
|
||||
virtual ~plRegistryPageIterator() {}
|
||||
virtual hsBool EatPage(plRegistryPageNode* keyNode) = 0;
|
||||
};
|
||||
|
||||
|
||||
//// plKeyCollector //////////////////////////////////////////////////////////
|
||||
// Helper key iterator that collects the given keys into the given hsTArray
|
||||
class plKeyCollector : public plRegistryKeyIterator
|
||||
{
|
||||
protected:
|
||||
hsTArray<plKey> &fKeys;
|
||||
|
||||
public:
|
||||
plKeyCollector(hsTArray<plKey>& keys);
|
||||
virtual hsBool EatKey(const plKey& key);
|
||||
};
|
||||
|
||||
// If you loaded keys with another iterator, this will ensure that they're unloaded
|
||||
class plIndirectUnloadIterator : public plRegistryPageIterator, public plRegistryKeyIterator
|
||||
{
|
||||
public:
|
||||
plIndirectUnloadIterator() {}
|
||||
|
||||
hsBool EatKey(const plKey& key) { return true; }
|
||||
|
||||
hsBool EatPage(plRegistryPageNode* page);
|
||||
};
|
||||
|
||||
#endif // _plRegistryHelpers_h
|
||||
|
@ -1,347 +1,347 @@
|
||||
/*==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 "plRegistryKeyList.h"
|
||||
#include "plRegistryHelpers.h"
|
||||
#include "hsStream.h"
|
||||
#include <algorithm>
|
||||
|
||||
plRegistryKeyList::plRegistryKeyList(UInt16 classType)
|
||||
{
|
||||
fClassType = classType;
|
||||
fReffedStaticKeys = 0;
|
||||
fLocked = 0;
|
||||
fFlags = 0;
|
||||
}
|
||||
|
||||
plRegistryKeyList::~plRegistryKeyList()
|
||||
{
|
||||
hsAssert(fLocked == 0, "Key list still locked on delete");
|
||||
|
||||
for (int i = 0; i < fStaticKeys.size(); i++)
|
||||
{
|
||||
plKeyImp* keyImp = fStaticKeys[i];
|
||||
if (!keyImp->ObjectIsLoaded())
|
||||
delete keyImp;
|
||||
}
|
||||
}
|
||||
|
||||
// Special dummy key that lets us set the return value of the GetName call.
|
||||
// Makes it easier to do STL searches.
|
||||
class plSearchKeyImp : public plKeyImp
|
||||
{
|
||||
public:
|
||||
const char* fSearchKeyName;
|
||||
const char* GetName() const { return fSearchKeyName; }
|
||||
};
|
||||
|
||||
plKeyImp* plRegistryKeyList::FindKey(const char* keyName)
|
||||
{
|
||||
static plSearchKeyImp searchKey;
|
||||
searchKey.fSearchKeyName = keyName;
|
||||
|
||||
// Search the static key list
|
||||
if (fFlags & kStaticUnsorted)
|
||||
{
|
||||
// We're unsorted, brute force it. May do a separate search table in the
|
||||
// future if this is a bottlneck
|
||||
for (int i = 0; i < fStaticKeys.size(); i++)
|
||||
{
|
||||
plKeyImp* curKey = fStaticKeys[i];
|
||||
if (curKey && hsStrCaseEQ(keyName, curKey->GetName()))
|
||||
return curKey;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We're sorted, do a fast lookup
|
||||
StaticVec::const_iterator it = std::lower_bound(fStaticKeys.begin(), fStaticKeys.end(), &searchKey, KeySorter());
|
||||
if (it != fStaticKeys.end() && hsStrCaseEQ(keyName, (*it)->GetName()))
|
||||
return *it;
|
||||
}
|
||||
|
||||
// Search the dynamic key list
|
||||
DynSet::const_iterator dynIt = fDynamicKeys.find(&searchKey);
|
||||
if (dynIt != fDynamicKeys.end())
|
||||
return *dynIt;
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
plKeyImp* plRegistryKeyList::FindKey(const plUoid& uoid)
|
||||
{
|
||||
UInt32 objectID = uoid.GetObjectID();
|
||||
|
||||
// Key is dynamic or doesn't know it's index. Do a find by name.
|
||||
if (objectID == 0)
|
||||
return FindKey(uoid.GetObjectName());
|
||||
|
||||
// Direct lookup
|
||||
if (objectID <= fStaticKeys.size())
|
||||
{
|
||||
#ifdef PLASMA_EXTERNAL_RELEASE
|
||||
return fStaticKeys[objectID-1];
|
||||
#else
|
||||
// If this is an internal release, our objectIDs might not match
|
||||
// because of local data. Verify that we have the right key by
|
||||
// name, and if it's wrong, do the slower find-by-name.
|
||||
plKeyImp *keyImp = fStaticKeys[objectID-1];
|
||||
if (!hsStrCaseEQ(keyImp->GetName(), uoid.GetObjectName()))
|
||||
return FindKey(uoid.GetObjectName());
|
||||
else
|
||||
return keyImp;
|
||||
#endif // PLASMA_EXTERNAL_RELEASE
|
||||
}
|
||||
|
||||
// If we got here it probably means we just deleted all our keys of the matching type
|
||||
// because no one was using them. No worries. The resManager will catch this and
|
||||
// reload our keys, then try again.
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
void plRegistryKeyList::ILock()
|
||||
{
|
||||
fLocked++;
|
||||
}
|
||||
|
||||
void plRegistryKeyList::IUnlock()
|
||||
{
|
||||
fLocked--;
|
||||
if (fLocked == 0)
|
||||
IRepack();
|
||||
}
|
||||
|
||||
bool plRegistryKeyList::IterateKeys(plRegistryKeyIterator* iterator)
|
||||
{
|
||||
ILock();
|
||||
|
||||
for (int i = 0; i < fStaticKeys.size(); i++)
|
||||
{
|
||||
plKeyImp* keyImp = fStaticKeys[i];
|
||||
if (keyImp != nil)
|
||||
{
|
||||
if (!iterator->EatKey(plKey::Make(keyImp)))
|
||||
{
|
||||
IUnlock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DynSet::const_iterator it;
|
||||
for (it = fDynamicKeys.begin(); it != fDynamicKeys.end(); it++)
|
||||
{
|
||||
plKeyImp* keyImp = *it;
|
||||
hsAssert(keyImp, "Shouldn't ever have a nil dynamic key");
|
||||
if (!iterator->EatKey(plKey::Make(keyImp)))
|
||||
{
|
||||
IUnlock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
IUnlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
void plRegistryKeyList::AddKey(plKeyImp* key, LoadStatus& loadStatusChange)
|
||||
{
|
||||
loadStatusChange = kNoChange;
|
||||
|
||||
hsAssert(fLocked == 0, "Don't currently support adding keys while locked");
|
||||
if (fLocked == 0 && key != nil)
|
||||
{
|
||||
// If this is the first key added, we just became loaded
|
||||
if (fDynamicKeys.empty())
|
||||
loadStatusChange = kDynLoaded;
|
||||
|
||||
hsAssert(fDynamicKeys.find(key) == fDynamicKeys.end(), "Key already added");
|
||||
fDynamicKeys.insert(key);
|
||||
}
|
||||
}
|
||||
|
||||
void plRegistryKeyList::SetKeyUsed(plKeyImp* key)
|
||||
{
|
||||
// If this is a static key, mark that we used it. Otherwise, just ignore it.
|
||||
UInt32 id = key->GetUoid().GetObjectID();
|
||||
if (id > 0)
|
||||
fReffedStaticKeys++;
|
||||
}
|
||||
|
||||
bool plRegistryKeyList::SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange)
|
||||
{
|
||||
loadStatusChange = kNoChange;
|
||||
|
||||
// Clones never officially get added to the key list (they're maintained by
|
||||
// the original key), so just ignore them
|
||||
if (key->GetUoid().IsClone())
|
||||
{
|
||||
delete key;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if it's a static key
|
||||
UInt32 id = key->GetUoid().GetObjectID();
|
||||
hsAssert(id <= fStaticKeys.size(), "Bad static key id");
|
||||
if (id != 0 && id <= fStaticKeys.size())
|
||||
{
|
||||
fReffedStaticKeys--;
|
||||
if (fLocked == 0)
|
||||
IRepack();
|
||||
|
||||
// That was our last used static key, we're static unloaded
|
||||
if (fReffedStaticKeys == 0)
|
||||
loadStatusChange = kStaticUnloaded;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to find it in the dynamic key list
|
||||
DynSet::iterator dynIt = fDynamicKeys.find(key);
|
||||
if (dynIt != fDynamicKeys.end())
|
||||
{
|
||||
hsAssert(fLocked == 0, "Don't currently support removing dynamic keys while locked");
|
||||
if (fLocked == 0)
|
||||
{
|
||||
fDynamicKeys.erase(dynIt);
|
||||
delete key;
|
||||
|
||||
// That was our last dynamic key, notify of dynamic unloaded
|
||||
if (fDynamicKeys.empty())
|
||||
loadStatusChange = kDynUnloaded;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
hsAssert(0, "Couldn't find this key, what is it?");
|
||||
return false;
|
||||
}
|
||||
|
||||
//// IRepack /////////////////////////////////////////////////////////////////
|
||||
// Frees the memory for our static key array if none of them are loaded
|
||||
void plRegistryKeyList::IRepack()
|
||||
{
|
||||
if (fReffedStaticKeys == 0 && !fStaticKeys.empty())
|
||||
{
|
||||
|
||||
for (int i = 0; i < fStaticKeys.size(); i++)
|
||||
delete fStaticKeys[i];
|
||||
|
||||
fStaticKeys.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void plRegistryKeyList::PrepForWrite()
|
||||
{
|
||||
// If we have any static keys already, we were read in. To keep from
|
||||
// invalidating old key indexes any new keys have to go on the end, hence we're
|
||||
// unsorted now.
|
||||
if (!fStaticKeys.empty())
|
||||
fFlags |= kStaticUnsorted;
|
||||
|
||||
// If a dynamic keys doesn't have an object assigned to it, we're not writing
|
||||
// it out. Figure out how many valid keys we have.
|
||||
int numDynKeys = 0;
|
||||
DynSet::const_iterator cIt;
|
||||
for (cIt = fDynamicKeys.begin(); cIt != fDynamicKeys.end(); cIt++)
|
||||
{
|
||||
plKeyImp* key = *cIt;
|
||||
// We're only going to write out keys that have objects
|
||||
if (key->ObjectIsLoaded())
|
||||
numDynKeys++;
|
||||
}
|
||||
|
||||
// Start our new object id's after any already created ones
|
||||
UInt32 objectID = fStaticKeys.size()+1;
|
||||
// Make room for our new keys
|
||||
fStaticKeys.resize(fStaticKeys.size()+numDynKeys);
|
||||
|
||||
DynSet::iterator it = fDynamicKeys.begin();
|
||||
while (it != fDynamicKeys.end())
|
||||
{
|
||||
plKeyImp* key = *it;
|
||||
it++;
|
||||
|
||||
// If we're gonna use this key, tag it with it's object id and move it to the static array.
|
||||
if (key->ObjectIsLoaded())
|
||||
{
|
||||
key->SetObjectID(objectID);
|
||||
fStaticKeys[objectID-1] = key;
|
||||
|
||||
objectID++;
|
||||
fReffedStaticKeys++;
|
||||
fDynamicKeys.erase(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plRegistryKeyList::Read(hsStream* s)
|
||||
{
|
||||
UInt32 keyListLen = s->ReadSwap32();
|
||||
if (!fStaticKeys.empty())
|
||||
{
|
||||
s->Skip(keyListLen);
|
||||
return;
|
||||
}
|
||||
|
||||
fFlags = s->ReadByte();
|
||||
|
||||
UInt32 numKeys = s->ReadSwap32();
|
||||
fStaticKeys.resize(numKeys);
|
||||
|
||||
for (int i = 0; i < numKeys; i++)
|
||||
{
|
||||
plKeyImp* newKey = TRACKED_NEW plKeyImp;
|
||||
newKey->Read(s);
|
||||
fStaticKeys[i] = newKey;
|
||||
}
|
||||
}
|
||||
|
||||
void plRegistryKeyList::Write(hsStream* s)
|
||||
{
|
||||
// Save space for the length of our data
|
||||
UInt32 beginPos = s->GetPosition();
|
||||
s->WriteSwap32(0);
|
||||
s->WriteByte(fFlags);
|
||||
|
||||
int numKeys = fStaticKeys.size();
|
||||
s->WriteSwap32(numKeys);
|
||||
|
||||
// Write out all our keys (anything in dynamic is unused, so just ignore those)
|
||||
for (int i = 0; i < numKeys; i++)
|
||||
{
|
||||
plKeyImp* key = fStaticKeys[i];
|
||||
key->Write(s);
|
||||
}
|
||||
|
||||
// Go back to the start and write the length of our data
|
||||
UInt32 endPos = s->GetPosition();
|
||||
s->SetPosition(beginPos);
|
||||
s->WriteSwap32(endPos-beginPos-sizeof(UInt32));
|
||||
s->SetPosition(endPos);
|
||||
}
|
||||
/*==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 "plRegistryKeyList.h"
|
||||
#include "plRegistryHelpers.h"
|
||||
#include "hsStream.h"
|
||||
#include <algorithm>
|
||||
|
||||
plRegistryKeyList::plRegistryKeyList(UInt16 classType)
|
||||
{
|
||||
fClassType = classType;
|
||||
fReffedStaticKeys = 0;
|
||||
fLocked = 0;
|
||||
fFlags = 0;
|
||||
}
|
||||
|
||||
plRegistryKeyList::~plRegistryKeyList()
|
||||
{
|
||||
hsAssert(fLocked == 0, "Key list still locked on delete");
|
||||
|
||||
for (int i = 0; i < fStaticKeys.size(); i++)
|
||||
{
|
||||
plKeyImp* keyImp = fStaticKeys[i];
|
||||
if (!keyImp->ObjectIsLoaded())
|
||||
delete keyImp;
|
||||
}
|
||||
}
|
||||
|
||||
// Special dummy key that lets us set the return value of the GetName call.
|
||||
// Makes it easier to do STL searches.
|
||||
class plSearchKeyImp : public plKeyImp
|
||||
{
|
||||
public:
|
||||
const char* fSearchKeyName;
|
||||
const char* GetName() const { return fSearchKeyName; }
|
||||
};
|
||||
|
||||
plKeyImp* plRegistryKeyList::FindKey(const char* keyName)
|
||||
{
|
||||
static plSearchKeyImp searchKey;
|
||||
searchKey.fSearchKeyName = keyName;
|
||||
|
||||
// Search the static key list
|
||||
if (fFlags & kStaticUnsorted)
|
||||
{
|
||||
// We're unsorted, brute force it. May do a separate search table in the
|
||||
// future if this is a bottlneck
|
||||
for (int i = 0; i < fStaticKeys.size(); i++)
|
||||
{
|
||||
plKeyImp* curKey = fStaticKeys[i];
|
||||
if (curKey && hsStrCaseEQ(keyName, curKey->GetName()))
|
||||
return curKey;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We're sorted, do a fast lookup
|
||||
StaticVec::const_iterator it = std::lower_bound(fStaticKeys.begin(), fStaticKeys.end(), &searchKey, KeySorter());
|
||||
if (it != fStaticKeys.end() && hsStrCaseEQ(keyName, (*it)->GetName()))
|
||||
return *it;
|
||||
}
|
||||
|
||||
// Search the dynamic key list
|
||||
DynSet::const_iterator dynIt = fDynamicKeys.find(&searchKey);
|
||||
if (dynIt != fDynamicKeys.end())
|
||||
return *dynIt;
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
plKeyImp* plRegistryKeyList::FindKey(const plUoid& uoid)
|
||||
{
|
||||
UInt32 objectID = uoid.GetObjectID();
|
||||
|
||||
// Key is dynamic or doesn't know it's index. Do a find by name.
|
||||
if (objectID == 0)
|
||||
return FindKey(uoid.GetObjectName());
|
||||
|
||||
// Direct lookup
|
||||
if (objectID <= fStaticKeys.size())
|
||||
{
|
||||
#ifdef PLASMA_EXTERNAL_RELEASE
|
||||
return fStaticKeys[objectID-1];
|
||||
#else
|
||||
// If this is an internal release, our objectIDs might not match
|
||||
// because of local data. Verify that we have the right key by
|
||||
// name, and if it's wrong, do the slower find-by-name.
|
||||
plKeyImp *keyImp = fStaticKeys[objectID-1];
|
||||
if (!hsStrCaseEQ(keyImp->GetName(), uoid.GetObjectName()))
|
||||
return FindKey(uoid.GetObjectName());
|
||||
else
|
||||
return keyImp;
|
||||
#endif // PLASMA_EXTERNAL_RELEASE
|
||||
}
|
||||
|
||||
// If we got here it probably means we just deleted all our keys of the matching type
|
||||
// because no one was using them. No worries. The resManager will catch this and
|
||||
// reload our keys, then try again.
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
void plRegistryKeyList::ILock()
|
||||
{
|
||||
fLocked++;
|
||||
}
|
||||
|
||||
void plRegistryKeyList::IUnlock()
|
||||
{
|
||||
fLocked--;
|
||||
if (fLocked == 0)
|
||||
IRepack();
|
||||
}
|
||||
|
||||
bool plRegistryKeyList::IterateKeys(plRegistryKeyIterator* iterator)
|
||||
{
|
||||
ILock();
|
||||
|
||||
for (int i = 0; i < fStaticKeys.size(); i++)
|
||||
{
|
||||
plKeyImp* keyImp = fStaticKeys[i];
|
||||
if (keyImp != nil)
|
||||
{
|
||||
if (!iterator->EatKey(plKey::Make(keyImp)))
|
||||
{
|
||||
IUnlock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DynSet::const_iterator it;
|
||||
for (it = fDynamicKeys.begin(); it != fDynamicKeys.end(); it++)
|
||||
{
|
||||
plKeyImp* keyImp = *it;
|
||||
hsAssert(keyImp, "Shouldn't ever have a nil dynamic key");
|
||||
if (!iterator->EatKey(plKey::Make(keyImp)))
|
||||
{
|
||||
IUnlock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
IUnlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
void plRegistryKeyList::AddKey(plKeyImp* key, LoadStatus& loadStatusChange)
|
||||
{
|
||||
loadStatusChange = kNoChange;
|
||||
|
||||
hsAssert(fLocked == 0, "Don't currently support adding keys while locked");
|
||||
if (fLocked == 0 && key != nil)
|
||||
{
|
||||
// If this is the first key added, we just became loaded
|
||||
if (fDynamicKeys.empty())
|
||||
loadStatusChange = kDynLoaded;
|
||||
|
||||
hsAssert(fDynamicKeys.find(key) == fDynamicKeys.end(), "Key already added");
|
||||
fDynamicKeys.insert(key);
|
||||
}
|
||||
}
|
||||
|
||||
void plRegistryKeyList::SetKeyUsed(plKeyImp* key)
|
||||
{
|
||||
// If this is a static key, mark that we used it. Otherwise, just ignore it.
|
||||
UInt32 id = key->GetUoid().GetObjectID();
|
||||
if (id > 0)
|
||||
fReffedStaticKeys++;
|
||||
}
|
||||
|
||||
bool plRegistryKeyList::SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange)
|
||||
{
|
||||
loadStatusChange = kNoChange;
|
||||
|
||||
// Clones never officially get added to the key list (they're maintained by
|
||||
// the original key), so just ignore them
|
||||
if (key->GetUoid().IsClone())
|
||||
{
|
||||
delete key;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if it's a static key
|
||||
UInt32 id = key->GetUoid().GetObjectID();
|
||||
hsAssert(id <= fStaticKeys.size(), "Bad static key id");
|
||||
if (id != 0 && id <= fStaticKeys.size())
|
||||
{
|
||||
fReffedStaticKeys--;
|
||||
if (fLocked == 0)
|
||||
IRepack();
|
||||
|
||||
// That was our last used static key, we're static unloaded
|
||||
if (fReffedStaticKeys == 0)
|
||||
loadStatusChange = kStaticUnloaded;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to find it in the dynamic key list
|
||||
DynSet::iterator dynIt = fDynamicKeys.find(key);
|
||||
if (dynIt != fDynamicKeys.end())
|
||||
{
|
||||
hsAssert(fLocked == 0, "Don't currently support removing dynamic keys while locked");
|
||||
if (fLocked == 0)
|
||||
{
|
||||
fDynamicKeys.erase(dynIt);
|
||||
delete key;
|
||||
|
||||
// That was our last dynamic key, notify of dynamic unloaded
|
||||
if (fDynamicKeys.empty())
|
||||
loadStatusChange = kDynUnloaded;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
hsAssert(0, "Couldn't find this key, what is it?");
|
||||
return false;
|
||||
}
|
||||
|
||||
//// IRepack /////////////////////////////////////////////////////////////////
|
||||
// Frees the memory for our static key array if none of them are loaded
|
||||
void plRegistryKeyList::IRepack()
|
||||
{
|
||||
if (fReffedStaticKeys == 0 && !fStaticKeys.empty())
|
||||
{
|
||||
|
||||
for (int i = 0; i < fStaticKeys.size(); i++)
|
||||
delete fStaticKeys[i];
|
||||
|
||||
fStaticKeys.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void plRegistryKeyList::PrepForWrite()
|
||||
{
|
||||
// If we have any static keys already, we were read in. To keep from
|
||||
// invalidating old key indexes any new keys have to go on the end, hence we're
|
||||
// unsorted now.
|
||||
if (!fStaticKeys.empty())
|
||||
fFlags |= kStaticUnsorted;
|
||||
|
||||
// If a dynamic keys doesn't have an object assigned to it, we're not writing
|
||||
// it out. Figure out how many valid keys we have.
|
||||
int numDynKeys = 0;
|
||||
DynSet::const_iterator cIt;
|
||||
for (cIt = fDynamicKeys.begin(); cIt != fDynamicKeys.end(); cIt++)
|
||||
{
|
||||
plKeyImp* key = *cIt;
|
||||
// We're only going to write out keys that have objects
|
||||
if (key->ObjectIsLoaded())
|
||||
numDynKeys++;
|
||||
}
|
||||
|
||||
// Start our new object id's after any already created ones
|
||||
UInt32 objectID = fStaticKeys.size()+1;
|
||||
// Make room for our new keys
|
||||
fStaticKeys.resize(fStaticKeys.size()+numDynKeys);
|
||||
|
||||
DynSet::iterator it = fDynamicKeys.begin();
|
||||
while (it != fDynamicKeys.end())
|
||||
{
|
||||
plKeyImp* key = *it;
|
||||
it++;
|
||||
|
||||
// If we're gonna use this key, tag it with it's object id and move it to the static array.
|
||||
if (key->ObjectIsLoaded())
|
||||
{
|
||||
key->SetObjectID(objectID);
|
||||
fStaticKeys[objectID-1] = key;
|
||||
|
||||
objectID++;
|
||||
fReffedStaticKeys++;
|
||||
fDynamicKeys.erase(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plRegistryKeyList::Read(hsStream* s)
|
||||
{
|
||||
UInt32 keyListLen = s->ReadSwap32();
|
||||
if (!fStaticKeys.empty())
|
||||
{
|
||||
s->Skip(keyListLen);
|
||||
return;
|
||||
}
|
||||
|
||||
fFlags = s->ReadByte();
|
||||
|
||||
UInt32 numKeys = s->ReadSwap32();
|
||||
fStaticKeys.resize(numKeys);
|
||||
|
||||
for (int i = 0; i < numKeys; i++)
|
||||
{
|
||||
plKeyImp* newKey = TRACKED_NEW plKeyImp;
|
||||
newKey->Read(s);
|
||||
fStaticKeys[i] = newKey;
|
||||
}
|
||||
}
|
||||
|
||||
void plRegistryKeyList::Write(hsStream* s)
|
||||
{
|
||||
// Save space for the length of our data
|
||||
UInt32 beginPos = s->GetPosition();
|
||||
s->WriteSwap32(0);
|
||||
s->WriteByte(fFlags);
|
||||
|
||||
int numKeys = fStaticKeys.size();
|
||||
s->WriteSwap32(numKeys);
|
||||
|
||||
// Write out all our keys (anything in dynamic is unused, so just ignore those)
|
||||
for (int i = 0; i < numKeys; i++)
|
||||
{
|
||||
plKeyImp* key = fStaticKeys[i];
|
||||
key->Write(s);
|
||||
}
|
||||
|
||||
// Go back to the start and write the length of our data
|
||||
UInt32 endPos = s->GetPosition();
|
||||
s->SetPosition(beginPos);
|
||||
s->WriteSwap32(endPos-beginPos-sizeof(UInt32));
|
||||
s->SetPosition(endPos);
|
||||
}
|
||||
|
@ -1,113 +1,113 @@
|
||||
/*==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 plRegistryKeyList_h_inc
|
||||
#define plRegistryKeyList_h_inc
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "pnKeyedObject/plKeyImp.h"
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
class plRegistryKeyIterator;
|
||||
|
||||
class KeySorter
|
||||
{
|
||||
public:
|
||||
bool operator() (plKeyImp* k1, plKeyImp* k2) const
|
||||
{
|
||||
hsAssert(k1 && k2, "Should have valid keys here");
|
||||
return stricmp(k1->GetName(), k2->GetName()) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// List of keys for a single class type.
|
||||
//
|
||||
class plRegistryKeyList
|
||||
{
|
||||
protected:
|
||||
friend class plKeyFinder;
|
||||
|
||||
UInt16 fClassType;
|
||||
// Lock counter for iterating. If this is >0, don't do any ops that
|
||||
// can change key positions in the array (instead, just leave holes)
|
||||
UInt16 fLocked;
|
||||
|
||||
enum Flags { kStaticUnsorted = 0x1 };
|
||||
UInt8 fFlags;
|
||||
|
||||
// Static keys are one's we read off disk. These don't change and are
|
||||
// assumed to be already sorted when they're read in.
|
||||
typedef std::vector<plKeyImp*> StaticVec;
|
||||
StaticVec fStaticKeys;
|
||||
UInt32 fReffedStaticKeys; // Number of static keys that are loaded
|
||||
|
||||
// Dynamic keys are anything created at runtime. They are put in the
|
||||
// correct sorted position when they are added
|
||||
typedef std::set<plKeyImp*, KeySorter> DynSet;
|
||||
DynSet fDynamicKeys;
|
||||
|
||||
plRegistryKeyList() {}
|
||||
|
||||
void ILock();
|
||||
void IUnlock();
|
||||
|
||||
void IRepack();
|
||||
|
||||
public:
|
||||
plRegistryKeyList(UInt16 classType);
|
||||
~plRegistryKeyList();
|
||||
|
||||
UInt16 GetClassType() const { return fClassType; }
|
||||
|
||||
// Find a key by name (case-insensitive)
|
||||
plKeyImp* FindKey(const char* keyName);
|
||||
// Find a key by uoid index.
|
||||
plKeyImp* FindKey(const plUoid& uoid);
|
||||
|
||||
bool IterateKeys(plRegistryKeyIterator* iterator);
|
||||
|
||||
// Changes in our load status that can be caused by loading or unloading a key
|
||||
enum LoadStatus
|
||||
{
|
||||
kNoChange,
|
||||
kDynLoaded,
|
||||
kDynUnloaded,
|
||||
kStaticUnloaded,
|
||||
};
|
||||
void AddKey(plKeyImp* key, LoadStatus& loadStatusChange);
|
||||
void SetKeyUsed(plKeyImp* key);
|
||||
bool SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange);
|
||||
|
||||
// Export time only. Before we write to disk, assign all the static keys
|
||||
// object ID's that they can use to do fast lookups at load time.
|
||||
void PrepForWrite();
|
||||
|
||||
void Read(hsStream* s);
|
||||
void Write(hsStream* s);
|
||||
};
|
||||
|
||||
#endif // plRegistryKeyList_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 plRegistryKeyList_h_inc
|
||||
#define plRegistryKeyList_h_inc
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "pnKeyedObject/plKeyImp.h"
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
class plRegistryKeyIterator;
|
||||
|
||||
class KeySorter
|
||||
{
|
||||
public:
|
||||
bool operator() (plKeyImp* k1, plKeyImp* k2) const
|
||||
{
|
||||
hsAssert(k1 && k2, "Should have valid keys here");
|
||||
return stricmp(k1->GetName(), k2->GetName()) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// List of keys for a single class type.
|
||||
//
|
||||
class plRegistryKeyList
|
||||
{
|
||||
protected:
|
||||
friend class plKeyFinder;
|
||||
|
||||
UInt16 fClassType;
|
||||
// Lock counter for iterating. If this is >0, don't do any ops that
|
||||
// can change key positions in the array (instead, just leave holes)
|
||||
UInt16 fLocked;
|
||||
|
||||
enum Flags { kStaticUnsorted = 0x1 };
|
||||
UInt8 fFlags;
|
||||
|
||||
// Static keys are one's we read off disk. These don't change and are
|
||||
// assumed to be already sorted when they're read in.
|
||||
typedef std::vector<plKeyImp*> StaticVec;
|
||||
StaticVec fStaticKeys;
|
||||
UInt32 fReffedStaticKeys; // Number of static keys that are loaded
|
||||
|
||||
// Dynamic keys are anything created at runtime. They are put in the
|
||||
// correct sorted position when they are added
|
||||
typedef std::set<plKeyImp*, KeySorter> DynSet;
|
||||
DynSet fDynamicKeys;
|
||||
|
||||
plRegistryKeyList() {}
|
||||
|
||||
void ILock();
|
||||
void IUnlock();
|
||||
|
||||
void IRepack();
|
||||
|
||||
public:
|
||||
plRegistryKeyList(UInt16 classType);
|
||||
~plRegistryKeyList();
|
||||
|
||||
UInt16 GetClassType() const { return fClassType; }
|
||||
|
||||
// Find a key by name (case-insensitive)
|
||||
plKeyImp* FindKey(const char* keyName);
|
||||
// Find a key by uoid index.
|
||||
plKeyImp* FindKey(const plUoid& uoid);
|
||||
|
||||
bool IterateKeys(plRegistryKeyIterator* iterator);
|
||||
|
||||
// Changes in our load status that can be caused by loading or unloading a key
|
||||
enum LoadStatus
|
||||
{
|
||||
kNoChange,
|
||||
kDynLoaded,
|
||||
kDynUnloaded,
|
||||
kStaticUnloaded,
|
||||
};
|
||||
void AddKey(plKeyImp* key, LoadStatus& loadStatusChange);
|
||||
void SetKeyUsed(plKeyImp* key);
|
||||
bool SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange);
|
||||
|
||||
// Export time only. Before we write to disk, assign all the static keys
|
||||
// object ID's that they can use to do fast lookups at load time.
|
||||
void PrepForWrite();
|
||||
|
||||
void Read(hsStream* s);
|
||||
void Write(hsStream* s);
|
||||
};
|
||||
|
||||
#endif // plRegistryKeyList_h_inc
|
||||
|
@ -1,403 +1,403 @@
|
||||
/*==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 "plRegistryNode.h"
|
||||
#include "plRegistryKeyList.h"
|
||||
#include "plRegistryHelpers.h"
|
||||
|
||||
#include "pnKeyedObject/plKeyImp.h"
|
||||
#include "plStatusLog/plStatusLog.h"
|
||||
#include "pnFactory/plFactory.h"
|
||||
#include "plFile/plFileUtils.h"
|
||||
#include "hsStlUtils.h"
|
||||
|
||||
#include "plVersion.h"
|
||||
|
||||
plRegistryPageNode::plRegistryPageNode(const char* path)
|
||||
: fValid(kPageCorrupt)
|
||||
, fPath(nil)
|
||||
, fDynLoadedTypes(0)
|
||||
, fStaticLoadedTypes(0)
|
||||
, fOpenRequests(0)
|
||||
, fIsNewPage(false)
|
||||
{
|
||||
fPath = hsStrcpy(path);
|
||||
|
||||
hsStream* stream = OpenStream();
|
||||
if (stream)
|
||||
{
|
||||
fPageInfo.Read(&fStream);
|
||||
fValid = IVerify();
|
||||
CloseStream();
|
||||
}
|
||||
}
|
||||
|
||||
plRegistryPageNode::plRegistryPageNode(const plLocation& location, const char* age, const char* page, const char* dataPath)
|
||||
: fValid(kPageOk)
|
||||
, fPath(nil)
|
||||
, fPageInfo(location)
|
||||
, fDynLoadedTypes(0)
|
||||
, fStaticLoadedTypes(0)
|
||||
, fOpenRequests(0)
|
||||
, fIsNewPage(true)
|
||||
{
|
||||
fPageInfo.SetStrings(age, page);
|
||||
|
||||
char filePath[512];
|
||||
|
||||
// Copy the path over
|
||||
strncpy(filePath, dataPath, sizeof(filePath));
|
||||
plFileUtils::AddSlash(filePath);
|
||||
|
||||
// Time to construct our actual file name. For now, we'll use the same old format
|
||||
// of age_page.extension
|
||||
strncat(filePath, fPageInfo.GetAge(), sizeof(filePath));
|
||||
strncat(filePath, "_District_", sizeof(filePath));
|
||||
strncat(filePath, fPageInfo.GetPage(), sizeof(filePath));
|
||||
strncat(filePath, ".prp", sizeof(filePath));
|
||||
|
||||
fPath = hsStrcpy(filePath);
|
||||
}
|
||||
|
||||
plRegistryPageNode::~plRegistryPageNode()
|
||||
{
|
||||
delete [] fPath;
|
||||
UnloadKeys();
|
||||
}
|
||||
|
||||
PageCond plRegistryPageNode::IVerify()
|
||||
{
|
||||
// Check the checksum values first, to make sure the files aren't corrupt
|
||||
UInt32 ourChecksum = 0;
|
||||
hsStream* stream = OpenStream();
|
||||
if (stream)
|
||||
{
|
||||
ourChecksum = stream->GetEOF() - fPageInfo.GetDataStart();
|
||||
CloseStream();
|
||||
}
|
||||
if (ourChecksum != fPageInfo.GetChecksum())
|
||||
return kPageCorrupt;
|
||||
|
||||
// If major version out-of-date, entire location is screwed
|
||||
if (fPageInfo.GetMajorVersion() > plVersion::GetMajorVersion())
|
||||
return kPageTooNew;
|
||||
else if (fPageInfo.GetMajorVersion() < plVersion::GetMajorVersion())
|
||||
return kPageOutOfDate;
|
||||
|
||||
// Check the minor versions
|
||||
const plPageInfo::ClassVerVec& classVersions = fPageInfo.GetClassVersions();
|
||||
for (int i = 0; i < classVersions.size(); i++)
|
||||
{
|
||||
const plPageInfo::ClassVersion& cv = classVersions[i];
|
||||
UInt16 curVersion = plVersion::GetCreatableVersion(cv.Class);
|
||||
|
||||
if (curVersion > cv.Version)
|
||||
return kPageOutOfDate;
|
||||
else if (curVersion < cv.Version)
|
||||
return kPageTooNew;
|
||||
}
|
||||
|
||||
return kPageOk;
|
||||
}
|
||||
|
||||
hsStream* plRegistryPageNode::OpenStream()
|
||||
{
|
||||
if (fOpenRequests == 0)
|
||||
{
|
||||
if (!fStream.Open(fPath, "rb"))
|
||||
return nil;
|
||||
}
|
||||
fOpenRequests++;
|
||||
return &fStream;
|
||||
}
|
||||
|
||||
void plRegistryPageNode::CloseStream()
|
||||
{
|
||||
if (fOpenRequests > 0)
|
||||
fOpenRequests--;
|
||||
|
||||
if (fOpenRequests == 0)
|
||||
fStream.Close();
|
||||
}
|
||||
|
||||
void plRegistryPageNode::LoadKeys()
|
||||
{
|
||||
hsAssert(IsValid(), "Trying to load keys for invalid page");
|
||||
hsAssert(!fIsNewPage, "Trying to read a new page");
|
||||
if (IsFullyLoaded())
|
||||
return;
|
||||
|
||||
hsStream* stream = OpenStream();
|
||||
if (!stream)
|
||||
{
|
||||
hsAssert(0, xtl::format("plRegistryPageNode::LoadKeysFromSource - bad stream %s,%s",
|
||||
GetPageInfo().GetAge(), GetPageInfo().GetPage()).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're loading keys in the middle of a read because FindKey() failed, we'd better
|
||||
// make note of our stream position and restore it when we're done.
|
||||
UInt32 oldPos = stream->GetPosition();
|
||||
stream->SetPosition(GetPageInfo().GetIndexStart());
|
||||
|
||||
// Read in the number of key types
|
||||
UInt32 numTypes = stream->ReadSwap32();
|
||||
for (UInt32 i = 0; i < numTypes; i++)
|
||||
{
|
||||
UInt16 classType = stream->ReadSwap16();
|
||||
plRegistryKeyList* keyList = IGetKeyList(classType);
|
||||
if (!keyList)
|
||||
{
|
||||
keyList = TRACKED_NEW plRegistryKeyList(classType);
|
||||
fKeyLists[classType] = keyList;
|
||||
}
|
||||
keyList->Read(stream);
|
||||
}
|
||||
|
||||
stream->SetPosition(oldPos);
|
||||
CloseStream();
|
||||
fStaticLoadedTypes = fKeyLists.size();
|
||||
}
|
||||
|
||||
void plRegistryPageNode::UnloadKeys()
|
||||
{
|
||||
KeyMap::iterator it = fKeyLists.begin();
|
||||
for (; it != fKeyLists.end(); it++)
|
||||
{
|
||||
plRegistryKeyList* keyList = it->second;
|
||||
delete keyList;
|
||||
}
|
||||
fKeyLists.clear();
|
||||
|
||||
fDynLoadedTypes = 0;
|
||||
fStaticLoadedTypes = 0;
|
||||
}
|
||||
|
||||
//// plWriteIterator /////////////////////////////////////////////////////////
|
||||
// Key iterator for writing objects
|
||||
class plWriteIterator : public plRegistryKeyIterator
|
||||
{
|
||||
protected:
|
||||
hsStream* fStream;
|
||||
|
||||
public:
|
||||
plWriteIterator(hsStream* s) : fStream(s) {}
|
||||
|
||||
virtual hsBool EatKey(const plKey& key)
|
||||
{
|
||||
plKeyImp* imp = (plKeyImp*)key;
|
||||
imp->WriteObject(fStream);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void plRegistryPageNode::Write()
|
||||
{
|
||||
hsAssert(fOpenRequests == 0, "Trying to write while the page is open for reading");
|
||||
|
||||
if (!fStream.Open(fPath, "wb"))
|
||||
{
|
||||
hsAssert(0, "Couldn't open file for writing");
|
||||
return;
|
||||
}
|
||||
|
||||
// Some prep stuff. Assign object IDs for every key in this page, and put the
|
||||
// versions of all our creatable types in the pageinfo.
|
||||
fPageInfo.ClearClassVersions();
|
||||
|
||||
KeyMap::const_iterator it;
|
||||
for (it = fKeyLists.begin(); it != fKeyLists.end(); it++)
|
||||
{
|
||||
plRegistryKeyList* keyList = it->second;
|
||||
keyList->PrepForWrite();
|
||||
|
||||
int ver = plVersion::GetCreatableVersion(keyList->GetClassType());
|
||||
fPageInfo.AddClassVersion(keyList->GetClassType(), ver);
|
||||
}
|
||||
|
||||
// First thing we write is the pageinfo. Later we'll rewind and overwrite this with the final values
|
||||
fPageInfo.Write(&fStream);
|
||||
|
||||
fPageInfo.SetDataStart(fStream.GetPosition());
|
||||
|
||||
// Write all our objects
|
||||
plWriteIterator writer(&fStream);
|
||||
IterateKeys(&writer);
|
||||
|
||||
fPageInfo.SetIndexStart(fStream.GetPosition());
|
||||
|
||||
// Write our keys
|
||||
fStream.WriteSwap32(fKeyLists.size());
|
||||
for (it = fKeyLists.begin(); it != fKeyLists.end(); it++)
|
||||
{
|
||||
plRegistryKeyList* keyList = it->second;
|
||||
fStream.WriteSwap16(keyList->GetClassType());
|
||||
keyList->Write(&fStream);
|
||||
}
|
||||
|
||||
// Rewind and write the pageinfo with the correct data and index offsets
|
||||
fStream.Rewind();
|
||||
fPageInfo.SetChecksum(fStream.GetEOF() - fPageInfo.GetDataStart());
|
||||
fPageInfo.Write(&fStream);
|
||||
|
||||
fStream.Close();
|
||||
}
|
||||
|
||||
//// IterateKeys /////////////////////////////////////////////////////////////
|
||||
|
||||
hsBool plRegistryPageNode::IterateKeys(plRegistryKeyIterator* iterator) const
|
||||
{
|
||||
KeyMap::const_iterator it = fKeyLists.begin();
|
||||
for (; it != fKeyLists.end(); it++)
|
||||
{
|
||||
plRegistryKeyList* keyList = it->second;
|
||||
if (!keyList->IterateKeys(iterator))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//// IterateKeys /////////////////////////////////////////////////////////////
|
||||
// Restricted version that only iterates through the keys of a given class
|
||||
// type.
|
||||
|
||||
hsBool plRegistryPageNode::IterateKeys(plRegistryKeyIterator* iterator, UInt16 classToRestrictTo) const
|
||||
{
|
||||
plRegistryKeyList* keyList = IGetKeyList(classToRestrictTo);
|
||||
if (keyList != nil)
|
||||
return keyList->IterateKeys(iterator);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
plKeyImp* plRegistryPageNode::FindKey(UInt16 classType, const char* name) const
|
||||
{
|
||||
plRegistryKeyList* keys = IGetKeyList(classType);
|
||||
if (keys == nil)
|
||||
return nil;
|
||||
|
||||
return keys->FindKey(name);
|
||||
}
|
||||
|
||||
plKeyImp* plRegistryPageNode::FindKey(const plUoid& uoid) const
|
||||
{
|
||||
plRegistryKeyList* keys = IGetKeyList(uoid.GetClassType());
|
||||
if (keys == nil)
|
||||
return nil;
|
||||
|
||||
return keys->FindKey(uoid);
|
||||
}
|
||||
|
||||
void plRegistryPageNode::AddKey(plKeyImp* key)
|
||||
{
|
||||
UInt16 classType = key->GetUoid().GetClassType();
|
||||
plRegistryKeyList* keys = fKeyLists[classType];
|
||||
if (keys == nil)
|
||||
{
|
||||
keys = TRACKED_NEW plRegistryKeyList(classType);
|
||||
fKeyLists[classType] = keys;
|
||||
}
|
||||
|
||||
// Error check
|
||||
if (keys->FindKey(key->GetUoid().GetObjectName()) != nil)
|
||||
{
|
||||
//char str[512], tempStr[128];
|
||||
//sprintf(str, "Attempting to add a key with a duplicate name. Not allowed."
|
||||
// "\n\n(Key name: %s, Class: %s, Loc: %s)", key->GetUoid().GetObjectName(),
|
||||
// plFactory::GetNameOfClass(classType), key->GetUoid().GetLocation().StringIze(tempStr));
|
||||
//hsStatusMessage(str);
|
||||
hsBool recovered = false;
|
||||
|
||||
// Attempt recovery
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
char tempName[512];
|
||||
sprintf(tempName, "%s%d", key->GetUoid().GetObjectName(), i);
|
||||
if (keys->FindKey(tempName) == nil)
|
||||
{
|
||||
plUoid uoid(key->GetUoid().GetLocation(), key->GetUoid().GetClassType(), tempName, key->GetUoid().GetLoadMask());
|
||||
key->SetUoid(uoid);
|
||||
recovered = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!recovered)
|
||||
{
|
||||
hsAssert(0, "Couldn't allocate a unique key");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
plRegistryKeyList::LoadStatus loadStatusChange;
|
||||
keys->AddKey(key, loadStatusChange);
|
||||
|
||||
if (loadStatusChange == plRegistryKeyList::kDynLoaded)
|
||||
fDynLoadedTypes++;
|
||||
}
|
||||
|
||||
void plRegistryPageNode::SetKeyUsed(plKeyImp* key)
|
||||
{
|
||||
plRegistryKeyList* keys = IGetKeyList(key->GetUoid().GetClassType());
|
||||
if (keys == nil)
|
||||
return;
|
||||
|
||||
keys->SetKeyUsed(key);
|
||||
}
|
||||
|
||||
hsBool plRegistryPageNode::SetKeyUnused(plKeyImp* key)
|
||||
{
|
||||
plRegistryKeyList* keys = IGetKeyList(key->GetUoid().GetClassType());
|
||||
if (keys == nil)
|
||||
return false;
|
||||
|
||||
plRegistryKeyList::LoadStatus loadStatusChange;
|
||||
hsBool removed = keys->SetKeyUnused(key, loadStatusChange);
|
||||
|
||||
// If the key type just changed load status, update our load counts
|
||||
if (loadStatusChange == plRegistryKeyList::kDynUnloaded)
|
||||
fDynLoadedTypes--;
|
||||
else if (loadStatusChange == plRegistryKeyList::kStaticUnloaded)
|
||||
fStaticLoadedTypes--;
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
plRegistryKeyList* plRegistryPageNode::IGetKeyList(UInt16 classType) const
|
||||
{
|
||||
KeyMap::const_iterator it = fKeyLists.find(classType);
|
||||
if (it != fKeyLists.end())
|
||||
return it->second;
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
void plRegistryPageNode::DeleteSource()
|
||||
{
|
||||
hsAssert(fOpenRequests == 0, "Deleting a stream that's open for reading");
|
||||
plFileUtils::RemoveFile(fPath);
|
||||
}
|
||||
|
||||
/*==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 "plRegistryNode.h"
|
||||
#include "plRegistryKeyList.h"
|
||||
#include "plRegistryHelpers.h"
|
||||
|
||||
#include "pnKeyedObject/plKeyImp.h"
|
||||
#include "plStatusLog/plStatusLog.h"
|
||||
#include "pnFactory/plFactory.h"
|
||||
#include "plFile/plFileUtils.h"
|
||||
#include "hsStlUtils.h"
|
||||
|
||||
#include "plVersion.h"
|
||||
|
||||
plRegistryPageNode::plRegistryPageNode(const char* path)
|
||||
: fValid(kPageCorrupt)
|
||||
, fPath(nil)
|
||||
, fDynLoadedTypes(0)
|
||||
, fStaticLoadedTypes(0)
|
||||
, fOpenRequests(0)
|
||||
, fIsNewPage(false)
|
||||
{
|
||||
fPath = hsStrcpy(path);
|
||||
|
||||
hsStream* stream = OpenStream();
|
||||
if (stream)
|
||||
{
|
||||
fPageInfo.Read(&fStream);
|
||||
fValid = IVerify();
|
||||
CloseStream();
|
||||
}
|
||||
}
|
||||
|
||||
plRegistryPageNode::plRegistryPageNode(const plLocation& location, const char* age, const char* page, const char* dataPath)
|
||||
: fValid(kPageOk)
|
||||
, fPath(nil)
|
||||
, fPageInfo(location)
|
||||
, fDynLoadedTypes(0)
|
||||
, fStaticLoadedTypes(0)
|
||||
, fOpenRequests(0)
|
||||
, fIsNewPage(true)
|
||||
{
|
||||
fPageInfo.SetStrings(age, page);
|
||||
|
||||
char filePath[512];
|
||||
|
||||
// Copy the path over
|
||||
strncpy(filePath, dataPath, sizeof(filePath));
|
||||
plFileUtils::AddSlash(filePath);
|
||||
|
||||
// Time to construct our actual file name. For now, we'll use the same old format
|
||||
// of age_page.extension
|
||||
strncat(filePath, fPageInfo.GetAge(), sizeof(filePath));
|
||||
strncat(filePath, "_District_", sizeof(filePath));
|
||||
strncat(filePath, fPageInfo.GetPage(), sizeof(filePath));
|
||||
strncat(filePath, ".prp", sizeof(filePath));
|
||||
|
||||
fPath = hsStrcpy(filePath);
|
||||
}
|
||||
|
||||
plRegistryPageNode::~plRegistryPageNode()
|
||||
{
|
||||
delete [] fPath;
|
||||
UnloadKeys();
|
||||
}
|
||||
|
||||
PageCond plRegistryPageNode::IVerify()
|
||||
{
|
||||
// Check the checksum values first, to make sure the files aren't corrupt
|
||||
UInt32 ourChecksum = 0;
|
||||
hsStream* stream = OpenStream();
|
||||
if (stream)
|
||||
{
|
||||
ourChecksum = stream->GetEOF() - fPageInfo.GetDataStart();
|
||||
CloseStream();
|
||||
}
|
||||
if (ourChecksum != fPageInfo.GetChecksum())
|
||||
return kPageCorrupt;
|
||||
|
||||
// If major version out-of-date, entire location is screwed
|
||||
if (fPageInfo.GetMajorVersion() > plVersion::GetMajorVersion())
|
||||
return kPageTooNew;
|
||||
else if (fPageInfo.GetMajorVersion() < plVersion::GetMajorVersion())
|
||||
return kPageOutOfDate;
|
||||
|
||||
// Check the minor versions
|
||||
const plPageInfo::ClassVerVec& classVersions = fPageInfo.GetClassVersions();
|
||||
for (int i = 0; i < classVersions.size(); i++)
|
||||
{
|
||||
const plPageInfo::ClassVersion& cv = classVersions[i];
|
||||
UInt16 curVersion = plVersion::GetCreatableVersion(cv.Class);
|
||||
|
||||
if (curVersion > cv.Version)
|
||||
return kPageOutOfDate;
|
||||
else if (curVersion < cv.Version)
|
||||
return kPageTooNew;
|
||||
}
|
||||
|
||||
return kPageOk;
|
||||
}
|
||||
|
||||
hsStream* plRegistryPageNode::OpenStream()
|
||||
{
|
||||
if (fOpenRequests == 0)
|
||||
{
|
||||
if (!fStream.Open(fPath, "rb"))
|
||||
return nil;
|
||||
}
|
||||
fOpenRequests++;
|
||||
return &fStream;
|
||||
}
|
||||
|
||||
void plRegistryPageNode::CloseStream()
|
||||
{
|
||||
if (fOpenRequests > 0)
|
||||
fOpenRequests--;
|
||||
|
||||
if (fOpenRequests == 0)
|
||||
fStream.Close();
|
||||
}
|
||||
|
||||
void plRegistryPageNode::LoadKeys()
|
||||
{
|
||||
hsAssert(IsValid(), "Trying to load keys for invalid page");
|
||||
hsAssert(!fIsNewPage, "Trying to read a new page");
|
||||
if (IsFullyLoaded())
|
||||
return;
|
||||
|
||||
hsStream* stream = OpenStream();
|
||||
if (!stream)
|
||||
{
|
||||
hsAssert(0, xtl::format("plRegistryPageNode::LoadKeysFromSource - bad stream %s,%s",
|
||||
GetPageInfo().GetAge(), GetPageInfo().GetPage()).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're loading keys in the middle of a read because FindKey() failed, we'd better
|
||||
// make note of our stream position and restore it when we're done.
|
||||
UInt32 oldPos = stream->GetPosition();
|
||||
stream->SetPosition(GetPageInfo().GetIndexStart());
|
||||
|
||||
// Read in the number of key types
|
||||
UInt32 numTypes = stream->ReadSwap32();
|
||||
for (UInt32 i = 0; i < numTypes; i++)
|
||||
{
|
||||
UInt16 classType = stream->ReadSwap16();
|
||||
plRegistryKeyList* keyList = IGetKeyList(classType);
|
||||
if (!keyList)
|
||||
{
|
||||
keyList = TRACKED_NEW plRegistryKeyList(classType);
|
||||
fKeyLists[classType] = keyList;
|
||||
}
|
||||
keyList->Read(stream);
|
||||
}
|
||||
|
||||
stream->SetPosition(oldPos);
|
||||
CloseStream();
|
||||
fStaticLoadedTypes = fKeyLists.size();
|
||||
}
|
||||
|
||||
void plRegistryPageNode::UnloadKeys()
|
||||
{
|
||||
KeyMap::iterator it = fKeyLists.begin();
|
||||
for (; it != fKeyLists.end(); it++)
|
||||
{
|
||||
plRegistryKeyList* keyList = it->second;
|
||||
delete keyList;
|
||||
}
|
||||
fKeyLists.clear();
|
||||
|
||||
fDynLoadedTypes = 0;
|
||||
fStaticLoadedTypes = 0;
|
||||
}
|
||||
|
||||
//// plWriteIterator /////////////////////////////////////////////////////////
|
||||
// Key iterator for writing objects
|
||||
class plWriteIterator : public plRegistryKeyIterator
|
||||
{
|
||||
protected:
|
||||
hsStream* fStream;
|
||||
|
||||
public:
|
||||
plWriteIterator(hsStream* s) : fStream(s) {}
|
||||
|
||||
virtual hsBool EatKey(const plKey& key)
|
||||
{
|
||||
plKeyImp* imp = (plKeyImp*)key;
|
||||
imp->WriteObject(fStream);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void plRegistryPageNode::Write()
|
||||
{
|
||||
hsAssert(fOpenRequests == 0, "Trying to write while the page is open for reading");
|
||||
|
||||
if (!fStream.Open(fPath, "wb"))
|
||||
{
|
||||
hsAssert(0, "Couldn't open file for writing");
|
||||
return;
|
||||
}
|
||||
|
||||
// Some prep stuff. Assign object IDs for every key in this page, and put the
|
||||
// versions of all our creatable types in the pageinfo.
|
||||
fPageInfo.ClearClassVersions();
|
||||
|
||||
KeyMap::const_iterator it;
|
||||
for (it = fKeyLists.begin(); it != fKeyLists.end(); it++)
|
||||
{
|
||||
plRegistryKeyList* keyList = it->second;
|
||||
keyList->PrepForWrite();
|
||||
|
||||
int ver = plVersion::GetCreatableVersion(keyList->GetClassType());
|
||||
fPageInfo.AddClassVersion(keyList->GetClassType(), ver);
|
||||
}
|
||||
|
||||
// First thing we write is the pageinfo. Later we'll rewind and overwrite this with the final values
|
||||
fPageInfo.Write(&fStream);
|
||||
|
||||
fPageInfo.SetDataStart(fStream.GetPosition());
|
||||
|
||||
// Write all our objects
|
||||
plWriteIterator writer(&fStream);
|
||||
IterateKeys(&writer);
|
||||
|
||||
fPageInfo.SetIndexStart(fStream.GetPosition());
|
||||
|
||||
// Write our keys
|
||||
fStream.WriteSwap32(fKeyLists.size());
|
||||
for (it = fKeyLists.begin(); it != fKeyLists.end(); it++)
|
||||
{
|
||||
plRegistryKeyList* keyList = it->second;
|
||||
fStream.WriteSwap16(keyList->GetClassType());
|
||||
keyList->Write(&fStream);
|
||||
}
|
||||
|
||||
// Rewind and write the pageinfo with the correct data and index offsets
|
||||
fStream.Rewind();
|
||||
fPageInfo.SetChecksum(fStream.GetEOF() - fPageInfo.GetDataStart());
|
||||
fPageInfo.Write(&fStream);
|
||||
|
||||
fStream.Close();
|
||||
}
|
||||
|
||||
//// IterateKeys /////////////////////////////////////////////////////////////
|
||||
|
||||
hsBool plRegistryPageNode::IterateKeys(plRegistryKeyIterator* iterator) const
|
||||
{
|
||||
KeyMap::const_iterator it = fKeyLists.begin();
|
||||
for (; it != fKeyLists.end(); it++)
|
||||
{
|
||||
plRegistryKeyList* keyList = it->second;
|
||||
if (!keyList->IterateKeys(iterator))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//// IterateKeys /////////////////////////////////////////////////////////////
|
||||
// Restricted version that only iterates through the keys of a given class
|
||||
// type.
|
||||
|
||||
hsBool plRegistryPageNode::IterateKeys(plRegistryKeyIterator* iterator, UInt16 classToRestrictTo) const
|
||||
{
|
||||
plRegistryKeyList* keyList = IGetKeyList(classToRestrictTo);
|
||||
if (keyList != nil)
|
||||
return keyList->IterateKeys(iterator);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
plKeyImp* plRegistryPageNode::FindKey(UInt16 classType, const char* name) const
|
||||
{
|
||||
plRegistryKeyList* keys = IGetKeyList(classType);
|
||||
if (keys == nil)
|
||||
return nil;
|
||||
|
||||
return keys->FindKey(name);
|
||||
}
|
||||
|
||||
plKeyImp* plRegistryPageNode::FindKey(const plUoid& uoid) const
|
||||
{
|
||||
plRegistryKeyList* keys = IGetKeyList(uoid.GetClassType());
|
||||
if (keys == nil)
|
||||
return nil;
|
||||
|
||||
return keys->FindKey(uoid);
|
||||
}
|
||||
|
||||
void plRegistryPageNode::AddKey(plKeyImp* key)
|
||||
{
|
||||
UInt16 classType = key->GetUoid().GetClassType();
|
||||
plRegistryKeyList* keys = fKeyLists[classType];
|
||||
if (keys == nil)
|
||||
{
|
||||
keys = TRACKED_NEW plRegistryKeyList(classType);
|
||||
fKeyLists[classType] = keys;
|
||||
}
|
||||
|
||||
// Error check
|
||||
if (keys->FindKey(key->GetUoid().GetObjectName()) != nil)
|
||||
{
|
||||
//char str[512], tempStr[128];
|
||||
//sprintf(str, "Attempting to add a key with a duplicate name. Not allowed."
|
||||
// "\n\n(Key name: %s, Class: %s, Loc: %s)", key->GetUoid().GetObjectName(),
|
||||
// plFactory::GetNameOfClass(classType), key->GetUoid().GetLocation().StringIze(tempStr));
|
||||
//hsStatusMessage(str);
|
||||
hsBool recovered = false;
|
||||
|
||||
// Attempt recovery
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
char tempName[512];
|
||||
sprintf(tempName, "%s%d", key->GetUoid().GetObjectName(), i);
|
||||
if (keys->FindKey(tempName) == nil)
|
||||
{
|
||||
plUoid uoid(key->GetUoid().GetLocation(), key->GetUoid().GetClassType(), tempName, key->GetUoid().GetLoadMask());
|
||||
key->SetUoid(uoid);
|
||||
recovered = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!recovered)
|
||||
{
|
||||
hsAssert(0, "Couldn't allocate a unique key");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
plRegistryKeyList::LoadStatus loadStatusChange;
|
||||
keys->AddKey(key, loadStatusChange);
|
||||
|
||||
if (loadStatusChange == plRegistryKeyList::kDynLoaded)
|
||||
fDynLoadedTypes++;
|
||||
}
|
||||
|
||||
void plRegistryPageNode::SetKeyUsed(plKeyImp* key)
|
||||
{
|
||||
plRegistryKeyList* keys = IGetKeyList(key->GetUoid().GetClassType());
|
||||
if (keys == nil)
|
||||
return;
|
||||
|
||||
keys->SetKeyUsed(key);
|
||||
}
|
||||
|
||||
hsBool plRegistryPageNode::SetKeyUnused(plKeyImp* key)
|
||||
{
|
||||
plRegistryKeyList* keys = IGetKeyList(key->GetUoid().GetClassType());
|
||||
if (keys == nil)
|
||||
return false;
|
||||
|
||||
plRegistryKeyList::LoadStatus loadStatusChange;
|
||||
hsBool removed = keys->SetKeyUnused(key, loadStatusChange);
|
||||
|
||||
// If the key type just changed load status, update our load counts
|
||||
if (loadStatusChange == plRegistryKeyList::kDynUnloaded)
|
||||
fDynLoadedTypes--;
|
||||
else if (loadStatusChange == plRegistryKeyList::kStaticUnloaded)
|
||||
fStaticLoadedTypes--;
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
plRegistryKeyList* plRegistryPageNode::IGetKeyList(UInt16 classType) const
|
||||
{
|
||||
KeyMap::const_iterator it = fKeyLists.find(classType);
|
||||
if (it != fKeyLists.end())
|
||||
return it->second;
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
void plRegistryPageNode::DeleteSource()
|
||||
{
|
||||
hsAssert(fOpenRequests == 0, "Deleting a stream that's open for reading");
|
||||
plFileUtils::RemoveFile(fPath);
|
||||
}
|
||||
|
||||
|
@ -1,132 +1,132 @@
|
||||
/*==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 plRegistryNode_h_inc
|
||||
#define plRegistryNode_h_inc
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsStream.h"
|
||||
#include "plPageInfo.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
class plRegistryKeyList;
|
||||
class hsStream;
|
||||
class plKeyImp;
|
||||
class plRegistryKeyIterator;
|
||||
|
||||
enum PageCond
|
||||
{
|
||||
kPageOk,
|
||||
kPageOutOfDate,
|
||||
kPageTooNew,
|
||||
kPageCorrupt,
|
||||
};
|
||||
|
||||
//
|
||||
// Represents one entire (age,page) location and contains all keys in that
|
||||
// location. Note: just because the node exists does not mean that the keys are loaded.
|
||||
//
|
||||
class plRegistryPageNode
|
||||
{
|
||||
protected:
|
||||
friend class plKeyFinder;
|
||||
|
||||
// Map from class type to a list of keys of that type
|
||||
typedef std::map<UInt16, plRegistryKeyList*> KeyMap;
|
||||
KeyMap fKeyLists;
|
||||
int fDynLoadedTypes; // The number of key types that have dynamic keys loaded
|
||||
int fStaticLoadedTypes; // The number of key types that have all their keys loaded
|
||||
|
||||
PageCond fValid; // Condition of the page
|
||||
char* fPath; // Path to the page file
|
||||
plPageInfo fPageInfo; // Info about this page
|
||||
|
||||
hsBufferedStream fStream; // Stream for reading/writing our page
|
||||
UInt8 fOpenRequests; // How many handles there are to fStream (or
|
||||
// zero if it's closed)
|
||||
hsBool fIsNewPage; // True if this page is new (not read off disk)
|
||||
|
||||
plRegistryPageNode() {}
|
||||
|
||||
inline plRegistryKeyList* IGetKeyList(UInt16 classType) const;
|
||||
PageCond IVerify();
|
||||
|
||||
public:
|
||||
// For reading a page off disk
|
||||
plRegistryPageNode(const char* path);
|
||||
|
||||
// For creating a new page.
|
||||
plRegistryPageNode(const plLocation& location, const char* age, const char* page, const char* dataPath);
|
||||
~plRegistryPageNode();
|
||||
|
||||
hsBool IsValid() const { return fValid == kPageOk; }
|
||||
PageCond GetPageCondition() { return fValid; }
|
||||
|
||||
// True if we have any static or dynamic keys loaded
|
||||
hsBool IsLoaded() const { return fDynLoadedTypes > 0 || fStaticLoadedTypes > 0; }
|
||||
// True if all of our static keys are loaded
|
||||
hsBool IsFullyLoaded() const { return (fStaticLoadedTypes == fKeyLists.size() && !fKeyLists.empty()) || fIsNewPage; }
|
||||
|
||||
// Export time only. If we want to reuse a page, load the keys we want then
|
||||
// call SetNewPage, so it will be considered a new page from now on. That
|
||||
// way we won't try to load it's keys again.
|
||||
hsBool IsNewPage() const { return fIsNewPage; }
|
||||
void SetNewPage() { fIsNewPage = true; }
|
||||
|
||||
const plPageInfo& GetPageInfo() const { return fPageInfo; }
|
||||
|
||||
void LoadKeys(); // Loads the keys off disk
|
||||
void UnloadKeys(); // Frees all our keys
|
||||
|
||||
// Find a key by type and name
|
||||
plKeyImp* FindKey(UInt16 classType, const char* name) const;
|
||||
// Find a key by direct uoid lookup (or fallback to name lookup if that doesn't work)
|
||||
plKeyImp* FindKey(const plUoid& uoid) const;
|
||||
|
||||
void AddKey(plKeyImp* key);
|
||||
|
||||
// Sets a key as used or unused, ie there aren't any refs to it anymore.
|
||||
// When all the static keys are unused we can free the memory associated with
|
||||
// them. When a dynamic key is unused we just delete it right away.
|
||||
void SetKeyUsed(plKeyImp* key);
|
||||
hsBool SetKeyUnused(plKeyImp* key);
|
||||
|
||||
hsBool IterateKeys(plRegistryKeyIterator* iterator) const;
|
||||
hsBool IterateKeys(plRegistryKeyIterator* iterator, UInt16 classToRestrictTo) const;
|
||||
|
||||
// Call this to get a read stream for the page. If a valid pointer is
|
||||
// returned, make sure to call CloseStream when you're done using it.
|
||||
hsStream* OpenStream();
|
||||
void CloseStream();
|
||||
|
||||
// Takes care of everything involved in writing this page to disk
|
||||
void Write();
|
||||
void DeleteSource();
|
||||
|
||||
const char* GetPagePath() const { return fPath; }
|
||||
};
|
||||
|
||||
#endif // plRegistryNode_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 plRegistryNode_h_inc
|
||||
#define plRegistryNode_h_inc
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsStream.h"
|
||||
#include "plPageInfo.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
class plRegistryKeyList;
|
||||
class hsStream;
|
||||
class plKeyImp;
|
||||
class plRegistryKeyIterator;
|
||||
|
||||
enum PageCond
|
||||
{
|
||||
kPageOk,
|
||||
kPageOutOfDate,
|
||||
kPageTooNew,
|
||||
kPageCorrupt,
|
||||
};
|
||||
|
||||
//
|
||||
// Represents one entire (age,page) location and contains all keys in that
|
||||
// location. Note: just because the node exists does not mean that the keys are loaded.
|
||||
//
|
||||
class plRegistryPageNode
|
||||
{
|
||||
protected:
|
||||
friend class plKeyFinder;
|
||||
|
||||
// Map from class type to a list of keys of that type
|
||||
typedef std::map<UInt16, plRegistryKeyList*> KeyMap;
|
||||
KeyMap fKeyLists;
|
||||
int fDynLoadedTypes; // The number of key types that have dynamic keys loaded
|
||||
int fStaticLoadedTypes; // The number of key types that have all their keys loaded
|
||||
|
||||
PageCond fValid; // Condition of the page
|
||||
char* fPath; // Path to the page file
|
||||
plPageInfo fPageInfo; // Info about this page
|
||||
|
||||
hsBufferedStream fStream; // Stream for reading/writing our page
|
||||
UInt8 fOpenRequests; // How many handles there are to fStream (or
|
||||
// zero if it's closed)
|
||||
hsBool fIsNewPage; // True if this page is new (not read off disk)
|
||||
|
||||
plRegistryPageNode() {}
|
||||
|
||||
inline plRegistryKeyList* IGetKeyList(UInt16 classType) const;
|
||||
PageCond IVerify();
|
||||
|
||||
public:
|
||||
// For reading a page off disk
|
||||
plRegistryPageNode(const char* path);
|
||||
|
||||
// For creating a new page.
|
||||
plRegistryPageNode(const plLocation& location, const char* age, const char* page, const char* dataPath);
|
||||
~plRegistryPageNode();
|
||||
|
||||
hsBool IsValid() const { return fValid == kPageOk; }
|
||||
PageCond GetPageCondition() { return fValid; }
|
||||
|
||||
// True if we have any static or dynamic keys loaded
|
||||
hsBool IsLoaded() const { return fDynLoadedTypes > 0 || fStaticLoadedTypes > 0; }
|
||||
// True if all of our static keys are loaded
|
||||
hsBool IsFullyLoaded() const { return (fStaticLoadedTypes == fKeyLists.size() && !fKeyLists.empty()) || fIsNewPage; }
|
||||
|
||||
// Export time only. If we want to reuse a page, load the keys we want then
|
||||
// call SetNewPage, so it will be considered a new page from now on. That
|
||||
// way we won't try to load it's keys again.
|
||||
hsBool IsNewPage() const { return fIsNewPage; }
|
||||
void SetNewPage() { fIsNewPage = true; }
|
||||
|
||||
const plPageInfo& GetPageInfo() const { return fPageInfo; }
|
||||
|
||||
void LoadKeys(); // Loads the keys off disk
|
||||
void UnloadKeys(); // Frees all our keys
|
||||
|
||||
// Find a key by type and name
|
||||
plKeyImp* FindKey(UInt16 classType, const char* name) const;
|
||||
// Find a key by direct uoid lookup (or fallback to name lookup if that doesn't work)
|
||||
plKeyImp* FindKey(const plUoid& uoid) const;
|
||||
|
||||
void AddKey(plKeyImp* key);
|
||||
|
||||
// Sets a key as used or unused, ie there aren't any refs to it anymore.
|
||||
// When all the static keys are unused we can free the memory associated with
|
||||
// them. When a dynamic key is unused we just delete it right away.
|
||||
void SetKeyUsed(plKeyImp* key);
|
||||
hsBool SetKeyUnused(plKeyImp* key);
|
||||
|
||||
hsBool IterateKeys(plRegistryKeyIterator* iterator) const;
|
||||
hsBool IterateKeys(plRegistryKeyIterator* iterator, UInt16 classToRestrictTo) const;
|
||||
|
||||
// Call this to get a read stream for the page. If a valid pointer is
|
||||
// returned, make sure to call CloseStream when you're done using it.
|
||||
hsStream* OpenStream();
|
||||
void CloseStream();
|
||||
|
||||
// Takes care of everything involved in writing this page to disk
|
||||
void Write();
|
||||
void DeleteSource();
|
||||
|
||||
const char* GetPagePath() const { return fPath; }
|
||||
};
|
||||
|
||||
#endif // plRegistryNode_h_inc
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,227 +1,227 @@
|
||||
/*==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 plResManager_h_inc
|
||||
#define plResManager_h_inc
|
||||
|
||||
#include "hsResMgr.h"
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class plRegistryPageNode;
|
||||
class plRegistryKeyIterator;
|
||||
class plRegistryPageIterator;
|
||||
class plRegistryDataStream;
|
||||
class plResAgeHolder;
|
||||
class plResManagerHelper;
|
||||
class plDispatch;
|
||||
|
||||
// plProgressProc is a proc called every time an object loads, to keep a progress bar for
|
||||
// loading ages up-to-date.
|
||||
typedef void(*plProgressProc)(plKey key);
|
||||
|
||||
class plResManager : public hsResMgr
|
||||
{
|
||||
public:
|
||||
plResManager();
|
||||
virtual ~plResManager();
|
||||
|
||||
// If the ResManager has already been initialized, you should call Reset after setting this
|
||||
void SetDataPath(const char* path) { fDataPath = path; }
|
||||
|
||||
// Mainly for external tools.
|
||||
void AddSinglePage(const char* path);
|
||||
plRegistryPageNode* FindSinglePage(const char* path) const;
|
||||
void RemoveSinglePage(const char* path);
|
||||
|
||||
//---------------------------
|
||||
// Load and Unload
|
||||
//---------------------------
|
||||
virtual void Load (const plKey& objKey); // places on list to be loaded
|
||||
virtual hsBool Unload(const plKey& objKey); // Unregisters (deletes) an object, Return true if successful
|
||||
virtual plKey CloneKey(const plKey& objKey);
|
||||
|
||||
//---------------------------
|
||||
// Finding Functions
|
||||
//---------------------------
|
||||
plKey FindOriginalKey(const plUoid&);
|
||||
virtual plKey FindKey(const plUoid&); // Same as above, but will check the uoid for clones
|
||||
const plLocation& FindLocation(const char* age, const char* page) const;
|
||||
// Use nil for any strings you don't need
|
||||
const void GetLocationStrings(const plLocation& loc, char* ageBuffer, char* pageBuffer) const;
|
||||
|
||||
//---------------------------
|
||||
// Establish reference linkage
|
||||
//---------------------------
|
||||
virtual hsBool AddViaNotify(const plKey& key, plRefMsg* msg, plRefFlags::Type flags);
|
||||
virtual hsBool AddViaNotify(plRefMsg* msg, plRefFlags::Type flags); // msg->fRef->GetKey() == sentKey
|
||||
|
||||
virtual hsBool SendRef(const plKey& key, plRefMsg* refMsg, plRefFlags::Type flags);
|
||||
virtual hsBool SendRef(hsKeyedObject* ko, plRefMsg* refMsg, plRefFlags::Type flags);
|
||||
|
||||
//---------------------------
|
||||
// Reding and Writing keys
|
||||
//---------------------------
|
||||
// Read a Key in, and Notify me when the Object is loaded
|
||||
virtual plKey ReadKeyNotifyMe(hsStream* stream, plRefMsg* retMsg, plRefFlags::Type flags);
|
||||
// Just read the Key data in and find a match in the registry and return it.
|
||||
virtual plKey ReadKey(hsStream* stream);
|
||||
|
||||
// For convenience you can write a key using the KeyedObject or the Key...same result
|
||||
virtual void WriteKey(hsStream* s, hsKeyedObject* obj);
|
||||
virtual void WriteKey(hsStream* s, const plKey& key);
|
||||
|
||||
//---------------------------
|
||||
// Reding and Writing Objects directly
|
||||
//---------------------------
|
||||
virtual plCreatable* ReadCreatable(hsStream* s);
|
||||
virtual void WriteCreatable(hsStream* s, plCreatable* cre);
|
||||
|
||||
virtual plCreatable* ReadCreatableVersion(hsStream* s);
|
||||
virtual void WriteCreatableVersion(hsStream* s, plCreatable* cre);
|
||||
|
||||
//---------------------------
|
||||
// Registry Modification Functions
|
||||
//---------------------------
|
||||
virtual plKey NewKey(const char* name, hsKeyedObject* object, const plLocation& loc, const plLoadMask& m = plLoadMask::kAlways);
|
||||
virtual plKey NewKey(plUoid& newUoid, hsKeyedObject* object);
|
||||
|
||||
virtual plDispatchBase* Dispatch();
|
||||
|
||||
virtual void SetProgressBarProc(plProgressProc proc);
|
||||
|
||||
//---------------------------
|
||||
// Load optimizations
|
||||
//---------------------------
|
||||
void LoadAgeKeys(const char* age);
|
||||
void DropAgeKeys(const char* age);
|
||||
void PageInRoom(const plLocation& page, UInt16 objClassToRef, plRefMsg* refMsg);
|
||||
void PageInAge(const char* age);
|
||||
|
||||
// Usually, a page file is kept open during load because the first keyed object
|
||||
// read causes all the other objects to be read before it returns. In some
|
||||
// cases though (mostly just the texture file), this doesn't work. In that
|
||||
// case, we just want to force it to stay open until we're done reading the age.
|
||||
void KeepPageOpen(const plLocation& page, hsBool keepOpen);
|
||||
|
||||
// We're on the way down, act accordingly.
|
||||
virtual void BeginShutdown();
|
||||
|
||||
// Determines whether the time to read each object is dumped to a log
|
||||
void LogReadTimes(hsBool logReadTimes);
|
||||
|
||||
// All keys version
|
||||
hsBool IterateKeys(plRegistryKeyIterator* iterator);
|
||||
// Single page version
|
||||
hsBool IterateKeys(plRegistryKeyIterator* iterator, const plLocation& pageToRestrictTo);
|
||||
// Iterate through loaded pages
|
||||
hsBool IteratePages(plRegistryPageIterator* iterator, const char* ageToRestrictTo = nil);
|
||||
// Iterate through ALL pages, loaded or not
|
||||
hsBool IterateAllPages(plRegistryPageIterator* iterator);
|
||||
|
||||
// Helpers for key iterators
|
||||
void LoadPageKeys(plRegistryPageNode* pageNode);
|
||||
void UnloadPageObjects(plRegistryPageNode* pageNode, UInt16 classIndexHint);
|
||||
void DumpUnusedKeys(plRegistryPageNode* page) const;
|
||||
plRegistryPageNode* FindPage(const plLocation& location) const;
|
||||
plRegistryPageNode* FindPage(const char* age, const char* page) const;
|
||||
|
||||
// Runs through all the pages and verifies that the data versions are good
|
||||
hsBool VerifyPages();
|
||||
|
||||
protected:
|
||||
friend class hsKeyedObject;
|
||||
friend class plKeyImp;
|
||||
friend class plResManagerHelper;
|
||||
|
||||
virtual plKey ReRegister(const char* nm, const plUoid& uoid);
|
||||
virtual hsBool ReadObject(plKeyImp* key); // plKeys call this when needed
|
||||
virtual hsBool IReadObject(plKeyImp* pKey, hsStream *stream);
|
||||
|
||||
plCreatable* IReadCreatable(hsStream* s) const;
|
||||
plKey ICloneKey(const plUoid& objUoid, UInt32 playerID, UInt32 cloneID);
|
||||
|
||||
virtual void IKeyReffed(plKeyImp* key);
|
||||
virtual void IKeyUnreffed(plKeyImp* key);
|
||||
|
||||
virtual hsBool IReset();
|
||||
virtual hsBool IInit();
|
||||
virtual void IShutdown();
|
||||
|
||||
void IPageOutSceneNodes(hsBool forceAll);
|
||||
void IDropAllAgeKeys();
|
||||
|
||||
hsKeyedObject* IGetSharedObject(plKeyImp* pKey);
|
||||
|
||||
void IUnloadPageKeys(plRegistryPageNode* pageNode, hsBool dontClear = false);
|
||||
|
||||
hsBool IDeleteBadPages(hsTArray<plRegistryPageNode*>& invalidPages, hsBool conflictingSeqNums);
|
||||
hsBool IWarnNewerPages(hsTArray<plRegistryPageNode*>& newerPages);
|
||||
|
||||
void ILockPages();
|
||||
void IUnlockPages();
|
||||
|
||||
void AddPage(plRegistryPageNode* page);
|
||||
|
||||
// Adds a key to the registry. Assumes uoid already set
|
||||
void AddKey(plKeyImp* key);
|
||||
|
||||
plRegistryPageNode* CreatePage(const plLocation& location, const char* age, const char* page);
|
||||
|
||||
hsBool fInited;
|
||||
UInt16 fPageOutHint;
|
||||
|
||||
// True if we're reading in an object. We only read one object at a time
|
||||
hsBool fReadingObject;
|
||||
std::vector<plKey> fQueuedReads;
|
||||
|
||||
std::string fDataPath;
|
||||
|
||||
plDispatch* fDispatch;
|
||||
|
||||
UInt32 fCurCloneID; // Current clone ID. If it isn't zero, we're cloning
|
||||
UInt32 fCurClonePlayerID;
|
||||
UInt32 fCloningCounter; // Next clone ID to use.
|
||||
|
||||
typedef std::map<std::string,plResAgeHolder*> HeldAgeKeyMap;
|
||||
HeldAgeKeyMap fHeldAgeKeys;
|
||||
plProgressProc fProgressProc;
|
||||
|
||||
plResManagerHelper *fMyHelper;
|
||||
|
||||
hsBool fLogReadTimes;
|
||||
|
||||
UInt8 fPageListLock; // Number of locks on the page lists. If it's greater than zero, they can't be modified
|
||||
hsBool fPagesNeedCleanup; // True if something modified the page lists while they were locked.
|
||||
|
||||
typedef std::set<plRegistryPageNode*> PageSet;
|
||||
PageSet fAllPages; // All the pages, loaded or not
|
||||
PageSet fLoadedPages; // Just the loaded pages
|
||||
|
||||
mutable plRegistryPageNode* fLastFoundPage;
|
||||
};
|
||||
|
||||
#endif // plResManager_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 plResManager_h_inc
|
||||
#define plResManager_h_inc
|
||||
|
||||
#include "hsResMgr.h"
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class plRegistryPageNode;
|
||||
class plRegistryKeyIterator;
|
||||
class plRegistryPageIterator;
|
||||
class plRegistryDataStream;
|
||||
class plResAgeHolder;
|
||||
class plResManagerHelper;
|
||||
class plDispatch;
|
||||
|
||||
// plProgressProc is a proc called every time an object loads, to keep a progress bar for
|
||||
// loading ages up-to-date.
|
||||
typedef void(*plProgressProc)(plKey key);
|
||||
|
||||
class plResManager : public hsResMgr
|
||||
{
|
||||
public:
|
||||
plResManager();
|
||||
virtual ~plResManager();
|
||||
|
||||
// If the ResManager has already been initialized, you should call Reset after setting this
|
||||
void SetDataPath(const char* path) { fDataPath = path; }
|
||||
|
||||
// Mainly for external tools.
|
||||
void AddSinglePage(const char* path);
|
||||
plRegistryPageNode* FindSinglePage(const char* path) const;
|
||||
void RemoveSinglePage(const char* path);
|
||||
|
||||
//---------------------------
|
||||
// Load and Unload
|
||||
//---------------------------
|
||||
virtual void Load (const plKey& objKey); // places on list to be loaded
|
||||
virtual hsBool Unload(const plKey& objKey); // Unregisters (deletes) an object, Return true if successful
|
||||
virtual plKey CloneKey(const plKey& objKey);
|
||||
|
||||
//---------------------------
|
||||
// Finding Functions
|
||||
//---------------------------
|
||||
plKey FindOriginalKey(const plUoid&);
|
||||
virtual plKey FindKey(const plUoid&); // Same as above, but will check the uoid for clones
|
||||
const plLocation& FindLocation(const char* age, const char* page) const;
|
||||
// Use nil for any strings you don't need
|
||||
const void GetLocationStrings(const plLocation& loc, char* ageBuffer, char* pageBuffer) const;
|
||||
|
||||
//---------------------------
|
||||
// Establish reference linkage
|
||||
//---------------------------
|
||||
virtual hsBool AddViaNotify(const plKey& key, plRefMsg* msg, plRefFlags::Type flags);
|
||||
virtual hsBool AddViaNotify(plRefMsg* msg, plRefFlags::Type flags); // msg->fRef->GetKey() == sentKey
|
||||
|
||||
virtual hsBool SendRef(const plKey& key, plRefMsg* refMsg, plRefFlags::Type flags);
|
||||
virtual hsBool SendRef(hsKeyedObject* ko, plRefMsg* refMsg, plRefFlags::Type flags);
|
||||
|
||||
//---------------------------
|
||||
// Reding and Writing keys
|
||||
//---------------------------
|
||||
// Read a Key in, and Notify me when the Object is loaded
|
||||
virtual plKey ReadKeyNotifyMe(hsStream* stream, plRefMsg* retMsg, plRefFlags::Type flags);
|
||||
// Just read the Key data in and find a match in the registry and return it.
|
||||
virtual plKey ReadKey(hsStream* stream);
|
||||
|
||||
// For convenience you can write a key using the KeyedObject or the Key...same result
|
||||
virtual void WriteKey(hsStream* s, hsKeyedObject* obj);
|
||||
virtual void WriteKey(hsStream* s, const plKey& key);
|
||||
|
||||
//---------------------------
|
||||
// Reding and Writing Objects directly
|
||||
//---------------------------
|
||||
virtual plCreatable* ReadCreatable(hsStream* s);
|
||||
virtual void WriteCreatable(hsStream* s, plCreatable* cre);
|
||||
|
||||
virtual plCreatable* ReadCreatableVersion(hsStream* s);
|
||||
virtual void WriteCreatableVersion(hsStream* s, plCreatable* cre);
|
||||
|
||||
//---------------------------
|
||||
// Registry Modification Functions
|
||||
//---------------------------
|
||||
virtual plKey NewKey(const char* name, hsKeyedObject* object, const plLocation& loc, const plLoadMask& m = plLoadMask::kAlways);
|
||||
virtual plKey NewKey(plUoid& newUoid, hsKeyedObject* object);
|
||||
|
||||
virtual plDispatchBase* Dispatch();
|
||||
|
||||
virtual void SetProgressBarProc(plProgressProc proc);
|
||||
|
||||
//---------------------------
|
||||
// Load optimizations
|
||||
//---------------------------
|
||||
void LoadAgeKeys(const char* age);
|
||||
void DropAgeKeys(const char* age);
|
||||
void PageInRoom(const plLocation& page, UInt16 objClassToRef, plRefMsg* refMsg);
|
||||
void PageInAge(const char* age);
|
||||
|
||||
// Usually, a page file is kept open during load because the first keyed object
|
||||
// read causes all the other objects to be read before it returns. In some
|
||||
// cases though (mostly just the texture file), this doesn't work. In that
|
||||
// case, we just want to force it to stay open until we're done reading the age.
|
||||
void KeepPageOpen(const plLocation& page, hsBool keepOpen);
|
||||
|
||||
// We're on the way down, act accordingly.
|
||||
virtual void BeginShutdown();
|
||||
|
||||
// Determines whether the time to read each object is dumped to a log
|
||||
void LogReadTimes(hsBool logReadTimes);
|
||||
|
||||
// All keys version
|
||||
hsBool IterateKeys(plRegistryKeyIterator* iterator);
|
||||
// Single page version
|
||||
hsBool IterateKeys(plRegistryKeyIterator* iterator, const plLocation& pageToRestrictTo);
|
||||
// Iterate through loaded pages
|
||||
hsBool IteratePages(plRegistryPageIterator* iterator, const char* ageToRestrictTo = nil);
|
||||
// Iterate through ALL pages, loaded or not
|
||||
hsBool IterateAllPages(plRegistryPageIterator* iterator);
|
||||
|
||||
// Helpers for key iterators
|
||||
void LoadPageKeys(plRegistryPageNode* pageNode);
|
||||
void UnloadPageObjects(plRegistryPageNode* pageNode, UInt16 classIndexHint);
|
||||
void DumpUnusedKeys(plRegistryPageNode* page) const;
|
||||
plRegistryPageNode* FindPage(const plLocation& location) const;
|
||||
plRegistryPageNode* FindPage(const char* age, const char* page) const;
|
||||
|
||||
// Runs through all the pages and verifies that the data versions are good
|
||||
hsBool VerifyPages();
|
||||
|
||||
protected:
|
||||
friend class hsKeyedObject;
|
||||
friend class plKeyImp;
|
||||
friend class plResManagerHelper;
|
||||
|
||||
virtual plKey ReRegister(const char* nm, const plUoid& uoid);
|
||||
virtual hsBool ReadObject(plKeyImp* key); // plKeys call this when needed
|
||||
virtual hsBool IReadObject(plKeyImp* pKey, hsStream *stream);
|
||||
|
||||
plCreatable* IReadCreatable(hsStream* s) const;
|
||||
plKey ICloneKey(const plUoid& objUoid, UInt32 playerID, UInt32 cloneID);
|
||||
|
||||
virtual void IKeyReffed(plKeyImp* key);
|
||||
virtual void IKeyUnreffed(plKeyImp* key);
|
||||
|
||||
virtual hsBool IReset();
|
||||
virtual hsBool IInit();
|
||||
virtual void IShutdown();
|
||||
|
||||
void IPageOutSceneNodes(hsBool forceAll);
|
||||
void IDropAllAgeKeys();
|
||||
|
||||
hsKeyedObject* IGetSharedObject(plKeyImp* pKey);
|
||||
|
||||
void IUnloadPageKeys(plRegistryPageNode* pageNode, hsBool dontClear = false);
|
||||
|
||||
hsBool IDeleteBadPages(hsTArray<plRegistryPageNode*>& invalidPages, hsBool conflictingSeqNums);
|
||||
hsBool IWarnNewerPages(hsTArray<plRegistryPageNode*>& newerPages);
|
||||
|
||||
void ILockPages();
|
||||
void IUnlockPages();
|
||||
|
||||
void AddPage(plRegistryPageNode* page);
|
||||
|
||||
// Adds a key to the registry. Assumes uoid already set
|
||||
void AddKey(plKeyImp* key);
|
||||
|
||||
plRegistryPageNode* CreatePage(const plLocation& location, const char* age, const char* page);
|
||||
|
||||
hsBool fInited;
|
||||
UInt16 fPageOutHint;
|
||||
|
||||
// True if we're reading in an object. We only read one object at a time
|
||||
hsBool fReadingObject;
|
||||
std::vector<plKey> fQueuedReads;
|
||||
|
||||
std::string fDataPath;
|
||||
|
||||
plDispatch* fDispatch;
|
||||
|
||||
UInt32 fCurCloneID; // Current clone ID. If it isn't zero, we're cloning
|
||||
UInt32 fCurClonePlayerID;
|
||||
UInt32 fCloningCounter; // Next clone ID to use.
|
||||
|
||||
typedef std::map<std::string,plResAgeHolder*> HeldAgeKeyMap;
|
||||
HeldAgeKeyMap fHeldAgeKeys;
|
||||
plProgressProc fProgressProc;
|
||||
|
||||
plResManagerHelper *fMyHelper;
|
||||
|
||||
hsBool fLogReadTimes;
|
||||
|
||||
UInt8 fPageListLock; // Number of locks on the page lists. If it's greater than zero, they can't be modified
|
||||
hsBool fPagesNeedCleanup; // True if something modified the page lists while they were locked.
|
||||
|
||||
typedef std::set<plRegistryPageNode*> PageSet;
|
||||
PageSet fAllPages; // All the pages, loaded or not
|
||||
PageSet fLoadedPages; // Just the loaded pages
|
||||
|
||||
mutable plRegistryPageNode* fLastFoundPage;
|
||||
};
|
||||
|
||||
#endif // plResManager_h_inc
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,130 +1,130 @@
|
||||
/*==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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// plResManagerHelper - The wonderful helper class that can receive messages
|
||||
// for the resManager.
|
||||
//
|
||||
//// History /////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 6.7.2002 mcn - Created
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plResManagerHelper_h
|
||||
#define _plResManagerHelper_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsTemplates.h"
|
||||
#include "plRegistryHelpers.h"
|
||||
#include "pnKeyedObject/hsKeyedObject.h"
|
||||
|
||||
// Defined as a project setting so we can do this right
|
||||
//#define MCN_RESMGR_DEBUGGING
|
||||
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef MCN_RESMGR_DEBUGGING
|
||||
class plStatusLog;
|
||||
class plDebugPrintIterator;
|
||||
class plResMgrDebugInterface;
|
||||
#endif
|
||||
|
||||
class plResManager;
|
||||
class plRegistryPageNode;
|
||||
class plResManagerHelper : public hsKeyedObject
|
||||
{
|
||||
protected:
|
||||
|
||||
plResManager *fResManager;
|
||||
static plResManagerHelper *fInstance;
|
||||
|
||||
hsBool fInShutdown;
|
||||
|
||||
#ifdef MCN_RESMGR_DEBUGGING
|
||||
friend class plDebugPrintIterator;
|
||||
friend class plResMgrDebugInterface;
|
||||
|
||||
plStatusLog *fDebugScreen;
|
||||
hsBool fRefreshing, fCurrAgeExpanded;
|
||||
int fCurrAge;
|
||||
int fDebugDisplayType;
|
||||
|
||||
enum DebugDisplayTypes
|
||||
{
|
||||
kSizes = 0,
|
||||
kPercents,
|
||||
kBars,
|
||||
kMaxDisplayType
|
||||
};
|
||||
plResMgrDebugInterface *fDebugInput;
|
||||
#endif
|
||||
|
||||
void IUpdateDebugScreen( hsBool force = false );
|
||||
|
||||
public:
|
||||
|
||||
plResManagerHelper( plResManager *resMgr );
|
||||
virtual ~plResManagerHelper();
|
||||
|
||||
CLASSNAME_REGISTER( plResManagerHelper );
|
||||
GETINTERFACE_ANY( plResManagerHelper, hsKeyedObject );
|
||||
|
||||
virtual hsBool MsgReceive( plMessage *msg );
|
||||
|
||||
virtual void Read( hsStream *s, hsResMgr *mgr );
|
||||
virtual void Write( hsStream *s, hsResMgr *mgr );
|
||||
|
||||
void Init( void );
|
||||
void Shutdown( void );
|
||||
|
||||
void LoadAndHoldPageKeys( plRegistryPageNode *page );
|
||||
|
||||
void EnableDebugScreen( hsBool enable );
|
||||
|
||||
// Please let the res manager handle telling this.
|
||||
void SetInShutdown(hsBool b) { fInShutdown = b; }
|
||||
hsBool GetInShutdown() const { return fInShutdown; }
|
||||
|
||||
static plResManagerHelper *GetInstance( void ) { return fInstance; }
|
||||
};
|
||||
|
||||
//// Reffer Class ////////////////////////////////////////////////////////////
|
||||
|
||||
class plResPageKeyRefList : public plKeyCollector
|
||||
{
|
||||
protected:
|
||||
|
||||
hsTArray<plKey> fKeyList;
|
||||
|
||||
public:
|
||||
|
||||
plResPageKeyRefList() : plKeyCollector( fKeyList ) {}
|
||||
virtual ~plResPageKeyRefList() { fKeyList.Reset(); }
|
||||
};
|
||||
|
||||
#endif // _plResManagerHelper_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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// plResManagerHelper - The wonderful helper class that can receive messages
|
||||
// for the resManager.
|
||||
//
|
||||
//// History /////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 6.7.2002 mcn - Created
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plResManagerHelper_h
|
||||
#define _plResManagerHelper_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsTemplates.h"
|
||||
#include "plRegistryHelpers.h"
|
||||
#include "pnKeyedObject/hsKeyedObject.h"
|
||||
|
||||
// Defined as a project setting so we can do this right
|
||||
//#define MCN_RESMGR_DEBUGGING
|
||||
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef MCN_RESMGR_DEBUGGING
|
||||
class plStatusLog;
|
||||
class plDebugPrintIterator;
|
||||
class plResMgrDebugInterface;
|
||||
#endif
|
||||
|
||||
class plResManager;
|
||||
class plRegistryPageNode;
|
||||
class plResManagerHelper : public hsKeyedObject
|
||||
{
|
||||
protected:
|
||||
|
||||
plResManager *fResManager;
|
||||
static plResManagerHelper *fInstance;
|
||||
|
||||
hsBool fInShutdown;
|
||||
|
||||
#ifdef MCN_RESMGR_DEBUGGING
|
||||
friend class plDebugPrintIterator;
|
||||
friend class plResMgrDebugInterface;
|
||||
|
||||
plStatusLog *fDebugScreen;
|
||||
hsBool fRefreshing, fCurrAgeExpanded;
|
||||
int fCurrAge;
|
||||
int fDebugDisplayType;
|
||||
|
||||
enum DebugDisplayTypes
|
||||
{
|
||||
kSizes = 0,
|
||||
kPercents,
|
||||
kBars,
|
||||
kMaxDisplayType
|
||||
};
|
||||
plResMgrDebugInterface *fDebugInput;
|
||||
#endif
|
||||
|
||||
void IUpdateDebugScreen( hsBool force = false );
|
||||
|
||||
public:
|
||||
|
||||
plResManagerHelper( plResManager *resMgr );
|
||||
virtual ~plResManagerHelper();
|
||||
|
||||
CLASSNAME_REGISTER( plResManagerHelper );
|
||||
GETINTERFACE_ANY( plResManagerHelper, hsKeyedObject );
|
||||
|
||||
virtual hsBool MsgReceive( plMessage *msg );
|
||||
|
||||
virtual void Read( hsStream *s, hsResMgr *mgr );
|
||||
virtual void Write( hsStream *s, hsResMgr *mgr );
|
||||
|
||||
void Init( void );
|
||||
void Shutdown( void );
|
||||
|
||||
void LoadAndHoldPageKeys( plRegistryPageNode *page );
|
||||
|
||||
void EnableDebugScreen( hsBool enable );
|
||||
|
||||
// Please let the res manager handle telling this.
|
||||
void SetInShutdown(hsBool b) { fInShutdown = b; }
|
||||
hsBool GetInShutdown() const { return fInShutdown; }
|
||||
|
||||
static plResManagerHelper *GetInstance( void ) { return fInstance; }
|
||||
};
|
||||
|
||||
//// Reffer Class ////////////////////////////////////////////////////////////
|
||||
|
||||
class plResPageKeyRefList : public plKeyCollector
|
||||
{
|
||||
protected:
|
||||
|
||||
hsTArray<plKey> fKeyList;
|
||||
|
||||
public:
|
||||
|
||||
plResPageKeyRefList() : plKeyCollector( fKeyList ) {}
|
||||
virtual ~plResPageKeyRefList() { fKeyList.Reset(); }
|
||||
};
|
||||
|
||||
#endif // _plResManagerHelper_h
|
||||
|
@ -1,29 +1,29 @@
|
||||
/*==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==*/
|
||||
|
||||
|
||||
// Future home of plResMgr
|
||||
|
||||
/*==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==*/
|
||||
|
||||
|
||||
// Future home of plResMgr
|
||||
|
||||
|
@ -1,26 +1,26 @@
|
||||
/*==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==*/
|
||||
// Future home of plResMgr
|
||||
/*==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==*/
|
||||
// Future home of plResMgr
|
||||
|
@ -1,37 +1,37 @@
|
||||
/*==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 plResMgrCreatable_inc
|
||||
#define plResMgrCreatable_inc
|
||||
|
||||
#include "pnFactory/plCreator.h"
|
||||
|
||||
|
||||
#include "plResManagerHelper.h"
|
||||
REGISTER_NONCREATABLE(plResManagerHelper);
|
||||
|
||||
|
||||
#endif // plResMgrCreatable_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 plResMgrCreatable_inc
|
||||
#define plResMgrCreatable_inc
|
||||
|
||||
#include "pnFactory/plCreator.h"
|
||||
|
||||
|
||||
#include "plResManagerHelper.h"
|
||||
REGISTER_NONCREATABLE(plResManagerHelper);
|
||||
|
||||
|
||||
#endif // plResMgrCreatable_inc
|
||||
|
@ -1,92 +1,92 @@
|
||||
/*==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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// plResMgrSettings - Class that holds all the various settings for
|
||||
// plResManager
|
||||
//
|
||||
//// History /////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 6.22.2002 mcn - Created
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plResMgrSettings_h
|
||||
#define _plResMgrSettings_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
|
||||
class plResMgrSettings
|
||||
{
|
||||
protected:
|
||||
friend class plResManager;
|
||||
|
||||
bool fFilterOlderPageVersions;
|
||||
bool fFilterNewerPageVersions;
|
||||
|
||||
UInt8 fLoggingLevel;
|
||||
|
||||
bool fPassiveKeyRead;
|
||||
bool fLoadPagesOnInit;
|
||||
|
||||
plResMgrSettings()
|
||||
{
|
||||
fFilterOlderPageVersions = true;
|
||||
fFilterNewerPageVersions = true;
|
||||
fPassiveKeyRead = false;
|
||||
fLoadPagesOnInit = true;
|
||||
fLoggingLevel = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
enum LogLevels
|
||||
{
|
||||
kNoLogging = 0,
|
||||
kBasicLogging = 1,
|
||||
kDetailedLogging = 2,
|
||||
kObjectLogging = 3,
|
||||
kObjectDetailLogging = 4
|
||||
};
|
||||
|
||||
bool GetFilterOlderPageVersions() const { return fFilterOlderPageVersions; }
|
||||
void SetFilterOlderPageVersions(bool f) { fFilterOlderPageVersions = f; }
|
||||
|
||||
bool GetFilterNewerPageVersions() const { return fFilterNewerPageVersions; }
|
||||
void SetFilterNewerPageVersions(bool f) { fFilterNewerPageVersions = f; }
|
||||
|
||||
UInt8 GetLoggingLevel() const { return fLoggingLevel; }
|
||||
void SetLoggingLevel(UInt8 level) { fLoggingLevel = level; }
|
||||
|
||||
bool GetPassiveKeyRead() const { return fPassiveKeyRead; }
|
||||
void SetPassiveKeyRead(bool p) { fPassiveKeyRead = p; }
|
||||
|
||||
bool GetLoadPagesOnInit() const { return fLoadPagesOnInit; }
|
||||
void SetLoadPagesOnInit(bool load) { fLoadPagesOnInit = load; }
|
||||
|
||||
static plResMgrSettings& Get();
|
||||
};
|
||||
|
||||
#endif // _plResMgrSettings_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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// plResMgrSettings - Class that holds all the various settings for
|
||||
// plResManager
|
||||
//
|
||||
//// History /////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 6.22.2002 mcn - Created
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plResMgrSettings_h
|
||||
#define _plResMgrSettings_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
|
||||
class plResMgrSettings
|
||||
{
|
||||
protected:
|
||||
friend class plResManager;
|
||||
|
||||
bool fFilterOlderPageVersions;
|
||||
bool fFilterNewerPageVersions;
|
||||
|
||||
UInt8 fLoggingLevel;
|
||||
|
||||
bool fPassiveKeyRead;
|
||||
bool fLoadPagesOnInit;
|
||||
|
||||
plResMgrSettings()
|
||||
{
|
||||
fFilterOlderPageVersions = true;
|
||||
fFilterNewerPageVersions = true;
|
||||
fPassiveKeyRead = false;
|
||||
fLoadPagesOnInit = true;
|
||||
fLoggingLevel = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
enum LogLevels
|
||||
{
|
||||
kNoLogging = 0,
|
||||
kBasicLogging = 1,
|
||||
kDetailedLogging = 2,
|
||||
kObjectLogging = 3,
|
||||
kObjectDetailLogging = 4
|
||||
};
|
||||
|
||||
bool GetFilterOlderPageVersions() const { return fFilterOlderPageVersions; }
|
||||
void SetFilterOlderPageVersions(bool f) { fFilterOlderPageVersions = f; }
|
||||
|
||||
bool GetFilterNewerPageVersions() const { return fFilterNewerPageVersions; }
|
||||
void SetFilterNewerPageVersions(bool f) { fFilterNewerPageVersions = f; }
|
||||
|
||||
UInt8 GetLoggingLevel() const { return fLoggingLevel; }
|
||||
void SetLoggingLevel(UInt8 level) { fLoggingLevel = level; }
|
||||
|
||||
bool GetPassiveKeyRead() const { return fPassiveKeyRead; }
|
||||
void SetPassiveKeyRead(bool p) { fPassiveKeyRead = p; }
|
||||
|
||||
bool GetLoadPagesOnInit() const { return fLoadPagesOnInit; }
|
||||
void SetLoadPagesOnInit(bool load) { fLoadPagesOnInit = load; }
|
||||
|
||||
static plResMgrSettings& Get();
|
||||
};
|
||||
|
||||
#endif // _plResMgrSettings_h
|
||||
|
@ -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 "plVersion.h"
|
||||
#include "pnFactory/plFactory.h"
|
||||
#include <vector>
|
||||
|
||||
#include "plCreatableIndex.h"
|
||||
#define ChangedCreatable(ver, creatable) if (minorVersion == ver) creatables.push_back(CLASS_INDEX_SCOPED(creatable));
|
||||
|
||||
//
|
||||
// Every time you bump the minor version number, add entries here for each
|
||||
// creatable that was changed. Every time the minor version is reset (for a
|
||||
// major version change), delete all the entries.
|
||||
//
|
||||
static void GetChangedCreatables(int minorVersion, std::vector<UInt16>& creatables)
|
||||
{
|
||||
ChangedCreatable(1, plLoadAvatarMsg);
|
||||
ChangedCreatable(1, plArmatureMod);
|
||||
ChangedCreatable(2, plAvBrainHuman);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
static int CreatableVersions[plCreatableIndex::plNumClassIndices];
|
||||
|
||||
static void CalcCreatableVersions()
|
||||
{
|
||||
memset(CreatableVersions, 0, sizeof(CreatableVersions));
|
||||
|
||||
for (int minorVer = 1; minorVer <= PLASMA2_MINOR_VERSION; minorVer++)
|
||||
{
|
||||
std::vector<UInt16> changedTypes;
|
||||
changedTypes.reserve(10);
|
||||
|
||||
GetChangedCreatables(minorVer, changedTypes);
|
||||
|
||||
for (int i = 0; i < changedTypes.size(); i++)
|
||||
{
|
||||
UInt16 changedType = changedTypes[i];
|
||||
CreatableVersions[changedType] = minorVer;
|
||||
|
||||
// Bump any classes that derive from this one
|
||||
for (UInt16 toCheck = 0; toCheck < plFactory::GetNumClasses(); toCheck++)
|
||||
{
|
||||
if (plFactory::DerivesFrom(changedType, toCheck))
|
||||
CreatableVersions[toCheck] = minorVer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UInt16 plVersion::GetMajorVersion() { return PLASMA2_MAJOR_VERSION; }
|
||||
UInt16 plVersion::GetMinorVersion() { return PLASMA2_MINOR_VERSION; }
|
||||
|
||||
int plVersion::GetCreatableVersion(UInt16 creatableIndex)
|
||||
{
|
||||
static bool calced = false;
|
||||
if (!calced)
|
||||
{
|
||||
calced = true;
|
||||
CalcCreatableVersions();
|
||||
}
|
||||
|
||||
return CreatableVersions[creatableIndex];
|
||||
}
|
||||
/*==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 "plVersion.h"
|
||||
#include "pnFactory/plFactory.h"
|
||||
#include <vector>
|
||||
|
||||
#include "plCreatableIndex.h"
|
||||
#define ChangedCreatable(ver, creatable) if (minorVersion == ver) creatables.push_back(CLASS_INDEX_SCOPED(creatable));
|
||||
|
||||
//
|
||||
// Every time you bump the minor version number, add entries here for each
|
||||
// creatable that was changed. Every time the minor version is reset (for a
|
||||
// major version change), delete all the entries.
|
||||
//
|
||||
static void GetChangedCreatables(int minorVersion, std::vector<UInt16>& creatables)
|
||||
{
|
||||
ChangedCreatable(1, plLoadAvatarMsg);
|
||||
ChangedCreatable(1, plArmatureMod);
|
||||
ChangedCreatable(2, plAvBrainHuman);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
static int CreatableVersions[plCreatableIndex::plNumClassIndices];
|
||||
|
||||
static void CalcCreatableVersions()
|
||||
{
|
||||
memset(CreatableVersions, 0, sizeof(CreatableVersions));
|
||||
|
||||
for (int minorVer = 1; minorVer <= PLASMA2_MINOR_VERSION; minorVer++)
|
||||
{
|
||||
std::vector<UInt16> changedTypes;
|
||||
changedTypes.reserve(10);
|
||||
|
||||
GetChangedCreatables(minorVer, changedTypes);
|
||||
|
||||
for (int i = 0; i < changedTypes.size(); i++)
|
||||
{
|
||||
UInt16 changedType = changedTypes[i];
|
||||
CreatableVersions[changedType] = minorVer;
|
||||
|
||||
// Bump any classes that derive from this one
|
||||
for (UInt16 toCheck = 0; toCheck < plFactory::GetNumClasses(); toCheck++)
|
||||
{
|
||||
if (plFactory::DerivesFrom(changedType, toCheck))
|
||||
CreatableVersions[toCheck] = minorVer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UInt16 plVersion::GetMajorVersion() { return PLASMA2_MAJOR_VERSION; }
|
||||
UInt16 plVersion::GetMinorVersion() { return PLASMA2_MINOR_VERSION; }
|
||||
|
||||
int plVersion::GetCreatableVersion(UInt16 creatableIndex)
|
||||
{
|
||||
static bool calced = false;
|
||||
if (!calced)
|
||||
{
|
||||
calced = true;
|
||||
CalcCreatableVersions();
|
||||
}
|
||||
|
||||
return CreatableVersions[creatableIndex];
|
||||
}
|
||||
|
@ -1,277 +1,277 @@
|
||||
/*==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 plVersion_h_inc
|
||||
#define plVersion_h_inc
|
||||
|
||||
#include "hsTypes.h"
|
||||
|
||||
// RULES:
|
||||
// Log your change
|
||||
// Set Minor Version to ZERO when you Bump Major Version
|
||||
// If you change the minor, see GetChangedCreateables in plVersion.cpp
|
||||
|
||||
#define PLASMA2_MAJOR_VERSION 70 // Major Version...every file will need to be reexported
|
||||
#define PLASMA2_MINOR_VERSION 2 // Minor Version...only files with the specified creatables
|
||||
// will need to be reexported
|
||||
|
||||
// Don't modify this, it's automatically updated when branches are made
|
||||
#define PLASMA2_BRANCH_NAME "Main Branch"
|
||||
|
||||
class plVersion
|
||||
{
|
||||
public:
|
||||
static UInt16 GetMajorVersion();
|
||||
static UInt16 GetMinorVersion();
|
||||
|
||||
// Pass in a creatable index to get its current version. Zero means it
|
||||
// hasn't changed since the last major version change, anything else is the
|
||||
// last minor version it changed at. This takes into account the version of
|
||||
// parent classes.
|
||||
static int GetCreatableVersion(UInt16 creatableIndex);
|
||||
};
|
||||
|
||||
/* Major Log ---Death to those who do not log changes---
|
||||
# Date Who comment
|
||||
1 5/8/01 Paulg Added version Number
|
||||
2 5/11/01 mf Changed sortable mesh format by 2 bytes.
|
||||
3 5/14/01 Paulg Index files Location is used for ReadConfig at Client Startup, RoomLoc added to Index
|
||||
4 5/21/01 matt Fixed errant bounding types for physicals (old bad codes will choke)
|
||||
5 5/24/01 mf Added Occluders to the data format.
|
||||
6 5/29/01 mf Purvis changed the sound data format and didn't change the version.
|
||||
7 5/3/01 thamer Cleaned up some object read/write routines
|
||||
8 6/12/01 mcn Obliterated hsGTexture on down. Now we use plBitmaps and plMipmaps (class IDs changed)
|
||||
9 6/21/01 mcn Updated drawable disk format. Forgot a field that made particle systems break when it wasn't there
|
||||
10 6/25/01 mcn Updated plMipmap format. Helps resolve the huge memory issues we were having
|
||||
11 6/28/01 mf Slight changes to material and geometry formats to support projective texturing.
|
||||
12 7/02/01 mcn Changed file format to fix disappearing objects in SceneViewer
|
||||
13 7/09/01 bob Changed file format of plSimpleParticleGenerator to allow mesh generated systems.
|
||||
14 7/13/01 thamer Changed uoid read/write to include clone number
|
||||
15 7/20/01 thamer Changed uoid sequence to support up to 4 player rooms
|
||||
16 7/20/01 mcn Added a second drawable + key to drawInterfaces
|
||||
17 7/22/01 bob Changed file format to have particle systems support material diffuse/opacity animations
|
||||
18 7/27/01 mcn Added stuff to drawableSpans for SceneViewer. Are we ever going to have another non-zero minor version? :)
|
||||
19 7/31/01 mf Did a get and the format had changed but the version hadn't been updated (again). Is this version thing dead?
|
||||
20 8/13/01 mcn Not that I know of. Change to various object formats to support object instancing.
|
||||
21 8/20/01 mf Like you'd know. Revised inter-object dependency connections throughout the five scene graphs.
|
||||
22 8/21/01 mf CoordinateInterfaces keep refs to child SceneObjects instead of child CoordinateInterfaces.
|
||||
22 8/21/01 mcn You hurt my feelings. I bump major version in retaliation. (Also upped max UV count)
|
||||
23 8/24/01 mf Made runtime lights respect Max's OTM.
|
||||
24 8/26/01 mcn Changed plSound format to support stereo (background music) sounds
|
||||
25 9/05/01 thamer Changed uoid to support 32bit clones
|
||||
26 9/14/01 mcn Added all 12 parameters to the Audio Region component.
|
||||
27 9/25/01 mf Added soft volumes to run-time lights. Breaks any scene with RT lights.
|
||||
28 10/03/01 matt Changed physics format just enough to make everyone reexport everything.
|
||||
29 10/9/01 ee Changed Uoid member types to a new format that can accomodate strings.
|
||||
30 10/10/01 mcn Split diffuse layer colors to static and runtime diffuse colors. Breaks the entire universe and parts of New Jersey.
|
||||
31 10/11/01 ee Activated string usage in uoids -- this version thing is sure not dead now.
|
||||
32 10/11/01 mf Changed format of plSpan. Only breaks scenes with visible geometry. Should that be Minor Version?
|
||||
33 10/12/01 cp changed read/write functions in plAnimTimeConvert. Breaks all previously exported animations
|
||||
34 10/22/01 Colin Changed format of plBitmap
|
||||
35 10/30/01 mf Change to span format, breaks anything with visible geometry.
|
||||
36 11/5/01 mcn Changed structure of sound classes to be far more intuitive and bug-free.
|
||||
37 11/9/01 ee Just for fun.
|
||||
38 11/13/01 bob Changed file format for plAnimTimeConvert / plAnimCmdMsg / plAGAnim (sense a theme?)
|
||||
39 11/25/01 mf More sorting info for drawable geometry.
|
||||
40 11/29/01 mcn Fixed sound fade param read/write. Anything with sounds must be re-exported.
|
||||
41 12/04/01 bob More animation file format changes.
|
||||
42 12/05/01 mcn Changes to sound format. Now properties are in a general props field. Also added disable-LOD prop to sounds
|
||||
43 12/18/01 cjp changes to physics system
|
||||
44 12/18/01 bob anim file format.
|
||||
45 12/19/01 Colin anim file format, again.
|
||||
46 12/28/01 mf DrawInterface format change to purge the last of the Opaque/Blending dualism.
|
||||
47 1/2/01 mf Decoupled the hardware and software skinning vertex formats.
|
||||
48 1/6/01 mf Added grey area to Soft Regions (formerly Soft Volumes).
|
||||
49 1/17/02 cp new camera system checked into client and plugins
|
||||
50 1/21/02 Colin Physics changes
|
||||
51 1/24/02 Colin Animation format change
|
||||
52 2/14/02 bob plAnimTimeConvert format change
|
||||
53 2/14/02 matt made all brains non-keyed. reordering all over the place
|
||||
54 3/15/02 cjp new LOS query types, format change to plHKPhysical
|
||||
55 4/09/02 cjp more new LOS query types, format change to plHKPhysical, camera type changes
|
||||
56 4/23/02 bob nuked plSimpleModifier from plAGMasterMod. Changes file format for animation.
|
||||
57 5/17/02 Colin Changed Uoid format for cloning
|
||||
58 7/02/02 thamer Changed synchedOject R/W format to support more LocalOnly options
|
||||
59 8/14/02 bob Anim file format
|
||||
60 2/08/03 mf Changed formats for everything drawable and/or physical. That leaves behaviors, but it's about time for a major version change anyway.
|
||||
61 2/18/03 mf Between my changes and Bob's, we're just not sure what hasn't changed anymore. At least drawables and avatars.
|
||||
62 3/30/03 mf Added LoadMask to plUoid
|
||||
63 5/30/03 thamer optimized Uoid size
|
||||
64 10/28/05 jeff changed plLocation to handle more pages and plUoid for optimization reasons
|
||||
65 2/22/06 bob animation key rewrite to save space
|
||||
66 2/27/06 bob 64-bit quaternion anim keys
|
||||
67 2/28/06 bob Anims store UInt16 frame numbers, not 32-bit float times.
|
||||
68 3/03/06 bob constant anim channels (plMatrixConstant, plScalarConstant had no R/W methods)
|
||||
69 5/08/06 bob changed plVertCoder and hsMatrix44::Read/Write
|
||||
70 2/12/07 bob Merged in several registry/resMangaer fixes
|
||||
*/
|
||||
|
||||
/* Minor Log ---Death to those who do not log changes---
|
||||
# Date Who comment
|
||||
1 5/8/01 Paulg Added version Number
|
||||
2 5/9/01 mcn Changed color components of drawableSpans
|
||||
0 5/11/01 mf Dropped back to zero on Major Version change
|
||||
1 8/06/01 thamer Upped the version for mf's anim callback changes.
|
||||
2 8/06/01 bob Changes to particle system read/write.
|
||||
0 8/13/01 mcn Bumped back to 0 due to major version change.
|
||||
1 8/23/01 bob Added animation controller to particle systems, changing their format.
|
||||
0 8/24/01 mcn Bumped back to 0 yet again.
|
||||
1 8/27/01 mcn Changed how emissive flags are handled on materials.
|
||||
2 8/29/01 bob Changed plAvatarMod file format
|
||||
0 9/05/01 thamer Bumped back to 0 yet again.
|
||||
1 9/17/01 matt Avatar only.
|
||||
2 9/24/01 bob Avatar and sound file formats changed. (For age linking effects)
|
||||
0 9/25/01 mf Reset to zero for major change.
|
||||
1 10/7/01 Colin Format of plResponderModifier and plEventCallbackMsg changed.
|
||||
0 10/9/01 ee Reset to zero for major change.
|
||||
1 10/11/01 mcn Changed sound format. Anything with sounds (including avatar b/c of linking sounds) breaks. Is this a record for # of version changes in one week?
|
||||
1 10/15/01 mcn Added soft volumes to sounds. Breaks anything with sounds. Again.
|
||||
2 10/17/01 Colin Changed format of plAGAnim
|
||||
0 10/22/01 Colin Reset to zero for major change.
|
||||
1 11/01/01 bob Changed format for plAGAnim and plAGMasterMod. Will break avatars without re-export.
|
||||
0 11/02/01 mf Reset to zero for major change.
|
||||
1 11/28/01 mcn Changed meaning of sound volume property. Will work if not re-exported, but will sound wrong.
|
||||
0 11/29/01 mcn Reset on major version change.
|
||||
1 12/10/01 bob Changes to animTimeConvert. Animated materials will need a re-export.
|
||||
0 12/18/01 bob Reset to zero for major change.
|
||||
1 1/07/02 bob File format change for particle systems.
|
||||
0 1/21/02 Colin Reset to zero for major change.
|
||||
1 1/24/02 Colin File format for responders
|
||||
2 1/24/02 mcn Changed postEffectMod format. Not many people use it though, so only minor version change.
|
||||
0 1/24/02 Colin Reset to zero for major change.
|
||||
1 1/28/02 bob File format change to avatars for clothing customization.
|
||||
2 1/30/02 Colin File format change to sit component
|
||||
3 1/31/02 Colin File format change to logic modifier (all detector components)
|
||||
4 2/13/02 Colin File format change to ladder modifier
|
||||
0 2/14/02 bob Reset to zero for major change.
|
||||
1(5) 2/14/02 mcn GUI control format changes to support dynamic text layers (the RIGHT way)
|
||||
2(6) 2/19/02 mcn Added version field to dialogs, to allow synching with C++ and Python code (just in case)
|
||||
7 3/01/02 mcn Moved GUI controls to pfGUIColorScheme methods of handling colors/fonts
|
||||
8 3/01/02 cjp changed format of new camera brains, only affects the few using them right now
|
||||
10 3/08/02 mcn Changed internal format of sounds to facilitate packing them in files later
|
||||
11 3/08/02 mcn Added a shadow option to GUI color schemes. Also added mouse-over animations to buttons.
|
||||
12 3/12/02 bob Change format of clothing
|
||||
13 3/15/02 matt Changed base class for sit modifier
|
||||
0 3/15/02 cjp Only chris forgot to log it - mf
|
||||
1 3/29/02 mf Added light group support for particle systems.
|
||||
2 4/02/02 Colin Format change for responder modifiers
|
||||
0 4/15/02 cjp Only chris forgot to log it - mf
|
||||
1 4/15/02 mf Added a parm to partycle systems just for fun.
|
||||
2 4/17/02 cjp Added new modifier for interface information, changed plMaxNode.cpp.
|
||||
0 4/23/02 bob Reset to zero.
|
||||
1 4/25/02 mcn GUI objects no longer fog. Must reexport GUI components.
|
||||
2 5/05/02 mf Particle system enhancements
|
||||
3 5/06/02 matt Changes to one shot modifier and multistage modifier
|
||||
4 5/06/02 bob Changes to plArmatureMod and Clothing stuff. For swappable meshes and footsteps.
|
||||
5 5/07/02 bob Changed clothing item file format (again) for text descriptions and thumbnails
|
||||
6 5/09/02 mcn Added sound event capabilities to GUI controls
|
||||
7 5/13/02 mcn Added some new options to GUI knobs
|
||||
8 5/14/02 matt Fix net propagation for animation stages (fading) and generic brains (exit flags)
|
||||
0 5/17/02 Colin Reset for major version
|
||||
1 5/21/02 mcn Added a channel select option for plWin32Sounds
|
||||
2 5/23/02 bob Added multiple texture layers per element in plClothingItem
|
||||
3 5/23/02 mcn Added some options to plSoundBuffer.
|
||||
4 6/18/02 mcn Added some more options to plSound, incl. localOnly flags
|
||||
6 6/21/02 mcn Updated plDynamicTextMap to include an initial image buffer
|
||||
7 6/26/02 mcn Major revision to sound system to support hardware acceleration
|
||||
0 7/02/02 thamer Reset for major version
|
||||
1 7/08/02 matt Format change for animation stages -- added next/prevStage override
|
||||
2 7/10/02 bob Format changes for avatar footstep sounds
|
||||
3 7/12/02 mcn Format change to sounds for EAX effects
|
||||
4 7/23/02 bob Format change to footstep sounds for more surface options
|
||||
5 7/29/02 mcn More EAX format changes to sounds
|
||||
6 7/29/02 mcn Added cutoff attenuation to spot/omni lights
|
||||
7 8/01/02 bob Format change to clothing items
|
||||
0 8/14/02 bob Reset for major version
|
||||
1 8/19/02 bob plClothingItem file format
|
||||
2 9/02/02 bob plArmatureLODMod file format change for bone LOD
|
||||
3 9/12/02 mf Making ripples and waves play nice with each other.
|
||||
4 9/18/02 bob plClothingItem file format... again
|
||||
5 9/19/02 mcn New GUI control proxy stuff
|
||||
6 9/23/02 mcn Removed dead sound stuff
|
||||
7 9/24/02 mcn Sound priority stuff
|
||||
8 9/25/02 mcn Support for new grouped random sound objects
|
||||
9 10/15/02 mcn Material anim support in GUI controls
|
||||
10 10/21/02 mcn Variable volume support to group sounds. No format break.
|
||||
11 10/29/02 cjp proper python notification of avatar page out & last avatar out plus elevator persistance fix - breaks message format for exclude regions
|
||||
12 10/29/02 mcn Fixing chris's booboo
|
||||
13 10/29/02 cjp Changed camera component data format slightly.
|
||||
16 11/18.02 cjp changed camera speed components & objects, don't know where v 14 & 15 went
|
||||
17 12/04/20 matt New line-of-sight categories; format change for physicals.
|
||||
18 12/05/02 mf Enhanced linefollowmod to play nice with stereizer, and added field to occluder's cullpoly.
|
||||
19 12/17/02 matt Bumped armaturemod, based on strong circumstantial evidenced that I missed something.
|
||||
20 12/31/02 matt New format for animation stages, written by the multistage mod.
|
||||
21 01/03/03 matt Change to sitmodifier.
|
||||
22 01/16/03 matt More simplification for animation stages and generic brains.
|
||||
23 01/20/03 bob Added layer to clothing items for aged skin blending
|
||||
24 01/21/03 mf plLayers now read and write out their shaders.
|
||||
25 01/29/03 bob plMorphSequence read/writes the plSharedMeshes it uses
|
||||
27 02/05/03 mcn Updates to pfGUIButtonMod
|
||||
0 02/18/03 mf Reset for major version change.
|
||||
1 02/19/03 bob Added layers to plClothingItem. Took the opp to cleanup the R/W functions
|
||||
2 02/21/03 mf Added features to dynamic water. No one should notice.
|
||||
3 02/24/03 cjp changed animated cameras - added new commands for controlling them
|
||||
4 02/24/03 mcn Updates to GUI stuff to support, er, new GUI stuff.
|
||||
5 03/11/03 bob Clothing and linkSound format change
|
||||
0 03/30/03 mf Reset for major version change.
|
||||
9 04/14/03 Colin Havok change. At 9 since mf forgot to bump the version (and Matt did a bunch of undocumented bumps)
|
||||
10 04/15/03 bob Added a footstep surface type
|
||||
11 4/18/03 mcn Added list of the layers grabbed by a GUI DynDisplay
|
||||
12 4/23/03 bob File format for plMultistageBehMod, needed for a ladder fix
|
||||
13 05/01/03 Colin Changed how Havok vectors and quats are written
|
||||
14 03/30/03 mf Particle effect enhancement
|
||||
0 05/30/03 thamer Reset for major version change.
|
||||
1 06/01/03 bob Added a flags variable to plSharedMesh
|
||||
2 06/06/03 markd Added NotifyType for GUIButtons
|
||||
3 06/07/03 mcn Added sound groups to physicals
|
||||
4 06/24/03 bob More params for Flocking particles
|
||||
5 07/05/03 mf Particle and footprints working together
|
||||
6 07/13/03 bob Avatar file format
|
||||
7 07/31/03 bob LinkToAgeMsg (which affects responders) and panic link regions
|
||||
8 08/21/03 Colin Removed some stuff from plSoundBuffer
|
||||
9 08/22/03 bob Added info to plClothingItem
|
||||
10 09/16/03 bob Removed stuff in plAnimCmdMsg, which affects responders.
|
||||
11 09/18/03 mf Changed plLoadMask, of which plWaveSet7 is the biggest user.
|
||||
12 01/03/04 jeff pfGUIDynDisplayCtrl now stores material as well as layer information
|
||||
!! 11 02/10/04 mf Dropped back a version, to reduce patch size for Expansion 1.
|
||||
12 03/12/04 bob New stuff in Swim Regions
|
||||
0 10/28/05 jeff Reset for major version change
|
||||
1 11/28/05 jeff GUI text boxes can now pull strings from the localization mgr
|
||||
2 12/01/05 jeff pfKIMsg can now handle unicode strings
|
||||
3 02/02/06 adam modified plDynamicEnvMap as a part of back-porting planar reflections from P21
|
||||
0 02/22/06 bob Reset for major version change
|
||||
1 04/12/06 Colin Changed physical format
|
||||
0 05/08/06 bob Reset for major version change
|
||||
1 05/16/06 markd Changed physics format to include boxes
|
||||
2 06/26/06 jeff Changed coop brain format so book sharing works again
|
||||
3 12/05/06 bob Avatar uses a render target instead of a plMipmap.
|
||||
4 01/16/07 bob Still does, it's just not created at export.
|
||||
5 01/24/07 adam Changed plAGMasterMod so one can be set as a group master in grouped anims
|
||||
0 02/12/07 bob Reset for major version change
|
||||
1 03/29/07 jeff Changed plLoadAvatarMsg and plArmatureMod to be more flexible
|
||||
2 06/28/07 jeff Changed plAvBrainHuman format to store whether it's an actor or not
|
||||
*/
|
||||
|
||||
#endif // plVersion_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 plVersion_h_inc
|
||||
#define plVersion_h_inc
|
||||
|
||||
#include "hsTypes.h"
|
||||
|
||||
// RULES:
|
||||
// Log your change
|
||||
// Set Minor Version to ZERO when you Bump Major Version
|
||||
// If you change the minor, see GetChangedCreateables in plVersion.cpp
|
||||
|
||||
#define PLASMA2_MAJOR_VERSION 70 // Major Version...every file will need to be reexported
|
||||
#define PLASMA2_MINOR_VERSION 2 // Minor Version...only files with the specified creatables
|
||||
// will need to be reexported
|
||||
|
||||
// Don't modify this, it's automatically updated when branches are made
|
||||
#define PLASMA2_BRANCH_NAME "Main Branch"
|
||||
|
||||
class plVersion
|
||||
{
|
||||
public:
|
||||
static UInt16 GetMajorVersion();
|
||||
static UInt16 GetMinorVersion();
|
||||
|
||||
// Pass in a creatable index to get its current version. Zero means it
|
||||
// hasn't changed since the last major version change, anything else is the
|
||||
// last minor version it changed at. This takes into account the version of
|
||||
// parent classes.
|
||||
static int GetCreatableVersion(UInt16 creatableIndex);
|
||||
};
|
||||
|
||||
/* Major Log ---Death to those who do not log changes---
|
||||
# Date Who comment
|
||||
1 5/8/01 Paulg Added version Number
|
||||
2 5/11/01 mf Changed sortable mesh format by 2 bytes.
|
||||
3 5/14/01 Paulg Index files Location is used for ReadConfig at Client Startup, RoomLoc added to Index
|
||||
4 5/21/01 matt Fixed errant bounding types for physicals (old bad codes will choke)
|
||||
5 5/24/01 mf Added Occluders to the data format.
|
||||
6 5/29/01 mf Purvis changed the sound data format and didn't change the version.
|
||||
7 5/3/01 thamer Cleaned up some object read/write routines
|
||||
8 6/12/01 mcn Obliterated hsGTexture on down. Now we use plBitmaps and plMipmaps (class IDs changed)
|
||||
9 6/21/01 mcn Updated drawable disk format. Forgot a field that made particle systems break when it wasn't there
|
||||
10 6/25/01 mcn Updated plMipmap format. Helps resolve the huge memory issues we were having
|
||||
11 6/28/01 mf Slight changes to material and geometry formats to support projective texturing.
|
||||
12 7/02/01 mcn Changed file format to fix disappearing objects in SceneViewer
|
||||
13 7/09/01 bob Changed file format of plSimpleParticleGenerator to allow mesh generated systems.
|
||||
14 7/13/01 thamer Changed uoid read/write to include clone number
|
||||
15 7/20/01 thamer Changed uoid sequence to support up to 4 player rooms
|
||||
16 7/20/01 mcn Added a second drawable + key to drawInterfaces
|
||||
17 7/22/01 bob Changed file format to have particle systems support material diffuse/opacity animations
|
||||
18 7/27/01 mcn Added stuff to drawableSpans for SceneViewer. Are we ever going to have another non-zero minor version? :)
|
||||
19 7/31/01 mf Did a get and the format had changed but the version hadn't been updated (again). Is this version thing dead?
|
||||
20 8/13/01 mcn Not that I know of. Change to various object formats to support object instancing.
|
||||
21 8/20/01 mf Like you'd know. Revised inter-object dependency connections throughout the five scene graphs.
|
||||
22 8/21/01 mf CoordinateInterfaces keep refs to child SceneObjects instead of child CoordinateInterfaces.
|
||||
22 8/21/01 mcn You hurt my feelings. I bump major version in retaliation. (Also upped max UV count)
|
||||
23 8/24/01 mf Made runtime lights respect Max's OTM.
|
||||
24 8/26/01 mcn Changed plSound format to support stereo (background music) sounds
|
||||
25 9/05/01 thamer Changed uoid to support 32bit clones
|
||||
26 9/14/01 mcn Added all 12 parameters to the Audio Region component.
|
||||
27 9/25/01 mf Added soft volumes to run-time lights. Breaks any scene with RT lights.
|
||||
28 10/03/01 matt Changed physics format just enough to make everyone reexport everything.
|
||||
29 10/9/01 ee Changed Uoid member types to a new format that can accomodate strings.
|
||||
30 10/10/01 mcn Split diffuse layer colors to static and runtime diffuse colors. Breaks the entire universe and parts of New Jersey.
|
||||
31 10/11/01 ee Activated string usage in uoids -- this version thing is sure not dead now.
|
||||
32 10/11/01 mf Changed format of plSpan. Only breaks scenes with visible geometry. Should that be Minor Version?
|
||||
33 10/12/01 cp changed read/write functions in plAnimTimeConvert. Breaks all previously exported animations
|
||||
34 10/22/01 Colin Changed format of plBitmap
|
||||
35 10/30/01 mf Change to span format, breaks anything with visible geometry.
|
||||
36 11/5/01 mcn Changed structure of sound classes to be far more intuitive and bug-free.
|
||||
37 11/9/01 ee Just for fun.
|
||||
38 11/13/01 bob Changed file format for plAnimTimeConvert / plAnimCmdMsg / plAGAnim (sense a theme?)
|
||||
39 11/25/01 mf More sorting info for drawable geometry.
|
||||
40 11/29/01 mcn Fixed sound fade param read/write. Anything with sounds must be re-exported.
|
||||
41 12/04/01 bob More animation file format changes.
|
||||
42 12/05/01 mcn Changes to sound format. Now properties are in a general props field. Also added disable-LOD prop to sounds
|
||||
43 12/18/01 cjp changes to physics system
|
||||
44 12/18/01 bob anim file format.
|
||||
45 12/19/01 Colin anim file format, again.
|
||||
46 12/28/01 mf DrawInterface format change to purge the last of the Opaque/Blending dualism.
|
||||
47 1/2/01 mf Decoupled the hardware and software skinning vertex formats.
|
||||
48 1/6/01 mf Added grey area to Soft Regions (formerly Soft Volumes).
|
||||
49 1/17/02 cp new camera system checked into client and plugins
|
||||
50 1/21/02 Colin Physics changes
|
||||
51 1/24/02 Colin Animation format change
|
||||
52 2/14/02 bob plAnimTimeConvert format change
|
||||
53 2/14/02 matt made all brains non-keyed. reordering all over the place
|
||||
54 3/15/02 cjp new LOS query types, format change to plHKPhysical
|
||||
55 4/09/02 cjp more new LOS query types, format change to plHKPhysical, camera type changes
|
||||
56 4/23/02 bob nuked plSimpleModifier from plAGMasterMod. Changes file format for animation.
|
||||
57 5/17/02 Colin Changed Uoid format for cloning
|
||||
58 7/02/02 thamer Changed synchedOject R/W format to support more LocalOnly options
|
||||
59 8/14/02 bob Anim file format
|
||||
60 2/08/03 mf Changed formats for everything drawable and/or physical. That leaves behaviors, but it's about time for a major version change anyway.
|
||||
61 2/18/03 mf Between my changes and Bob's, we're just not sure what hasn't changed anymore. At least drawables and avatars.
|
||||
62 3/30/03 mf Added LoadMask to plUoid
|
||||
63 5/30/03 thamer optimized Uoid size
|
||||
64 10/28/05 jeff changed plLocation to handle more pages and plUoid for optimization reasons
|
||||
65 2/22/06 bob animation key rewrite to save space
|
||||
66 2/27/06 bob 64-bit quaternion anim keys
|
||||
67 2/28/06 bob Anims store UInt16 frame numbers, not 32-bit float times.
|
||||
68 3/03/06 bob constant anim channels (plMatrixConstant, plScalarConstant had no R/W methods)
|
||||
69 5/08/06 bob changed plVertCoder and hsMatrix44::Read/Write
|
||||
70 2/12/07 bob Merged in several registry/resMangaer fixes
|
||||
*/
|
||||
|
||||
/* Minor Log ---Death to those who do not log changes---
|
||||
# Date Who comment
|
||||
1 5/8/01 Paulg Added version Number
|
||||
2 5/9/01 mcn Changed color components of drawableSpans
|
||||
0 5/11/01 mf Dropped back to zero on Major Version change
|
||||
1 8/06/01 thamer Upped the version for mf's anim callback changes.
|
||||
2 8/06/01 bob Changes to particle system read/write.
|
||||
0 8/13/01 mcn Bumped back to 0 due to major version change.
|
||||
1 8/23/01 bob Added animation controller to particle systems, changing their format.
|
||||
0 8/24/01 mcn Bumped back to 0 yet again.
|
||||
1 8/27/01 mcn Changed how emissive flags are handled on materials.
|
||||
2 8/29/01 bob Changed plAvatarMod file format
|
||||
0 9/05/01 thamer Bumped back to 0 yet again.
|
||||
1 9/17/01 matt Avatar only.
|
||||
2 9/24/01 bob Avatar and sound file formats changed. (For age linking effects)
|
||||
0 9/25/01 mf Reset to zero for major change.
|
||||
1 10/7/01 Colin Format of plResponderModifier and plEventCallbackMsg changed.
|
||||
0 10/9/01 ee Reset to zero for major change.
|
||||
1 10/11/01 mcn Changed sound format. Anything with sounds (including avatar b/c of linking sounds) breaks. Is this a record for # of version changes in one week?
|
||||
1 10/15/01 mcn Added soft volumes to sounds. Breaks anything with sounds. Again.
|
||||
2 10/17/01 Colin Changed format of plAGAnim
|
||||
0 10/22/01 Colin Reset to zero for major change.
|
||||
1 11/01/01 bob Changed format for plAGAnim and plAGMasterMod. Will break avatars without re-export.
|
||||
0 11/02/01 mf Reset to zero for major change.
|
||||
1 11/28/01 mcn Changed meaning of sound volume property. Will work if not re-exported, but will sound wrong.
|
||||
0 11/29/01 mcn Reset on major version change.
|
||||
1 12/10/01 bob Changes to animTimeConvert. Animated materials will need a re-export.
|
||||
0 12/18/01 bob Reset to zero for major change.
|
||||
1 1/07/02 bob File format change for particle systems.
|
||||
0 1/21/02 Colin Reset to zero for major change.
|
||||
1 1/24/02 Colin File format for responders
|
||||
2 1/24/02 mcn Changed postEffectMod format. Not many people use it though, so only minor version change.
|
||||
0 1/24/02 Colin Reset to zero for major change.
|
||||
1 1/28/02 bob File format change to avatars for clothing customization.
|
||||
2 1/30/02 Colin File format change to sit component
|
||||
3 1/31/02 Colin File format change to logic modifier (all detector components)
|
||||
4 2/13/02 Colin File format change to ladder modifier
|
||||
0 2/14/02 bob Reset to zero for major change.
|
||||
1(5) 2/14/02 mcn GUI control format changes to support dynamic text layers (the RIGHT way)
|
||||
2(6) 2/19/02 mcn Added version field to dialogs, to allow synching with C++ and Python code (just in case)
|
||||
7 3/01/02 mcn Moved GUI controls to pfGUIColorScheme methods of handling colors/fonts
|
||||
8 3/01/02 cjp changed format of new camera brains, only affects the few using them right now
|
||||
10 3/08/02 mcn Changed internal format of sounds to facilitate packing them in files later
|
||||
11 3/08/02 mcn Added a shadow option to GUI color schemes. Also added mouse-over animations to buttons.
|
||||
12 3/12/02 bob Change format of clothing
|
||||
13 3/15/02 matt Changed base class for sit modifier
|
||||
0 3/15/02 cjp Only chris forgot to log it - mf
|
||||
1 3/29/02 mf Added light group support for particle systems.
|
||||
2 4/02/02 Colin Format change for responder modifiers
|
||||
0 4/15/02 cjp Only chris forgot to log it - mf
|
||||
1 4/15/02 mf Added a parm to partycle systems just for fun.
|
||||
2 4/17/02 cjp Added new modifier for interface information, changed plMaxNode.cpp.
|
||||
0 4/23/02 bob Reset to zero.
|
||||
1 4/25/02 mcn GUI objects no longer fog. Must reexport GUI components.
|
||||
2 5/05/02 mf Particle system enhancements
|
||||
3 5/06/02 matt Changes to one shot modifier and multistage modifier
|
||||
4 5/06/02 bob Changes to plArmatureMod and Clothing stuff. For swappable meshes and footsteps.
|
||||
5 5/07/02 bob Changed clothing item file format (again) for text descriptions and thumbnails
|
||||
6 5/09/02 mcn Added sound event capabilities to GUI controls
|
||||
7 5/13/02 mcn Added some new options to GUI knobs
|
||||
8 5/14/02 matt Fix net propagation for animation stages (fading) and generic brains (exit flags)
|
||||
0 5/17/02 Colin Reset for major version
|
||||
1 5/21/02 mcn Added a channel select option for plWin32Sounds
|
||||
2 5/23/02 bob Added multiple texture layers per element in plClothingItem
|
||||
3 5/23/02 mcn Added some options to plSoundBuffer.
|
||||
4 6/18/02 mcn Added some more options to plSound, incl. localOnly flags
|
||||
6 6/21/02 mcn Updated plDynamicTextMap to include an initial image buffer
|
||||
7 6/26/02 mcn Major revision to sound system to support hardware acceleration
|
||||
0 7/02/02 thamer Reset for major version
|
||||
1 7/08/02 matt Format change for animation stages -- added next/prevStage override
|
||||
2 7/10/02 bob Format changes for avatar footstep sounds
|
||||
3 7/12/02 mcn Format change to sounds for EAX effects
|
||||
4 7/23/02 bob Format change to footstep sounds for more surface options
|
||||
5 7/29/02 mcn More EAX format changes to sounds
|
||||
6 7/29/02 mcn Added cutoff attenuation to spot/omni lights
|
||||
7 8/01/02 bob Format change to clothing items
|
||||
0 8/14/02 bob Reset for major version
|
||||
1 8/19/02 bob plClothingItem file format
|
||||
2 9/02/02 bob plArmatureLODMod file format change for bone LOD
|
||||
3 9/12/02 mf Making ripples and waves play nice with each other.
|
||||
4 9/18/02 bob plClothingItem file format... again
|
||||
5 9/19/02 mcn New GUI control proxy stuff
|
||||
6 9/23/02 mcn Removed dead sound stuff
|
||||
7 9/24/02 mcn Sound priority stuff
|
||||
8 9/25/02 mcn Support for new grouped random sound objects
|
||||
9 10/15/02 mcn Material anim support in GUI controls
|
||||
10 10/21/02 mcn Variable volume support to group sounds. No format break.
|
||||
11 10/29/02 cjp proper python notification of avatar page out & last avatar out plus elevator persistance fix - breaks message format for exclude regions
|
||||
12 10/29/02 mcn Fixing chris's booboo
|
||||
13 10/29/02 cjp Changed camera component data format slightly.
|
||||
16 11/18.02 cjp changed camera speed components & objects, don't know where v 14 & 15 went
|
||||
17 12/04/20 matt New line-of-sight categories; format change for physicals.
|
||||
18 12/05/02 mf Enhanced linefollowmod to play nice with stereizer, and added field to occluder's cullpoly.
|
||||
19 12/17/02 matt Bumped armaturemod, based on strong circumstantial evidenced that I missed something.
|
||||
20 12/31/02 matt New format for animation stages, written by the multistage mod.
|
||||
21 01/03/03 matt Change to sitmodifier.
|
||||
22 01/16/03 matt More simplification for animation stages and generic brains.
|
||||
23 01/20/03 bob Added layer to clothing items for aged skin blending
|
||||
24 01/21/03 mf plLayers now read and write out their shaders.
|
||||
25 01/29/03 bob plMorphSequence read/writes the plSharedMeshes it uses
|
||||
27 02/05/03 mcn Updates to pfGUIButtonMod
|
||||
0 02/18/03 mf Reset for major version change.
|
||||
1 02/19/03 bob Added layers to plClothingItem. Took the opp to cleanup the R/W functions
|
||||
2 02/21/03 mf Added features to dynamic water. No one should notice.
|
||||
3 02/24/03 cjp changed animated cameras - added new commands for controlling them
|
||||
4 02/24/03 mcn Updates to GUI stuff to support, er, new GUI stuff.
|
||||
5 03/11/03 bob Clothing and linkSound format change
|
||||
0 03/30/03 mf Reset for major version change.
|
||||
9 04/14/03 Colin Havok change. At 9 since mf forgot to bump the version (and Matt did a bunch of undocumented bumps)
|
||||
10 04/15/03 bob Added a footstep surface type
|
||||
11 4/18/03 mcn Added list of the layers grabbed by a GUI DynDisplay
|
||||
12 4/23/03 bob File format for plMultistageBehMod, needed for a ladder fix
|
||||
13 05/01/03 Colin Changed how Havok vectors and quats are written
|
||||
14 03/30/03 mf Particle effect enhancement
|
||||
0 05/30/03 thamer Reset for major version change.
|
||||
1 06/01/03 bob Added a flags variable to plSharedMesh
|
||||
2 06/06/03 markd Added NotifyType for GUIButtons
|
||||
3 06/07/03 mcn Added sound groups to physicals
|
||||
4 06/24/03 bob More params for Flocking particles
|
||||
5 07/05/03 mf Particle and footprints working together
|
||||
6 07/13/03 bob Avatar file format
|
||||
7 07/31/03 bob LinkToAgeMsg (which affects responders) and panic link regions
|
||||
8 08/21/03 Colin Removed some stuff from plSoundBuffer
|
||||
9 08/22/03 bob Added info to plClothingItem
|
||||
10 09/16/03 bob Removed stuff in plAnimCmdMsg, which affects responders.
|
||||
11 09/18/03 mf Changed plLoadMask, of which plWaveSet7 is the biggest user.
|
||||
12 01/03/04 jeff pfGUIDynDisplayCtrl now stores material as well as layer information
|
||||
!! 11 02/10/04 mf Dropped back a version, to reduce patch size for Expansion 1.
|
||||
12 03/12/04 bob New stuff in Swim Regions
|
||||
0 10/28/05 jeff Reset for major version change
|
||||
1 11/28/05 jeff GUI text boxes can now pull strings from the localization mgr
|
||||
2 12/01/05 jeff pfKIMsg can now handle unicode strings
|
||||
3 02/02/06 adam modified plDynamicEnvMap as a part of back-porting planar reflections from P21
|
||||
0 02/22/06 bob Reset for major version change
|
||||
1 04/12/06 Colin Changed physical format
|
||||
0 05/08/06 bob Reset for major version change
|
||||
1 05/16/06 markd Changed physics format to include boxes
|
||||
2 06/26/06 jeff Changed coop brain format so book sharing works again
|
||||
3 12/05/06 bob Avatar uses a render target instead of a plMipmap.
|
||||
4 01/16/07 bob Still does, it's just not created at export.
|
||||
5 01/24/07 adam Changed plAGMasterMod so one can be set as a group master in grouped anims
|
||||
0 02/12/07 bob Reset for major version change
|
||||
1 03/29/07 jeff Changed plLoadAvatarMsg and plArmatureMod to be more flexible
|
||||
2 06/28/07 jeff Changed plAvBrainHuman format to store whether it's an actor or not
|
||||
*/
|
||||
|
||||
#endif // plVersion_h_inc
|
||||
|
Reference in New Issue
Block a user