📄 netconnection.h
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifndef _RPGNETCONNECTION_H_
#define _RPGNETCONNECTION_H_
#ifndef _MPOINT_H_
#include "math/mPoint.h"
#endif
#ifndef _NETOBJECT_H_
#include "sim/netObject.h"
#endif
#ifndef _NETSTRINGTABLE_H_
#include "sim/netStringTable.h"
#endif
#ifndef _NETEVENT_H_
#include "sim/netEvent.h"
#endif
#ifndef _H_CONNECTIONSTRINGTABLE
#include "sim/connectionStringTable.h"
#endif
#ifndef _CONNECTIONPROTOCOL_H_
#include "connectionProtocol.h"
#endif
//#define _RPG_NOCOMMENT
class NetObject;
class BitStream;
class ResizeBitStream;
class Stream;
class Point3F;
//namespace CS
//{
struct GhostInfo;
struct SubPacketRef; // defined in NetConnection subclass
struct GhostRef;
//struct NetEventNote;
//#define TORQUE_DEBUG_NET
//#ifdef TORQUE_DEBUG_NET
//#define DEBUG_LOG(x) if(mLogging){Con::printf x;}
//#else
//#define DEBUG_LOG(x)
//#endif
//----------------------------------------------------------------------------
class NetConnection : public ConnectionProtocol
, public SimGroup
{
friend class NetInterface;
friend class NetworkBase;
friend class NetUDP;
friend class NetManager;
friend class NetTCP;
typedef SimGroup Parent;
public:
/// Structure to track ghost references in packets.
///
/// Every packet we send out with an update from a ghost causes one of these to be
/// allocated. mask is used to track what states were sent; that way if a packet is
/// dropped, we can easily manipulate the stored states and figure out what if any data
/// we need to resend.
///
struct GhostRef
{
U32 mask; ///< States we transmitted.
U32 ghostInfoFlags; ///< Flags from GhostInfo::Flags
GhostInfo *ghost; ///< Reference to the GhostInfo we're from.
GhostRef *nextRef; ///< Next GhostRef in this packet.
GhostRef *nextUpdateChain; ///< Next update we sent for this ghost.
};
enum Constants
{
HashTableSize = 127,
};
void sendDisconnectPacket(const char *reason);
virtual bool canRemoteCreate();
virtual void onTimedOut();
virtual void onConnectTimedOut();
virtual void onDisconnect(const char *reason);
virtual void onConnectionRejected(const char *reason);
virtual void onConnectionEstablished(bool isInitiator);
virtual void handleStartupError(const char *errorString);
virtual void writeConnectRequest(BitStream *stream);
virtual bool readConnectRequest(BitStream *stream, const char **errorString);
virtual void writeConnectAccept(BitStream *stream);
virtual bool readConnectAccept(BitStream *stream, const char **errorString);
void connect(const NetAddress *address);
//----------------------------------------------------------------
/// @name Global Connection List
/// @{
private:
///
NetConnection *mNextConnection; ///< Next item in list.
NetConnection *mPrevConnection; ///< Previous item in list.
static NetConnection *mConnectionList; ///< Head of list.
public:
static NetConnection *getConnectionList() { return mConnectionList; }
NetConnection *getNext() { return mNextConnection; }
/// @}
//----------------------------------------------------------------
enum NetConnectionFlags
{
ConnectionToServer = BIT(0),
ConnectionToClient = BIT(1),
LocalClientConnection = BIT(2),
NetworkConnection = BIT(3),
};
private:
BitSet32 mTypeFlags;
U32 mNetClassGroup; ///< The NetClassGroup of this connection.
/// @name Statistics
/// @{
U32 mLastUpdateTime;
F32 mRoundTripTime;
F32 mPacketLoss;
U32 mSimulatedPing;
F32 mSimulatedPacketLoss;
/// @}
/// @name State
/// @{
U32 mProtocolVersion;
U32 mSendDelayCredit;
U32 mConnectSequence;
U32 mAddressDigest[4];
bool mEstablished;
bool mMissionPathsSent;
struct NetRate
{
U32 updateDelay;
S32 packetSize;
bool changed;
};
NetRate mCurRate;
NetRate mMaxRate;
/// If we're doing a "short circuited" connection, this stores
/// a pointer to the other side.
SimObjectPtr<NetConnection> mRemoteConnection;
NetAddress mNetAddress;
/// @}
/// @name Timeout Management
/// @{
U32 mPingSendCount;
U32 mPingRetryCount;
U32 mLastPingSendTime;
/// @}
/// @name Connection Table
///
/// We store our connections on a hash table so we can
/// quickly find them.
/// @{
NetConnection *mNextTableHash;
static NetConnection *mHashTable[HashTableSize];
/// @}
protected:
static SimObjectPtr<NetConnection> mServerConnection;
static SimObjectPtr<NetConnection> mLocalClientConnection;
static bool mFilesWereDownloaded;
public:
U32 mConnectSendCount;
U32 mConnectLastSendTime;
public:
static NetConnection *getConnectionToServer() { return mServerConnection; }
static NetConnection *getLocalClientConnection() { return mLocalClientConnection; }
static void setLocalClientConnection(NetConnection *conn) { mLocalClientConnection = conn; }
U32 getNetClassGroup() { return mNetClassGroup; }
static bool filesWereDownloaded() { return mFilesWereDownloaded; }
static char *getErrorBuffer() { return mErrorBuffer; }
#ifdef TORQUE_DEBUG_NET
bool mLogging;
void setLogging(bool logging) { mLogging = logging; }
#endif
void setSimulatedNetParams(F32 packetLoss, U32 ping)
{ mSimulatedPacketLoss = packetLoss; mSimulatedPing = ping; }
bool isConnectionToServer() { return mTypeFlags.test(ConnectionToServer); }
bool isLocalConnection() { return !mRemoteConnection.isNull() ; }
bool isNetworkConnection() { return mTypeFlags.test(NetworkConnection); }
void setIsConnectionToServer() { mTypeFlags.set(ConnectionToServer); }
void setIsLocalClientConnection() { mTypeFlags.set(LocalClientConnection); }
void setNetworkConnection(bool net) { mTypeFlags.set(BitSet32(NetworkConnection), net); }
virtual void setEstablished();
/// Call this if the "connection" is local to this app. This short-circuits the protocol layer.
virtual void setRemoteConnectionObject(NetConnection *connection) { mRemoteConnection = connection; };
void setSequence(U32 connectSequence);
void setAddressDigest(U32 digest[4]);
void getAddressDigest(U32 digest[4]);
U32 getSequence();
void setProtocolVersion(U32 protocolVersion) { mProtocolVersion = protocolVersion; }
U32 getProtocolVersion() { return mProtocolVersion; }
F32 getRoundTripTime() { return mRoundTripTime; }
F32 getPacketLoss() { return( mPacketLoss ); }
static char mErrorBuffer[256];
static void setLastError(const char *fmt,...);
void checkMaxRate();
void handlePacket(BitStream *stream);
void processRawPacket(BitStream *stream);
void handleNotify(bool recvd);
void handleConnectionEstablished();
void keepAlive();
const NetAddress *getNetAddress();
void setNetAddress(const NetAddress *address);
Net::Error sendPacket(BitStream *stream);
private:
void netAddressTableInsert();
void netAddressTableRemove();
public:
/// Find a NetConnection, if any, with the specified address.
static NetConnection *lookup(const NetAddress *remoteAddress);
bool checkTimeout(U32 time); ///< returns true if the connection timed out
void checkPacketSend(bool force);
bool missionPathsSent() const { return mMissionPathsSent; }
void setMissionPathsSent(const bool s) { mMissionPathsSent = s; }
static void consoleInit();
void onRemove();
NetConnection();
~NetConnection();
public:
enum NetConnectionState
{
NotConnected,
AwaitingChallengeResponse, ///< We've sent a challenge request, awaiting the response.
AwaitingConnectRequest, ///< We've received a challenge request and sent a challenge response.
AwaitingConnectResponse, ///< We've received a challenge response and sent a connect request.
Connected, ///< We've accepted a connect request, or we've received a connect response accept.
};
U32 mConnectionSendCount; ///< number of connection messages we've sent.
U32 mConnectionState; ///< State of the connection, from NetConnectionState.
void setConnectionState(U32 state) { mConnectionState = state; }
U32 getConnectionState() { return mConnectionState; }
//void setGhostFrom(bool ghostFrom); ///< Sets whether ghosts transmit from this side of the connection.
//void setGhostTo(bool ghostTo); ///< Sets whether ghosts are allowed from the other side of the connection.
//void setSendingEvents(bool sending); ///< Sets whether this side actually sends the events that are posted to it.
void setTranslatesStrings(bool xl); ///< Sets whether this connection is capable of translating strings.
void setNetClassGroup(U32 group); ///< Sets the group of NetClasses this connection traffics in.
bool isEstablished() { return mEstablished; } ///< Is the connection established?
DECLARE_CONOBJECT(NetConnection);
/// Structure to track packets and what we sent over them.
///
/// We need to know what is sent in each packet, so that if a packet is
/// dropped, we know what to resend. This is the structure we use to track
/// this data.
struct PacketNotify
{
bool rateChanged; ///< Did the rate change on this packet?
bool maxRateChanged; ///< Did the max rate change on this packet?
U32 sendTime; ///< Timestampe, when we sent this packet.
NetEventNote *eventList; ///< Linked list of events sent over this packet.
GhostRef *ghostList; ///< Linked list of ghost updates we sent in this packet.
SubPacketRef *subList; ///< Defined by subclass - used as desired.
PacketNotify *nextPacket; ///< Next packet sent.
PacketNotify();
};
virtual PacketNotify *allocNotify();
PacketNotify *mNotifyQueueHead; ///< Head of packet notify list.
PacketNotify *mNotifyQueueTail; ///< Tail of packet notify list.
protected:
virtual void readPacket(BitStream *bstream);
virtual void writePacket(BitStream *bstream, PacketNotify *note);
virtual void packetReceived(PacketNotify *note);
virtual void packetDropped(PacketNotify *note);
virtual void connectionError(const char *errorString);
//----------------------------------------------------------------
/// @name Event Manager
/// @{
//private:
// NetEventNote *mSendEventQueueHead;
// NetEventNote *mSendEventQueueTail;
// NetEventNote *mUnorderedSendEventQueueHead;
// NetEventNote *mUnorderedSendEventQueueTail;
// NetEventNote *mWaitSeqEvents;
// NetEventNote *mNotifyEventList;
//
// static FreeListChunker<NetEventNote> mEventNoteChunker;
//
// bool mSendingEvents;
//
// S32 mNextSendEventSeq;
// S32 mNextRecvEventSeq;
// S32 mLastAckedEventSeq;
//
// enum NetEventConstants {
// InvalidSendEventSeq = -1,
// FirstValidSendEventSeq = 0
// };
//
// void eventOnRemove();
//
// void eventPacketDropped(PacketNotify *notify);
// void eventPacketReceived(PacketNotify *notify);
//
// void eventWritePacket(BitStream *bstream, PacketNotify *notify);
// void eventReadPacket(BitStream *bstream);
//
// void eventWriteStartBlock(ResizeBitStream *stream);
// void eventReadStartBlock(BitStream *stream);
public:
/// Post an event to this connection.
virtual bool postNetEvent(NetEvent *event){return false;}
/// @}
//----------------------------------------------------------------
/// @name Networked string table
/// @{
private:
bool mTranslateStrings;
ConnectionStringTable *mStringTable;
public:
void mapString(U32 netId, StringHandle &string)
{ mStringTable->mapString(netId, string); }
U32 checkString(StringHandle &string, bool *isOnOtherSide = NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -