netclient.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. // netclient.h
  19. // Project: RSPiX
  20. //
  21. // History:
  22. // 08/30/97 MJR Started.
  23. //
  24. // 11/25/97 JMI Changed m_error to m_msgError so we could store a whole
  25. // error message instead of just the error type.
  26. //
  27. ////////////////////////////////////////////////////////////////////////////////
  28. #ifndef NETCLIENT_H
  29. #define NETCLIENT_H
  30. #include "RSPiX.h"
  31. #include "socket.h"
  32. #include "net.h"
  33. #include "netmsgr.h"
  34. #include "NetInput.h"
  35. #include "ORANGE/CDT/fqueue.h"
  36. #include "IdBank.h"
  37. #include "Average.h"
  38. #define NUM_TIMES 8; // Number of frame times to remember
  39. #define TIME_MASK 0x7; // Mask for frame sequence number to index the array of frame times
  40. ////////////////////////////////////////////////////////////////////////////////
  41. //
  42. // CNetClient impliments the client side of the client-server architecture.
  43. //
  44. ////////////////////////////////////////////////////////////////////////////////
  45. class CNetClient
  46. {
  47. //------------------------------------------------------------------------------
  48. // Classes
  49. //------------------------------------------------------------------------------
  50. protected:
  51. ////////////////////////////////////////////////////////////////////////////////
  52. //
  53. // CClient is the server's representation of a client
  54. //
  55. // The general state is indicated by m_state, while the connection state is
  56. // indicated by m_msgr.State(). The two states will generally be "in agreement"
  57. // with one another, but since connecting and disconnecting are asynchronous
  58. // processes, it may seem like the connection status "lags behind" m_state,
  59. // which changes immediately.
  60. //
  61. ////////////////////////////////////////////////////////////////////////////////
  62. class CPeer
  63. {
  64. //------------------------------------------------------------------------------
  65. // Types, enums, etc.
  66. //------------------------------------------------------------------------------
  67. public:
  68. // Player states.
  69. typedef enum
  70. {
  71. Unused, // Becomes "Joined" when server sends JOINED msg
  72. Joined, // Becomes "Unused" if server sends DROPPED before game starts
  73. // Becomes "Dropped" if server sends DROPPED after game starts
  74. Dropped // Becomes "Unused" when new game starts
  75. } State;
  76. enum
  77. {
  78. NumAvgItems = 5
  79. };
  80. //------------------------------------------------------------------------------
  81. // Variables
  82. //------------------------------------------------------------------------------
  83. public:
  84. State m_state; // State
  85. RSocket::Address m_address; // Address
  86. char m_acName[Net::MaxPlayerNameSize];// Name
  87. unsigned char m_ucColor; // Color number
  88. unsigned char m_ucTeam; // Team number
  89. short m_sBandwidth; // Net::Bandwidth
  90. CNetInput m_netinput; // Sliding window of inputs
  91. Net::SEQ m_seqLastActive; // Last active sequence (only if dropped)
  92. bool m_bInactive; // True after last active sequence was used
  93. // Net::SEQ m_seqWhatHeNeeds; // What input seq he needs from me
  94. // Net::SEQ m_seqWhatINeed; // What input seq I need from him
  95. // long m_lNextSendTime; // When to next send inputs to him
  96. long m_lLastReceiveTime; // When we last got data from him *SPA
  97. // FQueue<long, NumAvgItems> m_qPings; // Queue of ping times for running average
  98. // long m_lRunnigAvgPing; // Running average
  99. U16 m_idDude; // Dude's ID
  100. //------------------------------------------------------------------------------
  101. // Functions
  102. //------------------------------------------------------------------------------
  103. public:
  104. ////////////////////////////////////////////////////////////////////////////////
  105. // Constructor
  106. ////////////////////////////////////////////////////////////////////////////////
  107. CPeer()
  108. {
  109. Reset();
  110. }
  111. ////////////////////////////////////////////////////////////////////////////////
  112. // Destructor
  113. ////////////////////////////////////////////////////////////////////////////////
  114. ~CPeer()
  115. {
  116. Reset();
  117. }
  118. ////////////////////////////////////////////////////////////////////////////////
  119. // Reset to post-construction state
  120. ////////////////////////////////////////////////////////////////////////////////
  121. void Reset(void)
  122. {
  123. m_state = Unused;
  124. m_address.Reset();
  125. m_acName[0] = 0;
  126. m_ucColor = 0;
  127. m_ucTeam = 0;
  128. m_sBandwidth = Net::FirstBandwidth;
  129. m_netinput.Reset();
  130. m_seqLastActive = 0;
  131. m_bInactive = false;
  132. // m_seqWhatHeNeeds = 0;
  133. // m_seqWhatINeed = 0;
  134. // m_lNextSendTime = 0;
  135. m_lLastReceiveTime = 0; // *SPA
  136. // m_qPings.Reset();
  137. // m_lRunnigAvgPing = 0;
  138. m_idDude = CIdBank::IdNil;
  139. }
  140. };
  141. //------------------------------------------------------------------------------
  142. // Types, enums, etc.
  143. //------------------------------------------------------------------------------
  144. public:
  145. // Client states
  146. typedef enum
  147. {
  148. Nothing,
  149. WaitForConnect,
  150. WaitForLoginResponse,
  151. WaitForJoinResponse,
  152. Joined
  153. } State;
  154. //------------------------------------------------------------------------------
  155. // Variables
  156. //------------------------------------------------------------------------------
  157. protected:
  158. CNetMsgr m_msgr; // Messenger to server
  159. RSocket m_socketPeers; // Socket used to communicate with peers
  160. RSocket::Address m_addressServer; // Server's address (with base port)
  161. RSocket::Address m_addressServerListen; // Server's address (listen port)
  162. RSocket::BLOCK_CALLBACK m_callback;
  163. State m_state; // My state
  164. NetMsg m_msgError; // Error type
  165. NetMsg::Status m_status; // Status type
  166. long m_lTimeOut; // Timer used to detect time-outs
  167. Net::ID m_id; // My id
  168. Net::ID m_idServer; // Server's client's ID
  169. short m_sNumJoined; // Number of joined players
  170. bool m_bGameStarted; // Whether game has started
  171. bool m_bPlaying; // true means playing, false means stopped
  172. bool m_bUseHaltFrame; // Whether to use m_seqStopFrame
  173. bool m_bReachedHaltFrame; // Whether we've reached the halt frame
  174. Net::SEQ m_seqHaltFrame; // Stop when we reach this frame seq
  175. Net::SEQ m_seqInput; // My input sequence
  176. Net::SEQ m_seqFrame; // My frame sequence
  177. Net::SEQ m_seqMaxAhead; // Max ahead for input versus frame
  178. Net::SEQ m_seqInputNotYetSent; // Input seq that we did NOT send yet
  179. CNetInput m_netinput; // My input buffer
  180. long m_lFrameTime; // Current frame time
  181. long m_lNextLocalInputTime; // When to get next local input
  182. bool m_bNextRealmPending; // Whether next realm is pending
  183. CPeer m_aPeers[Net::MaxNumIDs]; // Array of peers
  184. /** SPA **/
  185. long m_lStartTime; // The start from which time to calculate the frame delta
  186. long m_alAvgFrameTimes[8]; // Array to hold the last several average frame times
  187. /** SPA **/
  188. /** 12/16/97 AJC **/
  189. U16 m_u16PackageID; // Unique number for every package sent
  190. /** 12/16/97 AJC **/
  191. bool m_bSendNextFrame; // 12/30/97 *SPA True if we have all the info to render the current frame (m_seqFrame)
  192. long m_lMaxWaitTime;
  193. //------------------------------------------------------------------------------
  194. // Functions
  195. //------------------------------------------------------------------------------
  196. public:
  197. ////////////////////////////////////////////////////////////////////////////////
  198. // Constructor
  199. ////////////////////////////////////////////////////////////////////////////////
  200. CNetClient()
  201. {
  202. Reset();
  203. }
  204. ////////////////////////////////////////////////////////////////////////////////
  205. // Destructor
  206. ////////////////////////////////////////////////////////////////////////////////
  207. ~CNetClient()
  208. {
  209. Reset();
  210. }
  211. ////////////////////////////////////////////////////////////////////////////////
  212. // Reset
  213. ////////////////////////////////////////////////////////////////////////////////
  214. void Reset(void)
  215. {
  216. m_msgr.Reset();
  217. m_socketPeers.Reset();
  218. m_addressServer.Reset();
  219. m_addressServerListen.Reset();
  220. m_callback = 0;
  221. m_state = Nothing;
  222. m_msgError.msg.err.ucType = NetMsg::ERR;
  223. m_msgError.msg.err.error = NetMsg::NoError;
  224. m_msgError.msg.err.ulParam = 0;
  225. m_status = NetMsg::NoStatus;
  226. m_lTimeOut = 0;
  227. m_id = Net::InvalidID;
  228. m_idServer = Net::InvalidID;
  229. m_sNumJoined = 0;
  230. m_bGameStarted = false;
  231. m_bPlaying = false;
  232. m_bUseHaltFrame = false;
  233. m_bReachedHaltFrame = false;
  234. m_seqHaltFrame = 0;
  235. m_seqInput = 0;
  236. m_seqFrame = 0;
  237. m_seqMaxAhead = 0;
  238. m_seqInputNotYetSent = 0;
  239. m_netinput.Reset();
  240. m_lFrameTime = 0;
  241. m_lNextLocalInputTime = 0;
  242. m_bNextRealmPending = false;
  243. for (U8 id = 0; id < Net::MaxNumIDs; id++)
  244. m_aPeers[id].Reset();
  245. /** 12/15/97 SPA **/
  246. m_lStartTime = 0;
  247. for (short i = 0; i < 8; i++)
  248. m_alAvgFrameTimes[i] = 100;
  249. /** 12/15/97 SPA **/
  250. /** 12/16/97 AJC **/
  251. m_u16PackageID = 0;
  252. /** 12/16/97 AJC **/
  253. m_bSendNextFrame = false; // 12/30/97 *SPA
  254. m_lMaxWaitTime = 0;
  255. }
  256. ////////////////////////////////////////////////////////////////////////////////
  257. // Startup
  258. ////////////////////////////////////////////////////////////////////////////////
  259. void Startup(
  260. RSocket::BLOCK_CALLBACK callback); // In: Blocking callback
  261. ////////////////////////////////////////////////////////////////////////////////
  262. // Shutdown
  263. ////////////////////////////////////////////////////////////////////////////////
  264. void Shutdown(void);
  265. ////////////////////////////////////////////////////////////////////////////////
  266. // Start the process of joining the game on the specified host. The port in
  267. // in the host's address is assumed to be the so-called "base port".
  268. //
  269. // If this function returns an error, it indicates that the join process has
  270. // failed, most likely because the currently selected protocol is not supported.
  271. // Even if this happens, it is still safe to call Update() and GetMsg() as if
  272. // no error occurred, realizing, of course, that the join process will not
  273. // succeed and GetMsg() will shortly return an error to that effect.
  274. ////////////////////////////////////////////////////////////////////////////////
  275. short StartJoinProcess( // Returns 0 if successfull, non-zero otherwise
  276. RSocket::Address* paddressHost, // In: Host's address
  277. char* pszName, // In: Joiner's name
  278. unsigned char ucColor, // In: Joiner's color
  279. unsigned char ucTeam, // In: Joiner's team
  280. short sBandwidth); // In: Joiner's Net::Bandwidth
  281. ////////////////////////////////////////////////////////////////////////////////
  282. // Update (must be called regularly)
  283. ////////////////////////////////////////////////////////////////////////////////
  284. void Update(void);
  285. ////////////////////////////////////////////////////////////////////////////////
  286. // Get next available message from server
  287. ////////////////////////////////////////////////////////////////////////////////
  288. void GetMsg(
  289. NetMsg* pmsg); // Out: Message is returned here
  290. ////////////////////////////////////////////////////////////////////////////////
  291. // Send message to server
  292. ////////////////////////////////////////////////////////////////////////////////
  293. void SendMsg(
  294. NetMsg* pmsg, // In: Message to send
  295. bool bSendNow = true); // In: Whether to send now or wait until Update()
  296. ////////////////////////////////////////////////////////////////////////////////
  297. // Send chat message (text is sent with player's name as a prefix)
  298. ////////////////////////////////////////////////////////////////////////////////
  299. void SendChat(
  300. const char* pszText); // In: Text to send
  301. ////////////////////////////////////////////////////////////////////////////////
  302. // Send text message (text is send as is)
  303. ////////////////////////////////////////////////////////////////////////////////
  304. void SendText(
  305. const char* pszText); // In: Text to send
  306. ////////////////////////////////////////////////////////////////////////////////
  307. // Send realm status
  308. ////////////////////////////////////////////////////////////////////////////////
  309. void SendRealmStatus(
  310. bool bReady);
  311. ////////////////////////////////////////////////////////////////////////////////
  312. // Drop self
  313. ////////////////////////////////////////////////////////////////////////////////
  314. void Drop(void);
  315. ////////////////////////////////////////////////////////////////////////////////
  316. // Determine if there is more data waiting to be sent. If there is data to
  317. // to be sent AND there is a send error, then that data can't be sent, so we
  318. // return false to indicate "no more data".
  319. ////////////////////////////////////////////////////////////////////////////////
  320. bool IsMoreToSend(void)
  321. {
  322. return m_msgr.IsMoreToSend();
  323. }
  324. ////////////////////////////////////////////////////////////////////////////////
  325. // Get assigned ID
  326. ////////////////////////////////////////////////////////////////////////////////
  327. Net::ID GetID(void) // Returns ID
  328. {
  329. return m_id;
  330. }
  331. ////////////////////////////////////////////////////////////////////////////////
  332. // Get "servers net ID", which is really the ID of the server's client
  333. ////////////////////////////////////////////////////////////////////////////////
  334. Net::ID GetServerID(void) // Returns ID
  335. {
  336. return m_idServer;
  337. }
  338. ////////////////////////////////////////////////////////////////////////////////
  339. // Get the current number of players
  340. ////////////////////////////////////////////////////////////////////////////////
  341. short GetNumPlayers(void)
  342. {
  343. return m_sNumJoined;
  344. }
  345. ////////////////////////////////////////////////////////////////////////////////
  346. // Get the specified player's name
  347. ////////////////////////////////////////////////////////////////////////////////
  348. const char* GetPlayerName(
  349. Net::ID id)
  350. {
  351. ASSERT(id != Net::InvalidID);
  352. ASSERT(id < Net::MaxNumIDs);
  353. return m_aPeers[id].m_acName;
  354. }
  355. ////////////////////////////////////////////////////////////////////////////////
  356. // Get the specified player's color
  357. ////////////////////////////////////////////////////////////////////////////////
  358. unsigned char GetPlayerColor(
  359. Net::ID id)
  360. {
  361. ASSERT(id != Net::InvalidID);
  362. ASSERT(id < Net::MaxNumIDs);
  363. return m_aPeers[id].m_ucColor;
  364. }
  365. ////////////////////////////////////////////////////////////////////////////////
  366. // Determine whether ths specified player needs a dude
  367. ////////////////////////////////////////////////////////////////////////////////
  368. bool DoesPlayerNeedDude(
  369. Net::ID id)
  370. {
  371. return (m_aPeers[id].m_state == CPeer::Joined) || (m_aPeers[id].m_state == CPeer::Dropped);
  372. }
  373. ////////////////////////////////////////////////////////////////////////////////
  374. // Get or set specified player's dude ID (not to be confused with a Net::ID)
  375. ////////////////////////////////////////////////////////////////////////////////
  376. U16 GetPlayerDudeID(
  377. Net::ID id)
  378. {
  379. ASSERT(id != Net::InvalidID);
  380. ASSERT(id < Net::MaxNumIDs);
  381. return m_aPeers[id].m_idDude;
  382. }
  383. void SetPlayerDudeID(
  384. Net::ID id,
  385. U16 idDude)
  386. {
  387. ASSERT(id != Net::InvalidID);
  388. ASSERT(id < Net::MaxNumIDs);
  389. m_aPeers[id].m_idDude = idDude;
  390. }
  391. ////////////////////////////////////////////////////////////////////////////////
  392. // Determine whether we're playing or not
  393. ////////////////////////////////////////////////////////////////////////////////
  394. bool IsPlaying(void)
  395. {
  396. return m_bPlaying;
  397. }
  398. ////////////////////////////////////////////////////////////////////////////////
  399. // Determine whether another frame can be done. If so, the necessary peer
  400. // inputs are returned in the supplied array and the result is true.
  401. // Otherwise, the result is false, and a frame cannot be done.
  402. ////////////////////////////////////////////////////////////////////////////////
  403. bool CanDoFrame( // Returns true if frame can be done, false otherwise
  404. UINPUT aInputs[], // Out: Total of Net::MaxNumIDs inputs returned here
  405. short* psFrameTime); // Out the current frames elapsed time
  406. ////////////////////////////////////////////////////////////////////////////////
  407. // Check whether local input is required
  408. ////////////////////////////////////////////////////////////////////////////////
  409. bool IsLocalInputNeeded(void);
  410. ////////////////////////////////////////////////////////////////////////////////
  411. // Set local input.
  412. // Call this if and only if IsLocalInputNeeded() returns true!
  413. ////////////////////////////////////////////////////////////////////////////////
  414. void SetLocalInput(
  415. UINPUT input);
  416. ////////////////////////////////////////////////////////////////////////////////
  417. // Get the input seq that has NOT been sent yet to any other player
  418. ////////////////////////////////////////////////////////////////////////////////
  419. Net::SEQ GetInputSeqNotYetSent(void)
  420. {
  421. return m_seqInputNotYetSent;
  422. }
  423. ////////////////////////////////////////////////////////////////////////////////
  424. // This is normally used to handle a HALT_REALM message when we get one from
  425. // the server.
  426. //
  427. // It is also used the local server, if there is one, to directly inform the
  428. // local client (that would be us) about the halt frame. This is a necessary
  429. // breach of client/server separation that is more fully explained elsewhere.
  430. // (It may indicate a design flaw, but I'm at a loss for a better solution.)
  431. ////////////////////////////////////////////////////////////////////////////////
  432. void SetHaltFrame(
  433. Net::SEQ seqHalt);
  434. ////////////////////////////////////////////////////////////////////////////////
  435. // This is used to see if any peers have not sent data for too long of a period
  436. //
  437. // It returns the id of the first peer it finds that has exceeded the time limit
  438. // so that the server can drop him. It should only be called if this client is
  439. // attached to the server. If more than one peer has exceeded the time limit,
  440. // it will be handled on a subsequent pass. By then the first late peer will
  441. // have been marked as dropped
  442. // Returns -1 if no peer has exceeded time limit *SPA
  443. ////////////////////////////////////////////////////////////////////////////////
  444. Net::ID CheckForLostPeer(void);
  445. protected:
  446. ////////////////////////////////////////////////////////////////////////////////
  447. // Receive messages from peers
  448. ////////////////////////////////////////////////////////////////////////////////
  449. void ReceiveFromPeers(void);
  450. ////////////////////////////////////////////////////////////////////////////////
  451. // Send messages to peers
  452. ////////////////////////////////////////////////////////////////////////////////
  453. void SendToPeers(void);
  454. ////////////////////////////////////////////////////////////////////////////////
  455. // Send message to single peer
  456. ////////////////////////////////////////////////////////////////////////////////
  457. void SendToPeer(Net::ID id, Net::SEQ seqStart, bool bSeqReq);
  458. };
  459. #endif //NETCLIENT_H
  460. ////////////////////////////////////////////////////////////////////////////////
  461. // EOF
  462. ////////////////////////////////////////////////////////////////////////////////