2
3
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-14 02:27:40 -04:00

Initial Commit of CyanWorlds.com Engine Open Source Client/Plugin

This commit is contained in:
JWPlatt
2011-03-12 12:34:52 -05:00
commit a20a222fc2
3976 changed files with 1301356 additions and 0 deletions

View File

@ -0,0 +1,549 @@
/*==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 "hsStream.h"
#include "plAgeDescription.h"
#include "hsUtils.h"
#include "hsStlUtils.h"
#include "../plFile/hsFiles.h"
#include "../plFile/plInitFileReader.h"
#include "../plFile/plEncryptedStream.h"
#include "hsStringTokenizer.h"
#include <functional>
#include <algorithm>
const UInt32 plAgePage::kInvalidSeqSuffix = (UInt32)-1;
plAgePage::plAgePage( const char *name, UInt32 seqSuffix, Byte flags )
{
fName = name != nil ? hsStrcpy( name ) : nil;
fSeqSuffix = seqSuffix;
fFlags = flags;
}
plAgePage::plAgePage( char *stringFrom ) : fName(nil)
{
SetFromString( stringFrom );
}
plAgePage::plAgePage()
{
fName = nil;
fFlags = 0;
fSeqSuffix = 0;
}
plAgePage::plAgePage( const plAgePage &src ) : fName(nil)
{
fName = src.fName != nil ? hsStrcpy( src.fName ) : nil;
fSeqSuffix = src.fSeqSuffix;
fFlags = src.fFlags;
}
plAgePage::~plAgePage()
{
delete [] fName;
}
plAgePage &plAgePage::operator=( const plAgePage &src )
{
delete [] fName;
fName = src.fName != nil ? hsStrcpy( src.fName ) : nil;
fSeqSuffix = src.fSeqSuffix;
fFlags = src.fFlags;
return *this;
}
void plAgePage::SetFlags(Byte f, bool on)
{
if (on)
hsSetBits(fFlags, f);
else
hsClearBits(fFlags, f);
}
// now preservs original string
hsBool plAgePage::SetFromString( const char *stringIn )
{
char *c, seps[] = ", \n";
std::string string = stringIn;
// Parse. Format is going to be "pageName[,seqSuffix[,flags]]"
c = strtok( (char*)string.c_str(), seps );
if( c == nil )
return false;
delete [] fName;
fName = hsStrcpy( c );
// Look for seqSuffix
c = strtok( nil, seps );
if( c != nil )
{
fSeqSuffix = atoi( c );
// Look for flags
c = strtok( nil, seps );
if( c != nil )
{
fFlags = atoi( c );
}
else
fFlags = 0;
}
else
{
fSeqSuffix = kInvalidSeqSuffix;
fFlags = 0;
}
return true;
}
char *plAgePage::GetAsString( void ) const
{
static char str[ 256 ];
// Format is "pageName[,seqSuffix[,flags]]"
if( fFlags != 0 )
sprintf( str, "%s,%d,%d", fName, fSeqSuffix, fFlags );
else
sprintf( str, "%s,%d", fName, fSeqSuffix );
return str;
}
//
// plAgeDescription
//
//
//
// static
char plAgeDescription::kAgeDescPath[]={"dat"PATH_SEPARATOR_STR};
char *plAgeDescription::fCommonPages[] = { "Textures", "BuiltIn" };
// Also gotta init the separators for our helper reading function
plAgeDescription::plAgeDescription() : plInitSectionTokenReader()
{
IInit();
}
plAgeDescription::~plAgeDescription()
{
IDeInit();
}
void plAgeDescription::IDeInit()
{
ClearPageList();
delete [] fName;
}
plAgeDescription::plAgeDescription( const char *fileNameToReadFrom ) : plInitSectionTokenReader()
{
ReadFromFile(fileNameToReadFrom);
}
//
// Reads from a file, returns false if failed.
//
bool plAgeDescription::ReadFromFile( const char *fileNameToReadFrom )
{
IInit();
hsStream* stream = plEncryptedStream::OpenEncryptedFile(fileNameToReadFrom);
if( !stream )
return false;
Read( stream );
stream->Close();
delete stream;
SetAgeNameFromPath( fileNameToReadFrom );
return true;
}
void plAgeDescription::SetAgeNameFromPath( const char *path )
{
delete [] fName;
if( path == nil )
{
fName = nil;
return;
}
// Construct our name from the path
char *pathSep1 = strrchr( path, '\\' );
char *pathSep2 = strrchr( path, '/' );
if( pathSep2 > pathSep1 )
pathSep1 = pathSep2;
if( pathSep1 == nil )
pathSep1 = (char *)path;
else
pathSep1++; // Get past the actual character we found
char temp[ 512 ];
strcpy( temp, pathSep1 );
char *end = strrchr( temp, '.' );
if( end != nil )
*end = 0;
fName = hsStrcpy( temp );
}
void plAgeDescription::IInit( void )
{
fName = nil;
fDayLength = 24.0f;
fMaxCapacity = -1;
fLingerTime = 180; // seconds
fSeqPrefix = 0;
fReleaseVersion = 0;
fStart.SetMode( plUnifiedTime::kLocal );
fPageIterator = -1;
}
struct SzDelete { void operator()(char * str) { delete [] str;} };
void plAgeDescription::ClearPageList()
{
fPages.Reset();
}
void plAgeDescription::AppendPage( const char *name, int seqSuffix, Byte flags )
{
fPages.Append( plAgePage( name, ( seqSuffix == -1 ) ? fPages.GetCount() : (UInt32)seqSuffix, flags ) );
}
void plAgeDescription::SeekFirstPage( void )
{
fPageIterator = 0;
}
plAgePage *plAgeDescription::GetNextPage( void )
{
plAgePage *ret = nil;
if( fPageIterator >= 0 && fPageIterator < fPages.GetCount() )
{
ret = &fPages[ fPageIterator++ ];
if( fPageIterator >= fPages.GetCount() )
fPageIterator = -1;
}
return ret;
}
void plAgeDescription::RemovePage( const char *page )
{
int i;
for( i = 0; i < fPages.GetCount(); i++ )
{
if( strcmp( page, fPages[ i ].GetName() ) == 0 )
{
fPages.Remove( i );
return;
}
}
}
plAgePage *plAgeDescription::FindPage( const char *name ) const
{
int i;
for( i = 0; i < fPages.GetCount(); i++ )
{
if( strcmp( name, fPages[ i ].GetName() ) == 0 )
return &fPages[ i ];
}
return nil;
}
plLocation plAgeDescription::CalcPageLocation( const char *page ) const
{
plAgePage *ap = FindPage( page );
if( ap != nil )
{
// Combine our sequence # together
Int32 combined;
hsAssert(abs(fSeqPrefix) < 0xFF, "Age sequence prefex is out of range!"); // sequence prefix can NOT be larger or equal to 1-byte max value
UInt32 suffix = ap->GetSeqSuffix();
hsAssert(suffix <= 0xFFFF, "Page sequence number is out of range!"); // page sequence number can NOT be larger then 2-byte max value
if( fSeqPrefix < 0 ) // we are a global age
combined = -(Int32)( ( ( -fSeqPrefix ) << 16 ) + suffix );
else
combined = ( fSeqPrefix << 16 ) + suffix;
// Now, our 32 bit number looks like the following:
// 0xRRAAPPPP
// - RR is FF when reserved, and 00 when normal
// - AA is the one byte for age sequence prefix (FF not allowed because 0xFFFFFFFFFF is reserved for invalid sequence number)
// - PPPP is the two bytes for page sequence number
if( IsGlobalAge() )
return plLocation::MakeReserved( (UInt32)combined );
else
{
plLocation ret = plLocation::MakeNormal( combined );
if (page && !stricmp(page, "builtin"))
ret.SetFlags(plLocation::kBuiltIn);
return ret;
}
}
// Just make a blank (invalid) one
plLocation loc;
return loc;
}
//
// Writes the Age Description File
//
void plAgeDescription::Write(hsStream* stream) const
{
char buf[256];
// Write the date/time
sprintf(buf, "StartDateTime=%010u\n", fStart.GetSecs());
stream->WriteString(buf);
// Write the day length
sprintf(buf, "DayLength=%f\n", fDayLength);
stream->WriteString(buf);
// Write the max capacity
sprintf(buf, "MaxCapacity=%d\n", fMaxCapacity);
stream->WriteString(buf);
// Write the linger time
sprintf(buf, "LingerTime=%d\n", fLingerTime);
stream->WriteString(buf);
// Write out the sequence prefix
sprintf( buf, "SequencePrefix=%d\n", fSeqPrefix );
stream->WriteString( buf );
// Write out the release version
sprintf( buf, "ReleaseVersion=%d\n", fReleaseVersion );
stream->WriteString( buf );
// Write out the pages
int i;
for( i = 0; i < fPages.GetCount(); i++ )
{
sprintf(buf, "Page=%s\n", fPages[ i ].GetAsString() );
stream->WriteString(buf);
}
}
// Somewhat of an overkill, but I created it, so I better use it.
// The really nifty (or scary, depending on your viewpoint) thing is that, since
// we only have one section, we can safely use ourselves as the section reader.
// Later I might just add section readers with function pointers to avoid this need entirely
const char *plAgeDescription::GetSectionName( void ) const
{
return "AgeInfo";
}
hsBool plAgeDescription::IParseToken( const char *token, hsStringTokenizer *tokenizer, UInt32 userData )
{
char *tok;
if( !stricmp( token, "StartDateTime" ) )
{
if( ( tok = tokenizer->next() ) != nil )
{
char buf[11];
strncpy(buf, tok, 10); buf[10] = '\0';
fStart.SetSecs(atoi(buf));
}
}
else if (!stricmp(token, "DayLength"))
{
if( ( tok = tokenizer->next() ) != nil )
fDayLength = (float)atof(tok);
}
else if (!stricmp(token, "Page"))
{
fPages.Append( plAgePage( tokenizer->GetRestOfString() ) );
if( fPages[ fPages.GetCount() - 1 ].GetSeqSuffix() == plAgePage::kInvalidSeqSuffix )
fPages[ fPages.GetCount() - 1 ].SetSeqSuffix( fPages.GetCount() );
}
else if (!stricmp(token, "MaxCapacity"))
{
if( ( tok = tokenizer->next() ) != nil )
fMaxCapacity = atoi(tok);
}
else if (!stricmp(token, "LingerTime"))
{
if( ( tok = tokenizer->next() ) != nil )
fLingerTime = atoi(tok);
}
else if( !stricmp(token, "SequencePrefix"))
{
if( ( tok = tokenizer->next() ) != nil )
fSeqPrefix = atoi(tok);
}
else if( !stricmp(token, "ReleaseVersion"))
{
if( ( tok = tokenizer->next() ) != nil )
fReleaseVersion = atoi(tok);
}
return true;
}
//
// Reads the Age Description File
//
void plAgeDescription::Read(hsStream* stream)
{
plInitSectionReader *sections[] = { (plInitSectionReader *)this, nil };
plInitFileReader reader( stream, sections );
if( !reader.IsOpen() )
{
hsAssert( false, "Unable to open age description file for reading" );
return;
}
reader.Parse();
reader.Close();
}
//
// What is the current time in the age (in secs), based on dayLength.
//
int plAgeDescription::GetAgeTimeOfDaySecs(const plUnifiedTime& earthCurrentTime) const
{
double elapsedSecs = GetAgeElapsedSeconds(earthCurrentTime);
int secsInADay = (int)(fDayLength * 60 * 60);
int ageTime = (int)elapsedSecs % secsInADay;
return ageTime;
}
//
// What is the current time in the age (from 0-1), based on dayLength.
//
float plAgeDescription::GetAgeTimeOfDayPercent(const plUnifiedTime& earthCurrentTime) const
{
double elapsedSecs = GetAgeElapsedSeconds(earthCurrentTime);
int secsInADay = (int)(fDayLength * 60 * 60);
double ageTime = fmod(elapsedSecs, secsInADay);
float percent=(float)(ageTime/secsInADay);
if (percent<0.f)
percent=0.f;
if (percent>1.f)
percent=1.f;
return percent;
}
//
// How old is the age in days.
//
double plAgeDescription::GetAgeElapsedDays(plUnifiedTime earthCurrentTime) const
{
earthCurrentTime.SetMicros(0); // Ignore micros for this calculation
double elapsedSecs = GetAgeElapsedSeconds(earthCurrentTime);
return elapsedSecs / 60.0 / 60.0 / fDayLength; // days and fractions
}
//
// How many seconds have elapsed since the age was born. or how old is the age (in secs)
//
double plAgeDescription::GetAgeElapsedSeconds(const plUnifiedTime & earthCurrentTime) const
{
plUnifiedTime elapsed = earthCurrentTime - fStart;
return elapsed.GetSecsDouble();
}
// Static functions for the available common pages
enum CommonPages
{
kTextures,
kGlobal
};
const char *plAgeDescription::GetCommonPage( int pageType )
{
hsAssert( pageType < kNumCommonPages, "Invalid page type in GetCommonPage()" );
return fCommonPages[ pageType ];
}
void plAgeDescription::AppendCommonPages( void )
{
UInt32 startSuffix = 0xffff, i;
if( IsGlobalAge() )
return;
for( i = 0; i < kNumCommonPages; i++ )
fPages.Append( plAgePage( fCommonPages[ i ], startSuffix - i, 0 ) );
}
void plAgeDescription::CopyFrom(const plAgeDescription& other)
{
IDeInit();
fName = hsStrcpy(other.GetAgeName());
int i;
for(i=0;i<other.fPages.GetCount(); i++)
fPages.Append( other.fPages[ i ] );
fStart = other.fStart;
fDayLength = other.fDayLength;
fMaxCapacity = other.fMaxCapacity;
fLingerTime = other.fLingerTime;
fSeqPrefix = other.fSeqPrefix;
fReleaseVersion = other.fReleaseVersion;
}
bool plAgeDescription::FindLocation(const plLocation& loc) const
{
int i;
for( i = 0; i < fPages.GetCount(); i++ )
{
plLocation pageLoc = CalcPageLocation(fPages[i].GetName());
if (pageLoc == loc)
return true;
}
return false;
}

View File

@ -0,0 +1,196 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef PL_AGE_DESCRIPTION_H
#define PL_AGE_DESCRIPTION_H
#include "hsTypes.h"
#include "hsTemplates.h"
#include "hsUtils.h"
#include "../plUnifiedTime/plUnifiedTime.h"
#include "../pnKeyedObject/plUoid.h"
#include "../plFile/plInitFileReader.h"
//
// Age Definition File Reader/Writer
//
class hsStream;
class plAgePage
{
protected:
char *fName;
UInt32 fSeqSuffix;
Byte fFlags;
public:
static const UInt32 kInvalidSeqSuffix;
enum Flags
{
kPreventAutoLoad = 0x01,
kLoadIfSDLPresent = 0x02,
kIsLocalOnly = 0x04,
kIsVolatile = 0x08,
};
plAgePage( const char *name, UInt32 seqSuffix, Byte flags );
plAgePage( char *stringFrom );
plAgePage( const plAgePage &src );
plAgePage();
~plAgePage();
const char *GetName( void ) const { return fName; }
UInt32 GetSeqSuffix( void ) const { return fSeqSuffix; }
Byte GetFlags( void ) const { return fFlags; }
void SetSeqSuffix( UInt32 s ) { fSeqSuffix = s; }
void SetFlags(Byte f, bool on=true);
hsBool SetFromString( const char *string );
char *GetAsString( void ) const;
plAgePage &operator=( const plAgePage &src );
};
// Derived from plInitSectionTokenReader so we can do nifty things with reading the files
class plAgeDescription : public plInitSectionTokenReader
{
private:
char *fName;
Int32 fPageIterator;
hsTArray<plAgePage> fPages;
plUnifiedTime fStart;
float fDayLength;
short fMaxCapacity;
short fLingerTime; // seconds game instance should linger after last player leaves. -1 means never exit.
Int32 fSeqPrefix;
UInt32 fReleaseVersion; // 0 for pre-release, 1+ for actual released ages
static char *fCommonPages[];
void IInit( void );
void IDeInit( void );
// Overload for plInitSectionTokenReader
virtual hsBool IParseToken( const char *token, hsStringTokenizer *tokenizer, UInt32 userData );
public:
static char kAgeDescPath[];
plAgeDescription();
plAgeDescription( const char *fileNameToReadFrom );
plAgeDescription( const plAgeDescription &src )
{
IInit();
CopyFrom( src );
}
~plAgeDescription();
bool ReadFromFile( const char *fileNameToReadFrom ) ;
void Read(hsStream* stream);
void Write(hsStream* stream) const;
// Overload for plInitSectionTokenReader
virtual const char *GetSectionName( void ) const;
const char *GetAgeName( void ) const { return fName; }
void SetAgeNameFromPath( const char *path );
void SetAgeName(const char* ageName) { delete [] fName; fName=hsStrcpy(ageName); }
// Page list
void ClearPageList();
void RemovePage( const char *page );
void AppendPage( const char *name, int seqSuffix = -1, Byte flags = 0 );
void SeekFirstPage( void );
plAgePage *GetNextPage( void );
int GetNumPages() const { return fPages.GetCount(); }
plAgePage *FindPage( const char *name ) const;
bool FindLocation(const plLocation& loc) const;
plLocation CalcPageLocation( const char *page ) const;
// Getters
short GetStartMonth() const { return fStart.GetMonth(); }
short GetStartDay() const { return fStart.GetDay(); }
short GetStartYear() const { return fStart.GetYear(); }
short GetStartHour() const { return fStart.GetHour(); }
short GetStartMinute() const { return fStart.GetMinute(); }
short GetStartSecond() const { return fStart.GetSecond(); }
short GetMaxCapacity() const { return fMaxCapacity; }
short GetLingerTime() const { return fLingerTime;}
float GetDayLength() const { return fDayLength; }
Int32 GetSequencePrefix( void ) const { return fSeqPrefix; }
UInt32 GetReleaseVersion( void ) const { return fReleaseVersion; }
hsBool IsGlobalAge( void ) const { return ( fSeqPrefix < 0 ) ? true : false; }
// Setters
hsBool SetStart(short year, short month, short day, short hour, short minute, short second)
{ return fStart.SetTime(year,month,day,hour,minute,second); }
void SetDayLength(const float l) { fDayLength = l; }
void SetMaxCapacity(const short m) { fMaxCapacity=m; }
void SetLingerTime(const short v) { fLingerTime=v;}
void SetSequencePrefix( Int32 p ) { fSeqPrefix = p; }
void SetReleaseVersion( UInt32 v ) { fReleaseVersion = v; }
// calculations
double GetAgeElapsedDays(plUnifiedTime earthCurrentTime) const;
double GetAgeElapsedSeconds(const plUnifiedTime & earthCurrentTime) const;
int GetAgeTimeOfDaySecs(const plUnifiedTime& earthCurrentTime) const;
float GetAgeTimeOfDayPercent(const plUnifiedTime& earthCurrentTime) const;
// Static functions for the available common pages
enum CommonPages
{
kTextures = 0,
kGlobal,
kNumCommonPages
};
static const char *GetCommonPage( int pageType );
void AppendCommonPages( void );
void CopyFrom(const plAgeDescription& other);
plAgeDescription &operator=( const plAgeDescription &src )
{
CopyFrom( src );
return *this;
}
};
#endif //PL_AGE_DESCRIPTION_H

View File

@ -0,0 +1,248 @@
/*==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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// plManifest - Collection of version-specific info about an age, such //
// as the actual files constructing it, timestamps, and //
// release versions. //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "plAgeManifest.h"
#include "hsUtils.h"
#include "../plFile/hsFiles.h"
#include "../plFile/plFileUtils.h"
#include "../plFile/plInitFileReader.h"
#include "hsStringTokenizer.h"
//// plManifestFile ///////////////////////////////////////////////////////
plManifestFile::plManifestFile(const char* name, const char* serverPath, const plMD5Checksum& check, UInt32 size, UInt32 zippedSize, UInt32 flags, bool md5Now) :
fChecksum(check),
fSize(size),
fZippedSize(zippedSize),
fFlags(flags),
fMd5Checked(md5Now)
{
fName = name;
fServerPath = serverPath;
if (md5Now)
{
DoMd5Check();
}
}
plManifestFile::~plManifestFile()
{
}
void plManifestFile::DoMd5Check()
{
if (plFileUtils::FileExists(fName.c_str()))
{
plMD5Checksum localFile(fName.c_str());
fIsLocalUpToDate = (localFile == fChecksum);
fLocalExists = true;
}
else
{
fIsLocalUpToDate = false;
fLocalExists = false;
}
fMd5Checked = true;
}
bool plManifestFile::IsLocalUpToDate()
{
if (!fMd5Checked)
DoMd5Check();
return fIsLocalUpToDate;
}
bool plManifestFile::LocalExists()
{
if (!fMd5Checked)
DoMd5Check();
return fLocalExists;
}
//// plManifest ///////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
char* plManifest::fTimeFormat = "%m/%d/%y %H:%M:%S";
static const UInt32 kLatestFormatVersion = 5;
plManifest::plManifest()
{
fFormatVersion = kLatestFormatVersion;
fAgeName = nil;
}
plManifest::~plManifest()
{
IReset();
}
void plManifest::IReset()
{
fFormatVersion = 0;
delete [] fAgeName;
int i;
for (i = 0; i < fFiles.GetCount(); i++)
delete fFiles[i];
fFiles.Reset();
}
//// Read and helpers ////////////////////////////////////////////////////////
class plVersSection : public plInitSectionTokenReader
{
protected:
plManifest* fDest;
virtual const char* GetSectionName() const { return "version"; }
virtual hsBool IParseToken(const char* token, hsStringTokenizer* tokenizer, UInt32 userData)
{
if (stricmp(token, "format") == 0)
fDest->SetFormatVersion(atoi(tokenizer->next()));
return true;
}
public:
plVersSection(plManifest* dest) : plInitSectionTokenReader(), fDest(dest) {}
};
class plGenericSection : public plInitSectionTokenReader
{
protected:
plManifest* fDest;
virtual void AddFile(plManifestFile* file) = 0;
plManifestFile* IReadManifestFile(const char* token, hsStringTokenizer* tokenizer, UInt32 userData, bool isPage)
{
char name[256];
strcpy(name, token);
UInt32 size = atoi(tokenizer->next());
plMD5Checksum sum;
sum.SetFromHexString(tokenizer->next());
UInt32 flags = atoi(tokenizer->next());
UInt32 zippedSize = 0;
if (hsCheckBits(flags, plManifestFile::kFlagZipped))
zippedSize = atoi(tokenizer->next());
return TRACKED_NEW plManifestFile(name, "", sum, size, zippedSize, flags);
}
virtual hsBool IParseToken(const char* token, hsStringTokenizer* tokenizer, UInt32 userData)
{
plManifestFile* file = IReadManifestFile(token, tokenizer, userData, false);
AddFile(file);
return true;
}
public:
plGenericSection(plManifest* dest) : plInitSectionTokenReader(), fDest(dest) {}
};
class plBaseSection : public plGenericSection
{
public:
plBaseSection(plManifest* dest) : plGenericSection(dest) {}
protected:
virtual void AddFile(plManifestFile* file) { fDest->AddFile(file); }
virtual const char* GetSectionName() const { return "base"; }
};
bool plManifest::Read(hsStream* stream)
{
plVersSection versReader(this);
plBaseSection baseReader(this);
plInitSectionReader* readers[] = { &versReader, &baseReader, nil };
plInitFileReader reader(readers, 4096); // Allow extra long lines
reader.SetUnhandledSectionReader(&baseReader);
// manifests don't need to be encrypted
reader.SetRequireEncrypted(false);
if (!reader.Open(stream))
return false;
// Clear out before we read
IReset();
if (!reader.Parse())
return false;
return true;
}
bool plManifest::Read(const char* filename)
{
plVersSection versReader(this);
plBaseSection baseReader(this);
plInitSectionReader* readers[] = { &versReader, &baseReader, nil };
plInitFileReader reader(readers, 4096); // Allow extra long lines
reader.SetUnhandledSectionReader(&baseReader);
// manifests don't need to be encrypted
reader.SetRequireEncrypted(false);
if (!reader.Open(filename))
return false;
// Clear out before we read
IReset();
if (!reader.Parse())
return false;
return true;
}
void plManifest::AddFile(plManifestFile* file)
{
fFiles.Append(file);
}

View File

@ -0,0 +1,118 @@
/*==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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// plAgeManifest - Collection of version-specific info about an age, such //
// as the actual files constructing it, timestamps, and //
// release versions. //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _plAgeManifest_h
#define _plAgeManifest_h
#include "hsTypes.h"
#include "hsTemplates.h"
#include "hsUtils.h"
#include "../plUnifiedTime/plUnifiedTime.h"
#include "../plFile/plInitFileReader.h"
#include "../plEncryption/plChecksum.h"
//// Small Container Classes for a Single File ///////////////////////////////
class plManifestFile
{
protected:
std::string fName;
std::string fServerPath;
plMD5Checksum fChecksum;
UInt32 fSize;
UInt32 fZippedSize;
UInt32 fFlags;
bool fMd5Checked;
bool fIsLocalUpToDate;
bool fLocalExists;
public:
// fUser flags
enum
{
// Sound files only
kSndFlagCacheSplit = 1<<0,
kSndFlagStreamCompressed = 1<<1,
kSndFlagCacheStereo = 1<<2,
// Any file
kFlagZipped = 1<<3,
};
plManifestFile(const char* name, const char* serverPath, const plMD5Checksum& check, UInt32 size, UInt32 zippedSize, UInt32 flags, bool md5Now = true);
virtual ~plManifestFile();
const char* GetName() const { return fName.c_str(); }
const char* GetServerPath() const { return fServerPath.c_str(); }
const plMD5Checksum& GetChecksum() const { return fChecksum; }
UInt32 GetDiskSize() const { return fSize; }
UInt32 GetDownloadSize() const { return hsCheckBits(fFlags, kFlagZipped) ? fZippedSize : fSize; }
UInt32 GetFlags() const { return fFlags; }
void DoMd5Check();
bool IsLocalUpToDate();
bool LocalExists();
};
//// Actual Manifest Class ///////////////////////////////////////////////////
class plManifest
{
protected:
UInt32 fFormatVersion;
char* fAgeName; // Mostly just for debugging
hsTArray<plManifestFile*> fFiles;
void IReset();
public:
static char* fTimeFormat; // Standard string for the printed version of our timestamps
void SetFormatVersion(UInt32 v) { fFormatVersion = v; }
void AddFile(plManifestFile* file);
plManifest();
virtual ~plManifest();
bool Read(const char* filename);
bool Read(hsStream* stream);
UInt32 GetFormatVersion() const { return fFormatVersion; }
UInt32 GetNumFiles() const { return fFiles.GetCount(); }
const plManifestFile& GetFile(UInt32 i) const { return *fFiles[i]; }
};
#endif //_plAgeManifest_h