aboutsummaryrefslogtreecommitdiff
path: root/src/parsec_server/include/e_simnetoutput.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/parsec_server/include/e_simnetoutput.h')
-rwxr-xr-xsrc/parsec_server/include/e_simnetoutput.h361
1 files changed, 361 insertions, 0 deletions
diff --git a/src/parsec_server/include/e_simnetoutput.h b/src/parsec_server/include/e_simnetoutput.h
new file mode 100755
index 0000000..db2441b
--- /dev/null
+++ b/src/parsec_server/include/e_simnetoutput.h
@@ -0,0 +1,361 @@
+#ifndef E_SIMNETOUTPUT_H_
+#define E_SIMNETOUTPUT_H_
+
+
+// update todos ---------------------------------------------------------------
+//
+#define UPDATE_TODO_NOTHING 0x0000
+#define UPDATE_TODO_SEND 0x0001
+#define UPDATE_TODO_MASK 0x0001
+
+// update mode ---------------------------------------------------------------
+//
+#define UPDATEMODE_SENDMODE_UNRELIABLE 0x0000
+#define UPDATEMODE_SENDMODE_RELIABLE 0x0010
+#define UPDATEMODE_SENDMODE_MASK 0x0010
+
+#define UPDATEMODE_SENDWHAT_STATE 0x0000
+#define UPDATEMODE_SENDWHAT_REMOVE 0x0020
+#define UPDATEMODE_SENDWHAT_MASK 0x0020
+
+#define UPDATEMODE_FLAGS_SEND_TO_OWNER 0x0100
+#define UPDATEMODE_FLAGS_MASK 0xFF00
+
+
+enum {
+
+ RMEVSTATE_NEBULAID,
+ RMEVSTATE_PROBEXTRA,
+ RMEVSTATE_PROBHELIX,
+ RMEVSTATE_PROBLIGHTNING,
+ RMEVSTATE_PROBPHOTON,
+ RMEVSTATE_PROBMINE,
+ RMEVSTATE_PROBREPAIR,
+ RMEVSTATE_PROBAFTERBURNER,
+ RMEVSTATE_PROBHOLODECOY,
+ RMEVSTATE_PROBINVISIBILITY,
+ RMEVSTATE_PROBINVULNERABILITY,
+ RMEVSTATE_PROBENERGYFIELD,
+ RMEVSTATE_PROBLASERUPGRADE,
+ RMEVSTATE_PROBLASERUPGRADE1,
+ RMEVSTATE_PROBLASERUPGRADE2,
+ RMEVSTATE_PROBMISSPACK,
+ RMEVSTATE_PROBDUMBPACK,
+ RMEVSTATE_PROBGUIDEPACK,
+ RMEVSTATE_PROBSWARMPACK,
+ RMEVSTATE_PROBEMPUPGRADE1,
+ RMEVSTATE_PROBEMPUPGRADE2,
+ RMEVSTATE_AMAZING,
+ RMEVSTATE_BRILLIANT,
+ RMEVSTATE_KILLLIMIT,
+ RMEVSTATE_ENERGYBOOST,
+ RMEVSTATE_REPAIRBOOST,
+ RMEVSTATE_DUMBPACK,
+ RMEVSTATE_HOMPACK,
+ RMEVSTATE_SWARMPACK,
+ RMEVSTATE_PROXPACK,
+
+ RMEVSTATE_NUMSTATES
+};
+
+// info about a E_Distributable -------------------------------------------------
+//
+class E_Distributable
+{
+protected:
+ dword m_objectid;
+ int m_listno;
+ int m_update_mode;
+ byte* m_update_to_client;
+public:
+ E_Distributable( dword objectid, int listno, int reliable, int send_to_owner ) :
+ m_objectid( objectid ),
+ m_listno( listno ),
+ m_update_mode( UPDATE_TODO_NOTHING ),
+ m_update_to_client( NULL )
+ {
+ // translate to internal format
+ if ( reliable ) {
+ m_update_mode |= UPDATEMODE_SENDMODE_RELIABLE;
+ }
+ if ( send_to_owner ) {
+ m_update_mode |= UPDATEMODE_FLAGS_SEND_TO_OWNER;
+ }
+
+ ResetUpdateInfo();
+ }
+
+ ~E_Distributable()
+ {
+ delete []m_update_to_client;
+ }
+
+ // reset the update info
+ void ResetUpdateInfo();
+
+ // get the object id
+ dword GetObjectID() { return m_objectid; }
+
+ // return the list # the object belongs to
+ int GetListNo() { return m_listno; }
+
+ // set updatemode for all clients to STATE
+ void UpdateMode_STATE();
+
+ // set updatemode for all clients to REMOVE
+ void UpdateMode_REMOVE();
+
+ // check whether this E_Distributable is marked as REMOVE
+ int IsInRemoving()
+ {
+ return ( ( m_update_mode & UPDATEMODE_SENDWHAT_MASK ) == UPDATEMODE_SENDWHAT_REMOVE );
+ }
+
+ // return whether the E_Distributable will be sent to the owner
+ int WillBeSentToOwner()
+ {
+ return ( ( m_update_mode & UPDATEMODE_FLAGS_SEND_TO_OWNER ) != 0 );
+ }
+
+ // check whether the E_Distributable is a ZOMBIE ( client has received the REMOVE update )
+ int IsZombie( int nClientID );
+
+ // check whethe the E_Distributable has an update for a specific client
+ int HasUpdate( int nClientID );
+
+ // mark, that we sent an update to a client
+ void MarkUpdateSent( int nClientID );
+
+ // mark, that we need to send an update to a client
+ void MarkForUpdate( int nClientID );
+
+ // check whether the E_Distributable should be sent reliable
+ int NeedsReliable()
+ {
+ return ( ( m_update_mode & UPDATEMODE_SENDMODE_MASK ) == UPDATEMODE_SENDMODE_RELIABLE );
+ }
+
+ // write a corresponding RE to the REList
+ void DistributeToREList( E_REList* relist );
+
+ // determine the size this E_Distributable is
+ size_t DetermineSizeInPacket();
+};
+
+
+
+
+
+// send modi for client updates -----------------------------------------------
+//
+#define SEND_MODE_NONE 0
+#define SEND_MODE_UNRELIABLE 1
+#define SEND_MODE_RELIABLE 2
+
+#define MAX_NUM_DISTRIBUTABLES_TO_SEND_PER_PACKET 256
+
+// information about packets sent out ( time and size ) -----------------------
+//
+struct sent_packet_info_s {
+
+ sent_packet_info_s()
+ {
+ Reset();
+ }
+
+ void Reset()
+ {
+ m_size = 0;
+ m_sendtime = 0;
+ }
+
+ size_t m_size;
+ refframe_t m_sendtime;
+};
+
+
+// class handling the network output for a client -----------------------------
+// class with all necessary information on what to send to the destination client
+class E_SimClientNetOutput
+{
+protected:
+
+ int m_nDestClientID;
+
+ E_REList* m_pReliableBuffer;
+ E_REList* m_pUnreliableBuffer;
+
+ sent_packet_info_s* m_SentPacketInfo;
+ unsigned int m_nPacket;
+
+ refframe_t m_LastSendFrame;
+ refframe_t m_Send_FrameTime;
+
+ refframe_t m_Heartbeat_Timeout_Frame;
+
+ int m_nNumPacketSlots;
+ int m_nAveragePacketSize;
+
+ // list of all distributables for the client
+ UTL_List<E_Distributable*>* m_AllDistributables;
+
+protected:
+
+ // list of client ids the client is to be updated in the next packet
+ int* m_ClientIDList;
+ bool_t* m_SendReliable;
+ int m_nNumClients;
+
+ // inidicate that we should send a the state of the client itself to the destination client ( energy, damage, shields )
+ bool_t m_bIncludeDestClientState;
+
+ // indicate whether to send the gamestate to the client
+ bool_t m_bIncludeGameState;
+
+ // indicate whether to send the killstats to the client
+ bool_t m_bIncludeKillStats;
+
+ //Indicate whether to send state variables to client
+ bool_t m_bIncludeStateSync;
+
+ // array of distributables for next packet
+ E_Distributable* m_DistsForNextPacket[ MAX_NUM_DISTRIBUTABLES_TO_SEND_PER_PACKET ];
+ int m_nNumDistsForNextPacket;
+
+ // # of byte available for the update
+ int m_nSizeAvail;
+
+public:
+
+ // default ctor/dtor
+ E_SimClientNetOutput();
+ ~E_SimClientNetOutput();
+
+ // connect a client
+ void Connect( int nClientID );
+
+ // disconnect a client
+ void Disconnect();
+
+ // sent udpate information to a client if bandwidth available
+ int SendUpdateToClient();
+
+ // the NET.SERVERRATE for this client has changed - recalc frame-time
+ void RateChanged();
+
+ // (re)calculate the average packet size
+ void CalculateAveragePacketSize();
+
+ // schedule a E_Distributable to be sent to the client
+ void ScheduleDistributable( E_Distributable* pDist, int check_unique = FALSE );
+
+ // buffer an RE for output
+ void BufferRE( RE_Header* re, int reliable );
+
+protected:
+
+ // reset all data members
+ void _Reset();
+
+ // clear the list of things to update
+ void _ClearUpdates();
+
+ // check whether there are any updates to send to the client
+ int _HasUpdates();
+
+ // add a E_Distributable to be sent out with the next packet
+ void _AddDistForOutput( E_Distributable* pDist );
+
+ // include the information about a client in the next update ( reliable or unreliable )
+ void _FlagIncludeClient( int nClientID, bool_t bReliable );
+
+ // check whether we can reserve size for output, and do so if space avail.
+ bool_t _ReserveForOutput( int size );
+
+ // fill the RE lists to be sent to the client
+ int _FillPacketForClient( E_REList* pReliable, E_REList* pUnreliable );
+
+ // getters/setters
+ size_t _GetSizeAvail() { return m_nSizeAvail; }
+
+ // check whether we should send a packet to this client
+ int _CanSendPacket();
+
+ // create buffer E_RELists for pass-through multicasts
+ void _CreateBuffers();
+
+ // terminate the multicast data in the E_REList buffers
+ void _TerminateBufferMulticast();
+
+ // determine which states must be updated for this client
+ int _PrepareClientUpdateInfo();
+
+ // check whether to send a heartbeat to the client
+ int _ShouldSendHeartbeat();
+
+ // set the new heartbeat timeout value
+ void _DoHeartbeat();
+};
+
+
+
+// class for handling the network output from the simulation ------------------
+//
+class E_SimNetOutput {
+protected:
+ E_SimClientNetOutput* m_SimClientNetOutput;
+ UTL_List<E_Distributable*>* m_Distributables;
+
+protected:
+ E_SimNetOutput();
+ ~E_SimNetOutput();
+
+public:
+ // SINGLETON access
+ static E_SimNetOutput* GetSimNetOutput()
+ {
+ static E_SimNetOutput _TheSimNetOutput;
+ return &_TheSimNetOutput;
+ }
+
+ // reset all data
+ void Reset();
+
+ // connect the player in a specific slot
+ int ConnectPlayer( int nClientID );
+
+ // disconnect the player in a specific slot
+ int DisconnectPlayer( int nClientID );
+
+ // update all clients
+ void DoClientUpdates();
+
+ // buffer a RE for sending to all clients minus sender
+ void BufferForMulticastRE( RE_Header* relist, int nSenderClientID, int reliable );
+
+ // buffer a RE for sending to a specific client
+ void BufferForDirectRE( RE_Header* relist, int nClientID, int reliable );
+
+ // update NET.SERVERRATE dependent stuff of E_SimClientNetOutput
+ void RateChangedForClient( int nClientID );
+
+ // recalculate the average packet sizes for all connected clients
+ void RecalcAveragePacketSizes();
+
+ // create a new E_Distributable for all connected clients
+ E_Distributable* CreateDistributable( GenObject* object, int reliable = FALSE, int send_to_owner = FALSE );
+
+ // release a E_Distributable
+ void ReleaseDistributable( E_Distributable* pDist );
+
+ // cleanup all distributables, that are complete zombies
+ void CleanupZombieDistributables();
+
+protected:
+ // destroy m_Distributables
+ void _DestroyDistributables();
+
+};
+
+
+#endif // !E_SIMNETOUTPUT_H_