openclonk/src/network/C4Client.h

191 lines
6.0 KiB
C++

/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2010-2016, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
#ifndef C4CLIENT_H
#define C4CLIENT_H
#include "lib/C4InputValidation.h"
#include "network/C4NetIO.h"
#include "network/C4PacketBase.h"
// special ids
const int32_t C4ClientIDUnknown = -1,
C4ClientIDHost = 0,
C4ClientIDStart = 1;
// client core difference levels
const int32_t C4ClientCoreDL_None = 0, // identical
C4ClientCoreDL_IDMatch = 1, // status change
C4ClientCoreDL_IDChange = 2, // identification changed (host only!)
C4ClientCoreDL_Different = 3; // really different
class C4ClientCore : public C4PacketBase
{
public:
C4ClientCore();
~C4ClientCore() override;
protected:
// identification
int32_t iID{-1};
ValidatedStdCopyStrBuf<C4InVal::VAL_NameNoEmpty> Name, Nick;
ValidatedStdCopyStrBuf<C4InVal::VAL_NameAllowEmpty> CUID;
ValidatedStdCopyStrBuf<C4InVal::VAL_NameAllowEmpty> Revision; // engine hg revision number
// version info
int iVersion[4];
// status
bool fActivated{false}, fObserver{false}, fLobbyReady{false};
public:
// status data
int32_t getID() const { return iID; }
bool isHost() const { return iID == C4ClientIDHost; }
bool isActivated() const { return fActivated; }
bool isObserver() const { return fObserver; }
bool isLobbyReady() const { return fLobbyReady; }
void SetID(int32_t inID) { iID = inID; }
void SetName(const char *sznName) { Name.CopyValidated(sznName); }
void SetActivated(bool fnActivated) { fActivated = fnActivated; fObserver = false; }
void SetObserver(bool fnObserver) { fActivated &= !(fObserver = fnObserver); }
void SetLobbyReady(bool fnLobbyReady){ fLobbyReady = fnLobbyReady; }
// misc
const char *getName() const { return Name.getData(); }
const char *getCUID() const { return CUID.getData(); }
const char *getNick() const { return Nick.getData(); }
const char *getRevision() const { return Revision.getData(); }
bool isRegistered()const { return CUID.getLength()>0; }
// initialization
void SetLocal(int32_t iID, bool fnActivated, bool fnObserver);
void SetUnknown(int32_t iID);
int32_t getDiffLevel(const C4ClientCore &CCore2) const;
void CompileFunc(StdCompiler *pComp) override;
};
class C4Client
{
friend class C4ClientList;
public:
C4Client();
C4Client(const C4ClientCore &Core);
~C4Client();
private:
C4ClientCore Core;
bool fLocal{false}; // Local, NoSync
class C4Network2Client *pNetClient{nullptr}; // Local, NoSync
time_t last_lobby_ready_change{0}; // Local, NoSync: Time when the lobby ready state was changed last through the SetLobbyReady call. 0 for never changed.
bool fIsIgnored{false}; // Local, NoSync: chat messages from this client are suppressed
C4Client *pNext;
public:
const C4ClientCore &getCore() const { return Core; }
int32_t getID() const { return Core.getID(); }
bool isHost() const { return Core.isHost(); }
const char *getName() const { return Core.getName(); }
const char *getCUID() const { return Core.getCUID(); }
const char *getNick() const { return Core.getNick(); }
bool isActivated() const { return Core.isActivated(); }
bool isObserver() const { return Core.isObserver(); }
bool isLobbyReady()const { return Core.isLobbyReady(); }
bool isRegistered()const { return Core.isRegistered(); }
bool IsIgnored() const { return fIsIgnored; }
bool isLocal() const { return fLocal; }
C4Network2Client *getNetClient() const { return pNetClient; }
void SetCore(const C4ClientCore &NewCore) { Core = NewCore; }
void SetID(int32_t iID) { Core.SetID(iID); }
void SetActivated(bool fnActivated);
void SetObserver() { Core.SetObserver(true); }
void SetLobbyReady(bool fnLobbyReady, time_t *time_since_last_change = nullptr);
void SetLocal();
void ToggleIgnore() { fIsIgnored = !fIsIgnored; }
void UnlinkNetClient() { pNetClient = nullptr; }
void Remove();
void CompileFunc(StdCompiler *pComp);
};
class C4ClientList
{
public:
C4ClientList();
~C4ClientList();
C4ClientList &operator = (const C4ClientList &List);
void Clear();
protected:
// client list
C4Client *pFirst{nullptr};
// pointer to local client
C4Client *pLocal{nullptr};
// network client list (may be nullptr if network is not active)
class C4Network2ClientList *pNetClients{nullptr};
void Add(C4Client *pClient);
public:
C4Client *getClient(const C4Client *pAfter = nullptr) const { return pAfter ? pAfter->pNext : pFirst; }
C4Client *getLocal() const { return pLocal; }
C4Client *getClientByID(int32_t iID) const;
C4Client *getHost() const { return getClientByID(C4ClientIDHost); }
C4Client *getNextClientByID(int32_t iAfterID) const;
C4Client *getClientByName(const char *szName) const;
int32_t getClientCnt() const;
const C4ClientCore &getLocalCore() const { return getLocal()->getCore(); }
const char *getLocalName() const { return pLocal ? getLocalCore().getName() : "???"; }
int32_t getLocalID() const { return pLocal ? getLocalCore().getID() : C4ClientIDUnknown; }
StdStrBuf GetAllClientNames() const;
bool Init(int32_t iLocalClientID = C4ClientIDHost);
void InitNetwork(class C4Network2ClientList *pNetClients);
void ClearNetwork();
bool Remove(C4Client *pClient, bool fTemporary = false);
C4Client *Add(const C4ClientCore &Core);
C4Client *AddLocal(int32_t iID, bool fActivated, bool fObserver);
void SetLocalID(int32_t iID);
void CtrlRemove(const C4Client *pClient, const char *szReason);
void RemoveRemote();
void CompileFunc(StdCompiler *pComp);
};
#endif // C4CLIENT_H