/*==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 . 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==*/ #ifndef PL_NET_MSG_HELPERS_inc #define PL_NET_MSG_HELPERS_inc // // These are not messages per se, but helper classes which are used // in to avoid multiple derivation by net messages. // #include "HeadSpin.h" #include "hsStream.h" #include "hsStlUtils.h" #include "pnNetCommon/pnNetCommon.h" #include "pnFactory/plCreatable.h" #include "pnKeyedObject/plUoid.h" #include "pnKeyedObject/plKey.h" #include "plUnifiedTime/plUnifiedTime.h" #include "plNetCommon/plClientGuid.h" #include class plKey; class hsStream; //////////////////////////////////////////////////////////////////// // plNetMsgStreamableHelper // Will peek/poke anything derived from hsStreamable class plNetMsgStreamableHelper : public plCreatable { hsStreamable * fObject; public: plNetMsgStreamableHelper():fObject(nil){} plNetMsgStreamableHelper(hsStreamable * object):fObject(object){} plNetMsgStreamableHelper & operator =(hsStreamable * value); operator hsStreamable *() const { return fObject;} operator const hsStreamable *() const { return fObject;} CLASSNAME_REGISTER( plNetMsgStreamableHelper ); GETINTERFACE_ANY(plNetMsgStreamableHelper, plCreatable); void SetObject(hsStreamable * object) { fObject=object;} hsStreamable * GetObject() const { return fObject;} int Poke(hsStream* stream, uint32_t peekOptions=0); int Peek(hsStream* stream, uint32_t peekOptions=0); }; //////////////////////////////////////////////////////////////////// // plNetMsgCreatableHelper // Will peek/poke anything derived from plCreatable. // Will create the object upon read if it hasn't been set by SetObject(). // When helper goes away, object will be unref-ed if it was created by // the helper, so if you GetObject() and want to keep it longer than the // lifetime of the helper, ref it. class plNetMsgCreatableHelper : public plCreatable { plCreatable * fCreatable; bool fWeCreatedIt; public: plNetMsgCreatableHelper(plCreatable * object = nil); ~plNetMsgCreatableHelper(); plNetMsgCreatableHelper & operator =(plCreatable * value); operator plCreatable*(); operator const plCreatable*(); CLASSNAME_REGISTER( plNetMsgCreatableHelper ); GETINTERFACE_ANY(plNetMsgCreatableHelper, plCreatable); void SetObject(plCreatable * object); plCreatable * GetObject(); int Poke(hsStream* stream, uint32_t peekOptions=0); int Peek(hsStream* stream, uint32_t peekOptions=0); }; //////////////////////////////////////////////////////////////////// // // Net msg helper class for a stream buffer of some type (saveState, voice, plMessage...) // class plNetMsgStreamHelper : public plCreatable { private: enum ContentsFlags { kUncompressedSize, kStreamBuf, kStreamLen, kCompressionType, }; protected: uint32_t fUncompressedSize; int16_t fStreamType; // set to creatable type, not read/written, gleaned from creatable stream uint8_t* fStreamBuf; uint32_t fStreamLen; uint8_t fCompressionType; // see plNetMessage::CompressionType uint32_t fCompressionThreshold; // NOT WRITTEN void IAllocStream(uint32_t len); public: enum { kDefaultCompressionThreshold = 255 }; // bytes plNetMsgStreamHelper(); virtual ~plNetMsgStreamHelper() { delete [] fStreamBuf; } CLASSNAME_REGISTER( plNetMsgStreamHelper ); GETINTERFACE_ANY(plNetMsgStreamHelper, plCreatable); virtual int Poke(hsStream* stream, uint32_t peekOptions=0); virtual int Peek(hsStream* stream, uint32_t peekOptions=0); // creatable ops virtual void Read(hsStream* s, hsResMgr* mgr) { Peek(s); } virtual void Write(hsStream* s, hsResMgr* mgr) { Poke(s); } void ReadVersion(hsStream* s, hsResMgr* mgr); void WriteVersion(hsStream* s, hsResMgr* mgr); void Clear(); // copiers void CopyFrom(const plNetMsgStreamHelper* other); void CopyStream(hsStream* ssStream); // copies to fStream void CopyStream(int32_t len, const void* buf); // copies to fStream // setters void SetCompressionType(uint8_t t) { fCompressionType=t; } void SetStreamLen(uint32_t l) { fStreamLen=l; } void SetStreamBuf(uint8_t* b) { fStreamBuf=b; } void SetUncompressedSize(uint32_t s) { fUncompressedSize=s; } // Getters uint8_t GetCompressionType() const { return fCompressionType; } int16_t GetStreamType() const { return fStreamType; } uint32_t GetStreamLen() const { return fStreamLen; } uint8_t* GetStreamBuf() const { return fStreamBuf; } uint32_t GetUncompressedSize() const { return fUncompressedSize; } bool Compress(int offset=2 /* skip 2 bytes as creatable index */ ); bool Uncompress(int offset=2 /* skip 2 bytes as creatable index */ ); bool IsCompressed() const; bool IsCompressable() const; uint32_t GetCompressionThreshold() const { return fCompressionThreshold; } void SetCompressionThreshold( uint32_t v ) { fCompressionThreshold=v; } }; // // Contains info about a scene object // class plNetMsgObjectHelper : public plCreatable { private: enum ContentFlags { kObjHelperUoid, }; protected: // string names for debug purposes only plUoid fUoid; // update operator()= fxn when adding new members public: plNetMsgObjectHelper() {} plNetMsgObjectHelper(const plKey key) { SetFromKey(key); } virtual ~plNetMsgObjectHelper() { } CLASSNAME_REGISTER( plNetMsgObjectHelper ); GETINTERFACE_ANY(plNetMsgObjectHelper, plCreatable); virtual int Poke(hsStream* stream, uint32_t peekOptions=0); virtual int Peek(hsStream* stream, uint32_t peekOptions=0); plNetMsgObjectHelper & operator =(const plNetMsgObjectHelper & other); // setters bool SetFromKey(const plKey &key); void SetUoid(const plUoid &u) { fUoid=u; } // getters const plString& GetObjectName() const { return fUoid.GetObjectName(); } uint32_t GetPageID() const { return fUoid.GetLocation().GetSequenceNumber(); } const plUoid& GetUoid() const { return fUoid; } void ReadVersion(hsStream* s, hsResMgr* mgr); void WriteVersion(hsStream* s, hsResMgr* mgr); }; // // Contains a list of info about scene objects. // class plNetMsgObjectListHelper : public plCreatable { protected: std::vector fObjects; public: plNetMsgObjectListHelper() {} virtual ~plNetMsgObjectListHelper(); CLASSNAME_REGISTER( plNetMsgObjectListHelper ); GETINTERFACE_ANY(plNetMsgObjectListHelper, plCreatable); virtual int Poke(hsStream* stream, uint32_t peekOptions=0); virtual int Peek(hsStream* stream, uint32_t peekOptions=0); void Reset(); int GetNumObjects() const { return fObjects.size(); } plNetMsgObjectHelper* GetObject(int i) { return fObjects[i]; } void AddObject(plKey key) { fObjects.push_back(new plNetMsgObjectHelper(key)); } }; // // Contains a info about a net member. // class plNetMsgMemberInfoHelper : public plCreatable { protected: uint32_t fFlags; plUoid fAvatarUoid; plClientGuid fClientGuid; public: plNetMsgMemberInfoHelper(); CLASSNAME_REGISTER( plNetMsgMemberInfoHelper ); GETINTERFACE_ANY( plNetMsgMemberInfoHelper, plCreatable); virtual int Poke(hsStream* stream, uint32_t peekOptions=0); virtual int Peek(hsStream* stream, uint32_t peekOptions=0); const plClientGuid * GetClientGuid() const { return &fClientGuid; } plClientGuid * GetClientGuid() { return &fClientGuid; } uint32_t GetFlags() const { return fFlags; } plUoid GetAvatarUoid() const { return fAvatarUoid; } void SetFlags(uint32_t v) { fFlags=v; } void SetAvatarUoid(plUoid u) { fAvatarUoid=u; } }; // // Contains a info about a list of net members. // This is sent from server to client. // class plNetMsgMemberListHelper : public plCreatable { public: typedef std::vector MemberInfoHelperVec; struct MatchesPlayerID { uint32_t fID; MatchesPlayerID( uint32_t id ): fID( id ){} bool operator()( const plNetMsgMemberInfoHelper * mbr ) const { return ( mbr && mbr->GetClientGuid()->GetPlayerID()==fID ); } }; protected: MemberInfoHelperVec fMembers; public: plNetMsgMemberListHelper() {} virtual ~plNetMsgMemberListHelper(); CLASSNAME_REGISTER( plNetMsgMemberListHelper ); GETINTERFACE_ANY( plNetMsgMemberListHelper, plCreatable); virtual int Poke(hsStream* stream, uint32_t peekOptions=0); virtual int Peek(hsStream* stream, uint32_t peekOptions=0); int GetNumMembers() const { return fMembers.size(); } const plNetMsgMemberInfoHelper* GetMember(int i) const { return fMembers[i]; } void AddMember(plNetMsgMemberInfoHelper* a) { fMembers.push_back(a); } const MemberInfoHelperVec * GetMembers() const { return &fMembers;} }; ///////////////////////////////////////////////////////////////// // // Contains a list of other players (members). // This is commonly used to route p2p msgs to groups of players. // Sent client to server. // class plNetMsgReceiversListHelper : public plCreatable { protected: std::vector fPlayerIDList; public: plNetMsgReceiversListHelper() {} virtual ~plNetMsgReceiversListHelper() {} CLASSNAME_REGISTER( plNetMsgReceiversListHelper ); GETINTERFACE_ANY( plNetMsgReceiversListHelper, plCreatable); virtual int Poke(hsStream* stream, uint32_t peekOptions=0); virtual int Peek(hsStream* stream, uint32_t peekOptions=0); void Clear() { fPlayerIDList.clear(); } int GetNumReceivers() const { return fPlayerIDList.size(); } uint32_t GetReceiverPlayerID(int i) const { return fPlayerIDList[i]; } void AddReceiverPlayerID(uint32_t a) { fPlayerIDList.push_back(a); } bool RemoveReceiverPlayerID(uint32_t n); // returns true if found and removed }; #endif // PL_NET_MSG__HELPERS_inc