PageRenderTime 27ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/v1.13.127/network/tracker.cpp

https://github.com/simX/d2x-xl
C++ | 382 lines | 293 code | 66 blank | 23 comment | 58 complexity | ea2bef7193fe3470c7b0ecf558d34f69 MD5 | raw file
Possible License(s): GPL-2.0
  1. // tracker.c
  2. // game server tracker communication
  3. #ifdef HAVE_CONFIG_H
  4. #include <conf.h>
  5. #endif
  6. #include <string.h>
  7. #ifdef _WIN32
  8. # include <winsock.h>
  9. #else
  10. # include <sys/socket.h>
  11. #endif
  12. #ifndef _WIN32
  13. # include <arpa/inet.h>
  14. # include <netinet/in.h> /* for htons & co. */
  15. #endif
  16. #include "inferno.h"
  17. #include "args.h"
  18. #include "u_mem.h"
  19. #include "ipx.h"
  20. #include "network.h"
  21. #include "network_lib.h"
  22. #include "key.h"
  23. #include "menu.h"
  24. #include "tracker.h"
  25. #ifdef __macosx__
  26. # include <SDL/SDL.h>
  27. #else
  28. # include <SDL.h>
  29. #endif
  30. static int bTestTracker = 0;
  31. #if 0
  32. static tUdpAddress testServer;
  33. #endif
  34. typedef struct tServerListTable {
  35. struct tServerListTable *nextList;
  36. tServerList serverList;
  37. tUdpAddress *tracker;
  38. time_t lastActive;
  39. } tServerListTable;
  40. static tUdpAddress d2xTracker = {85,119,152,28,0,0};
  41. static tUdpAddress kbTracker = {207,210,100,66,0,0};
  42. tServerListTable *serverListTable = NULL;
  43. tServerList trackerList;
  44. #if DBG
  45. # define S_TIMEOUT 1000
  46. # define R_TIMEOUT 1000
  47. #else
  48. # define S_TIMEOUT 20000
  49. # define R_TIMEOUT 3000
  50. #endif
  51. //------------------------------------------------------------------------------
  52. int FindTracker (tUdpAddress *addr)
  53. {
  54. int i;
  55. unsigned int a = UDP_ADDR (addr);
  56. short p = (short) ntohs (UDP_PORT (addr));
  57. for (i = 0; i < trackerList.nServers; i++)
  58. if ((a == UDP_ADDR (trackerList.servers + i)) &&
  59. (p == UDP_PORT (trackerList.servers + i)))
  60. return i;
  61. return -1;
  62. }
  63. //------------------------------------------------------------------------------
  64. static void CallTracker (int i, ubyte *pData, int nDataLen)
  65. {
  66. unsigned int network = 0;
  67. tUdpAddress tracker;
  68. UDP_ADDR (&tracker) = UDP_ADDR (trackerList.servers + i);
  69. UDP_PORT (&tracker) = htons (UDP_PORT (trackerList.servers + i));
  70. gameStates.multi.bTrackerCall = 1;
  71. IPXSendInternetPacketData (pData, nDataLen, (ubyte *) &network, (ubyte *) &tracker);
  72. gameStates.multi.bTrackerCall = 0;
  73. }
  74. //------------------------------------------------------------------------------
  75. int AddServerToTracker (void)
  76. {
  77. if ((gameStates.multi.bServer || bTestTracker) && gameStates.multi.bUseTracker) {
  78. int i, t;
  79. static int nTimeout = 0;
  80. ubyte id = 'S';
  81. if ((t = SDL_GetTicks ()) - nTimeout < S_TIMEOUT)
  82. return 0;
  83. nTimeout = t;
  84. for (i = 0; i < trackerList.nServers; i++)
  85. CallTracker (i, &id, sizeof (id));
  86. return 1;
  87. }
  88. return 0;
  89. }
  90. //------------------------------------------------------------------------------
  91. int RequestServerListFromTracker (void)
  92. {
  93. int i, t;
  94. static int nTimeout = 0;
  95. ubyte id = 'R';
  96. if (!gameStates.multi.bUseTracker)
  97. return 0;
  98. if (bTestTracker)
  99. AddServerToTracker ();
  100. if ((t = SDL_GetTicks ()) - nTimeout < R_TIMEOUT)
  101. return 0;
  102. nTimeout = t;
  103. for (i = 0; i < trackerList.nServers; i++)
  104. CallTracker (i, &id, sizeof (id));
  105. return 1;
  106. }
  107. //------------------------------------------------------------------------------
  108. int ReceiveServerListFromTracker (ubyte *data)
  109. {
  110. tServerListTable *pslt;
  111. int i = FindTracker ((tUdpAddress *) &ipx_udpSrc.src_node);
  112. if (i < 0)
  113. return 0;
  114. for (pslt = serverListTable; pslt; pslt = pslt->nextList)
  115. if (--i < 0) {
  116. tUdpAddress *ps = pslt->serverList.servers;
  117. memcpy (&pslt->serverList, data, sizeof (tServerList));
  118. for (i = pslt->serverList.nServers; i; i--, ps++)
  119. UDP_PORT (ps) = (unsigned short) ntohs (UDP_PORT (ps));
  120. pslt->lastActive = SDL_GetTicks ();
  121. return 1;
  122. }
  123. return 0;
  124. }
  125. //------------------------------------------------------------------------------
  126. void SetServerFromList (tServerList *psl, int i)
  127. {
  128. memcpy (ipx_ServerAddress + 4, psl->servers + i, 4);
  129. *((ushort *) (ipx_ServerAddress + 8)) = (ushort) htons (UDP_PORT (psl->servers + i));
  130. //udpBasePort = psl->servers [i].port;
  131. }
  132. //------------------------------------------------------------------------------
  133. int GetServerFromList (int i)
  134. {
  135. tServerListTable *pslt = serverListTable;
  136. while (pslt) {
  137. if (i < pslt->serverList.nServers) {
  138. SetServerFromList (&pslt->serverList, i);
  139. return 1;
  140. }
  141. i -= pslt->serverList.nServers;
  142. pslt = pslt->nextList;
  143. }
  144. return 0;
  145. }
  146. //------------------------------------------------------------------------------
  147. int IsTracker (unsigned int addr, ushort port)
  148. {
  149. int i;
  150. #if DBG
  151. unsigned int a;
  152. ushort p;
  153. #endif
  154. port = ntohs (port);
  155. for (i = 0; i < trackerList.nServers; i++) {
  156. #if DBG
  157. a = UDP_ADDR (trackerList.servers + i);
  158. p = UDP_PORT (trackerList.servers + i);
  159. #endif
  160. if ((addr == UDP_ADDR (trackerList.servers + i)) &&
  161. (port == UDP_PORT (trackerList.servers + i)))
  162. return 1;
  163. }
  164. return 0;
  165. }
  166. //------------------------------------------------------------------------------
  167. int AddTracker (tUdpAddress *addr)
  168. {
  169. int i;
  170. tServerListTable *pslt;
  171. if (trackerList.nServers >= MAX_TRACKER_SERVERS)
  172. return -1;
  173. if (0 < (i = FindTracker (addr)))
  174. return i;
  175. if (!(pslt = (tServerListTable *) D2_ALLOC (sizeof (tServerListTable))))
  176. return -1;
  177. memset (pslt, 0, sizeof (*pslt));
  178. pslt->nextList = serverListTable;
  179. serverListTable = pslt;
  180. pslt->tracker = trackerList.servers + trackerList.nServers;
  181. UDP_ADDR (pslt->tracker) = UDP_ADDR (addr);
  182. UDP_PORT (pslt->tracker) = UDP_PORT (addr) ? UDP_PORT (addr) : 9424;
  183. pslt->lastActive = 0;
  184. return trackerList.nServers++;
  185. }
  186. //------------------------------------------------------------------------------
  187. inline int CountActiveTrackers (void)
  188. {
  189. tServerListTable *pslt;
  190. time_t t = SDL_GetTicks ();
  191. int i = 0;
  192. for (pslt = serverListTable; pslt; pslt = pslt->nextList)
  193. if (pslt->lastActive && (t - pslt->lastActive < 30000))
  194. i++;
  195. return i;
  196. }
  197. //------------------------------------------------------------------------------
  198. static time_t nQueryTimeout;
  199. int TrackerPoll (int nItems, tMenuItem *m, int *key, int nCurItem)
  200. {
  201. time_t t;
  202. if (NetworkListen () && CountActiveTrackers ())
  203. *key = -2;
  204. else if (*key == KEY_ESC)
  205. *key = -3;
  206. else if ((t = SDL_GetTicks () - nQueryTimeout) > 60000)
  207. *key = -4;
  208. else {
  209. int v = (int) (t / 60);
  210. if (m [0].value != v) {
  211. m [0].value = v;
  212. m [0].rebuild = 1;
  213. }
  214. *key = 0;
  215. }
  216. return nCurItem;
  217. }
  218. //------------------------------------------------------------------------------
  219. int QueryTrackers (void)
  220. {
  221. tMenuItem m [3];
  222. int i;
  223. if (!RequestServerListFromTracker ())
  224. return 0;
  225. memset (m, 0, sizeof (m));
  226. ADD_GAUGE (0, " ", 0, 1000);
  227. ADD_TEXT (1, "", 0);
  228. ADD_TEXT (2, "(Press Escape to cancel)", 0);
  229. m [2].centered = 1;
  230. nQueryTimeout = SDL_GetTicks ();
  231. do {
  232. i = ExecMenu2 (NULL, "Looking for Trackers", 3, m, TrackerPoll, 0, NULL);
  233. } while (i >= 0);
  234. return i;
  235. }
  236. //------------------------------------------------------------------------------
  237. int ActiveTrackerCount (int bQueryTrackers)
  238. {
  239. if (bQueryTrackers)
  240. return QueryTrackers ();
  241. return CountActiveTrackers ();
  242. }
  243. //------------------------------------------------------------------------------
  244. extern int stoip (char *szServerIpAddr, unsigned char *pIpAddr);
  245. int stoport (char *szPort, int *pPort, int *pSign);
  246. static int ParseIpAndPort (char *pszAddr, tUdpAddress *addr)
  247. {
  248. int port;
  249. char szAddr [22], *pszPort;
  250. strncpy (szAddr, pszAddr, sizeof (szAddr));
  251. szAddr [21] = '\0';
  252. if (!(pszPort = strchr (szAddr, ':')))
  253. return 0;
  254. *pszPort++ = '\0';
  255. if (!stoip (szAddr, (unsigned char *) addr))
  256. return 0;
  257. if (!stoport (pszPort, &port, NULL))
  258. return 0;
  259. if (port > 0xFFFF)
  260. return 0;
  261. UDP_PORT (addr) = port;
  262. return 1;
  263. }
  264. //------------------------------------------------------------------------------
  265. void AddTrackersFromCmdLine (void)
  266. {
  267. unsigned int i, j, t;
  268. char szKwd [20];
  269. tUdpAddress tracker;
  270. if ((t = FindArg ("-test_tracker")))
  271. bTestTracker = 1;
  272. if (!(t = FindArg ("-num_trackers")))
  273. return;
  274. if (!(i = atoi (pszArgList [t + 1])))
  275. return;
  276. if (i > MAX_TRACKER_SERVERS)
  277. i = MAX_TRACKER_SERVERS;
  278. for (j = 0; j < i; j++) {
  279. sprintf (szKwd, "-tracker%d", j + 1);
  280. if (!(t = FindArg (szKwd)))
  281. continue;
  282. if (ParseIpAndPort (pszArgList [t + 1], &tracker))
  283. AddTracker (&tracker);
  284. }
  285. }
  286. //------------------------------------------------------------------------------
  287. void ResetTrackerList (void)
  288. {
  289. serverListTable = NULL;
  290. gameStates.multi.bTrackerCall = 0;
  291. memset (&trackerList, 0, sizeof (trackerList));
  292. }
  293. //------------------------------------------------------------------------------
  294. void CreateTrackerList (void)
  295. {
  296. int a;
  297. ResetTrackerList ();
  298. if (!(a = FindArg ("-internal_tracker")) || atoi (pszArgList [a + 1])) {
  299. AddTracker (&d2xTracker);
  300. AddTracker (&kbTracker);
  301. }
  302. AddTrackersFromCmdLine ();
  303. }
  304. //------------------------------------------------------------------------------
  305. void DestroyTrackerList (void)
  306. {
  307. tServerListTable *pslt;
  308. while (serverListTable) {
  309. pslt = serverListTable;
  310. serverListTable = serverListTable->nextList;
  311. D2_FREE (pslt);
  312. }
  313. ResetTrackerList ();
  314. }
  315. //------------------------------------------------------------------------------
  316. // eof