/*==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