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

📄 netconnection.h

📁 五行MMORPG引擎系统V1.0
💻 H
📖 第 1 页 / 共 3 页
字号:
      FileDownloadSizeMessage,
      NumConnectionMessages,
   };
   GhostInfo **mGhostArray;    ///< Linked list of ghostInfos ghosted by this side of the connection

   U32 mGhostZeroUpdateIndex;  ///< Index in mGhostArray of first ghost with 0 update mask.
   U32 mGhostFreeIndex;        ///< Index in mGhostArray of first free ghost.

   U32 mGhostsActive;			///- Track actve ghosts on client side

   bool mGhosting;             ///< Am I currently ghosting objects?
   bool mScoping;              ///< am I currently scoping objects?
   U32  mGhostingSequence;     ///< Sequence number describing this ghosting session.

   NetObject **mLocalGhosts;  ///< Local ghost for remote object.
                              ///
                              /// mLocalGhosts pointer is NULL if mGhostTo is false

   GhostInfo *mGhostRefs;           ///< Allocated array of ghostInfos. Null if ghostFrom is false.
   GhostInfo **mGhostLookupTable;   ///< Table indexed by object id to GhostInfo. Null if ghostFrom is false.

   /// The object around which we are scoping this connection.
   ///
   /// This is usually the player object, or a related object, like a vehicle
   /// that the player is driving.
   SimObjectPtr<NetObject> mScopeObject;

   void clearGhostInfo();
   bool validateGhostArray();

   void ghostPacketDropped(PacketNotify *notify);
   void ghostPacketReceived(PacketNotify *notify);

   void ghostWritePacket(BitStream *bstream, PacketNotify *notify);
   void ghostReadPacket(BitStream *bstream);
   void freeGhostInfo(GhostInfo *);

   void ghostWriteStartBlock(ResizeBitStream *stream);
   void ghostReadStartBlock(BitStream *stream);

public:
   /// Some configuration values.
   enum GhostConstants
   {
      GhostIdBitSize = 12,
      MaxGhostCount = 1 << GhostIdBitSize, //4096,
      GhostLookupTableSize = 1 << GhostIdBitSize, //4096
      GhostIndexBitSize = 4 // number of bits GhostIdBitSize-3 fits into
   };

   U32 getGhostsActive() { return mGhostsActive;};

   /// Are we ghosting to someone?
   bool isGhostingTo() { return mLocalGhosts != NULL; };

   /// Are we ghosting from someone?
   bool isGhostingFrom() { return mGhostArray != NULL; };

   /// Called by onRemove, to shut down the ghost subsystem.
   void ghostOnRemove();

   /// Called when we're done with normal scoping.
   ///
   /// This gives subclasses a chance to shove things into scope, such as
   /// the results of a sensor network calculation, that would otherwise
   /// be awkward to add.
   virtual void doneScopingScene() { /* null */ }

   /// Set the object around which we are currently scoping network traffic.
   void setScopeObject(NetObject *object);

   /// Get the object aorund which we are currently scoping network traffic.
   NetObject *getScopeObject();

   /// Add an object to scope.
   void objectInScope(NetObject *object);

   /// Add an object to scope, marking that it should always be scoped to this connection.
   void objectLocalScopeAlways(NetObject *object);

   /// Mark an object that is being ghosted as not always needing to be scoped.
   ///
   /// This undoes objectLocalScopeAlways(), but doesn't immediately flush it from scope.
   ///
   /// Instead, the standard scoping mechanisms will clear it from scope when it is appropos
   /// to do so.
   void objectLocalClearAlways(NetObject *object);

   /// Get a NetObject* from a ghost ID (on client side).
   NetObject *resolveGhost(S32 id);

   /// Get a NetObject* from a ghost index (on the server side).
   NetObject *resolveObjectFromGhostIndex(S32 id);

   /// Get the ghost index corresponding to a given NetObject. This is only
   /// meaningful on the server side.
   S32 getGhostIndex(NetObject *object);

   /// Move a GhostInfo into the nonzero portion of the list (so that we know to update it).
   void ghostPushNonZero(GhostInfo *gi);

   /// Move a GhostInfo into the zero portion of the list (so that we know not to update it).
   void ghostPushToZero(GhostInfo *gi);

   /// Move a GhostInfo from the zero portion of the list to the free portion.
   void ghostPushZeroToFree(GhostInfo *gi);

   /// Move a GhostInfo from the free portion of the list to the zero portion.
   inline void ghostPushFreeToZero(GhostInfo *info);

   /// Stop all ghosting activity and inform the other side about this.
   ///
   /// Turns off ghosting.
   void resetGhosting();

   /// Activate ghosting, once it's enabled.
   void activateGhosting();

   /// Are we ghosting?
   bool isGhosting() { return mGhosting; }

   /// Begin to stop ghosting an object.
   void detachObject(GhostInfo *info);

   /// Mark an object to be always ghosted. Index is the ghost index of the object.
   void setGhostAlwaysObject(NetObject *object, U32 index);


   /// Send ghost connection handshake message.
   ///
   /// As part of the ghoost connection process, extensive hand-shaking must be performed.
   ///
   /// This is done by passing ConnectionMessageEvents; this is a helper function
   /// to more effectively perform this task. Messages are dealt with by
   /// handleConnectionMessage().
   ///
   /// @param  message     One of GhostStates
   /// @param  sequence    A sequence number, if any.
   /// @param  ghostCount  A count of ghosts relating to this message.
   void sendConnectionMessage(U32 message, U32 sequence = 0, U32 ghostCount = 0);

   /// Handle message from sendConnectionMessage().
   ///
   /// This is called to handle messages sent via sendConnectionMessage.
   ///
   /// @param  message     One of GhostStates
   /// @param  sequence    A sequence number, if any.
   /// @param  ghostCount  A count of ghosts relating to this message.
   virtual void handleConnectionMessage(U32 message, U32 sequence, U32 ghostCount);

   /// @}
public:
//----------------------------------------------------------------
/// @name File transfer
/// @{

protected:
   /// List of files missing for this connection.
   ///
   /// The currently downloading file is always first in the list (ie, [0]).
   Vector<char *> mMissingFileList;

   /// Stream for currently uploading file (if any).
   Stream *mCurrentDownloadingFile;

   /// Storage for currently downloading file.
   void *mCurrentFileBuffer;

   /// Size of currently downloading file in bytes.
   U32 mCurrentFileBufferSize;

   /// Our position in the currently downloading file in bytes.
   U32 mCurrentFileBufferOffset;

   /// Number of files we have downloaded.
   U32 mNumDownloadedFiles;

   /// Error storage for file transfers.
   char mLastFileErrorBuffer[256];

   /// Structure to track ghost-always objects and their ghost indices.
   struct GhostSave {
      NetObject *ghost;
      U32 index;
   };

   /// List of objects to ghost-always.
   Vector<GhostSave> mGhostAlwaysSaveList;

public:
   /// Start sending the specified file over the link.
   bool startSendingFile(const char *fileName);

   /// Called when we receive a FileChunkEvent.
   void chunkReceived(U8 *chunkData, U32 chunkLen);

   /// Get the next file...
   void sendNextFileDownloadRequest();

   /// Post the next FileChunkEvent.
   void sendFileChunk();

   /// Called when we finish downloading file data.
   virtual void fileDownloadSegmentComplete();

   /// This is part of the file transfer logic; basically, we call this
   /// every time we finish downloading new files. It attempts to load
   /// the GhostAlways objects; if they fail, it marks an error and we
   /// have chance to retry.
   void loadNextGhostAlwaysObject(bool hadNewFiles);
/// @}

//----------------------------------------------------------------
/// @name Demo Recording
/// @{

private:
   Stream *mDemoWriteStream;
   Stream *mDemoReadStream;
   U32 mDemoNextBlockType;
   U32 mDemoNextBlockSize;

   U32 mDemoWriteStartTime;
   U32 mDemoReadStartTime;
   U32 mDemoLastWriteTime;

   U32 mDemoRealStartTime;

public:
   enum DemoBlockTypes {
      BlockTypePacket,
      BlockTypeSendPacket,
      NetConnectionBlockTypeCount
   };

   enum DemoConstants {
      MaxNumBlockTypes = 16,
      MaxBlockSize = 0x1000,
   };

   bool isRecording()
      { return mDemoWriteStream != NULL; }
   bool isPlayingBack()
      { return mDemoReadStream != NULL; }

   U32 getNextBlockType() { return mDemoNextBlockType; }
   void recordBlock(U32 type, U32 size, void *data);
   virtual void handleRecordedBlock(U32 type, U32 size, void *data);
   bool processNextBlock();

   bool startDemoRecord(const char *fileName);
   bool replayDemoRecord(const char *fileName);
   void startDemoRead();
   void stopRecording();
   void stopDemoPlayback();

   virtual void writeDemoStartBlock(ResizeBitStream *stream);
   virtual bool readDemoStartBlock(BitStream *stream);
   virtual void demoPlaybackComplete();
/// @}
};


//----------------------------------------------------------------------------
/// Information about a ghosted object.
///
/// @note If the size of this structure changes, the
///       NetConnection::getGhostIndex function MUST be changed
///       to reflect the new size.
struct GhostInfo
{
public:  // required for MSVC
   NetObject *obj;                        ///< The object being ghosted.
   U32 updateMask;                        ///< Flags indicating what state data needs to be transferred.

   U32 updateSkipCount;                   ///< How many updates have we skipped this guy?
   U32 flags;                             ///< Flags from GhostInfo::Flags
   F32 priority;                          ///< A float value indicating the priority of this object for
                                          ///  updates.

   /// @name References
   ///
   /// The GhostInfo structure is used in several linked lists; these members are
   /// the implementation for this.
   /// @{

   NetConnection::GhostRef *updateChain;  ///< List of references in NetConnections to us.

   GhostInfo *nextObjectRef;              ///< Next ghosted object.
   GhostInfo *prevObjectRef;              ///< Previous ghosted object.
   NetConnection *connection;             ///< Connection that we're ghosting over.
   GhostInfo *nextLookupInfo;             ///< GhostInfo references are stored in a hash; this is the bucket
                                          ///  implementation.

   /// @}

   U32 index;
   U32 arrayIndex;

   /// Flags relating to the state of the object.
   enum Flags
   {
      Valid             = BIT(0),
      InScope           = BIT(1),
      ScopeAlways       = BIT(2),
      NotYetGhosted     = BIT(3),
      Ghosting          = BIT(4),
      KillGhost         = BIT(5),
      KillingGhost      = BIT(6),
      ScopedEvent       = BIT(7),
      ScopeLocalAlways  = BIT(8),
   };
};

inline void NetConnection::ghostPushNonZero(GhostInfo *info)
{
   AssertFatal(info->arrayIndex >= mGhostZeroUpdateIndex && info->arrayIndex < mGhostFreeIndex, "Out of range arrayIndex.");
   AssertFatal(mGhostArray[info->arrayIndex] == info, "Invalid array object.");
   if(info->arrayIndex != mGhostZeroUpdateIndex)
   {
      mGhostArray[mGhostZeroUpdateIndex]->arrayIndex = info->arrayIndex;
      mGhostArray[info->arrayIndex] = mGhostArray[mGhostZeroUpdateIndex];
      mGhostArray[mGhostZeroUpdateIndex] = info;
      info->arrayIndex = mGhostZeroUpdateIndex;
   }
   mGhostZeroUpdateIndex++;
   //AssertFatal(validateGhostArray(), "Invalid ghost array!");
}

inline void NetConnection::ghostPushToZero(GhostInfo *info)
{
   AssertFatal(info->arrayIndex < mGhostZeroUpdateIndex, "Out of range arrayIndex.");
   AssertFatal(mGhostArray[info->arrayIndex] == info, "Invalid array object.");
   mGhostZeroUpdateIndex--;
   if(info->arrayIndex != mGhostZeroUpdateIndex)
   {
      mGhostArray[mGhostZeroUpdateIndex]->arrayIndex = info->arrayIndex;
      mGhostArray[info->arrayIndex] = mGhostArray[mGhostZeroUpdateIndex];
      mGhostArray[mGhostZeroUpdateIndex] = info;
      info->arrayIndex = mGhostZeroUpdateIndex;
   }
   //AssertFatal(validateGhostArray(), "Invalid ghost array!");
}

inline void NetConnection::ghostPushZeroToFree(GhostInfo *info)
{
   AssertFatal(info->arrayIndex >= mGhostZeroUpdateIndex && info->arrayIndex < mGhostFreeIndex, "Out of range arrayIndex.");
   AssertFatal(mGhostArray[info->arrayIndex] == info, "Invalid array object.");
   mGhostFreeIndex--;
   if(info->arrayIndex != mGhostFreeIndex)
   {
      mGhostArray[mGhostFreeIndex]->arrayIndex = info->arrayIndex;
      mGhostArray[info->arrayIndex] = mGhostArray[mGhostFreeIndex];
      mGhostArray[mGhostFreeIndex] = info;
      info->arrayIndex = mGhostFreeIndex;
   }
   //AssertFatal(validateGhostArray(), "Invalid ghost array!");
}

inline void NetConnection::ghostPushFreeToZero(GhostInfo *info)
{
   AssertFatal(info->arrayIndex >= mGhostFreeIndex, "Out of range arrayIndex.");
   AssertFatal(mGhostArray[info->arrayIndex] == info, "Invalid array object.");
   if(info->arrayIndex != mGhostFreeIndex)
   {
      mGhostArray[mGhostFreeIndex]->arrayIndex = info->arrayIndex;
      mGhostArray[info->arrayIndex] = mGhostArray[mGhostFreeIndex];
      mGhostArray[mGhostFreeIndex] = info;
      info->arrayIndex = mGhostFreeIndex;
   }
   mGhostFreeIndex++;
   //AssertFatal(validateGhostArray(), "Invalid ghost array!");
}

#endif//#ifdef _USE_TGE_NETCONNTION_

#endif


⌨️ 快捷键说明

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