58 # define closesocket(s) CloseSocket(s) |
59 # define closesocket(s) CloseSocket(s) |
59 # define GET_LAST_ERROR() Errno() |
60 # define GET_LAST_ERROR() Errno() |
60 # define ioctlsocket(s,request,status) IoctlSocket((LONG)s,(ULONG)request,(char*)status) |
61 # define ioctlsocket(s,request,status) IoctlSocket((LONG)s,(ULONG)request,(char*)status) |
61 |
62 |
62 struct Library *SocketBase = NULL; |
63 struct Library *SocketBase = NULL; |
|
64 |
|
65 // usleep() implementation |
|
66 #include <devices/timer.h> |
|
67 #include <dos/dos.h> |
|
68 |
|
69 struct Device *TimerBase = NULL; |
|
70 struct MsgPort *TimerPort = NULL; |
|
71 struct timerequest *TimerRequest = NULL; |
|
72 |
63 #endif /* __MORPHOS__ || __AMIGA__ */ |
73 #endif /* __MORPHOS__ || __AMIGA__ */ |
64 |
74 |
65 |
75 |
66 #define SEND_MTU 1460 |
76 #define SEND_MTU 1460 |
67 |
77 |
238 void CSleep(int milliseconds) { |
248 void CSleep(int milliseconds) { |
239 #if defined(WIN32) |
249 #if defined(WIN32) |
240 Sleep(milliseconds); |
250 Sleep(milliseconds); |
241 #endif |
251 #endif |
242 #if defined(UNIX) |
252 #if defined(UNIX) |
243 #ifndef __BEOS__ |
253 #if !defined(__BEOS__) && !defined(__MORPHOS__) && !defined(__AMIGAOS__) |
244 usleep(milliseconds*1000); |
254 usleep(milliseconds*1000); |
245 #endif |
255 #endif |
246 #ifdef __BEOS__ |
256 #ifdef __BEOS__ |
247 snooze(milliseconds*1000); |
257 snooze(milliseconds*1000); |
248 #endif |
258 #endif |
|
259 #if defined(__MORPHOS__) || defined(__AMIGAOS__) |
|
260 { |
|
261 ULONG signals; |
|
262 ULONG TimerSigBit = 1 << TimerPort->mp_SigBit; |
|
263 |
|
264 // send IORequest |
|
265 TimerRequest->tr_node.io_Command = TR_ADDREQUEST; |
|
266 TimerRequest->tr_time.tv_secs = (milliseconds * 1000) / 1000000; |
|
267 TimerRequest->tr_time.tv_micro = (milliseconds * 1000) % 1000000; |
|
268 SendIO((struct IORequest *)TimerRequest); |
|
269 |
|
270 if ( !((signals = Wait(TimerSigBit|SIGBREAKF_CTRL_C)) & TimerSigBit) ) { |
|
271 AbortIO((struct IORequest *)TimerRequest); |
|
272 } |
|
273 WaitIO((struct IORequest *)TimerRequest); |
|
274 } |
|
275 #endif // __MORPHOS__ || __AMIGAOS__ |
249 #endif |
276 #endif |
250 } |
277 } |
251 |
278 |
252 ////////////////////////////////////////////////////////////////////// |
279 ////////////////////////////////////////////////////////////////////// |
253 |
280 |
829 |
856 |
830 // ************************** // |
857 // ************************** // |
831 // * TCP Networking * // |
858 // * TCP Networking * // |
832 // ************************** // |
859 // ************************** // |
833 |
860 |
|
861 unsigned long NetworkResolveHost(const char *hostname) { |
|
862 struct hostent* remotehost; |
|
863 |
|
864 if ((hostname[0]<0x30) || (hostname[0]>0x39)) { |
|
865 // seems to be an hostname [first character is no number] |
|
866 remotehost = gethostbyname(hostname); |
|
867 if (remotehost == NULL) { |
|
868 DEBUG(misc, 2) ("[NET][IP] cannot resolve %s", hostname); |
|
869 return 0; |
|
870 } else { |
|
871 DEBUG(misc,2) ("[NET][IP] resolved %s to %s",hostname, inet_ntoa(*(struct in_addr *) remotehost->h_addr_list[0])); |
|
872 return inet_addr(inet_ntoa(*(struct in_addr *) remotehost->h_addr_list[0])); |
|
873 } |
|
874 } else { |
|
875 // seems to be an ip [first character is a number] |
|
876 return inet_addr(hostname); |
|
877 } |
|
878 |
|
879 } |
|
880 |
834 bool NetworkConnect(const char *hostname, int port) |
881 bool NetworkConnect(const char *hostname, int port) |
835 { |
882 { |
836 SOCKET s; |
883 SOCKET s; |
837 struct sockaddr_in sin; |
884 struct sockaddr_in sin; |
838 int b; |
885 int b; |
844 |
891 |
845 b = 1; |
892 b = 1; |
846 setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)); |
893 setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)); |
847 |
894 |
848 sin.sin_family = AF_INET; |
895 sin.sin_family = AF_INET; |
849 sin.sin_addr.s_addr = inet_addr(hostname); |
896 sin.sin_addr.s_addr = NetworkResolveHost(hostname); |
850 sin.sin_port = htons(port); |
897 sin.sin_port = htons(port); |
851 |
898 |
852 if (connect(s, (struct sockaddr*) &sin, sizeof(sin)) != 0) { |
899 if (connect(s, (struct sockaddr*) &sin, sizeof(sin)) != 0) { |
853 NetworkClose(true); |
900 NetworkClose(true); |
854 return false; |
901 return false; |
1068 } |
1115 } |
1069 _num_future_seed = 0; |
1116 _num_future_seed = 0; |
1070 _sync_seed_1 = _sync_seed_2 = 0; |
1117 _sync_seed_1 = _sync_seed_2 = 0; |
1071 memset(_my_seed_list, 0, sizeof(_my_seed_list)); |
1118 memset(_my_seed_list, 0, sizeof(_my_seed_list)); |
1072 |
1119 |
|
1120 } |
|
1121 |
|
1122 // ********************************* // |
|
1123 // * Network Core Console Commands * // |
|
1124 // ********************************* // |
|
1125 |
|
1126 static _iconsole_var * NetworkConsoleCmdConnect(byte argc, byte* argv[], byte argt[]) { |
|
1127 if (argc<2) return NULL; |
|
1128 if (argc==2) { |
|
1129 IConsolePrintF(_iconsole_color_default, "connecting to %s",argv[1]); |
|
1130 NetworkCoreConnectGame(argv[1],_network_server_port); |
|
1131 } else if (argc==3) { |
|
1132 IConsolePrintF(_iconsole_color_default, "connecting to %s on port %s",argv[1],argv[2]); |
|
1133 NetworkCoreConnectGame(argv[1],atoi(argv[2])); |
|
1134 } |
|
1135 return NULL; |
1073 } |
1136 } |
1074 |
1137 |
1075 // ************************** // |
1138 // ************************** // |
1076 // * UDP Network Extensions * // |
1139 // * UDP Network Extensions * // |
1077 // ************************** // |
1140 // ************************** // |
1304 DEBUG(misc,3) ("[NET][Core] using bsd socket library"); |
1367 DEBUG(misc,3) ("[NET][Core] using bsd socket library"); |
1305 if (!(SocketBase = OpenLibrary("bsdsocket.library", 4))) { |
1368 if (!(SocketBase = OpenLibrary("bsdsocket.library", 4))) { |
1306 DEBUG(misc,3) ("[NET][Core] Couldn't open bsdsocket.library version 4."); |
1369 DEBUG(misc,3) ("[NET][Core] Couldn't open bsdsocket.library version 4."); |
1307 _network_available=false; |
1370 _network_available=false; |
1308 } |
1371 } |
|
1372 |
|
1373 // for usleep() implementation |
|
1374 if ( (TimerPort = CreateMsgPort()) ) { |
|
1375 if ( (TimerRequest = (struct timerequest *) CreateIORequest(TimerPort, sizeof(struct timerequest))) ) { |
|
1376 if ( OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *) TimerRequest, 0) == 0 ) { |
|
1377 if ( !(TimerBase = TimerRequest->tr_node.io_Device) ) { |
|
1378 // free ressources... |
|
1379 DEBUG(misc,3) ("[NET][Core] Couldn't initialize timer."); |
|
1380 _network_available=false; |
|
1381 } |
|
1382 } |
|
1383 } |
|
1384 } |
1309 } |
1385 } |
1310 #else |
1386 #else |
1311 |
1387 |
1312 // [linux/macos] unix-socket startup |
1388 // [linux/macos] unix-socket startup |
1313 |
1389 |
1320 |
1396 |
1321 if (_network_available) { |
1397 if (_network_available) { |
1322 DEBUG(misc,3) ("[NET][Core] OK: multiplayer available"); |
1398 DEBUG(misc,3) ("[NET][Core] OK: multiplayer available"); |
1323 // initiate network ip list |
1399 // initiate network ip list |
1324 NetworkIPListInit(); |
1400 NetworkIPListInit(); |
|
1401 IConsoleCmdRegister("connect",NetworkConsoleCmdConnect); |
1325 } else { |
1402 } else { |
1326 DEBUG(misc,3) ("[NET][Core] FAILED: multiplayer not available"); |
1403 DEBUG(misc,3) ("[NET][Core] FAILED: multiplayer not available"); |
1327 } |
1404 } |
1328 } |
1405 } |
1329 |
1406 |
1333 |
1410 |
1334 DEBUG(misc,3) ("[NET][Core] shutdown()"); |
1411 DEBUG(misc,3) ("[NET][Core] shutdown()"); |
1335 |
1412 |
1336 #if defined(__MORPHOS__) || defined(__AMIGA__) |
1413 #if defined(__MORPHOS__) || defined(__AMIGA__) |
1337 { |
1414 { |
|
1415 // free allocated ressources |
|
1416 if (TimerBase) { CloseDevice((struct IORequest *) TimerRequest); } |
|
1417 if (TimerRequest) { DeleteIORequest(TimerRequest); } |
|
1418 if (TimerPort) { DeleteMsgPort(TimerPort); } |
|
1419 |
1338 if (SocketBase) { |
1420 if (SocketBase) { |
1339 CloseLibrary(SocketBase); |
1421 CloseLibrary(SocketBase); |
1340 } |
1422 } |
1341 } |
1423 } |
1342 #endif |
1424 #endif |