netserver.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  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. // netserver.h
  19. // Project: RSPiX
  20. //
  21. // History:
  22. // 08/30/97 MJR Started.
  23. //
  24. // 11/20/97 JMI Added support for new sCoopLevels & sCoopMode flags in
  25. // StartGame and SetupGame messages.
  26. //
  27. // 05/26/98 JMB Added CNetServer::GetNumberOfClients()
  28. //
  29. //
  30. ////////////////////////////////////////////////////////////////////////////////
  31. #ifndef NETSERVER_H
  32. #define NETSERVER_H
  33. #include "RSPiX.h"
  34. #include "netmsgr.h"
  35. #include "net.h"
  36. #include "socket.h"
  37. #include "ORANGE/CDT/fqueue.h"
  38. ////////////////////////////////////////////////////////////////////////////////
  39. //
  40. // CNetServer impliments the server side of the client-server architecture.
  41. //
  42. ////////////////////////////////////////////////////////////////////////////////
  43. class CNetServer
  44. {
  45. //------------------------------------------------------------------------------
  46. // Classes
  47. //------------------------------------------------------------------------------
  48. protected:
  49. ////////////////////////////////////////////////////////////////////////////////
  50. //
  51. // CClient is the server's representation of a client
  52. //
  53. // The general state is indicated by m_state, while the connection state is
  54. // indicated by m_msgr.State(). The two states will generally be "in agreement"
  55. // with one another, but since connecting and disconnecting are asynchronous
  56. // processes, it may seem like the connection status "lags behind" m_state,
  57. // which changes immediately.
  58. //
  59. ////////////////////////////////////////////////////////////////////////////////
  60. class CClient
  61. {
  62. //------------------------------------------------------------------------------
  63. // Types, enums, etc.
  64. //------------------------------------------------------------------------------
  65. public:
  66. // Player states.
  67. typedef enum
  68. {
  69. Unused, // Becomes "Used" when connection is established
  70. Used, // Becomes "Unused" if connection is terminated before JOIN_REQ is accepted
  71. // Becomes "Joined" if JOIN_REQ is accepted
  72. Joined, // Becomes "Unused" if dropped before game starts
  73. // Becomes "Dropped" if dropped after game starts
  74. Dropped // Becomes "Unused" when new game starts
  75. } State;
  76. //------------------------------------------------------------------------------
  77. // Variables
  78. //------------------------------------------------------------------------------
  79. public:
  80. State m_state; // State
  81. RSocket::Address m_address; // Address
  82. char m_acName[Net::MaxPlayerNameSize];// Name
  83. unsigned char m_ucColor; // Color number
  84. unsigned char m_ucTeam; // Team number
  85. short m_sBandwidth; // Net::Bandwidth
  86. CNetMsgr m_msgr; // Messenger for communicating with client
  87. bool m_bLoggedIn; // Whether client is logged in
  88. long m_lLatestPingTime; // Latest ping time
  89. Net::SEQ m_seqLastDoneFrame; // Last frame client did
  90. Net::SEQ m_seqInput;
  91. bool m_bSentReadyRealm; // Whether this client sent READY_REALM msg
  92. bool m_bSentDropAck; // Whether this client sent DROP_ACK msg
  93. Net::SEQ m_seqHighestDropeeInput; // Highest input seq client got from dropee
  94. //------------------------------------------------------------------------------
  95. // Functions
  96. //------------------------------------------------------------------------------
  97. public:
  98. ////////////////////////////////////////////////////////////////////////////////
  99. // Constructor
  100. ////////////////////////////////////////////////////////////////////////////////
  101. CClient()
  102. {
  103. Reset();
  104. }
  105. ////////////////////////////////////////////////////////////////////////////////
  106. // Destructor
  107. ////////////////////////////////////////////////////////////////////////////////
  108. ~CClient()
  109. {
  110. Reset();
  111. }
  112. ////////////////////////////////////////////////////////////////////////////////
  113. // Reset to post-construction state
  114. ////////////////////////////////////////////////////////////////////////////////
  115. void Reset(void)
  116. {
  117. m_state = Unused;
  118. m_address.Reset();
  119. m_acName[0] = 0;
  120. m_ucColor = 0;
  121. m_ucTeam = 0;
  122. m_sBandwidth = Net::FirstBandwidth;
  123. m_msgr.Reset();
  124. m_bLoggedIn = false;
  125. m_lLatestPingTime = 0;
  126. m_seqLastDoneFrame = 0;
  127. m_seqInput = 0;
  128. m_bSentReadyRealm = false;
  129. m_bSentDropAck = false;
  130. }
  131. };
  132. //------------------------------------------------------------------------------
  133. // Types, enums, etc.
  134. //------------------------------------------------------------------------------
  135. //------------------------------------------------------------------------------
  136. // Variables
  137. //------------------------------------------------------------------------------
  138. public: // MADE PUBLIC BY JMB for testing TAPI
  139. RSocket m_socketListen; // Listen socket
  140. RSocket m_socketAntenna; // Socket used to receive browse broadcasts
  141. protected:
  142. RSocket::BLOCK_CALLBACK m_callback; // Blocking callback
  143. unsigned short m_usBasePort; // Base port number
  144. CClient m_aClients[Net::MaxNumIDs]; // Array of clients
  145. Net::ID m_idPrevGet; // Client we got last msg from
  146. Net::ID m_idLocalClient; // Local client's ID (or Net::Invalid if not set)
  147. bool m_bGameStarted; // Whether game was started
  148. bool m_bWaitingForRealmStatus; // Whether we're waiting for realm status messages
  149. char m_acHostName[Net::MaxHostNameSize]; // Host's name
  150. long m_lHostMagic; // Host's magic number
  151. bool m_bSetupGameValid; // Whether m_msgSetupGame is valid
  152. NetMsg m_msgSetupGame; // The latest SetupGame msg (if valid)
  153. FQueue<Net::ID, Net::MaxNumIDs> m_qDropIDs; // Queue of ID's to be dropped
  154. Net::SEQ m_seqHighestDoneFrame; // Highest frame
  155. bool m_bWaitingForInputData; // Whether we're waiting for input data
  156. //------------------------------------------------------------------------------
  157. // Functions
  158. //------------------------------------------------------------------------------
  159. public:
  160. ////////////////////////////////////////////////////////////////////////////////
  161. // Constructor
  162. ////////////////////////////////////////////////////////////////////////////////
  163. CNetServer()
  164. {
  165. Reset();
  166. }
  167. ////////////////////////////////////////////////////////////////////////////////
  168. // Destructor
  169. ////////////////////////////////////////////////////////////////////////////////
  170. ~CNetServer()
  171. {
  172. Reset();
  173. }
  174. ////////////////////////////////////////////////////////////////////////////////
  175. // Reset
  176. ////////////////////////////////////////////////////////////////////////////////
  177. void Reset(void)
  178. {
  179. m_socketListen.Close(true);
  180. m_socketAntenna.Close(true);
  181. m_callback = 0;
  182. m_usBasePort = 0;
  183. for (Net::ID id = 0; id < Net::MaxNumIDs; id++)
  184. m_aClients[id].Reset();
  185. m_idPrevGet = 0;
  186. m_idLocalClient = Net::InvalidID;
  187. m_bGameStarted = false;
  188. m_bWaitingForRealmStatus = false;
  189. m_acHostName[0] = 0;
  190. m_lHostMagic = 0;
  191. m_bSetupGameValid = false;
  192. m_msgSetupGame.Reset();
  193. m_qDropIDs.Reset();
  194. m_seqHighestDoneFrame = 0;
  195. m_bWaitingForInputData = false;
  196. }
  197. ////////////////////////////////////////////////////////////////////////////////
  198. // Startup
  199. ////////////////////////////////////////////////////////////////////////////////
  200. short Startup( // Returns 0 if successfull, non-zero otherwise
  201. unsigned short usPort, // In: Server base port number
  202. char* pszHostName, // In: Host name (max size is MaxHostName!!!)
  203. RSocket::BLOCK_CALLBACK callback); // In: Blocking callback
  204. ////////////////////////////////////////////////////////////////////////////////
  205. // Shutdown
  206. ////////////////////////////////////////////////////////////////////////////////
  207. void Shutdown(void);
  208. ////////////////////////////////////////////////////////////////////////////////
  209. // Update server. This should be called regularly.
  210. ////////////////////////////////////////////////////////////////////////////////
  211. void Update(void);
  212. ////////////////////////////////////////////////////////////////////////////////
  213. // Get message
  214. ////////////////////////////////////////////////////////////////////////////////
  215. void GetMsg(
  216. NetMsg* pmsg); // Out: Message is returned here
  217. private:
  218. ////////////////////////////////////////////////////////////////////////////////
  219. // Send message to specified client
  220. ////////////////////////////////////////////////////////////////////////////////
  221. void SendMsg(
  222. Net::ID id, // In: ID to send message to
  223. NetMsg* pmsg); // In: Message to send
  224. ////////////////////////////////////////////////////////////////////////////////
  225. // Send message to specified group of clients - only Joined clients are allowed!
  226. ////////////////////////////////////////////////////////////////////////////////
  227. void SendMsg(
  228. U16 mask, // In: Bit-mask indicating who to send to
  229. NetMsg* pmsg); // In: Message to send
  230. ////////////////////////////////////////////////////////////////////////////////
  231. // Send message to all joined clients
  232. ////////////////////////////////////////////////////////////////////////////////
  233. void SendMsg(
  234. NetMsg* pmsg); // In: Message to send
  235. public:
  236. ////////////////////////////////////////////////////////////////////////////////
  237. // Determine if there is more data waiting to be sent. If there is data to
  238. // to be sent AND there is a send error, then that data can't be sent, so we
  239. // return false to indicate "no more data".
  240. ////////////////////////////////////////////////////////////////////////////////
  241. bool IsMoreToSend(void); // Returns true if more to send, false otherwise
  242. ////////////////////////////////////////////////////////////////////////////////
  243. // Drop specified client
  244. ////////////////////////////////////////////////////////////////////////////////
  245. void DropClient(
  246. Net::ID id); // In: Client to drop
  247. ////////////////////////////////////////////////////////////////////////////////
  248. // Send the specified game settings to all joined clients
  249. ////////////////////////////////////////////////////////////////////////////////
  250. void SetupGame(
  251. short sRealmNum, // In: Realm number
  252. const char* pszRealmFile, // In: Realm file name
  253. short sDifficulty, // In: Difficulty
  254. short sRejuvenate, // In: Rejuvenate flag
  255. short sTimeLimit, // In: Time limit in minutes, or negative if none
  256. short sKillLimit, // In: Kill limit, or negative if none
  257. short sCoopLevels, // In: Zero for deathmatch levels, non-zero for cooperative levels.
  258. short sCoopMode); // In: Zero for deathmatch mode, non-zero for cooperative mode.
  259. ////////////////////////////////////////////////////////////////////////////////
  260. // Start game using specified settings
  261. ////////////////////////////////////////////////////////////////////////////////
  262. void StartGame(
  263. Net::ID idServer, // In: Server's client's ID
  264. short sRealmNum, // In: Realm number
  265. char* pszRealmFile, // In: Realm file name
  266. short sDifficulty, // In: Difficulty
  267. short sRejuvenate, // In: Rejuvenate flag
  268. short sTimeLimit, // In: Time limit in minutes, or negative if none
  269. short sKillLimit, // In: Kill limit, or negative if none
  270. short sCoopLevels, // In: Zero for deathmatch levels, non-zero for cooperative levels.
  271. short sCoopMode, // In: Zero for deathmatch mode, non-zero for cooperative mode.
  272. short sFrameTime, // In: Time per frame (in milliseconds)
  273. Net::SEQ seqMaxAhead); // In: Initial max ahead for input versus frame seq
  274. ////////////////////////////////////////////////////////////////////////////////
  275. // Abort game
  276. ////////////////////////////////////////////////////////////////////////////////
  277. void AbortGame(
  278. unsigned char ucReason); // In: Why game was aborted
  279. ////////////////////////////////////////////////////////////////////////////////
  280. // Tell clients to go to the next realm when they reach the specified frame seq.
  281. // It is okay to call this multiple times -- "extra" calls are ignored.
  282. //
  283. // The return value is true if a new "next realm" sequence was initiated, and
  284. // false if there was already one in progress.
  285. ////////////////////////////////////////////////////////////////////////////////
  286. bool NextRealm(
  287. Net::SEQ seq); // In: The seq on which to go to next realm
  288. ////////////////////////////////////////////////////////////////////////////////
  289. // Tell clients to proceed. This is used when all players are at a point where
  290. // they need to be told it's time to move on. There is NO attempt to
  291. // syncrhonize the clients, so this must only be used in non-critical sections
  292. // or at a point prior to a syncrhonized section. For instance, if all players
  293. // are viewing a dialog, the local user on the server might hit a key to go
  294. // on, at which point this function would be called to tell all the other
  295. // players to proceed.
  296. ////////////////////////////////////////////////////////////////////////////////
  297. void Proceed(void);
  298. ////////////////////////////////////////////////////////////////////////////////
  299. // Set local client's ID
  300. ////////////////////////////////////////////////////////////////////////////////
  301. void SetLocalClientID(
  302. Net::ID id)
  303. {
  304. m_idLocalClient = id;
  305. }
  306. ////////////////////////////////////////////////////////////////////////////////
  307. // Get host's magic number
  308. ////////////////////////////////////////////////////////////////////////////////
  309. long GetHostMagic(void)
  310. {
  311. return m_lHostMagic;
  312. }
  313. ////////////////////////////////////////////////////////////////////////////////
  314. // Get host's name
  315. ////////////////////////////////////////////////////////////////////////////////
  316. const char* GetHostName(void)
  317. {
  318. return m_acHostName;
  319. }
  320. ////////////////////////////////////////////////////////////////////////////////
  321. // Get the specified client's name
  322. ////////////////////////////////////////////////////////////////////////////////
  323. const char* GetPlayerName(
  324. Net::ID id)
  325. {
  326. ASSERT(id != Net::InvalidID);
  327. ASSERT(id < Net::MaxNumIDs);
  328. return m_aClients[id].m_acName;
  329. }
  330. ////////////////////////////////////////////////////////////////////////////////
  331. // Counts how many clients are logged in
  332. ////////////////////////////////////////////////////////////////////////////////
  333. short GetNumberOfClients()
  334. {
  335. short sNumClients = 0;
  336. for(int id = 0; id < Net::MaxNumIDs; id++)
  337. if(m_aClients[id].m_bLoggedIn)
  338. sNumClients++;
  339. return sNumClients;
  340. }
  341. protected:
  342. ////////////////////////////////////////////////////////////////////////////////
  343. // Start the process of dropping a client during a game
  344. ////////////////////////////////////////////////////////////////////////////////
  345. void StartDroppingClientDuringGame(
  346. Net::ID id);
  347. ////////////////////////////////////////////////////////////////////////////////
  348. // Got all drop acks, now figure out what to do next
  349. //
  350. // A return value of true indicates that one or more clients needed inputs,
  351. // so the drop process is not yet complete. A return of false indicates that
  352. // no clients needed inputs, so we can proceed directly to the next phase.
  353. ////////////////////////////////////////////////////////////////////////////////
  354. bool GotAllDropAcks(void);
  355. ////////////////////////////////////////////////////////////////////////////////
  356. // Finish the process of dropping client. If there's more clients in the drop
  357. // queue, this could also start the dropping of the next victim
  358. ////////////////////////////////////////////////////////////////////////////////
  359. void FinishDroppingClientDuringGame(void);
  360. };
  361. #endif //NETSERVER_H
  362. ////////////////////////////////////////////////////////////////////////////////
  363. // EOF
  364. ////////////////////////////////////////////////////////////////////////////////