You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

498 lines
17 KiB

/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
/*****************************************************************************
*
* $/Plasma20/Sources/Plasma/NucleusLib/pnNetProtocol/Private/pnNpCommon.h
*
***/
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNNETPROTOCOL_PRIVATE_PNNPCOMMON_H
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnNetProtocol/Private/pnNpCommon.h included more than once"
#endif
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNNETPROTOCOL_PRIVATE_PNNPCOMMON_H
/*****************************************************************************
*
* Client message field types
*
***/
#ifdef USES_NETCLI
const NetMsgField kNetMsgFieldAccountName = NET_MSG_FIELD_STRING(kMaxAccountNameLength);
const NetMsgField kNetMsgFieldPlayerName = NET_MSG_FIELD_STRING(kMaxPlayerNameLength);
const NetMsgField kNetMsgFieldShaDigest = NET_MSG_FIELD_RAW_DATA(sizeof(ShaDigest));
const NetMsgField kNetMsgFieldUuid = NET_MSG_FIELD_DATA(sizeof(Uuid));
const NetMsgField kNetMsgFieldTransId = NET_MSG_FIELD_DWORD();
const NetMsgField kNetMsgFieldTimeMs = NET_MSG_FIELD_DWORD();
const NetMsgField kNetMsgFieldENetError = NET_MSG_FIELD_DWORD();
const NetMsgField kNetMsgFieldEAgeId = NET_MSG_FIELD_DWORD();
const NetMsgField kNetMsgFieldNetNode = NET_MSG_FIELD_DWORD();
const NetMsgField kNetMsgFieldBuildId = NET_MSG_FIELD_DWORD();
#endif
/*****************************************************************************
*
* Player information structures
*
***/
#include <PshPack1.h>
struct SrvPlayerInfo {
unsigned playerInt;
wchar playerName[kMaxPlayerNameLength];
wchar avatarShape[kMaxVaultNodeStringLength];
unsigned explorer;
};
#include <PopPack.h>
/*****************************************************************************
*
* NetAgeInfo
*
***/
struct NetAgeInfo {
Uuid ageInstId;
wchar ageFilename[kMaxAgeNameLength];
wchar ageInstName[kMaxAgeNameLength];
wchar ageUserName[kMaxAgeNameLength];
wchar ageDesc[1024];
dword ageSequenceNumber;
dword ageLanguage;
dword population; // only used with GetPublicAgeList query results
dword currentPopulation; // only used with GetPublicAgeList query results
};
/*****************************************************************************
*
* NetGameScore
*
***/
struct NetGameScore {
unsigned scoreId;
unsigned ownerId;
UInt32 createdTime;
wchar gameName[kMaxGameScoreNameLength];
unsigned gameType;
int value;
unsigned Read (const byte inbuffer[], unsigned bufsz, byte** end = nil); // returns number of bytes read
unsigned Write (ARRAY(byte) * buffer) const; // returns number of bytes written
void CopyFrom (const NetGameScore & score);
};
/*****************************************************************************
*
* NetGameRank
*
***/
struct NetGameRank {
unsigned rank;
int score;
wchar name[kMaxPlayerNameLength];
unsigned Read (const byte inbuffer[], unsigned bufsz, byte** end = nil); // returns number of bytes read
unsigned Write (ARRAY(byte) * buffer) const; // returns number of bytes written
void CopyFrom (const NetGameRank & fromRank);
};
/*****************************************************************************
*
* Server vault structures
*
***/
//============================================================================
// NetVaultNode
//============================================================================
// Threaded apps: App is responsible for locking node->critsect before accessing *any* field in this struct
struct NetVaultNode : AtomicRef {
enum RwOptions {
kRwDirtyOnly = 1<<0, // READ : No meaning
// WRITE: Only write fields marked dirty
kRwUpdateDirty = 1<<1, // READ : Set dirty flag on fields read from stream
// WRITE: Clear dirty flag on fields written to stream
};
enum CopyOptions {
kCopySetDirty = 1<<0, // set dirty flag on changed dst fields
kCopyOverwrite = 1<<1, // overwrite fields for which dst node already has values
kCopyClear = 1<<2, // clear dst fields for which src node does not have values
};
// These flag values must not change unless all servers are
// simultaneously replaced, so basically forget it.
static const qword kNodeId = (qword)1<< 0;
static const qword kCreateTime = (qword)1<< 1;
static const qword kModifyTime = (qword)1<< 2;
static const qword kCreateAgeName = (qword)1<< 3;
static const qword kCreateAgeUuid = (qword)1<< 4;
static const qword kCreatorAcct = (qword)1<< 5;
static const qword kCreatorId = (qword)1<< 6;
static const qword kNodeType = (qword)1<< 7;
static const qword kInt32_1 = (qword)1<< 8;
static const qword kInt32_2 = (qword)1<< 9;
static const qword kInt32_3 = (qword)1<<10;
static const qword kInt32_4 = (qword)1<<11;
static const qword kUInt32_1 = (qword)1<<12;
static const qword kUInt32_2 = (qword)1<<13;
static const qword kUInt32_3 = (qword)1<<14;
static const qword kUInt32_4 = (qword)1<<15;
static const qword kUuid_1 = (qword)1<<16;
static const qword kUuid_2 = (qword)1<<17;
static const qword kUuid_3 = (qword)1<<18;
static const qword kUuid_4 = (qword)1<<19;
static const qword kString64_1 = (qword)1<<20;
static const qword kString64_2 = (qword)1<<21;
static const qword kString64_3 = (qword)1<<22;
static const qword kString64_4 = (qword)1<<23;
static const qword kString64_5 = (qword)1<<24;
static const qword kString64_6 = (qword)1<<25;
static const qword kIString64_1 = (qword)1<<26;
static const qword kIString64_2 = (qword)1<<27;
// blobs always come last
static const qword kText_1 = (qword)1<<28;
static const qword kText_2 = (qword)1<<29;
static const qword kBlob_1 = (qword)1<<30;
static const qword kBlob_2 = (qword)1<<31;
CCritSect critsect;
qword fieldFlags;
qword dirtyFlags;
Uuid revisionId;
// Treat these as read-only or node flag fields will become invalid
// Threaded apps: Must be accessed with node->critsect locked
unsigned nodeId;
unsigned createTime;
unsigned modifyTime;
wchar * createAgeName;
Uuid createAgeUuid;
Uuid creatorAcct; // accountId of node creator
unsigned creatorId; // playerId of node creator
unsigned nodeType;
int int32_1;
int int32_2;
int int32_3;
int int32_4;
unsigned uint32_1;
unsigned uint32_2;
unsigned uint32_3;
unsigned uint32_4;
Uuid uuid_1;
Uuid uuid_2;
Uuid uuid_3;
Uuid uuid_4;
wchar * string64_1;
wchar * string64_2;
wchar * string64_3;
wchar * string64_4;
wchar * string64_5;
wchar * string64_6;
wchar * istring64_1;
wchar * istring64_2;
wchar * text_1;
wchar * text_2;
byte * blob_1; unsigned blob_1Length;
byte * blob_2; unsigned blob_2Length;
NetVaultNode ();
~NetVaultNode ();
// Threaded apps: Must be called with node->critsect locked
unsigned Read_LCS (const byte buffer[], unsigned bufsz, unsigned rwOpts); // returns number of bytes read
unsigned Write_LCS (ARRAY(byte) * buffer, unsigned rwOpts); // returns number of bytes written
bool Matches (const NetVaultNode * other);
void CopyFrom (const NetVaultNode * other, unsigned copyOpts);
// Threaded apps: Must be called with node->critsect locked
void SetNodeId (unsigned v);
void SetCreateTime (unsigned v);
void SetModifyTime (unsigned v);
void SetCreateAgeName (const wchar v[]);
void SetCreateAgeUuid (const Uuid & v);
void SetCreatorAcct (const Uuid & v);
void SetCreatorId (unsigned v);
void SetNodeType (unsigned v);
void SetInt32_1 (int v);
void SetInt32_2 (int v);
void SetInt32_3 (int v);
void SetInt32_4 (int v);
void SetUInt32_1 (unsigned v);
void SetUInt32_2 (unsigned v);
void SetUInt32_3 (unsigned v);
void SetUInt32_4 (unsigned v);
void SetUuid_1 (const Uuid & v);
void SetUuid_2 (const Uuid & v);
void SetUuid_3 (const Uuid & v);
void SetUuid_4 (const Uuid & v);
void SetString64_1 (const wchar v[]);
void SetString64_2 (const wchar v[]);
void SetString64_3 (const wchar v[]);
void SetString64_4 (const wchar v[]);
void SetString64_5 (const wchar v[]);
void SetString64_6 (const wchar v[]);
void SetIString64_1 (const wchar v[]);
void SetIString64_2 (const wchar v[]);
void SetText_1 (const wchar v[]);
void SetText_2 (const wchar v[]);
void SetBlob_1 (const byte v[], unsigned len);
void SetBlob_2 (const byte v[], unsigned len);
void SetText (qword fieldFlag, const wchar v[]);
void SetBlob (qword fieldFlag, const byte v[], unsigned len);
// These are only here to aid macro expansions (naming case matches field flags)
inline unsigned GetNodeId () const { return nodeId; }
inline unsigned GetCreateTime () const { return createTime; }
inline unsigned GetModifyTime () const { return modifyTime; }
inline wchar * GetCreateAgeName () const { return createAgeName; }
inline Uuid GetCreateAgeUuid () const { return createAgeUuid; }
inline Uuid GetCreatorAcct () const { return creatorAcct; }
inline unsigned GetCreatorId () const { return creatorId; }
inline unsigned GetNodeType () const { return nodeType; }
inline int GetInt32_1 () const { return int32_1; }
inline int GetInt32_2 () const { return int32_2; }
inline int GetInt32_3 () const { return int32_3; }
inline int GetInt32_4 () const { return int32_4; }
inline unsigned GetUInt32_1 () const { return uint32_1; }
inline unsigned GetUInt32_2 () const { return uint32_2; }
inline unsigned GetUInt32_3 () const { return uint32_3; }
inline unsigned GetUInt32_4 () const { return uint32_4; }
inline Uuid GetUuid_1 () const { return uuid_1; }
inline Uuid GetUuid_2 () const { return uuid_2; }
inline Uuid GetUuid_3 () const { return uuid_3; }
inline Uuid GetUuid_4 () const { return uuid_4; }
inline wchar * GetString64_1 () const { return string64_1; }
inline wchar * GetString64_2 () const { return string64_2; }
inline wchar * GetString64_3 () const { return string64_3; }
inline wchar * GetString64_4 () const { return string64_4; }
inline wchar * GetString64_5 () const { return string64_5; }
inline wchar * GetString64_6 () const { return string64_6; }
inline wchar * GetIString64_1 () const { return istring64_1; }
inline wchar * GetIString64_2 () const { return istring64_2; }
// no blob "getters"
};
//============================================================================
inline void IVaultNodeSetString (
qword bit,
NetVaultNode * node,
char ** pdst,
const char src[],
unsigned chars
) {
FREE(*pdst);
if (src && src[0])
*pdst = StrDupLen(src, chars);
else
*pdst = StrDupLen("", chars);
node->fieldFlags |= bit;
node->dirtyFlags |= bit;
}
//============================================================================
inline void IVaultNodeSetString (
qword bit,
NetVaultNode * node,
wchar ** pdst,
const wchar src[],
unsigned chars
) {
FREE(*pdst);
if (src && src[0])
*pdst = StrDupLen(src, chars);
else
*pdst = StrDupLen(L"", chars);
node->fieldFlags |= bit;
node->dirtyFlags |= bit;
}
//============================================================================
template <typename T>
inline void IVaultNodeSetValue (
qword bit,
NetVaultNode * node,
T * pdst,
const T & src
) {
*pdst = src;
node->fieldFlags |= bit;
node->dirtyFlags |= bit;
}
//============================================================================
inline void IVaultNodeSetBlob (
qword bit,
NetVaultNode * node,
byte ** pdst,
unsigned * pdstLen,
const byte src[],
unsigned srcLen
) {
FREE(*pdst);
if (src) {
*pdst = (byte*)MEMDUP(src, srcLen);
*pdstLen = srcLen;
}
else {
*pdst = nil;
*pdstLen = 0;
}
node->fieldFlags |= bit;
node->dirtyFlags |= bit;
}
//============================================================================
// NetVaultNodeFieldArray
//============================================================================
struct NetVaultNodeFieldArray {
enum EWhereCondition {
kAnd,
kOr
};
enum ESqlType {
kSqlInvalid,
kSqlInt32,
kSqlUInt32,
kSqlUuid,
kSqlString,
kSqlCLob,
KSqlBlob,
};
struct Field {
void * addr;
const wchar * name;
Field (void * addr, const wchar name[])
: addr(addr), name(name)
{ }
};
ARRAY(Field) fields;
NetVaultNode * node;
NetVaultNodeFieldArray (NetVaultNode * node);
~NetVaultNodeFieldArray ();
void * GetFieldAddress (qword bit);
const wchar * GetFieldName (qword bit);
// client must lock node's local critical section before calling these.
void GetFieldValueString_LCS (qword bit, wchar * dst, unsigned dstChars);
void BuildWhereClause_LCS (EWhereCondition condition, wchar * dst, unsigned dstChars);
ESqlType GetSqlType_LCS (qword bit);
};
//============================================================================
// NetVaultNodeRef (packed because is sent over wire directly)
//============================================================================
#include <PshPack1.h>
struct NetVaultNodeRef {
unsigned parentId;
unsigned childId;
unsigned ownerId;
bool seen;
};
#include <PopPack.h>
//============================================================================
// SrvPackBuffer
//============================================================================
// Allocate a CSrvPackBuffer on the heap with one extra dword to allow for padding
#define SRV_ALLOC_BUFFER(bytes) \
new(ALLOC(sizeof(CSrvPackBuffer) + (bytes) + sizeof(dword))) \
CSrvPackBuffer(bytes + sizeof(dword))
// Allocate a CSrvPackBuffer on the stack with one extra dword to allow for padding
#define SRV_ALLOCA_BUFFER(bytes) \
new(_alloca(sizeof(CSrvPackBuffer) + (bytes) + sizeof(dword))) \
CSrvPackBuffer(bytes + sizeof(dword))
class CSrvPackBuffer {
public:
CSrvPackBuffer (unsigned bytes);
void * Alloc (unsigned bytes);
void AddData (const void * ptr, unsigned bytes);
void AddString (const wchar str[]);
void AddDWordArray (const UInt32 * arr, unsigned count);
// add new "Add..." methods here as needed
unsigned Size ();
private:
byte * m_pos;
byte * m_end;
byte * m_data;
};
class CSrvUnpackBuffer {
public:
CSrvUnpackBuffer (const void * buffer, unsigned count);
const void * GetData (unsigned bytes);
const wchar * GetString ();
const dword * GetDWordArray (unsigned count);
unsigned BytesLeft ();
bool ParseError ();
private:
const byte * m_pos;
const byte * m_end;
};