⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netconnection.h

📁 五行MMORPG引擎系统V1.0
💻 H
📖 第 1 页 / 共 3 页
字号:
/// resolveGhost() is used on the client side, and resolveObjectFromGhostIndex() on the server side, to
/// turn ghost IDs into object references.
///
/// The NetConnection is a SimGroup. On the client side, it contains all the objects which have been
/// ghosted to that client. On the server side, it is empty; it can be used (typically in script) to
/// hold objects related to the connection. For instance, you might place an observation camera in the
/// NetConnnection. In both cases, when the connection is destroyed, so are the contained objects.
///
/// @see NetObject, which is the superclass for ghostable objects, and ShapeBase, which is the base
///      for player and vehicle classes.
///
/// @nosubgrouping
class NetConnection : public ConnectionProtocol, public SimGroup
{
   friend class NetInterface;
#ifdef TGE_RPG
	friend class NetworkBase;
	friend class NetUDP;
	friend class NetManager;
	friend class NetTCP;
#endif

   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;

#ifdef TGE_RPG
public:
#endif
   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.
   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.
   bool postNetEvent(NetEvent *event);

/// @}

//----------------------------------------------------------------
/// @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)
      { if(mStringTable) return mStringTable->checkString(string, isOnOtherSide); else return 0; }
   U32  getNetSendId(StringHandle &string)
      { if(mStringTable) return mStringTable->getNetSendId(string); else return 0;}
   void confirmStringReceived(StringHandle &string, U32 index)
      { if(!isRemoved()) mStringTable->confirmStringReceived(string, index); }

   StringHandle translateRemoteStringId(U32 id) { return mStringTable->lookupString(id); }
   void         validateSendString(const char *str);

   void   packString(BitStream *stream, const char *str);
   void unpackString(BitStream *stream, char readBuffer[1024]);

   void           packStringHandleU(BitStream *stream, StringHandle &h);
   StringHandle unpackStringHandleU(BitStream *stream);
/// @}

//----------------------------------------------------------------
/// @name Ghost manager
/// @{

protected:
   enum GhostStates
   {
      GhostAlwaysDone,
      ReadyForNormalGhosts,
      EndGhosting,
      GhostAlwaysStarting,
      SendNextDownloadRequest,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -