openclonk/src/network/C4Network2Client.h

213 lines
6.3 KiB
C++

/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2013-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 INC_C4Network2Client
#define INC_C4Network2Client
#include "network/C4NetIO.h"
#include "network/C4Network2IO.h"
#include "network/C4PacketBase.h"
#include "network/C4Client.h"
#include "network/C4Network2Address.h"
class C4Network2; class C4Network2IOConnection;
// maximum address count that is saved for one client
const int32_t C4ClientMaxAddr = 20;
// retry count and interval for connecting a client
const int32_t C4NetClientConnectAttempts = 3,
C4NetClientConnectInterval = 6; // s
// network client status (host only)
enum C4Network2ClientStatus
{
NCS_Joining, // waiting for join data
NCS_Chasing, // client is behind (status not acknowledged, isn't waited for)
NCS_NotReady, // client is behind (status not acknowledged)
NCS_Ready, // client acknowledged network status
NCS_Remove // client is to be removed
};
class C4Network2Client
{
friend class C4Network2ClientList;
public:
C4Network2Client(C4Client *pClient);
~C4Network2Client();
protected:
// client data
C4Client *pClient;
// addresses
C4Network2Address Addr[C4ClientMaxAddr];
int32_t AddrAttempts[C4ClientMaxAddr];
int32_t iAddrCnt;
// interface ids
std::set<int> InterfaceIDs;
// status
C4Network2ClientStatus eStatus;
// frame of last activity
int32_t iLastActivity;
// connections
C4Network2IOConnection *pMsgConn, *pDataConn;
time_t iNextConnAttempt;
// part of client list
C4Network2Client *pNext;
class C4Network2ClientList *pParent;
// statistics
class C4TableGraph *pstatPing;
public:
C4Client *getClient() const { return pClient; }
const C4ClientCore &getCore() const { return getClient()->getCore(); }
int32_t getID() const { return getCore().getID(); }
bool isLocal() const { return pClient->isLocal(); }
bool isHost() const { return getID() == C4ClientIDHost; }
const char *getName() const { return getCore().getName(); }
bool isActivated() const { return getCore().isActivated(); }
bool isObserver() const { return getCore().isObserver(); }
int32_t getAddrCnt() const { return iAddrCnt; }
const C4Network2Address &getAddr(int32_t i) const { return Addr[i]; }
const std::set<int> &getInterfaceIDs() const { return InterfaceIDs; }
C4Network2ClientStatus getStatus() const { return eStatus; }
bool hasJoinData() const { return getStatus() != NCS_Joining; }
bool isChasing() const { return getStatus() == NCS_Chasing; }
bool isReady() const { return getStatus() == NCS_Ready; }
bool isWaitedFor() const { return getStatus() == NCS_NotReady || getStatus() == NCS_Ready; }
bool isRemoved() const { return getStatus() == NCS_Remove; }
bool isConnected() const { return !! pMsgConn; }
time_t getNextConnAttempt() const { return iNextConnAttempt; }
int32_t getLastActivity() const { return iLastActivity; }
class C4TableGraph *getStatPing() const { return pstatPing; }
C4Network2Client *getNext() const { return pNext; }
void SetStatus(C4Network2ClientStatus enStatus) { eStatus = enStatus; }
void SetLastActivity(int32_t iTick) { iLastActivity = iTick; }
C4Network2IOConnection *getMsgConn() const { return pMsgConn; }
C4Network2IOConnection *getDataConn() const { return pDataConn; }
bool hasConn(C4Network2IOConnection *pConn);
void SetMsgConn(C4Network2IOConnection *pConn);
void SetDataConn(C4Network2IOConnection *pConn);
void RemoveConn(C4Network2IOConnection *pConn);
void CloseConns(const char *szMsg);
bool SendMsg(C4NetIOPacket rPkt) const;
bool SendData(C4NetIOPacket rPkt) const;
bool DoConnectAttempt(class C4Network2IO *pIO);
// addresses
bool hasAddr(const C4Network2Address &addr) const;
void ClearAddr();
bool AddAddr(const C4Network2Address &addr, bool fAnnounce);
void AddLocalAddrs(int16_t iPortTCP, int16_t iPortUDP);
void SendAddresses(C4Network2IOConnection *pConn);
// runtime statistics
void CreateGraphs();
void ClearGraphs();
};
class C4Network2ClientList
{
public:
C4Network2ClientList(C4Network2IO *pIO);
~C4Network2ClientList();
protected:
C4Network2IO *pIO;
C4Network2Client *pFirst;
C4Network2Client *pLocal;
C4ClientList *pClientList;
bool fHost;
public:
C4Network2Client *GetClientByID(int32_t iID) const;
C4Network2Client *GetNextClientAfterID(int32_t iSmallerClientID) const;
C4Network2Client *GetClient(const char *szName) const;
C4Network2Client *GetClient(const C4ClientCore &CCore, int32_t iMaxDiffLevel = C4ClientCoreDL_IDMatch);
C4Network2Client *GetClient(C4Network2IOConnection *pConn) const;
C4Network2Client *GetLocal() const { return pLocal; }
C4Network2Client *GetHost();
C4Network2Client *GetNextClient(C4Network2Client *pClient);
unsigned int Count();
void Init(C4ClientList *pClientList, bool fHost);
C4Network2Client *RegClient(C4Client *pClient);
void DeleteClient(C4Network2Client *pClient);
void Clear();
// messages
bool BroadcastMsgToConnClients(const C4NetIOPacket &rPkt);
bool BroadcastMsgToClients(const C4NetIOPacket &rPkt);
bool SendMsgToHost(C4NetIOPacket rPkt);
bool SendMsgToClient(int32_t iClient, C4NetIOPacket &&rPkt);
// packet handling
void HandlePacket(char cStatus, const C4PacketBase *pBasePkt, C4Network2IOConnection *pConn);
// addresses
void SendAddresses(C4Network2IOConnection *pConn);
// connecting
void DoConnectAttempts();
// ready-ness
void ResetReady();
bool AllClientsReady() const;
// activity
void UpdateClientActivity();
};
// * Packets *
class C4PacketAddr : public C4PacketBase
{
public:
C4PacketAddr() { }
C4PacketAddr(int32_t iClientID, const C4Network2Address &addr)
: iClientID(iClientID), addr(addr)
{ }
protected:
int32_t iClientID;
C4Network2Address addr;
public:
int32_t getClientID() const { return iClientID; }
const C4Network2Address &getAddr() const { return addr; }
virtual void CompileFunc(StdCompiler *pComp);
};
#endif