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.

468 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
#include "pnUUID/pnUUID.h"
#include "hsRefCnt.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(plUUID));
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
*
***/
#pragma pack(push,1)
struct SrvPlayerInfo {
unsigned playerInt;
wchar_t playerName[kMaxPlayerNameLength];
wchar_t avatarShape[kMaxVaultNodeStringLength];
unsigned explorer;
};
#pragma pack(pop)
/*****************************************************************************
*
* NetAgeInfo
*
***/
struct NetAgeInfo {
plUUID ageInstId;
wchar_t ageFilename[kMaxAgeNameLength];
wchar_t ageInstName[kMaxAgeNameLength];
wchar_t ageUserName[kMaxAgeNameLength];
wchar_t ageDesc[1024];
uint32_t ageSequenceNumber;
uint32_t ageLanguage;
uint32_t population; // only used with GetPublicAgeList query results
uint32_t currentPopulation; // only used with GetPublicAgeList query results
};
/*****************************************************************************
*
* NetGameScore
*
***/
struct NetGameScore {
unsigned scoreId;
unsigned ownerId;
uint32_t createdTime;
wchar_t gameName[kMaxGameScoreNameLength];
unsigned gameType;
int value;
unsigned Read (const uint8_t inbuffer[], unsigned bufsz, uint8_t** end = nil); // returns number of bytes read
unsigned Write (ARRAY(uint8_t) * buffer) const; // returns number of bytes written
void CopyFrom (const NetGameScore & score);
};
/*****************************************************************************
*
* NetGameRank
*
***/
struct NetGameRank {
unsigned rank;
int score;
wchar_t name[kMaxPlayerNameLength];
unsigned Read (const uint8_t inbuffer[], unsigned bufsz, uint8_t** end = nil); // returns number of bytes read
unsigned Write (ARRAY(uint8_t) * 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 : hsRefCnt {
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 uint64_t kNodeId = (uint64_t)1<< 0;
static const uint64_t kCreateTime = (uint64_t)1<< 1;
static const uint64_t kModifyTime = (uint64_t)1<< 2;
static const uint64_t kCreateAgeName = (uint64_t)1<< 3;
static const uint64_t kCreateAgeUuid = (uint64_t)1<< 4;
static const uint64_t kCreatorAcct = (uint64_t)1<< 5;
static const uint64_t kCreatorId = (uint64_t)1<< 6;
static const uint64_t kNodeType = (uint64_t)1<< 7;
static const uint64_t kInt32_1 = (uint64_t)1<< 8;
static const uint64_t kInt32_2 = (uint64_t)1<< 9;
static const uint64_t kInt32_3 = (uint64_t)1<<10;
static const uint64_t kInt32_4 = (uint64_t)1<<11;
static const uint64_t kUInt32_1 = (uint64_t)1<<12;
static const uint64_t kUInt32_2 = (uint64_t)1<<13;
static const uint64_t kUInt32_3 = (uint64_t)1<<14;
static const uint64_t kUInt32_4 = (uint64_t)1<<15;
static const uint64_t kUuid_1 = (uint64_t)1<<16;
static const uint64_t kUuid_2 = (uint64_t)1<<17;
static const uint64_t kUuid_3 = (uint64_t)1<<18;
static const uint64_t kUuid_4 = (uint64_t)1<<19;
static const uint64_t kString64_1 = (uint64_t)1<<20;
static const uint64_t kString64_2 = (uint64_t)1<<21;
static const uint64_t kString64_3 = (uint64_t)1<<22;
static const uint64_t kString64_4 = (uint64_t)1<<23;
static const uint64_t kString64_5 = (uint64_t)1<<24;
static const uint64_t kString64_6 = (uint64_t)1<<25;
static const uint64_t kIString64_1 = (uint64_t)1<<26;
static const uint64_t kIString64_2 = (uint64_t)1<<27;
// blobs always come last
static const uint64_t kText_1 = (uint64_t)1<<28;
static const uint64_t kText_2 = (uint64_t)1<<29;
static const uint64_t kBlob_1 = (uint64_t)1<<30;
static const uint64_t kBlob_2 = (uint64_t)1<<31;
static const uint64_t kAllValidFields = 0x00000000FFFFFFFFULL;
CCritSect critsect;
plUUID revisionId;
private:
uint64_t fieldFlags;
uint64_t dirtyFlags;
// Treat these as read-only or node flag fields will become invalid
// Threaded apps: Must be accessed with node->critsect locked
uint32_t nodeId;
uint32_t createTime;
uint32_t modifyTime;
wchar_t * createAgeName;
plUUID createAgeUuid;
plUUID creatorAcct; // accountId of node creator
uint32_t creatorId; // playerId of node creator
uint32_t nodeType;
int32_t int32_1;
int32_t int32_2;
int32_t int32_3;
int32_t int32_4;
uint32_t uint32_1;
uint32_t uint32_2;
uint32_t uint32_3;
uint32_t uint32_4;
plUUID uuid_1;
plUUID uuid_2;
plUUID uuid_3;
plUUID uuid_4;
wchar_t * string64_1;
wchar_t * string64_2;
wchar_t * string64_3;
wchar_t * string64_4;
wchar_t * string64_5;
wchar_t * string64_6;
wchar_t * istring64_1;
wchar_t * istring64_2;
wchar_t * text_1;
wchar_t * text_2;
uint8_t * blob_1; uint32_t blob_1Length;
uint8_t * blob_2; uint32_t blob_2Length;
void IVaultNodeSetString (
uint64_t bit,
char ** pdst,
const char src[],
unsigned chars
) {
free(*pdst);
if (src && src[0])
*pdst = StrDupLen(src, chars);
else
*pdst = StrDupLen("", chars);
fieldFlags |= bit;
dirtyFlags |= bit;
}
void IVaultNodeSetString (
uint64_t bit,
wchar_t ** pdst,
const wchar_t src[],
unsigned chars
) {
free(*pdst);
if (src && src[0])
*pdst = StrDupLen(src, chars);
else
*pdst = StrDupLen(L"", chars);
fieldFlags |= bit;
dirtyFlags |= bit;
}
template <typename T>
inline void IVaultNodeSetValue (
uint64_t bit,
T * pdst,
const T & src
) {
*pdst = src;
fieldFlags |= bit;
dirtyFlags |= bit;
}
void IVaultNodeSetBlob (
uint64_t bit,
uint8_t ** pdst,
unsigned * pdstLen,
const uint8_t src[],
unsigned srcLen
) {
free(*pdst);
if (src) {
*pdst = (uint8_t*)malloc(srcLen);
memcpy(*pdst, src, srcLen);
*pdstLen = srcLen;
}
else {
*pdst = nil;
*pdstLen = 0;
}
fieldFlags |= bit;
dirtyFlags |= bit;
}
void DeallocNodeFields();
public:
NetVaultNode ();
~NetVaultNode ();
// Threaded apps: Must be called with node->critsect locked
uint32_t Read_LCS (const uint8_t buffer[], uint32_t bufsz, uint32_t rwOpts); // returns number of bytes read
uint32_t Write_LCS (ARRAY(uint8_t) * buffer, uint32_t rwOpts); // returns number of bytes written
bool Matches (const NetVaultNode * other);
void CopyFrom (const NetVaultNode * other, uint32_t copyOpts);
uint64_t GetFieldFlags () const { return fieldFlags; }
void ClearFieldFlags () { fieldFlags = 0; }
uint64_t GetDirtyFlags () const { return dirtyFlags; }
void SetDirtyFlags (uint64_t flags) { dirtyFlags |= flags; }
void ClearDirtyFlags (uint64_t flags) { dirtyFlags &= ~flags; }
// Threaded apps: Must be called with node->critsect locked
void SetNodeId (uint32_t v);
void SetNodeId_NoDirty (uint32_t v) { nodeId = v; }
void SetCreateTime (uint32_t v);
void SetModifyTime (uint32_t v);
void SetCreateAgeName (const wchar_t v[]);
void SetCreateAgeUuid (const plUUID & v);
void SetCreatorAcct (const plUUID & v);
void SetCreatorId (uint32_t v);
void SetNodeType (uint32_t v);
void SetInt32_1 (int32_t v);
void SetInt32_2 (int32_t v);
void SetInt32_3 (int32_t v);
void SetInt32_4 (int32_t v);
void SetUInt32_1 (uint32_t v);
void SetUInt32_2 (uint32_t v);
void SetUInt32_3 (uint32_t v);
void SetUInt32_4 (uint32_t v);
void SetUuid_1 (const plUUID & v);
void SetUuid_2 (const plUUID & v);
void SetUuid_3 (const plUUID & v);
void SetUuid_4 (const plUUID & v);
void SetString64_1 (const wchar_t v[]);
void SetString64_2 (const wchar_t v[]);
void SetString64_3 (const wchar_t v[]);
void SetString64_4 (const wchar_t v[]);
void SetString64_5 (const wchar_t v[]);
void SetString64_6 (const wchar_t v[]);
void SetIString64_1 (const wchar_t v[]);
void SetIString64_2 (const wchar_t v[]);
void SetText_1 (const wchar_t v[]);
void SetText_2 (const wchar_t v[]);
void SetBlob_1 (const uint8_t v[], uint32_t len);
void SetBlob_2 (const uint8_t v[], uint32_t len);
uint32_t GetNodeId () const { return nodeId; }
uint32_t GetCreateTime () const { return createTime; }
uint32_t GetModifyTime () const { return modifyTime; }
const wchar_t * GetCreateAgeName () const { return createAgeName; }
plUUID GetCreateAgeUuid () const { return createAgeUuid; }
plUUID GetCreatorAcct () const { return creatorAcct; }
uint32_t GetCreatorId () const { return creatorId; }
uint32_t GetNodeType () const { return nodeType; }
int32_t GetInt32_1 () const { return int32_1; }
int32_t GetInt32_2 () const { return int32_2; }
int32_t GetInt32_3 () const { return int32_3; }
int32_t GetInt32_4 () const { return int32_4; }
uint32_t GetUInt32_1 () const { return uint32_1; }
uint32_t GetUInt32_2 () const { return uint32_2; }
uint32_t GetUInt32_3 () const { return uint32_3; }
uint32_t GetUInt32_4 () const { return uint32_4; }
plUUID GetUuid_1 () const { return uuid_1; }
plUUID GetUuid_2 () const { return uuid_2; }
plUUID GetUuid_3 () const { return uuid_3; }
plUUID GetUuid_4 () const { return uuid_4; }
const wchar_t * GetString64_1 () const { return string64_1; }
const wchar_t * GetString64_2 () const { return string64_2; }
const wchar_t * GetString64_3 () const { return string64_3; }
const wchar_t * GetString64_4 () const { return string64_4; }
const wchar_t * GetString64_5 () const { return string64_5; }
const wchar_t * GetString64_6 () const { return string64_6; }
const wchar_t * GetIString64_1 () const { return istring64_1; }
const wchar_t * GetIString64_2 () const { return istring64_2; }
const wchar_t * GetText_1 () const { return text_1; }
const wchar_t * GetText_2 () const { return text_2; }
const uint8_t * GetBlob_1 () const { return blob_1; }
size_t GetBlob_1Length () const { return blob_1Length; }
const uint8_t * GetBlob_2 () const { return blob_2; }
size_t GetBlob_2Length () const { return blob_2Length; }
};
//============================================================================
// NetVaultNodeRef (packed because is sent over wire directly)
//============================================================================
#pragma pack(push,1)
struct NetVaultNodeRef {
unsigned parentId;
unsigned childId;
unsigned ownerId;
bool seen;
};
#pragma pack(pop)
//============================================================================
// SrvPackBuffer
//============================================================================
// Allocate a CSrvPackBuffer on the heap with one extra uint32_t to allow for padding
#define SRV_ALLOC_BUFFER(bytes) \
new(malloc(sizeof(CSrvPackBuffer) + (bytes) + sizeof(uint32_t))) \
CSrvPackBuffer(bytes + sizeof(uint32_t))
// Allocate a CSrvPackBuffer on the stack with one extra uint32_t to allow for padding
#define SRV_ALLOCA_BUFFER(bytes) \
new(_alloca(sizeof(CSrvPackBuffer) + (bytes) + sizeof(uint32_t))) \
CSrvPackBuffer(bytes + sizeof(uint32_t))
class CSrvPackBuffer {
public:
CSrvPackBuffer (unsigned bytes);
void * Alloc (unsigned bytes);
void AddData (const void * ptr, unsigned bytes);
void AddString (const wchar_t str[]);
void AddDWordArray (const uint32_t * arr, unsigned count);
// add new "Add..." methods here as needed
unsigned Size ();
private:
uint8_t * m_pos;
uint8_t * m_end;
uint8_t * m_data;
};
class CSrvUnpackBuffer {
public:
CSrvUnpackBuffer (const void * buffer, unsigned count);
const void * GetData (unsigned bytes);
const wchar_t * GetString ();
const uint32_t * GetDWordArray (unsigned count);
unsigned BytesLeft ();
bool ParseError ();
private:
const uint8_t * m_pos;
const uint8_t * m_end;
};