2
3
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-14 14:37:41 +00: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 1301355 additions and 0 deletions

View File

@ -0,0 +1,345 @@
/*==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 "plGenericVar.h"
#include "hsMemory.h"
#include "hsStlUtils.h"
//////////////////////////////////////////////////////
// plGenericType
//////////////////////////////////////////////////////
// reset runtime state, not inherent state
void plGenericType::Reset()
{
fI=0;
}
void plGenericType::CopyFrom(const plGenericType& c)
{
IDeallocString();
fType = c.fType;
if (fType==kString || fType==kAny)
{
fS=hsStrcpy(c.fS);
}
else
{
HSMemory::BlockMove((void*)&c.fI, (void*)&fI, 4);
}
}
//// Conversion Functions ////////////////////////////////////////////////////
const Int32 & plGenericType::IToInt( void ) const
{
hsAssert( fType == kInt || fType == kAny, "Trying to use a non-int parameter as an int!" );
static Int32 i;
if( fType == kAny )
{
hsAssert( fS != nil, "Weird parameter during conversion" );
i = atoi( fS );
return i;
}
return fI;
}
const UInt32 & plGenericType::IToUInt( void ) const
{
hsAssert( fType == kUInt || fType == kAny, "Trying to use a non-int parameter as an int!" );
static UInt32 i;
if( fType == kAny )
{
hsAssert( fS != nil, "Weird parameter during conversion" );
i = atoi( fS );
return i;
}
return fU;
}
const double & plGenericType::IToDouble( void ) const
{
hsAssert( fType == kDouble || fType == kAny, "Trying to use a non-float parameter as a Double!" );
static double d;
if( fType == kAny )
{
hsAssert( fS != nil, "Weird parameter during conversion" );
d = atof( fS );
return d;
}
return fD;
}
const float & plGenericType::IToFloat( void ) const
{
hsAssert( fType == kFloat || fType == kAny, "Trying to use a non-float parameter as a float!" );
static float f;
if( fType == kAny )
{
hsAssert( fS != nil, "Weird parameter during conversion" );
f = (float)atof( fS );
return f;
}
return fF;
}
const bool & plGenericType::IToBool( void ) const
{
hsAssert( fType == kBool || fType == kAny, "Trying to use a non-bool parameter as a bool!" );
static bool b;
if( fType == kAny )
{
hsAssert( fS != nil, "Weird parameter during conversion" );
if( atoi( fS ) > 0 || stricmp( fS, "true" ) == 0 )
b = true;
else
b = false;
return b;
}
return fB;
}
const plGenericType::CharPtr & plGenericType::IToString( void ) const
{
hsAssert( fType == kString || fType == kAny, "Trying to use a non-string parameter as a string!" );
return fS;
}
const char & plGenericType::IToChar( void ) const
{
hsAssert( fType == kChar || fType == kAny, "Trying to use a non-char parameter as a char!" );
static char c;
if( fType == kAny )
{
hsAssert( fS != nil, "Weird parameter during conversion" );
c = fS[ 0 ];
return c;
}
return fC;
}
void plGenericType::Read(hsStream* s)
{
IDeallocString();
s->ReadSwap(&fType);
switch ( fType )
{
case kString:
case kAny:
fS=s->ReadSafeString();
break;
case kBool:
{Int8 b;
s->ReadSwap( &b );
fB = b?true:false;}
break;
case kChar:
s->ReadSwap( &fC );
break;
case kInt :
s->ReadSwap( &fI );
break;
case kUInt:
s->ReadSwap( &fU );
break;
case kFloat:
s->ReadSwap( &fF );
break;
case kDouble:
s->ReadSwap( &fD );
break;
case kNone :
break;
}
}
void plGenericType::Write(hsStream* s)
{
s->WriteSwap(fType);
switch ( fType )
{
case kString:
case kAny:
s->WriteSafeString(fS);
break;
case kBool:
{Int8 b = fB?1:0;
s->WriteSwap( b );}
break;
case kChar:
s->WriteSwap( fC );
break;
case kInt :
s->WriteSwap( fI );
break;
case kUInt:
s->WriteSwap( fU );
break;
case kFloat:
s->WriteSwap( fF );
break;
case kDouble:
s->WriteSwap( fD );
break;
case kNone :
break;
}
}
///////////////////////////////////////////////////
///////////////////////////////////////////////////
void plGenericVar::Read(hsStream* s)
{
delete [] fName;
fName = s->ReadSafeString();
fValue.Read(s);
}
void plGenericVar::Write(hsStream* s)
{
s->WriteSafeString(fName);
fValue.Write(s);
}
//////////////////////////////////
void plGenericType::SetVar(Types t, unsigned int size, void* val)
{
fType = t;
switch (t)
{
case kInt :
{
hsAssert(size <= sizeof(fI), "plGenericType::SetVar size too large for int");
memcpy(&fI, val, size);
break;
}
case kUInt :
{
hsAssert(size <= sizeof(fU), "plGenericType::SetVar size too large for unsigned int");
memcpy(&fU, val, size);
break;
}
case kFloat :
{
hsAssert(size <= sizeof(fF), "plGenericType::SetVar size too large for float");
memcpy(&fF, val, size);
break;
}
case kDouble :
{
hsAssert(size <= sizeof(fD), "plGenericType::SetVar size too large for double");
memcpy(&fD, val, size);
break;
}
case kBool :
{
hsAssert(size <= sizeof(fB), "plGenericType::SetVar size too large for bool");
memcpy(&fB, val, size);
break;
}
case kChar :
{
hsAssert(size <= sizeof(fC), "plGenericType::SetVar size too large for char");
memcpy(&fC, val, size);
break;
}
case kString :
{
delete [] fS;
fS = TRACKED_NEW char[size+1];
memcpy(fS,val,size);
fS[size] = 0;
break;
}
case kNone :
break;
default:
hsAssert(false,"plGenericType::SetVar unknown type");
}
}
std::string plGenericType::GetAsStdString() const
{
std::string s;
switch (fType)
{
case kInt :
{
xtl::format(s,"%d",fI);
break;
}
case kBool :
case kUInt :
{
xtl::format(s,"%u",fType==kBool?fB:fU);
break;
}
case kFloat :
case kDouble :
{
xtl::format(s,"%f",fType==kDouble?fD:fF);
break;
}
case kChar :
{
xtl::format(s,"%c",fC);
break;
}
case kAny :
case kString :
{
s = fS;
break;
}
case kNone :
break;
default:
hsAssert(false,"plGenericType::GetAsStdString unknown type");
}
return s;
}

View File

@ -0,0 +1,181 @@
/*==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 plGenericVar_inc
#define plGenericVar_inc
#include "hsTypes.h"
#include "hsUtils.h"
#include "hsStlUtils.h"
#include "../pnFactory/plCreatable.h"
class hsStream;
//
// a generic (unioned) type
//
class plGenericType
{
public:
typedef char* CharPtr;
protected:
union
{
Int32 fI;
UInt32 fU;
float fF;
double fD;
bool fB;
CharPtr fS;
char fC;
};
public:
enum Types
{
kInt = 0,
kFloat,
kBool,
kString,
kChar,
kAny,
kUInt,
kDouble,
kNone = 0xff
};
protected:
UInt8 fType;
const Int32 &IToInt( void ) const;
const UInt32 &IToUInt( void ) const;
const float &IToFloat( void ) const;
const double &IToDouble( void ) const;
const bool &IToBool( void ) const;
const CharPtr &IToString( void ) const;
const char &IToChar( void ) const;
void IDeallocString() { if (fType==kString || fType==kAny) {delete [] fS; fS=nil;} }
public:
plGenericType() : fType(kNone) { Reset(); }
plGenericType(const plGenericType& c) { CopyFrom(c); }
virtual ~plGenericType() { IDeallocString(); }
plGenericType& operator=(const plGenericType& c) { CopyFrom(c); return *this; }
void CopyFrom(const plGenericType& c);
virtual void Reset();
operator Int32() const { return IToInt(); }
operator UInt32() const { return IToUInt(); }
operator double() const { return IToDouble(); }
operator float() const { return IToFloat(); }
operator bool() const { return IToBool(); }
operator const CharPtr() const { return IToString(); }
operator char() const { return IToChar(); }
operator unsigned int() const { return IToUInt(); }
operator int() const { return IToInt(); }
void SetType(Types t) { fType=t; }
UInt8 GetType( void ) const { return fType; }
std::string GetAsStdString() const;
// implicit set
void Set( Int32 i ) { fI = i; fType = kInt; }
void Set( UInt32 i ) { fU = i; fType = kUInt; }
void Set( float f ) { fF = f; fType = kFloat; }
void Set( double d ) { fD = d; fType = kDouble; }
void Set( bool b ) { fB = b; fType = kBool; }
void Set( CharPtr s ) { IDeallocString(); fS = hsStrcpy(s); fType = kString; }
void Set( char c ) { fC = c; fType = kChar; }
// explicit set
void SetInt( Int32 i ) { fI = i; fType = kInt; }
void SetUInt( UInt32 i ) { fU = i; fType = kUInt; }
void SetFloat( float f ) { fF = f; fType = kFloat; }
void SetDouble( double d ) { fD = d; fType = kDouble; }
void SetBool( bool b ) { fB = b; fType = kBool; }
void SetString( CharPtr s ) { IDeallocString(); fS = hsStrcpy(s); fType = kString; }
void SetChar( char c ) { fC = c; fType = kChar; }
void SetAny( CharPtr s ) { IDeallocString(); fS = hsStrcpy(s); fType = kAny; }
void SetNone( void ) { fType = kNone; }
void SetVar(Types t, unsigned int size, void* val);
virtual void Read(hsStream* s);
virtual void Write(hsStream* s);
};
//
// a generic variable (similar to pfConsoleCmdParam)
//
class plGenericVar
{
protected:
plGenericType fValue;
char* fName;
public:
plGenericVar(const plGenericVar &c) : fName(nil) { CopyFrom(c); }
plGenericVar(const char* name=nil) : fName(nil) { SetName(name); }
virtual ~plGenericVar() { delete [] fName; }
virtual void Reset() { Value().Reset(); } // reset runtime state, not inherent state
plGenericVar& operator=(const plGenericVar &c) { CopyFrom(c); return *this; }
void CopyFrom(const plGenericVar &c) { delete [] fName; fName=hsStrcpy(c.GetName()); fValue=c.Value(); }
const char* GetName() const { return fName; }
void SetName(const char* n) { delete [] fName; fName = hsStrcpy(n); }
plGenericType& Value() { return fValue; }
const plGenericType& Value() const { return fValue; }
virtual void Read(hsStream* s);
virtual void Write(hsStream* s);
};
// A creatable wrapper for plGenericType
class plCreatableGenericValue : public plCreatable
{
public:
plGenericType fValue;
CLASSNAME_REGISTER( plCreatableGenericValue );
GETINTERFACE_ANY( plCreatableGenericValue, plCreatable );
void Read(hsStream* s, hsResMgr* mgr) { fValue.Read(s);}
void Write(hsStream* s, hsResMgr* mgr) { fValue.Write(s);}
plGenericType& Value() { return fValue; }
const plGenericType& Value() const { return fValue; }
operator Int32() const { return (Int32)fValue; }
operator UInt32() const { return (UInt32)fValue; }
operator float() const { return (float)fValue; }
operator double() const { return (double)fValue; }
operator bool() const { return (bool)fValue; }
operator const char *() const { return (const char *)fValue; }
operator char() const { return (char)fValue; }
};
#endif

View File

@ -0,0 +1,149 @@
/*==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 SERVER
#include "plNetAddress.h"
#include "pnNetCommon.h"
plNetAddress::plNetAddress()
{
Clear();
}
plNetAddress::plNetAddress(UInt32 addr, int port)
{
Clear();
SetHost(addr);
SetPort(port);
}
plNetAddress::plNetAddress(const char * addr, int port)
{
Clear();
SetHost(addr);
SetPort(port);
}
bool plNetAddress::SetAnyAddr()
{
fAddr.sin_family = AF_INET;
fAddr.sin_addr.s_addr = INADDR_ANY;
return true;
}
bool plNetAddress::SetAnyPort()
{
fAddr.sin_family = AF_INET;
fAddr.sin_port = htons(0);
return true;
}
bool plNetAddress::SetPort(int port)
{
fAddr.sin_family = AF_INET;
fAddr.sin_port = htons(port);
return true;
}
void plNetAddress::Clear()
{
memset(&fAddr,0,sizeof(fAddr));
fAddr.sin_family = AF_INET;
fAddr.sin_addr.s_addr = INADDR_ANY;
}
int plNetAddress::GetPort() const
{
return ntohs(fAddr.sin_port);
}
std::string plNetAddress::GetHostString() const
{
return std::string(pnNetCommon::GetTextAddr(fAddr.sin_addr.s_addr));
}
UInt32 plNetAddress::GetHost() const
{
return fAddr.sin_addr.s_addr;
}
std::string plNetAddress::GetHostWithPort() const
{
static const int buf_len = 1024;
char buf[buf_len];
sprintf(buf,"%s:%d",pnNetCommon::GetTextAddr(fAddr.sin_addr.s_addr),GetPort());
return std::string(buf);
}
bool plNetAddress::SetHost(const char * hostname)
{
fAddr.sin_addr.s_addr = pnNetCommon::GetBinAddr(hostname);
fAddr.sin_family = AF_INET;
return true;
}
bool plNetAddress::SetHost(UInt32 addr)
{
memcpy(&fAddr.sin_addr, &addr,sizeof(addr));
fAddr.sin_family = AF_INET;
return true;
}
std::string plNetAddress::AsString() const
{
char buf[100] = "";
sprintf(buf,"IP:%s:%d",pnNetCommon::GetTextAddr(fAddr.sin_addr.s_addr),GetPort());
return std::string(buf);
}
void plNetAddress::Read(hsStream * s)
{
s->ReadSwap((UInt32*)&fAddr.sin_addr.s_addr);
s->ReadSwap(&fAddr.sin_port);
s->ReadSwap(&fAddr.sin_family);
}
void plNetAddress::Write(hsStream * s)
{
s->WriteSwap((UInt32)fAddr.sin_addr.s_addr);
s->WriteSwap(fAddr.sin_port);
s->WriteSwap(fAddr.sin_family);
}
#endif

View File

@ -0,0 +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==*/
#ifndef SERVER
#ifndef plNetAddress_h_inc
#define plNetAddress_h_inc
#include "hsUtils.h"
#include "hsStlUtils.h"
#include "hsStream.h"
#if defined(HS_BUILD_FOR_WIN32)
#include "hsWindows.h"
#elif defined( HS_BUILD_FOR_UNIX )
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#else
#error "Must Include net stuff for this OS here"
#endif
#ifdef SetPort
#undef SetPort
#endif
typedef sockaddr_in AddressType;
class plNetAddress
{
// fAddr must be first field
AddressType fAddr;
public:
plNetAddress();
plNetAddress(UInt32 addr, int port);
plNetAddress(const char * addr, int port);
virtual ~plNetAddress(){}
void Clear();
bool SetAnyAddr();
bool SetAnyPort();
bool SetPort(int port);
bool SetHost(const char * hostname);
bool SetHost(UInt32 ip4addr);
int GetPort() const;
std::string GetHostString() const;
UInt32 GetHost() const;
std::string GetHostWithPort() const;
const AddressType & GetAddressInfo() const { return fAddr; }
AddressType & GetAddressInfo() { return fAddr; }
std::string AsString() const;
void Read(hsStream * stream);
void Write(hsStream * stream);
};
#endif // plNetAddress_h_inc
#endif // SERVER

View File

@ -0,0 +1,153 @@
/*==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 "plNetApp.h"
#include "hsStlUtils.h"
#include "../pnMessage/plMessage.h"
plNetApp* plNetApp::fInstance = nil;
plNetObjectDebuggerBase* plNetObjectDebuggerBase::fInstance=nil;
//
// STATIC
//
plNetApp* plNetApp::GetInstance()
{
return fInstance;
}
void plNetApp::SetInstance(plNetApp* app)
{
fInstance = app;
}
bool plNetApp::StaticErrorMsg(const char* fmt, ...)
{
if ( !GetInstance() )
return true;
va_list args;
va_start(args, fmt);
return GetInstance()->ErrorMsgV(fmt, args);
}
bool plNetApp::StaticDebugMsg(const char* fmt, ...)
{
if ( !GetInstance() )
return true;
va_list args;
va_start(args, fmt);
return GetInstance()->DebugMsgV(fmt, args);
}
bool plNetApp::StaticWarningMsg(const char* fmt, ...)
{
if ( !GetInstance() )
return true;
va_list args;
va_start(args, fmt);
return GetInstance()->WarningMsgV(fmt, args);
}
bool plNetApp::StaticAppMsg(const char* fmt, ...)
{
if ( !GetInstance() )
return true;
va_list args;
va_start(args, fmt);
return GetInstance()->AppMsgV(fmt, args);
}
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
plNetClientApp::plNetClientApp() : fCCRLevel(0)
{
}
//
// STATIC FXN
// Inherit net cascade state. Msg version
//
void plNetClientApp::InheritNetMsgFlags(const plMessage* parentMsg, plMessage* childMsg, bool startCascade)
{
if (childMsg)
{
UInt32 childMsgFlags = childMsg->GetAllBCastFlags();
InheritNetMsgFlags(parentMsg ? parentMsg->GetAllBCastFlags() : 0, &childMsgFlags, startCascade);
childMsg->SetAllBCastFlags(childMsgFlags);
}
}
//
// STATIC FXN
// Inherit net cascade state. Flags version
// Set startCasCascade=true if called from outside the dispatcher, so that
// the dispatcher won't mess with the flags when it goes to send out the msg.
//
void plNetClientApp::InheritNetMsgFlags(UInt32 parentMsgFlags, UInt32* childMsgFlags, bool startCascade)
{
if (!(*childMsgFlags & plMessage::kNetStartCascade))
{
if (parentMsgFlags & plMessage::kNetSent)
*childMsgFlags |= plMessage::kNetSent;
else
*childMsgFlags &= ~plMessage::kNetSent;
if (parentMsgFlags & plMessage::kNetNonLocal)
*childMsgFlags |= plMessage::kNetNonLocal;
else
*childMsgFlags &= ~plMessage::kNetNonLocal;
if (startCascade)
*childMsgFlags |= plMessage::kNetStartCascade;
else
*childMsgFlags &= ~plMessage::kNetStartCascade;
}
}
//
// STATIC
//
void plNetClientApp::UnInheritNetMsgFlags(plMessage* msg)
{
msg->SetBCastFlag( plMessage::kCCRSendToAllPlayers, 0 );
// if msg was propagated from another client...(and not originated on the server)
if (msg && msg->HasBCastFlag(plMessage::kNetPropagate))
{
// This msg (and all it's responses) should not be resent, since we just recvd it.
// Make sure it's marked for localPropagation now that it has arrived.
// Also flag it as a remote (non-local) msg
msg->SetBCastFlag(plMessage::kNetSent |
plMessage::kNetNonLocal |
plMessage::kLocalPropagate |
plMessage::kNetStartCascade);
// clear the 'force' option, so it doesn't get sent out again
msg->SetBCastFlag(plMessage::kNetForce | plMessage::kNetNonDeterministic, 0);
}
}

View File

@ -0,0 +1,245 @@
/*==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 plNetApp_h
#define plNetApp_h
#include "hsTypes.h"
#include "hsStlUtils.h"
#include "hsBitVector.h"
#include "plNetGroup.h"
#include "../pnKeyedObject/hsKeyedObject.h"
#include "../pnKeyedObject/plUoid.h"
#include "../../PubUtilLib/plStatusLog/plLoggable.h"
#include <stdarg.h>
#define plVerifyConditionRet(NetApp,cond,ret,str) \
do { \
if (!(cond)) { \
char * _str_ = str; \
(NetApp)->ErrorMsg(_str_); \
hsAssert(cond,_str_); \
return ret; \
} \
} while (0)
#define plVerifyCondition(NetApp,cond,str) \
plVerifyConditionRet(NetApp,cond,hsFail,str)
class plNetMember;
class plSynchedObject;
class plKey;
class plNetMessage;
typedef std::vector<plNetMember*> plNetMemberList;
typedef std::vector<UInt32> plNetPlayerIDList;
//
// Common baseclasses for client and server net apps
//
class plNetApp : public hsKeyedObject, public plLoggable // so it can recv messages
{
protected:
static plNetApp* fInstance;
hsBitVector fFlagsVec;
public:
enum FlagBits // common to both client and server
{
kNullSend=0,
kNetCoreSingleThreaded,
kScreenMessages, // filter out illegal net game messages, used by gameserver&client
FLAG_CEILING = 10 // stay below this or conflict with client/server specific flags
};
static plNetApp* GetInstance();
static void SetInstance(plNetApp* app);
plNetApp() {}
virtual ~plNetApp() {}
CLASSNAME_REGISTER( plNetApp );
GETINTERFACE_ANY( plNetApp, hsKeyedObject);
virtual void Shutdown() {}
void SetFlagsBit(int b, hsBool on=true) { fFlagsVec.SetBit(b, on); }
bool GetFlagsBit(int b) const { return fFlagsVec.IsBitSet(b) ? true : false; }
static bool StaticWarningMsg(const char* fmt, ...);
static bool StaticErrorMsg(const char* fmt, ...);
static bool StaticDebugMsg(const char* fmt, ...);
static bool StaticAppMsg(const char* fmt, ...);
};
//
// base netApp class specific to client code
//
class plVaultPlayerNode;
class plNetClientApp : public plNetApp
{
private:
int fCCRLevel; // 0 for players, 1-4 for CCRs
friend class plDispatch;
virtual int ISendGameMessage(plMessage* msg) { hsAssert(false, "stub"); return hsFail; }
public:
enum ClientFlagBits
{
kDeferMsgs = FLAG_CEILING, // currently ignoring most msgs because the game is not active
kDisabled, // client. networking has been disabled
kDisableOnNextUpdate, // client. disable networking in next update call
kLocalTriggers, // marks all triggers as local only
kEchoVoice, // send voice packets back to the speaker
kRequestP2P, // wants to play peer to peer
kIndirectMember, // behind a firewall, can't player P2P
kSendingVoice, // sending a voice packet
kSendingActions, // sending a game message
kAllowTimeOut, // allow clients to timeout and be kicked off the server
kAllowAuthTimeOut, // allow clients to timeout while authenticating
kPlayingGame, // set when client is actively part of an age.
kShowLists, // debug info on-screen
kShowRooms, // debug info on-screen
kShowAvatars, // Avatar position/orientation info
kShowRelevanceRegions, // debug info on-screen
kConnectedToVault, // initial connection to vault achieved
kBanLinking, // player is not allowed to link
kSilencePlayer, // player's outbound communication is shutoff
kConsoleOutput, // net log output is echoed to console
kLoadingInitialAgeState, // set when we first link in to an age and are recving its initial state
kLaunchedFromSetup, // set if we were launched from the setup program
kCCRVaultConnected, // set if we've connected to the CCR vault
kNetClientCommInited, // set if the netClientComm interface has been initialized
kNeedToSendInitialAgeStateLoadedMsg,// internal use only, when we need to send plInitialAgeStateLoadedMsg
kNeedToSendAgeLoadedMsg,
kDemoMode, // set if this is a demo - limited play
kNeedInitialAgeStateCount, // the server must tell us how many age states to expect
kLinkingToOfflineAge, // set if we're linking to the startup age
};
CLASSNAME_REGISTER( plNetClientApp );
GETINTERFACE_ANY( plNetClientApp, plNetApp);
plNetClientApp();
// statics
static plNetClientApp* GetInstance() { return plNetClientApp::ConvertNoRef(fInstance); }
static const plNetClientApp* GetConstInstance() { return plNetClientApp::ConvertNoRef(fInstance); }
static void InheritNetMsgFlags(const plMessage* parentMsg, plMessage* childMsg, bool startCascade);
static void InheritNetMsgFlags(UInt32 parentMsgFlags, UInt32* childMsgFlags, bool startCascade);
static void UnInheritNetMsgFlags(plMessage* msg);
// functions that all net client apps should implement
virtual int SendMsg(plNetMessage* msg) = 0;
virtual UInt32 GetPlayerID() const = 0;
virtual const char * GetPlayerName( const plKey avKey=nil ) const = 0;
// commonly used net client app functions
virtual float GetCurrentAgeTimeOfDayPercent() const { hsAssert(false, "stub"); return 0.; }
virtual bool ObjectInLocalAge(const plSynchedObject* obj) const { hsAssert(false, "stub"); return false; }
virtual UInt8 GetJoinOrder() const { hsAssert(false, "stub"); return 0; }
virtual hsBool IsRemotePlayerKey(const plKey p, int* idx=nil) { hsAssert(false, "stub"); return false; }
virtual plKey GetLocalPlayerKey() const { hsAssert(false, "stub"); return nil; }
virtual plSynchedObject* GetLocalPlayer(hsBool forceLoad=false) const { hsAssert(false, "stub"); return nil; }
virtual plNetGroupId SelectNetGroup(plSynchedObject* objIn, plKey groupKey) { hsAssert(false, "stub"); return plNetGroup::kNetGroupUnknown; }
virtual int IsLocallyOwned(const plSynchedObject* obj) const { hsAssert(false, "stub"); return 0; }
virtual int IsLocallyOwned(const plUoid&) const { hsAssert(false, "stub"); return 0; }
virtual plNetGroupId GetEffectiveNetGroup(const plSynchedObject* obj) const { hsAssert(false, "stub"); return plNetGroup::kNetGroupUnknown; }
virtual int Update(double secs) { return hsOK;}
virtual const char* GetServerLogTimeAsString(std::string& ts) const { hsAssert(false, "stub"); return nil; }
virtual plUoid GetAgeSDLObjectUoid(const char* ageName) const { hsAssert(false, "stub"); return plUoid(); }
virtual void StayAlive(double secs) {}
virtual void QueueDisableNet( bool showDlg, const char msg[] ) {}
bool IsEnabled() const { return !GetFlagsBit(kDisabled); }
bool InDemoMode() const { return GetFlagsBit(kDemoMode); }
bool IsLoadingInitialAgeState() const { return GetFlagsBit(kLoadingInitialAgeState); }
void SetLaunchedFromSetup(bool b) { SetFlagsBit(kLaunchedFromSetup, b); }
bool GetLaunchedFromSetup() const { return GetFlagsBit(kLaunchedFromSetup); }
// CCR stuff
#ifdef PLASMA_EXTERNAL_RELEASE
void SetCCRLevel(int level) { }
int GetCCRLevel() const { return 0; }
bool AmCCR() const { return false; }
#else
void SetCCRLevel(int level) { fCCRLevel=level; }
int GetCCRLevel() const { return fCCRLevel; }
bool AmCCR() const { return (fCCRLevel>0); }
#endif
};
//
// base netApp class specific to server code
//
class plNetServerApp : public plNetApp
{
public:
enum ServerFlagBits
{
kLastFlagBitsValue = FLAG_CEILING, // get past plNetApp flags
kDone, // exit update loop.
kDumpStats, // dump stats to log file
kDisableStateLogging, // used by gameserver
kGameStateIsDirty, // used by gameserver
kDumpConfigDoc, // dump config options queries to log file
kProtectedServer, // set by a protected lobby
kRequireProtectedCCRs, // CCRS must have logged in thru a protected lobby, used by gameserver
kProcessedPendingMsgs, // Used by front-end server
};
CLASSNAME_REGISTER( plNetServerApp );
GETINTERFACE_ANY( plNetServerApp, plNetApp);
virtual int SendMsg(plNetMessage* msg) = 0;
};
//
// abstract base class for net client object debugger
//
class plNetObjectDebuggerBase
{
private:
static plNetObjectDebuggerBase* fInstance;
public:
static plNetObjectDebuggerBase* GetInstance() { return fInstance; }
static void SetInstance(plNetObjectDebuggerBase* i) { fInstance=i; }
virtual bool IsDebugObject(const hsKeyedObject* obj) const = 0;
virtual void LogMsgIfMatch(const char* msg) const = 0; // write to status log if there's a string match
virtual void LogMsg(const char* msg) const = 0;
virtual bool GetDebugging() const = 0;
virtual void SetDebugging(bool b) = 0;
};
#endif // plNetApp_h

View File

@ -0,0 +1,44 @@
/*==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 plNetCommonStats_inc
#define plNetCommonStats_inc
/*
//
// abstract class for NetCore stats
//
class hsStream;
class plNetCommonStats
{
public:
plNetCommonStats() {}
virtual ~plNetCommonStats() {}
virtual void Read(hsStream* s) = 0;
virtual void Write(hsStream* s) = 0;
virtual plNetCommonStats* Copy() const = 0;
};
*/
#endif // plNetCommonStats_inc

View File

@ -0,0 +1,32 @@
/*==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 "plNetGroup.h"
plNetGroupId plNetGroup::kNetGroupUnknown( plLocation::MakeReserved( 0 ) );
plNetGroupId plNetGroup::kNetGroupLocalPlayer( plLocation::MakeReserved( 1 ), 1);
plNetGroupId plNetGroup::kNetGroupRemotePlayer( plLocation::MakeReserved( 2 ) , 1);
plNetGroupId plNetGroup::kNetGroupLocalPhysicals( plLocation::MakeReserved( 3 ) , 1);
plNetGroupId plNetGroup::kNetGroupRemotePhysicals( plLocation::MakeReserved( 4 ) , 1);

View File

@ -0,0 +1,77 @@
/*==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 plNetGroup_h
#define plNetGroup_h
#include "../pnKeyedObject/plUoid.h"
#include "hsStream.h"
#include "hsStlUtils.h"
class plNetGroupId
{
private:
enum NetGroupConstants
{
kNetGroupConstant = 0x01,
kNetGroupLocal = 0x02,
};
plLocation fId;
UInt8 fFlags;
std::string fDesc; // description of room
public:
plNetGroupId() : fFlags(0) {}
plNetGroupId(const plLocation& id, const UInt8 flags) : fId(id), fFlags(flags) { }
plNetGroupId(const plLocation& id) : fId(id), fFlags(0) { }
hsBool IsConstant() { return (fFlags & kNetGroupConstant) != 0; }
void SetConstant(hsBool constantGroup) { fFlags &= constantGroup ? kNetGroupConstant : 0; }
plLocation& Room() { return fId; }
const char* GetDesc() const { return fDesc.c_str(); }
void SetDesc(const char* c) { fDesc = c; }
hsBool operator==(const plNetGroupId& netGroup) const { return fId == netGroup.fId; }
hsBool operator!=(const plNetGroupId& netGroup) const { return fId != netGroup.fId; }
bool operator<(const plNetGroupId& netGroup) const { return fId < netGroup.fId; }
// read and write to hsStream
void Write(hsStream *s) const { fId.Write(s); s->WriteSwap(fFlags); }
void Read(hsStream *s) { fId.Read(s); s->LogReadSwap(&fFlags,"GroupId Flags"); }
};
namespace plNetGroup
{
extern plNetGroupId kNetGroupLocalPlayer;
extern plNetGroupId kNetGroupRemotePlayer;
extern plNetGroupId kNetGroupUnknown;
extern plNetGroupId kNetGroupLocalPhysicals;
extern plNetGroupId kNetGroupRemotePhysicals;
}
#endif // plNetGroup_h

View File

@ -0,0 +1,128 @@
/*==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 "plNetServers.h"
// Server Defns
const char* plNetServerConstants::ServerPrograms[] =
{
#ifndef HS_DEBUGGING
#if HS_BUILD_FOR_WIN32
"plNetServerAgent.exe",
"plNetLobbyServer.exe",
"plNetGameServer.exe",
"plNetVaultServer.exe",
"plNetAuthServer.exe",
"plNetAdminServer.exe",
"plNetLookupServer.exe",
#elif HS_BUILD_FOR_UNIX
"plNetServerAgent",
"plNetLobbyServer",
"plNetGameServer",
"plNetVaultServer",
"plNetAuthServer",
"plNetAdminServer",
"plNetLookupServer",
#else
#error "No servers work on this Platform!"
#endif
#else // Debug
#if HS_BUILD_FOR_WIN32
"plNetServerAgent_dbg.exe",
"plNetLobbyServer_dbg.exe",
"plNetGameServer_dbg.exe",
"plNetVaultServer_dbg.exe",
"plNetAuthServer_dbg.exe",
"plNetAdminServer_dbg.exe",
"plNetLookupServer_dbg.exe",
#elif HS_BUILD_FOR_UNIX
"plNetServerAgent.dbg",
"plNetLobbyServer.dbg",
"plNetGameServer.dbg",
"plNetVaultServer.dbg",
"plNetAuthServer.dbg",
"plNetAdminServer.dbg",
"plNetLookupServer.dbg",
#else
#error "No servers work on this Platform!"
#endif
#endif
};
//
// STATIC
//
const char* plNetServerConstants::GetServerName(int type)
{
switch(type)
{
default:
// hsAssert(false, "unknown type"); // not the right place to catch this problem.
return "UNKNOWN";
case kAgent:
return plNetServerAgentConstants::GetName();
case kLobby:
return plNetLobbyServerConstants::GetName();
case kGame:
return plNetGameServerConstants::GetName();
case kVault:
return plNetVaultServerConstants::GetName();
case kAuth:
return plNetAuthServerConstants::GetName();
case kAdmin:
return plNetAdminServerConstants::GetName();
case kLookup:
return plNetLookupServerConstants::GetName();
case kClient:
return "plClient";
}
}
UInt16 plNetServerConstants::GetPort(int type)
{
switch(type)
{
default:
// hsAssert(false, "unknown type"); // not the right place to catch this problem.
return 0;
case kGame:
return 0;
case kAgent:
return plNetServerAgentConstants::GetPort();
case kLobby:
return plNetLobbyServerConstants::GetPort();
case kVault:
return plNetVaultServerConstants::GetPort();
case kAuth:
return plNetAuthServerConstants::GetPort();
case kAdmin:
return plNetAdminServerConstants::GetPort();
case kLookup:
return plNetLookupServerConstants::GetPort();
}
}

View File

@ -0,0 +1,148 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef PL_NET_SERVERS_H
#define PL_NET_SERVERS_H
//
// Server Declarations and Constants
//
#include "hsTypes.h"
//
// Windows Class Name for All Servers
//
#define PARABLE_WINCLASSNAME "ParableServer"
#define PARABLE_PLS_WINCLASSNAME "ParableServer_PLS"
class plNetServerConstants
{
public:
enum ServerTypes // Changing the order WILL affect Data including Databases!!!
{
kInvalidLo,
kAgent,
kLobby,
kGame,
kVault,
kAuth,
kAdmin,
kLookup,
kClient,
kInvalidHi,
};
private:
static const char* ServerPrograms[];
public:
static const char* GetServerExe(int type) { return (type > kInvalidLo && type < kInvalidHi)?ServerPrograms[type-1]:nil; }
static const char* GetServerName(int type);
static UInt16 GetPort(int type);
static const char* GetServerTypeStr(int type)
{
switch(type)
{
case kAgent: return "kAgent";
case kLobby: return "kLobby";
case kGame: return "kGame";
case kVault: return "kVault";
case kAuth: return "kAuth";
case kAdmin: return "kAdmin";
case kLookup: return "kLookup";
case kClient: return "kClient";
default: return "???";
}
}
};
class plNetServerAgentConstants
{
public:
static const char* GetName() { return "Server_Agent"; }
static const UInt16 GetPort() { return 4800; }
static const plNetServerConstants::ServerTypes GetType() { return plNetServerConstants::kAgent; }
};
class plNetLookupServerConstants
{
public:
static const char* GetName() { return "Lookup_Server"; }
static const UInt16 GetPort() { return 2000; }
static const plNetServerConstants::ServerTypes GetType() { return plNetServerConstants::kLookup; }
};
class plNetLobbyServerConstants
{
public:
static const char* GetName() { return "Generated_Lobby"; }
static const UInt16 GetPort() { return 5000; }
static const plNetServerConstants::ServerTypes GetType() { return plNetServerConstants::kLobby; }
};
class plNetVaultServerConstants
{
public:
static const char* GetName() { return "Vault_Server"; }
static const UInt16 GetPort() { return 2001; }
static const plNetServerConstants::ServerTypes GetType() { return plNetServerConstants::kVault; }
};
class plNetAuthServerConstants
{
public:
static const char* GetName() { return "Auth_Server"; }
static const UInt16 GetPort() { return 2002; }
static const plNetServerConstants::ServerTypes GetType() { return plNetServerConstants::kAuth; }
};
class plNetAdminServerConstants
{
public:
static const char* GetName() { return "Admin_Server"; }
static const UInt16 GetPort() { return 2003; }
static const plNetServerConstants::ServerTypes GetType() { return plNetServerConstants::kAdmin; }
};
class plNetGameServerConstants
{
public:
static const char* GetName() { return "Game_Server"; }
static const UInt16 GetLowPort() { return 5001;}
static const UInt16 GetHighPort() { return 6001;}
static const plNetServerConstants::ServerTypes GetType() { return plNetServerConstants::kGame; }
};
#endif //PL_NET_SERVERS_H

View File

@ -0,0 +1,99 @@
/*==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 "plNetSharedState.h"
#include "plGenericVar.h"
#include "../pnMessage/plMessage.h"
plNetSharedState::plNetSharedState(char* name) : fServerMayDelete(false)
{
SetName(name);
}
plNetSharedState::~plNetSharedState()
{
Reset();
}
void plNetSharedState::Reset()
{
int i;
for(i=0;i<fVars.size();i++)
delete fVars[i];
fVars.clear();
}
void plNetSharedState::Copy(plNetSharedState *ss)
{
Reset();
// copy name
SetName(ss->GetName());
SetServerMayDelete(ss->GetServerMayDelete());
// copy vars
int i;
for(i=0;i<ss->GetNumVars();i++)
{
plGenericVar* sv = TRACKED_NEW plGenericVar;
*sv = *(ss->GetVar(i));
AddVar(sv);
}
}
void plNetSharedState::Read(hsStream* stream)
{
Reset();
plMsgStdStringHelper::Peek(fName, stream);
Int32 num=stream->ReadSwap32();
fServerMayDelete = stream->Readbool();
fVars.reserve(num);
int i;
for(i=0;i<num;i++)
{
plGenericVar* v = TRACKED_NEW plGenericVar;
v->Read(stream);
AddVar(v);
}
}
void plNetSharedState::Write(hsStream* stream)
{
plMsgStdStringHelper::Poke(fName, stream);
Int32 num=GetNumVars();
stream->WriteSwap32(num);
stream->Writebool(fServerMayDelete);
int i;
for(i=0;i<num;i++)
{
fVars[i]->Write(stream);
}
}

View File

@ -0,0 +1,70 @@
/*==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 plNetSharedState_inc
#define plNetSharedState_inc
#include "hsTypes.h"
#include "hsUtils.h"
#include "hsStlUtils.h"
class hsStream;
//
// used to exchange generic state with the server
//
class plGenericVar;
class plNetSharedState
{
protected:
std::string fName;
std::vector<plGenericVar*> fVars;
bool fServerMayDelete; // ok to delete (don't save) since this state is equivalent to the default state
public:
plNetSharedState(char* name=nil);
virtual ~plNetSharedState();
virtual void Copy(plNetSharedState* ss);
void Reset();
int GetNumVars() const { return fVars.size(); }
plGenericVar* GetVar(int i) const { return fVars[i]; }
void RemoveVar(int i) { fVars.erase(fVars.begin()+i); }
void AddVar(plGenericVar* v) { fVars.push_back(v); }
const char* GetName() const { return fName.c_str(); }
void SetName(const char* n) { if (n) fName=n; }
bool GetServerMayDelete() const { return fServerMayDelete; }
void SetServerMayDelete(bool d) { fServerMayDelete=d; }
// IO
virtual void Read(hsStream* stream);
virtual void Write(hsStream* stream);
};
#endif // plNetSharedState_inc

View File

@ -0,0 +1,39 @@
/*==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 "plSDLTypes.h"
const char kSDLPhysical[]="Physical";
const char kSDLAGMaster[]="AGMaster";
const char kSDLResponder[]="Responder";
const char kSDLClothing[]="Clothing";
const char kSDLAvatar[]="Avatar";
const char kSDLAvatarPhysical[]="AvatarPhysical";
const char kSDLLayer[]="Layer";
const char kSDLSound[]="Sound";
const char kSDLXRegion[]="XRegion";
const char kSDLMorphSequence[]="MorphSequence";
const char kSDLParticleSystem[]="ParticleSystem";
const char kSDLCloneMessage[]="CloneMessage";

View File

@ -0,0 +1,42 @@
/*==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 plSDLTypes_inc
#define plSDLTypes_inc
extern const char kSDLPhysical[];
extern const char kSDLAGMaster[];
extern const char kSDLResponder[];
extern const char kSDLClothing[];
extern const char kSDLAvatar[];
extern const char kSDLAvatarPhysical[];
extern const char kSDLLayer[];
extern const char kSDLSound[];
extern const char kSDLXRegion[];
extern const char kSDLMorphSequence[];
extern const char kSDLParticleSystem[];
extern const char kSDLCloneMessage[];
#endif // plSDLTypes_inc

View File

@ -0,0 +1,600 @@
/*==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 "plSynchedObject.h"
#include "plSynchedValue.h"
#include "plNetApp.h"
#include "plNetGroup.h"
#include "hsResMgr.h"
#include "../pnSceneObject/plSceneObject.h"
#include "../pnKeyedObject/plKey.h"
#include "../pnMessage/plSDLModifierMsg.h"
#include "../pnMessage/plSetNetGroupIDMsg.h"
#include <algorithm>
// statics
plSynchedObject* plSynchedObject::fStaticSynchedObj=nil;
std::vector<plSynchedObject::StateDefn> plSynchedObject::fDirtyStates;
std::vector<hsBool> plSynchedObject::fSynchStateStack;
plSynchedObject::plSynchedObject() :
fSynchFlags(0),
#ifdef USE_SYNCHED_VALUES
fSynchedValueAddrOffsets(nil),
fNumSynchedValues(0),
fSynchedValueFriends(nil),
fNumSynchedValueFriends(0),
#endif
fNetGroup(plNetGroup::kNetGroupUnknown)
{
fStaticSynchedObj=this;
}
plSynchedObject::~plSynchedObject()
{
#ifdef USE_SYNCHED_VALUES
delete [] fSynchedValueAddrOffsets;
delete [] fSynchedValueFriends;
#endif
}
hsBool plSynchedObject::MsgReceive(plMessage* msg)
{
plSetNetGroupIDMsg* setNetGroupID = plSetNetGroupIDMsg::ConvertNoRef(msg);
if (setNetGroupID)
{
SetNetGroupConstant(setNetGroupID->fId);
return true;
}
return hsKeyedObject::MsgReceive(msg);
}
#ifdef USE_SYNCHED_VALUES
plSynchedValueBase* plSynchedObject::GetSynchedValue(int i) const
{
if (i<fNumSynchedValues)
return IGetSynchedValue((NumSynchedValuesType)i);
return IGetSynchedValueFriend((NumSynchedValuesType)(i-fNumSynchedValues));
}
// realloc and add
void plSynchedObject::IAppendSynchedValueAddrOffset(AddrOffsetType synchedValueAddrOffset)
{
// copy to new larger array
AddrOffsetType* tmp = TRACKED_NEW AddrOffsetType[fNumSynchedValues+1];
Int32 i;
for(i=0;i<fNumSynchedValues;i++)
tmp[i] = fSynchedValueAddrOffsets[i];
// delete old one
delete [] fSynchedValueAddrOffsets;
// point to new array and append value
fSynchedValueAddrOffsets=tmp;
tmp[fNumSynchedValues++]=synchedValueAddrOffset;
}
void plSynchedObject::IAppendSynchedValueFriend(plSynchedValueBase* v)
{
// copy to new larger array
plSynchedValueBase** tmp = TRACKED_NEW plSynchedValueBase*[fNumSynchedValueFriends+1];
Int32 i;
for(i=0;i<fNumSynchedValueFriends;i++)
tmp[i] = fSynchedValueFriends[i];
// delete old one
delete [] fSynchedValueFriends;
// point to new array and append value
fSynchedValueFriends=tmp;
tmp[fNumSynchedValueFriends++]=v;
}
// adds synchedValue and returns index
UInt8 plSynchedObject::RegisterSynchedValue(plSynchedValueBase* v)
{
Int32 addrOff = ((Int32)v - (Int32)this)>>2;
hsAssert(hsABS(addrOff) < (UInt32)(1<<(sizeof(AddrOffsetType)<<3)), "address offset overflow");
IAppendSynchedValueAddrOffset((AddrOffsetType)addrOff);
Int32 idx = fNumSynchedValues-1;
hsAssert(idx<256, "index too big");
return (UInt8)idx;
}
hsBool plSynchedObject::RemoveSynchedValue(plSynchedValueBase* v)
{
int i;
for(i=0;i<GetNumSynchedValues(); i++)
if (GetSynchedValue(i)==v)
break;
// couldn't find it
if (i==GetNumSynchedValues())
return false;
int idx=i;
if (idx<fNumSynchedValues)
{
AddrOffsetType* tmp = TRACKED_NEW AddrOffsetType[fNumSynchedValues-1];
for(i=0;i<idx;i++)
tmp[i] = fSynchedValueAddrOffsets[i];
for(i=idx+1;i<fNumSynchedValues;i++)
tmp[i-1] = fSynchedValueAddrOffsets[i];
delete [] fSynchedValueAddrOffsets;
fSynchedValueAddrOffsets=tmp;
fNumSynchedValues--;
}
else
{
idx -= fNumSynchedValues;
plSynchedValueBase** tmp = TRACKED_NEW plSynchedValueBase*[fNumSynchedValueFriends-1];
for(i=0;i<idx;i++)
tmp[i] = fSynchedValueFriends[i];
for(i=idx+1;i<fNumSynchedValueFriends;i++)
tmp[i-1] = fSynchedValueFriends[i];
delete [] fSynchedValueFriends;
fSynchedValueFriends=tmp;
fNumSynchedValueFriends--;
}
return true;
}
// adds synchedValueFriend
void plSynchedObject::RegisterSynchedValueFriend(plSynchedValueBase* v)
{
IAppendSynchedValueFriend(v);
}
#endif
//
// send sdl state msg immediately
//
void plSynchedObject::SendSDLStateMsg(const char* SDLStateName, UInt32 synchFlags /*SendSDLStateFlags*/)
{
plSDLModifierMsg* sdlMsg = TRACKED_NEW plSDLModifierMsg(SDLStateName,
(synchFlags & kBCastToClients) ? plSDLModifierMsg::kSendToServerAndClients : plSDLModifierMsg::kSendToServer /* action */);
sdlMsg->SetFlags(synchFlags);
hsAssert(GetKey(), "nil key on synchedObject?");
sdlMsg->Send(GetKey());
}
//
// Tell an object to send an sdl state update.
// The request will get queued (returns true)
//
hsBool plSynchedObject::DirtySynchState(const char* SDLStateName, UInt32 synchFlags /*SendSDLStateFlags*/)
{
if (!IOKToDirty(SDLStateName))
{
#if 0
if (plNetClientApp::GetInstance())
plNetClientApp::GetInstance()->DebugMsg("NotOKToDirty - Not queueing SDL state, obj %s, sdl %s",
GetKeyName(), SDLStateName);
#endif
return false;
}
if (!IOKToNetwork(SDLStateName, &synchFlags))
{
#if 0
if (plNetClientApp::GetInstance())
plNetClientApp::GetInstance()->DebugMsg("LocalOnly Object - Not queueing SDL msg, obj %s, sdl %s",
GetKeyName(), SDLStateName);
#endif
return false;
}
if (!(synchFlags & kSkipLocalOwnershipCheck))
{
int localOwned=IsLocallyOwned();
if (localOwned==plSynchedObject::kNo)
return false;
if (localOwned==plSynchedObject::kYes)
synchFlags |= kSkipLocalOwnershipCheck; // don't have to check again
else
{
if (plNetClientApp::GetInstance())
plNetClientApp::GetInstance()->DebugMsg("Queueing SDL state with 'maybe' ownership, obj %s, sdl %s",
GetKeyName(), SDLStateName);
}
}
if (synchFlags & kSendImmediately)
{
SendSDLStateMsg(SDLStateName, synchFlags);
}
else
{
IAddDirtyState(GetKey(), SDLStateName, synchFlags);
}
return true;
}
//
// STATIC
// add state defn if not already there.
// if there adjust flags if necessary
//
void plSynchedObject::IAddDirtyState(plKey objKey, const char* sdlName, UInt32 sendFlags)
{
bool found=false;
std::vector<StateDefn>::iterator it=fDirtyStates.begin();
for( ; it != fDirtyStates.end(); it++)
{
if ((*it).fObjKey==objKey && !stricmp((*it).fSDLName.c_str(), sdlName))
{
if (sendFlags & kForceFullSend)
(*it).fSendFlags |= kForceFullSend;
if (sendFlags & kBCastToClients)
(*it).fSendFlags |= kBCastToClients;
found=true;
break;
}
}
if (!found)
{
StateDefn state(objKey, sendFlags, sdlName);
fDirtyStates.push_back(state);
}
else
{
#if 0
plNetClientApp::GetInstance()->DebugMsg("Not queueing diplicate request for SDL state, obj %s, sdl %s",
objKey->GetName(), sdlName);
#endif
}
}
//
// STATIC
//
void plSynchedObject::IRemoveDirtyState(plKey objKey, const char* sdlName)
{
std::vector<StateDefn>::iterator it=fDirtyStates.begin();
for( ; it != fDirtyStates.end(); it++)
{
if ((*it).fObjKey==objKey && !stricmp((*it).fSDLName.c_str(), sdlName))
{
fDirtyStates.erase(it);
break;
}
}
}
void plSynchedObject::SetNetGroupConstant(plNetGroupId netGroup)
{
ClearSynchFlagsBit(kHasConstantNetGroup);
SetNetGroup(netGroup); // may recurse
SetSynchFlagsBit(kHasConstantNetGroup);
}
plNetGroupId plSynchedObject::SelectNetGroup(plKey rmKey)
{
return plNetClientApp::GetInstance() ?
plNetClientApp::GetInstance()->SelectNetGroup(this, rmKey) : plNetGroup::kNetGroupUnknown;
}
plNetGroupId plSynchedObject::GetEffectiveNetGroup() const
{
return plNetClientApp::GetInstance() ?
plNetClientApp::GetInstance()->GetEffectiveNetGroup(this) : plNetGroup::kNetGroupLocalPlayer;
}
int plSynchedObject::IsLocallyOwned() const
{
return plNetClientApp::GetInstance() ?
plNetClientApp::GetInstance()->IsLocallyOwned(this) : kYes;
}
void plSynchedObject::Read(hsStream* stream, hsResMgr* mgr)
{
hsKeyedObject::Read(stream, mgr);
fNetGroup = GetKey()->GetUoid().GetLocation();
stream->ReadSwap(&fSynchFlags);
if (fSynchFlags & kExcludePersistentState)
{
Int16 num;
stream->ReadSwap(&num);
fSDLExcludeList.clear();
int i;
for(i=0;i<num;i++)
{
std::string s;
plMsgStdStringHelper::Peek(s, stream);
fSDLExcludeList.push_back(s);
}
}
if (fSynchFlags & kHasVolatileState)
{
Int16 num;
stream->ReadSwap(&num);
fSDLVolatileList.clear();
int i;
for(i=0;i<num;i++)
{
std::string s;
plMsgStdStringHelper::Peek(s, stream);
fSDLVolatileList.push_back(s);
}
}
}
void plSynchedObject::Write(hsStream* stream, hsResMgr* mgr)
{
hsKeyedObject::Write(stream, mgr);
stream->WriteSwap(fSynchFlags);
if (fSynchFlags & kExcludePersistentState)
{
Int16 num=fSDLExcludeList.size();
stream->WriteSwap(num);
SDLStateList::iterator it=fSDLExcludeList.begin();
for(; it != fSDLExcludeList.end(); it++)
{
plMsgStdStringHelper::Poke(*it, stream);
}
}
if (fSynchFlags & kHasVolatileState)
{
Int16 num=fSDLVolatileList.size();
stream->WriteSwap(num);
SDLStateList::iterator it=fSDLVolatileList.begin();
for(; it != fSDLVolatileList.end(); it++)
{
plMsgStdStringHelper::Poke(*it, stream);
}
}
}
//
// static
//
hsBool plSynchedObject::PopSynchDisabled()
{
if (fSynchStateStack.size())
{
hsBool ret=fSynchStateStack.back();
fSynchStateStack.pop_back();
return ret;
}
else
{
hsAssert(false, "invalid stack size?");
}
return true; // disabled
}
#ifdef USE_DIRTY_NOTIFIERS
void plSynchedObject::AddDirtyNotifier(plDirtyNotifier* dn)
{
if (dn)
{
std::vector<plDirtyNotifier*>::iterator it=std::find(fDirtyNotifiers.begin(), fDirtyNotifiers.end(), dn);
if (it == fDirtyNotifiers.end()) // not there
{
dn->SetSynchedObjKey(GetKey());
fDirtyNotifiers.push_back(dn);
}
}
}
void plSynchedObject::RemoveDirtyNotifier(plDirtyNotifier* dn)
{
if (dn)
{
std::vector<plDirtyNotifier*>::iterator it=std::find(fDirtyNotifiers.begin(), fDirtyNotifiers.end(), dn);
if (it != fDirtyNotifiers.end()) // its there
fDirtyNotifiers.erase(it);
}
}
void plSynchedObject::CallDirtyNotifiers()
{
int i;
for(i=0;i<fDirtyNotifiers.size();i++)
fDirtyNotifiers[i]->Callback();
}
#else
void plSynchedObject::CallDirtyNotifiers() {}
#endif
//
// return true if it's ok to dirty this object
//
bool plSynchedObject::IOKToDirty(const char* SDLStateName) const
{
// is synching disabled?
bool synchDisabled = (GetSynchDisabled()!=0);
if (synchDisabled)
return false;
// is object dirtyAble?
bool dontDirty = (fSynchFlags & kDontDirty) != 0;
if (dontDirty)
return false;
// is object in a LocalOnly age?
if (plNetClientApp::GetConstInstance() && plNetClientApp::GetConstInstance()->ObjectInLocalAge(this))
return false;
return true; // OK to dirty
}
//
// return true if this object should send his SDL msg (for persistence or synch) over the net
//
bool plSynchedObject::IOKToNetwork(const char* sdlName, UInt32* synchFlags) const
{
// determine destination
bool dstServerOnly=false, dstClientsOnly=false, dstClientsAndServer=false;
if ((*synchFlags) & kBCastToClients)
{ // bcasting to clients and server
if ((*synchFlags) & kDontPersistOnServer)
dstClientsOnly=true;
else
dstClientsAndServer=true;
}
else
{ // not bcasting, must be sending to server only
hsAssert( ((*synchFlags) & kDontPersistOnServer)==0, "invalid synchedObject msg flag");
dstServerOnly=true;
}
bool netSynched = IsNetSynched();
bool inExcludeList = IsInSDLExcludeList(sdlName);
//
// check if ok to network based on destination
//
if (dstClientsOnly)
{
return netSynched;
}
if (dstClientsAndServer)
{
if ( !netSynched )
{
*synchFlags &= ~kBCastToClients; // don't send to clients
}
if ( inExcludeList )
{
*synchFlags |= kDontPersistOnServer; // don't store on server
}
return !inExcludeList || netSynched;
}
if (dstServerOnly)
{
return !inExcludeList;
}
hsAssert(false, "how did I get here");
return false;
}
plSynchedObject::SDLStateList::const_iterator plSynchedObject::IFindInSDLStateList(const SDLStateList& list, const char* sdlName) const
{
if (!sdlName)
return list.end(); // false
SDLStateList::const_iterator it = list.begin();
for(; it != list.end(); it++)
if (!_stricmp((*it).c_str(), sdlName))
return it;
return it; // .end(), false
}
///////////////////////////
// EXCLUDE LIST
///////////////////////////
void plSynchedObject::AddToSDLExcludeList(const char* sdlName)
{
if (sdlName)
{
if (IFindInSDLStateList(fSDLExcludeList, sdlName)==fSDLExcludeList.end())
{
fSDLExcludeList.push_back(sdlName); // Don't dupe sdlName, std::string will copy
fSynchFlags |= kExcludePersistentState;
}
}
}
void plSynchedObject::RemoveFromSDLExcludeList(const char* sdlName)
{
SDLStateList::const_iterator it=IFindInSDLStateList(fSDLExcludeList, sdlName);
if (it != fSDLExcludeList.end())
{
fSDLExcludeList.erase(fSDLExcludeList.begin()+(it-fSDLExcludeList.begin()));
if (fSDLExcludeList.size()==0)
fSynchFlags &= ~kExcludePersistentState;
}
}
bool plSynchedObject::IsInSDLExcludeList(const char* sdlName) const
{
if ((fSynchFlags & kExcludeAllPersistentState) != 0)
return true;
if ((fSynchFlags & kExcludePersistentState) == 0)
return false;
SDLStateList::const_iterator it=IFindInSDLStateList(fSDLExcludeList, sdlName);
return (it != fSDLExcludeList.end());
}
///////////////////////////
// VOLATILE LIST
///////////////////////////
void plSynchedObject::AddToSDLVolatileList(const char* sdlName)
{
if (sdlName)
{
if (IFindInSDLStateList(fSDLVolatileList,sdlName)==fSDLVolatileList.end())
{
fSDLVolatileList.push_back(sdlName); // Don't dupe sdlName, std::string will copy
fSynchFlags |= kHasVolatileState;
}
}
}
void plSynchedObject::RemoveFromSDLVolatileList(const char* sdlName)
{
SDLStateList::const_iterator it=IFindInSDLStateList(fSDLVolatileList,sdlName);
if (it != fSDLVolatileList.end())
{
fSDLVolatileList.erase(fSDLVolatileList.begin()+(it-fSDLVolatileList.begin()));
if (fSDLVolatileList.size()==0)
fSynchFlags &= ~kHasVolatileState;
}
}
bool plSynchedObject::IsInSDLVolatileList(const char* sdlName) const
{
if ((fSynchFlags & kAllStateIsVolatile) != 0)
return true;
if ((fSynchFlags & kHasVolatileState) == 0)
return false;
SDLStateList::const_iterator it=IFindInSDLStateList(fSDLVolatileList,sdlName);
return (it != fSDLVolatileList.end());
}

View File

@ -0,0 +1,270 @@
/*==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 PLSYNCHOBJ_inc
#define PLSYNCHOBJ_inc
#include "hsTypes.h"
#include "../pnKeyedObject/hsKeyedObject.h"
#include "../pnKeyedObject/plKey.h"
#include "hsStlUtils.h"
#include "plNetGroup.h"
/////////////////////////////////////
// plSynchedObject
// one per savable object
/////////////////////////////////////
class hsStream;
class plDirtyNotifier;
class plSynchedObject : public hsKeyedObject
{
public:
enum LocallyOwnedAnswer
{
kNo=false,
kYes=true
};
enum Flags
{
kDontDirty = 0x1,
kSendReliably = 0x2, // object wants reliable send
kHasConstantNetGroup = 0x4, // has a constant net group.
kDontSynchGameMessages = 0x8, // don't send/recv game actions
kExcludePersistentState = 0x10, // don't send SDL state msgs to server, check exclude list
kExcludeAllPersistentState=0x20, // don't send ANY type of SDL state
kLocalOnly = (kExcludeAllPersistentState | kDontSynchGameMessages), // localOnly in all respects
kHasVolatileState = 0x40, // server won't save this state on shutdown
kAllStateIsVolatile = 0x80
};
enum SDLSendFlags
{
kBCastToClients = 0x1,
kForceFullSend = 0x2,
kSkipLocalOwnershipCheck= 0x4,
kSendImmediately = 0x8,
kDontPersistOnServer = 0x10, // for an SDL bcast msg which is used for synching only, not persisting
kUseRelevanceRegions = 0x20,
kNewState = 0x40,
kIsAvatarState = 0x80,
};
struct StateDefn
{
plKey fObjKey;
UInt32 fSendFlags;
std::string fSDLName;
plSynchedObject* GetObject() const { return plSynchedObject::ConvertNoRef(fObjKey->ObjectIsLoaded()); }
StateDefn() : fObjKey(nil),fSendFlags(0) {}
StateDefn(plKey k, UInt32 f, const char* sdlName) : fObjKey(k),fSendFlags(f) { fSDLName=sdlName; }
};
private:
typedef std::vector<std::string> SDLStateList;
SDLStateList fSDLExcludeList;
SDLStateList fSDLVolatileList;
UInt32 fSynchFlags;
plNetGroupId fNetGroup;
static std::vector<hsBool> fSynchStateStack;
static plSynchedObject* fStaticSynchedObj; // static which temporarily holds address of each object's synchMgr
static std::vector<StateDefn> fDirtyStates;
static void IRemoveDirtyState(plKey o, const char* sdlName);
static void IAddDirtyState(plKey o, const char* sdlName, UInt32 sendFlags);
bool IOKToDirty(const char* SDLStateName) const;
SDLStateList::const_iterator IFindInSDLStateList(const SDLStateList& list, const char* sdlName) const;
protected:
bool IOKToNetwork(const char* sdlName, UInt32* synchFlags) const;
public:
plSynchedObject();
virtual ~plSynchedObject();
CLASSNAME_REGISTER( plSynchedObject );
GETINTERFACE_ANY( plSynchedObject, hsKeyedObject);
virtual hsBool MsgReceive(plMessage* msg);
// getters
int GetSynchFlags() const { return fSynchFlags; }
plNetGroupId GetNetGroup() const { return fNetGroup; };
plNetGroupId GetEffectiveNetGroup() const;
// setters
void SetSynchFlagsBit(UInt32 f) { fSynchFlags |= f; }
virtual void SetNetGroupConstant(plNetGroupId netGroup);
virtual void SetNetGroup(plNetGroupId netGroup) { fNetGroup = netGroup; }
plNetGroupId SelectNetGroup(plKey groupKey);
virtual hsBool DirtySynchState(const char* sdlName, UInt32 sendFlags);
void SendSDLStateMsg(const char* SDLStateName, UInt32 synchFlags); // don't use, only for net code
void ClearSynchFlagsBit(UInt32 f) { fSynchFlags &= ~f; }
// static
static hsBool GetSynchDisabled() { return fSynchStateStack.size() ? fSynchStateStack.back() : true; }
static void PushSynchDisabled(hsBool b) { fSynchStateStack.push_back(b); }
static hsBool PopSynchDisabled();
static plSynchedObject* GetStaticSynchedObject() { return fStaticSynchedObj; }
static Int32 GetNumDirtyStates() { return fDirtyStates.size(); }
static plSynchedObject::StateDefn* GetDirtyState(Int32 i) { return &fDirtyStates[i]; }
static void ClearDirtyState(std::vector<StateDefn>& carryOver) { fDirtyStates=carryOver; }
// IO
// void SendCreationMsg(double secs);
// void SendDestructionMsg(double secs) ;
virtual void Read(hsStream* s, hsResMgr* mgr);
virtual void Write(hsStream* s, hsResMgr* mgr);
int IsLocallyOwned() const; // returns yes/no/maybe
// disable net synching only
bool IsNetSynched() const { return (fSynchFlags & kDontSynchGameMessages)==0; }
void SetNetSynched(bool b) { if (!b) fSynchFlags |= kDontSynchGameMessages; else fSynchFlags &= ~kDontSynchGameMessages; }
// disable net synching AND persisting
bool IsLocalOnly() const { return (fSynchFlags & kLocalOnly)==0; }
void SetLocalOnly(bool b) { if (b) fSynchFlags |= kLocalOnly; else fSynchFlags &= ~kLocalOnly; }
// disable particular types of persistence
void AddToSDLExcludeList(const char*);
void RemoveFromSDLExcludeList(const char*);
bool IsInSDLExcludeList(const char*) const;
// make volatile particular types of state
void AddToSDLVolatileList(const char*);
void RemoveFromSDLVolatileList(const char*);
bool IsInSDLVolatileList(const char*) const;
//
// synched value stuff, currently unused
// current size is 16 + numValue bytes*2 + numFriends*4 bytes
//
#ifdef USE_SYNCHED_VALUES
public:
typedef UInt16 AddrOffsetType;
typedef UInt8 NumSynchedValuesType;
typedef UInt16 FlagsType;
friend class plSynchedValueBase;
private:
AddrOffsetType* fSynchedValueAddrOffsets; // represent dwords offsets
NumSynchedValuesType fNumSynchedValues;
// array of friends
plSynchedValueBase** fSynchedValueFriends;
NumSynchedValuesType fNumSynchedValueFriends;
// dirty callback notifiers
std::vector<plDirtyNotifier*> fDirtyNotifiers;
void IAppendSynchedValueAddrOffset(AddrOffsetType synchedValueAddrOffset);
void IAppendSynchedValueFriend(plSynchedValueBase* v);
plSynchedValueBase* IGetSynchedValue(NumSynchedValuesType i) const
{ return (plSynchedValueBase*)((Int32)this + (fSynchedValueAddrOffsets[i]<<2)); }
plSynchedValueBase* IGetSynchedValueFriend(NumSynchedValuesType i) const
{ return fSynchedValueFriends[i]; }
public:
Int32 GetNumSynchedValues() const { return fNumSynchedValues+fNumSynchedValueFriends; }
plSynchedValueBase* GetSynchedValue(int i) const;
UInt8 RegisterSynchedValue(plSynchedValueBase* v);
hsBool RemoveSynchedValue(plSynchedValueBase* v); // handles SVFriends too
void RegisterSynchedValueFriend(plSynchedValueBase* v);
#endif
#ifdef USE_DIRTY_NOTIFIERS
// dirty CB notifiers
void AddDirtyNotifier(plDirtyNotifier* dn);
void RemoveDirtyNotifier(plDirtyNotifier* dn);
#endif
void CallDirtyNotifiers();
};
//
// helper class to set dirty tracking on/off within scope
//
class plSynchEnabler
{
public:
plSynchEnabler(hsBool enable) { plSynchedObject::PushSynchDisabled(!enable); }
~plSynchEnabler() { plSynchedObject::PopSynchDisabled(); }
};
#ifdef USE_DIRTY_NOTIFIERS
///////////////////////////////////
// plDirtyNotifier - When a synchedObj
// gets dirty, this callback will be called.
///////////////////////////////////
class plDirtyNotifier
{
protected:
plKey fSynchedObjKey;
void* fUserData;
public:
plDirtyNotifier() : fSynchedObjKey(nil),fUserData(nil) {}
virtual ~plDirtyNotifier()
{
if (fSynchedObjKey)
{
plSynchedObject* so = plSynchedObject::ConvertNoRef(fSynchedObjKey->ObjectIsLoaded());
if (so)
so->RemoveDirtyNotifier(this);
}
}
void SetSynchedObjKey(plKey k) { fSynchedObjKey=k; } // should be set
void SetUserData(void* v) { fUserData=v;} // optional
plKey GetSynchedObjKey() { return fSynchedObjKey; }
void* GetUserData() { return fUserData;}
// override
virtual void Callback() = 0;
};
#endif
//
// MACROS
//
#ifdef USE_SYNCHED_VALUES
#define SYNCHED_VALUE(type) plSynchedValue<type>
#define SYNCHED_TARRAY(type) plSynchedTArray<type>
#define SYNCHED_VALUE_FRIEND(type) plSynchedValueFriend<type>
#define SYNCHED_TARRAY_FRIEND(type) plSynchedTArrayFriend<type>
#else
#define SYNCHED_VALUE(type) type
#define SYNCHED_TARRAY(type) hsTArray<type>
#define SYNCHED_VALUE_FRIEND(type) type
#define SYNCHED_TARRAY_FRIEND(type) hsTArray<type>
#endif
#endif // PLSYNCHOBJ_inc

View File

@ -0,0 +1,153 @@
/*==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 "plSynchedValue.h"
#ifdef USE_SYNCHED_VALUES
#include "../pnKeyedObject/plKey.h"
#include "hsBitVector.h"
#include "../pnSceneObject/plSceneObject.h"
#include "hsResMgr.h"
#include "../pnKeyedObject/plUoid.h"
#include "../pnSceneObject/plCoordinateInterface.h"
#define ISaveOrLoadSimpleType() \
{ \
if (save) \
stream->WriteSwap(v); \
else \
stream->ReadSwap(&v); \
return v; \
}
//
// baseclass save/load methods for various types
//
hsBitVector plSynchedValueBase::ISaveOrLoad(hsBitVector& v, hsBool32 save, hsStream* stream, hsResMgr* mgr)
{
if (save)
v.Write(stream);
else
v.Read(stream);
return v;
}
hsScalar plSynchedValueBase::ISaveOrLoad(hsScalar v, hsBool32 save, hsStream* stream, hsResMgr* mgr)
ISaveOrLoadSimpleType();
double plSynchedValueBase::ISaveOrLoad(double v, hsBool32 save, hsStream* stream, hsResMgr* mgr)
ISaveOrLoadSimpleType();
Int32 plSynchedValueBase::ISaveOrLoad(Int32 v, hsBool32 save, hsStream* stream, hsResMgr* mgr)
ISaveOrLoadSimpleType();
UInt32 plSynchedValueBase::ISaveOrLoad(UInt32 v, hsBool32 save, hsStream* stream, hsResMgr* mgr)
ISaveOrLoadSimpleType();
int plSynchedValueBase::ISaveOrLoad(int v, hsBool32 save, hsStream* stream, hsResMgr* mgr)
ISaveOrLoadSimpleType();
bool plSynchedValueBase::ISaveOrLoad(bool v, hsBool32 save, hsStream* stream, hsResMgr* mgr)
ISaveOrLoadSimpleType();
//
// save or load a key. return the key.
//
const plKey plSynchedValueBase::ISaveOrLoad(const plKey key, hsBool32 save, hsStream* stream, hsResMgr* mgr)
{
if (save)
{
if (key)
{
stream->WriteByte(1);
// I need to write a key to MY stream...
#if 0 // DEBUG
Int32 len = hsStrlen(key->GetName());
stream->WriteSwap32(len);
stream->Write(len, key->GetName());
#endif
key->GetUoid().Write(stream);
}
else
{
stream->WriteByte(0);
}
return key;
}
else
{
Int32 has=stream->ReadByte();
if (has)
{
// read a key from MY stream
#if 0 // DEBUG
Int32 len = stream->ReadSwap32();
char tmp[256];
hsAssert(len<256, "key name overflow");
stream->Read(len, tmp);
#endif
plUoid uoid;
uoid.Read(stream);
return mgr->FindKey(uoid);
}
else
return (nil);
}
return nil;
}
hsKeyedObject* plSynchedValueBase::ISaveOrLoad(hsKeyedObject* obj, hsBool32 save, hsStream* stream, hsResMgr* mgr)
{
plKey key = obj ? obj->GetKey() : nil;
key = ISaveOrLoad(key, save, stream, mgr);
return key ? key->ObjectIsLoaded() : nil;
}
plSceneNode* plSynchedValueBase::ISaveOrLoad(plSceneNode* obj, hsBool32 save, hsStream* stream, hsResMgr* mgr)
{
// return plSceneNode::ConvertNoRef(ISaveOrLoad(hsKeyedObject::ConvertNoRef(obj), save, stream, mgr));
hsAssert(false, "SceneNode synchedValues currently not implemented");
return nil;
}
plSceneObject* plSynchedValueBase::ISaveOrLoad(plSceneObject* obj, hsBool32 save, hsStream* stream, hsResMgr* mgr)
{ return plSceneObject::ConvertNoRef(ISaveOrLoad(hsKeyedObject::ConvertNoRef(obj), save, stream, mgr)); }
plCoordinateInterface* plSynchedValueBase::ISaveOrLoad(const plCoordinateInterface* cInt, hsBool32 save, hsStream* stream, hsResMgr* mgr)
{
plSceneObject* obj = ISaveOrLoad(cInt ? cInt->fOwner : nil, save, stream, mgr);
return obj ? obj->fCoordinateInterface : nil;
}
#else
// dummy function to prevent a linker warning complaining about no public symbols if the
// contents of the file get compiled out via pre-processor
void _preventLNK4221WarningStub()
{
}
#endif // USE_SYNCHED_VALUES

View File

@ -0,0 +1,396 @@
/*==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_SYNCHEDVALUE_inc
#define PL_SYNCHEDVALUE_inc
#include "plSynchedObject.h"
#ifdef USE_SYNCHED_VALUES
#include "hsTypes.h"
#include "hsStream.h"
#include "hsBitVector.h"
#include "hsMemory.h"
//
// Defines a class for variable types which need to automatically be synchronized
// (replicated) over the network.
// current size is 8 bytes
//
//
// -----------------------------------------------------
// SYNCHED VALUE BASE CLASS
// -----------------------------------------------------
//
class hsResMgr;
class plSceneNode;
class plSceneObject;
class plCoordinateInterface;
class plSynchedValueBase
{
public:
enum Flags // 16 bits
{
kValueIsDirty = 0x1,
kValueSendOnlyOnce = 0x2, // perm flag
kValueHasBeenSent = 0x4, // perm flag
kRegistered = 0x8, // perm flag
kDontDirty = 0x10 // perm flag
};
protected:
Int16 fSynchedObjectAddrOffset; // this could represent dwords instead of byte offsets
UInt16 fFlags;
void IConstruct() // too bad this can't be virtual (because it's called from ctor)
{
// The synchMgr for the class that owns us is constructed first and the staticMgr
// is set to his address so we can automatically get at it during construction.
fFlags=0;
Int32 off = (Int32)plSynchedObject::GetStaticSynchedObject() - (Int32)this;
if ( hsABS(off) < (1<<(sizeof(fSynchedObjectAddrOffset)<<3)) )
fSynchedObjectAddrOffset = (Int16)off;
else
fSynchedObjectAddrOffset=-1;
}
hsBool32 IOKToDirty()
{
if (fFlags & (kDontDirty | kValueIsDirty))
return false;
return GetSynchedObject() ? GetSynchedObject()->IOKToDirty() : false;
}
virtual void ISaveOrLoad(hsBool32 save, hsStream* stream, hsResMgr* mgr) = 0;
// save/load methods for different types
const plKey ISaveOrLoad(const plKey key, hsBool32 save, hsStream* stream, hsResMgr* mgr);
hsKeyedObject* ISaveOrLoad(hsKeyedObject* obj, hsBool32 save, hsStream* stream, hsResMgr* mgr);
plSceneNode* ISaveOrLoad(plSceneNode* obj, hsBool32 save, hsStream* stream, hsResMgr* mgr);
plSceneObject* ISaveOrLoad(plSceneObject* obj, hsBool32 save, hsStream* stream, hsResMgr* mgr);
Int32 ISaveOrLoad(Int32 v, hsBool32 save, hsStream* stream, hsResMgr* mgr);
UInt32 ISaveOrLoad(UInt32 v, hsBool32 save, hsStream* stream, hsResMgr* mgr);
bool ISaveOrLoad(bool v, hsBool32 save, hsStream* stream, hsResMgr* mgr);
int ISaveOrLoad(int v, hsBool32 save, hsStream* stream, hsResMgr* mgr); // or hsBool32
hsScalar ISaveOrLoad(hsScalar v, hsBool32 save, hsStream* stream, hsResMgr* mgr);
double ISaveOrLoad(double v, hsBool32 save, hsStream* stream, hsResMgr* mgr);
hsBitVector ISaveOrLoad(hsBitVector& v, hsBool32 save, hsStream* stream, hsResMgr* mgr);
plCoordinateInterface* ISaveOrLoad(const plCoordinateInterface* cInt, hsBool32 save, hsStream* stream, hsResMgr* mgr);
public:
plSynchedValueBase() { IConstruct(); }
virtual ~plSynchedValueBase() {}
// getters
virtual plSynchedObject* GetSynchedObject()
{
hsAssert(fSynchedObjectAddrOffset!=-1, "invalid synchedObject address offset");
plSynchedObject* so = fSynchedObjectAddrOffset == -1 ? nil : (plSynchedObject*)((Int32)this+fSynchedObjectAddrOffset);
if (!(fFlags & kRegistered) && so)
{
so->RegisterSynchedValue(this);
fFlags |= kRegistered;
}
return so;
}
UInt16 GetFlags() { return fFlags; }
// setters
void SetFlags(UInt16 f) { fFlags=f; }
void MakeDirty() { SetFlags(GetFlags() | kValueIsDirty); }
void MakeClean() { SetFlags(GetFlags() & ~kValueIsDirty); }
void DirtyIfNecessary()
{
if (IOKToDirty())
{
MakeDirty(); // dirty value
if (GetSynchedObject())
GetSynchedObject()->DirtySynchState(nil, 0); // dirty owner
}
}
// save/load
static void Save(plSynchedValueBase& obj, hsStream* stream, hsResMgr* mgr) { obj.ISaveOrLoad(true, stream, mgr); }
static void Load(plSynchedValueBase& obj, hsStream* stream, hsResMgr* mgr) { obj.ISaveOrLoad(false, stream, mgr); }
};
//
// -----------------------------------
// SYNCHED VALUE TEMPLATE
// -----------------------------------
//
template <class T>
class plSynchedValue : public plSynchedValueBase
{
protected:
T fValue;
void ISaveOrLoad(hsBool32 save, hsStream* stream, hsResMgr* mgr)
{ fValue=(T)plSynchedValueBase::ISaveOrLoad(fValue, save, stream, mgr); } // default method
public:
plSynchedValue() {}
plSynchedValue(const T& v) : plSynchedValueBase() { fValue=v; }
plSynchedValue(const plSynchedValue<T>& pRHS) : plSynchedValueBase() { fValue=pRHS.GetValue(); } // copy ctor
// conversion operators
operator T() const { return fValue; }
T* operator &() const { return &fValue; }
T* operator &() { return &fValue; }
// equality
hsBool32 operator==(const T& other) const { return fValue==(T)other; }
hsBool32 operator!=(const T& other) const { return !(*this == other); }
// other operators
T operator++() { DirtyIfNecessary(); return ++fValue; }
T operator++(int) { DirtyIfNecessary(); return fValue++; } // postfix
T operator--() { DirtyIfNecessary(); return --fValue; }
T operator--(int) { DirtyIfNecessary(); return fValue--; } // postfix
T operator+=(const T& other) { return SetValue(fValue+other); }
T operator*=(const T& other) { return SetValue(fValue*other); }
T operator/=(const T& other) { return SetValue(fValue/other); }
// these return reference in the event they are bitvector types
T& operator&=(const T& other) { return SetValue(fValue&other); }
T& operator|=(const T& other) { return SetValue(fValue|other); }
T& operator^=(const T& other) { return SetValue(fValue^other); }
T& operator-=(const T& other) { return SetValue(fValue-other); }
const T& operator=(const T& v){ return SetValue(v); }
#if HS_BUILD_FOR_WIN32
#pragma warning( push )
#pragma warning( disable : 4284 ) // disable annoying warnings in release build for non pointer types
#endif
// for pointer types, which are allowed to change the object pointed to
T operator->(void) { return fValue; }
#if HS_BUILD_FOR_WIN32
#pragma warning( pop )
#endif
// asignment, can use instead of setvalue
const T& operator=(const plSynchedValue<T>& pRHS ) { return SetValue(pRHS.GetValue()); }
// setters
T& SetValue(const T& v) // return true if changed value
{
if (v != fValue) // dont dirty unless value changes
{
fValue=v;
DirtyIfNecessary();
}
return fValue;
}
// getters
const T& GetValue() const { return fValue; }
// for hsBitVector
hsBool32 IsBitSet(UInt32 which) const { return fValue.IsBitSet(which); }
hsBool32 SetBit(UInt32 which, hsBool32 on = true)
{ hsBool32 bitSet = IsBitSet(which);
if ( (on && !bitSet) || (!on && bitSet) )
DirtyIfNecessary();
return fValue.SetBit(which, on);
}
void Read(hsStream* s) { fValue.Read(s); }
void Write(hsStream* s) const { fValue.Write(s); }
void Clear() { DirtyIfNecessary(); fValue.Clear(); }
hsBool32 ClearBit(UInt32 which) { if (fValue.IsBitSet(which)) DirtyIfNecessary(); return fValue.ClearBit(which); }
void Reset() { if (fValue.GetSize()!=0) DirtyIfNecessary(); fValue.Reset(); }
hsBool32 ToggleBit(UInt32 which) { DirtyIfNecessary(); return fValue.ToggleBit(which); }
UInt32 GetSize() { return fValue.GetSize(); }
};
//////////////////////////////////////
// Synched Value Friend - allows a synched value to be contained
// in an object which is not a synchedObject. Uses a pointer instead
// of an computer the addr offset of it's associated synchedObject.
// This one is 4 bytes bigger than regular synched values.
//////////////////////////////////////
template <class T>
class plSynchedValueFriend : public plSynchedValue<T>
{
protected:
plSynchedObject** fSynchedObject;
public:
plSynchedValueFriend() : fSynchedObject(nil) { }
// this is explicit so it won't be invoked instead of operator()=
explicit plSynchedValueFriend(const T& v) : plSynchedValue<T>(v),fSynchedObject(nil) { }
plSynchedValueFriend(const plSynchedValueFriend<T>& pRHS) : plSynchedValue<T>(pRHS)
{ fSynchedObject = pRHS.fSynchedObject; }
~plSynchedValueFriend()
{
if (GetSynchedObject())
GetSynchedObject()->RemoveSynchedValue(this);
}
// this isn't inherited for some reason
const T& operator=(const T& v) { return SetValue(v); }
plSynchedObject* GetSynchedObject()
{
hsAssert(fSynchedObject, "nil synched object, need to SetSynchedObjectPtrAddr?");
if (*fSynchedObject && !(fFlags & kRegistered))
{
(*fSynchedObject)->RegisterSynchedValueFriend(this);
fFlags |= kRegistered;
}
return *fSynchedObject;
}
void SetSynchedObjectPtrAddr(plSynchedObject** so)
{
hsAssert(!(fFlags & kRegistered), "SynchedValueFriend already registered?");
fSynchedObject=so;
}
};
/////////////////////////////////////
// Synched TArray Template
/////////////////////////////////////
#include "hsTemplates.h"
template <class T>
class plSynchedTArray : public plSynchedValueBase
{
private:
hsTArray<T> fValueList;
void ISaveOrLoad(hsBool32 save, hsStream* stream, hsResMgr* mgr);
public:
enum { kMissingIndex = hsTArray<T>::kMissingIndex };
plSynchedTArray() {}
~plSynchedTArray() {}
// conversion operators
operator T() const { return fValueList; }
// common methods
const T& operator[](int i) const { return Get(i); }
const T& Get(int i) const { return fValueList.Get(i); }
void Set(int i, const T& item) { if (fValueList[i] != item) DirtyIfNecessary(); fValueList[i]=item; }
void Append(const T& item) { fValueList.Append(item); DirtyIfNecessary(); }
T* Insert(int index) { fValueList.Insert(index); DirtyIfNecessary(); }
void Remove(int index) { fValueList.Remove(index); DirtyIfNecessary(); }
int Count() const { return fValueList.Count(); }
int GetCount() const { return Count(); }
void Reset() { if (fValueList.GetCount() != 0) DirtyIfNecessary(); fValueList.Reset(); }
void SetCountAndZero(int count) { if (count || GetCount()) DirtyIfNecessary(); fValueList.SetCountAndZero(count); }
void SetCount(int count) { if (count || GetCount()) DirtyIfNecessary(); fValueList.SetCount(count); }
void ExpandAndZero(int count) { if (count || GetCount()) DirtyIfNecessary(); fValueList.ExpandAndZero(count); }
int Find(const T& item) const { return fValueList.Find(item); }
T* Push() { DirtyIfNecessary(); return fValueList.Push(); }
void Push(const T& item) { DirtyIfNecessary(); return fValueList.Push(item); }
T Pop() { DirtyIfNecessary(); return fValueList.Pop(); }
const T& Peek() const { return fValue.Peek(); }
T* DetachArray() { DirtyIfNecessary(); return fValueList.DetachArray(); }
T* AcquireArray() { DirtyIfNecessary(); return fValueList.AcquireArray(); }
};
//
// inlines
//
template <class T> inline
void plSynchedTArray<T>::ISaveOrLoad(hsBool32 save, hsStream* stream, hsResMgr* mgr)
{
if (save)
{
// write out size of array
Int32 i, num = fValueList.GetCount();
stream->WriteSwap(num);
for(i=0;i<num;i++)
{
plSynchedValueBase::ISaveOrLoad(fValueList[i], save, stream, mgr);
}
}
else
{
// clear array
fValueList.Reset();
// read in size of array
Int32 i, num;
stream->ReadSwap(&num);
for(i=0;i<num;i++)
{
T v;
HSMemory::ClearMemory(&v, sizeof(v));
v=(T)plSynchedValueBase::ISaveOrLoad(v, save, stream, mgr);
fValueList.Append(v);
}
}
}
//////////////////////////////////////
// Variation on synchedTArray. See plSynchedValueFriend above for more info
//////////////////////////////////////
template <class T>
class plSynchedTArrayFriend : public plSynchedTArray<T>
{
protected:
plSynchedObject** fSynchedObject;
public:
plSynchedTArrayFriend() : fSynchedObject(nil) { }
plSynchedObject* GetSynchedObject()
{
hsAssert(fSynchedObject, "nil synched object, need to SetSynchedObjectPtrAddr?");
if (*fSynchedObject && !(fFlags & kRegistered))
{
(*fSynchedObject)->RegisterSynchedValueFriend(this);
fFlags |= kRegistered;
}
return *fSynchedObject;
}
void SetSynchedObjectPtrAddr(plSynchedObject** so)
{
hsAssert(!(fFlags & kRegistered), "SynchedValueTArrayFriend already registered?");
fSynchedObject=so;
}
#if 0
//
// redefine operators since they are not inherited
//
// conversion operators
operator T() const { return fValueList; }
// common methods
const T& operator[](int i) const { return Get(i); }
#endif
};
#endif // USE_SYNCHED_VALUES
#endif // PL_SYNCHEDVALUE_inc

View File

@ -0,0 +1,108 @@
/*==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 "pnNetCommon.h"
#include "../pnAddrInfo/pnAddrInfo.h"
#ifdef HS_BUILD_FOR_WIN32
# include "hsWindows.h"
#elif HS_BUILD_FOR_UNIX
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <string.h> // for memcpy
#else
#error "Not implemented for this platform"
#endif
namespace pnNetCommon
{
#ifndef SERVER
// NOTE: On Win32, WSAStartup() must be called before GetTextAddr() will work.
const char * GetTextAddr(UInt32 binAddr)
{
in_addr in;
memcpy(&in,&binAddr,sizeof(binAddr));
return inet_ntoa(in);
}
// NOTE: On Win32, WSAStartup() must be called before GetBinAddr() will work.
UInt32 GetBinAddr(const char * textAddr)
{
UInt32 addr = 0;
if (!textAddr)
return addr;
struct addrinfo * ai = NULL;
addr = inet_addr(textAddr);
if(addr == INADDR_NONE)
{
ai = pnAddrInfo::GetAddrByNameSimple(textAddr);
if(ai!= NULL)
memcpy(&addr,(void*)(&(((sockaddr_in*)(ai->ai_addr))->sin_addr)),sizeof(addr));
pnAddrInfo::Free(ai);
}
return addr;
}
#endif
} // pnNetCommon namespace
////////////////////////////////////////////////////////////////////
void plCreatableStream::Write( hsStream* stream, hsResMgr* mgr )
{
fStream.Rewind();
std::string buf;
UInt32 len = fStream.GetEOF();
stream->WriteSwap( len );
buf.resize( len );
fStream.Read( len, (void*)buf.data() );
stream->Write( len, (const void*)buf.data() );
fStream.Rewind();
}
void plCreatableStream::Read( hsStream* stream, hsResMgr* mgr )
{
fStream.Rewind();
std::string buf;
UInt32 len;
stream->LogReadSwap( &len,"CreatableStream Len");
buf.resize( len );
stream->LogRead( len, (void*)buf.data(),"CreatableStream Data");
fStream.Write( len, (const void*)buf.data() );
fStream.Rewind();
}
////////////////////////////////////////////////////////////////////
// End.

View File

@ -0,0 +1,131 @@
/*==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 pnNetCommon_h_inc
#define pnNetCommon_h_inc
#include "hsConfig.h"
#include "hsTypes.h"
#include "hsStlUtils.h"
#include "hsRefCnt.h"
#include "hsStream.h"
#include "../pnFactory/plCreatable.h"
//
// main logging switch
//
#ifndef PLASMA_EXTERNAL_RELEASE
# define NET_LOGGING
#endif
#ifndef hsLogEntry
# ifdef NET_LOGGING
# define hsLogEntry(x) x
# else
# define hsLogEntry(x)
# endif
#endif
#define hsDbgLogEntry(x)
#ifdef NET_LOGGING
# ifdef HS_DEBUGGING
# undef hsDbgLogEntry
# define hsDbgLogEntry(x) x
# endif
#endif
#define Bool2Int(value) ((value)?1:0)
#define Int2Bool(value) ((value)?true:false)
///////////////////////////////////////////////////////////////////
namespace pnNetCommon
{
#ifndef SERVER
UInt32 GetBinAddr(const char * textAddr);
const char * GetTextAddr(UInt32 binAddr);
#endif // SERVER
}
///////////////////////////////////////////////////////////////////
class plCreatableStream : public plCreatable
{
hsRAMStream fStream;
public:
CLASSNAME_REGISTER( plCreatableStream );
GETINTERFACE_ANY( plCreatableStream, plCreatable );
void Read( hsStream* stream, hsResMgr* mgr=nil );
void Write( hsStream* stream, hsResMgr* mgr=nil );
hsStream * GetStream( void ) { return &fStream;}
};
///////////////////////////////////////////////////////////////////
// hsTempRef is incomplete. This type fills in some of the gaps
// (like symmetrical ref/unref and correct self-assign)
#ifndef SERVER
template <class T>
class plSafePtr
{
T * fPtr;
public:
plSafePtr(T * ptr = nil): fPtr(ptr) {hsRefCnt_SafeRef(fPtr);}
~plSafePtr() { hsRefCnt_SafeUnRef(fPtr); }
operator T*() const { return fPtr; }
operator T*&() { return fPtr; }
operator const T&() const { return *fPtr; }
operator bool() const { return fPtr!=nil;}
T * operator->() const { return fPtr; }
T * operator *() const { return fPtr; }
T * operator=(T * ptr)
{
hsRefCnt_SafeRef(ptr);
hsRefCnt_SafeUnRef(fPtr);
fPtr = ptr;
return fPtr;
}
void Attach(T * ptr)
{
if (fPtr==ptr)
return;
hsRefCnt_SafeUnRef(fPtr);
fPtr = ptr;
}
void Detach() { fPtr=nil;}
};
#endif // SERVER
#endif // pnNetCommon_h_inc
///////////////////////////////////////////////////////////////////
// End.

View File

@ -0,0 +1,47 @@
/*==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 pnNetCommonCreatable_inc
#define pnNetCommonCreatable_inc
#include "../pnFactory/plCreator.h"
#include "plSynchedObject.h"
REGISTER_CREATABLE( plSynchedObject );
#include "plNetApp.h"
REGISTER_NONCREATABLE( plNetApp );
REGISTER_NONCREATABLE( plNetClientApp );
REGISTER_NONCREATABLE( plNetServerApp );
#include "plGenericVar.h"
REGISTER_CREATABLE( plCreatableGenericValue );
#include "pnNetCommon.h"
REGISTER_CREATABLE( plCreatableStream );
#endif // pnNetCommonCreatable_inc