/*==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 . 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 struct SrvPlayerInfo { unsigned playerInt; wchar playerName[kMaxPlayerNameLength]; wchar avatarShape[kMaxVaultNodeStringLength]; unsigned explorer; }; #include /***************************************************************************** * * 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 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 struct NetVaultNodeRef { unsigned parentId; unsigned childId; unsigned ownerId; bool seen; }; #include //============================================================================ // 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 dword * arr, unsigned count); void AddDWordArray (const unsigned * 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; };