/*==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==*/ #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 "plStatusLog/plLoggable.h" #include #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 plNetMemberList; typedef std::vector 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