1 (* Copyright (C) Doom 2D: Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License ONLY.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *)
15 {$INCLUDE ../shared/a_modes.inc}
18 interface
20 uses
23 const
33 type
57 type
59 public
63 public
64 //host: pENetHost;
68 // inside the game, calling `connect()` is disasterous, as it is blocking.
69 // so we'll use this variable to indicate if "connected" event is received.
77 private
80 private
83 public
95 // returns `false` if connection failed
98 // call as often as you want, the object will do the rest
99 // but try to call this at least once in 100 msecs
100 // returns `true` if we got a packet (it won't be parsed to TMsg)
111 // call only if `service()` returned `true`!
116 var
128 {
129 procedure g_Net_Slist_Update (immediateSend: Boolean=true);
130 procedure g_Net_Slist_Remove ();
131 function g_Net_Slist_Connect (blocking: Boolean=True): Boolean;
132 procedure g_Net_Slist_Check ();
133 procedure g_Net_Slist_Disconnect (spamConsole: Boolean=true);
134 procedure g_Net_Slist_WriteInfo ();
136 function g_Net_Slist_IsConnectionActive (): Boolean; // returns `false` if totally disconnected
137 function g_Net_Slist_IsConnectionInProgress (): Boolean;
138 }
140 // make this server private
143 // called on network mode init
145 // called on network mode shutdown
157 implementation
159 uses
164 // make this server private
166 begin
170 // called on network mode init
172 begin
175 // called on network mode shutdown
177 begin
181 var
189 {
190 NetMHost: pENetHost = nil;
191 NetMPeer: pENetPeer = nil;
192 NetMEvent: ENetEvent;
193 // inside the game, calling `g_Net_Slist_Connect()` is disasterous, as it is blocking.
194 // so we'll use this variable to indicate if "connected" event is received.
195 NetHostConnected: Boolean = false;
196 NetHostConReqTime: Int64 = 0; // to timeout `connect`
197 NetUpdatePending: Boolean = false;
198 }
201 //==========================================================================
202 //
203 // GetTimerMS
204 //
205 //==========================================================================
207 begin
212 //==========================================================================
213 //
214 // TMasterHost.Create
215 //
216 //==========================================================================
218 begin
219 //host := nil;
233 //==========================================================================
234 //
235 // TMasterHost.clear
236 //
237 //==========================================================================
239 begin
248 //==========================================================================
249 //
250 // TMasterHost.setAddress
251 //
252 //==========================================================================
254 var
256 begin
265 begin
269 begin
273 begin
274 try
276 except
286 begin
288 begin
299 //==========================================================================
300 //
301 // TMasterHost.isValid
302 //
303 //==========================================================================
305 begin
310 //==========================================================================
311 //
312 // TMasterHost.isAlive
313 //
314 // not disconnected
315 //
316 //==========================================================================
318 begin
323 //==========================================================================
324 //
325 // TMasterHost.isConnecting
326 //
327 // is connection in progress?
328 //
329 //==========================================================================
331 begin
336 //==========================================================================
337 //
338 // TMasterHost.isConnected
339 //
340 //==========================================================================
342 begin
347 //==========================================================================
348 //
349 // TMasterHost.disconnect
350 //
351 //==========================================================================
353 begin
361 //enet_host_destroy(NetMHost);
364 //NetMHost := nil;
374 //==========================================================================
375 //
376 // TMasterHost.connect
377 //
378 //==========================================================================
380 var
382 begin
391 begin
394 begin
396 Exit;
401 begin
403 begin
406 exit;
414 begin
416 //enet_host_destroy(NetMHost);
417 //NetMHost := nil;
418 exit;
423 begin
426 exit;
431 begin
433 begin
436 exit;
443 {
444 if (blocking) then
445 begin
446 g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_SLIST_ERROR], True);
448 if NetMPeer <> nil then enet_peer_reset(NetMPeer);
449 if NetMHost <> nil then enet_host_destroy(NetMHost);
450 NetMPeer := nil;
451 NetMHost := nil;
452 NetHostConnected := False;
453 NetHostConReqTime := 0;
454 NetUpdatePending := false;
455 end
456 else
457 begin
458 NetHostConReqTime := GetTimerMS();
459 g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_SLIST_WCONN]);
460 end;
461 }
465 //==========================================================================
466 //
467 // TMasterHost.processPendingConnection
468 //
469 // should be called only if host/peer is here
470 // returns `false` if not connected or dead
471 //
472 //==========================================================================
474 var
477 begin
480 // are we waiting for connection?
482 begin
483 // check for connection event
486 begin
487 //TODO: reconnect here
490 exit;
493 begin
495 begin
500 exit;
501 end
503 begin
504 //TODO: reconnect here
507 exit;
508 end
510 begin
514 // check for connection timeout
516 begin
519 begin
520 // do not spam with error messages, it looks like the master is down
521 //g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_SLIST_ERROR], True);
524 exit;
531 //==========================================================================
532 //
533 // TMasterHost.writeInfo
534 //
535 //==========================================================================
537 var
539 begin
557 //==========================================================================
558 //
559 // TMasterHost.update
560 //
561 //==========================================================================
563 var
565 begin
567 begin
569 exit;
582 begin
591 //==========================================================================
592 //
593 // TMasterHost.remove
594 //
595 //==========================================================================
597 var
599 begin
608 begin
617 //==========================================================================
618 //
619 // TMasterHost.waitForConnection
620 //
621 // returns `false` if connection failed
622 //
623 //==========================================================================
625 begin
629 begin
633 begin
641 //==========================================================================
642 //
643 // TMasterHost.service
644 //
645 // call as often as you want, the object will do the rest
646 // but try to call this at least once in 100 msecs
647 //
648 // returns `true` if we got a packet (it won't be parsed to TMsg)
649 //
650 //==========================================================================
652 var
655 begin
662 begin
668 begin
671 begin
672 //TODO: reconnect here
675 exit;
679 begin
683 end
685 begin
686 //TODO: reconnect here
690 exit;
691 end
693 begin
694 //enet_packet_destroy(event.packet);
695 //if (timeout <> 0) then break;
697 exit;
703 //==========================================================================
704 //
705 // TMasterHost.clearPacket
706 //
707 //==========================================================================
709 begin
711 begin
718 //**************************************************************************
719 //
720 // other functions
721 //
722 //**************************************************************************
725 begin
727 begin
730 end
731 else
732 begin
736 {
737 if NetInitDone then
738 begin
739 enet_address_set_host(@NetSlistAddr, PChar(Addr(IP[1])));
740 NetSlistAddr.Port := Port;
741 e_WriteLog('Masterserver address set to ' + IP + ':' + IntToStr(Port), TMsgType.Notify);
742 end;
743 }
747 //**************************************************************************
748 //
749 // main pulse
750 //
751 //**************************************************************************
753 begin
757 //**************************************************************************
758 //
759 // gui and server list
760 //
761 //**************************************************************************
763 //==========================================================================
764 //
765 // PingServer
766 //
767 //==========================================================================
769 var
773 begin
787 //==========================================================================
788 //
789 // PingBcast
790 //
791 //==========================================================================
793 var
795 begin
805 //==========================================================================
806 //
807 // g_Net_Slist_Fetch
808 //
809 //==========================================================================
811 var
825 begin
829 begin
847 begin
862 begin
883 begin
888 begin
890 Exit;
894 begin
896 Exit;
900 begin
902 Exit;
911 // TODO: what should we identify the build with?
920 begin
923 begin
925 continue;
931 begin
933 continue;
940 begin
944 begin
962 begin
963 // new master, supports version reports
966 begin
967 { TODO }
970 // even newer master, supports extra info
972 begin
975 // check if the message has updated and the user has to read it again
983 break;
990 begin
992 Exit;
1011 begin
1027 begin
1029 begin
1045 break;
1056 //==========================================================================
1057 //
1058 // GetServerFromTable
1059 //
1060 //==========================================================================
1061 function GetServerFromTable (Index: Integer; SL: TNetServerList; ST: TNetServerTable): TNetServer;
1062 begin
1078 Exit;
1080 Exit;
1085 //==========================================================================
1086 //
1087 // g_Serverlist_Draw
1088 //
1089 //==========================================================================
1091 var
1099 begin
1116 e_TextureFontPrintEx(gScreenWidth div 2 - mw, gScreenHeight-24, ip, gStdFont, 225, 225, 225, 1);
1118 // MOTD
1120 begin
1126 // Urgent message
1128 begin
1147 Exit;
1151 begin
1158 Exit;
1163 begin
1170 else
1172 end else
1199 begin
1201 // Name and map
1205 // Ping and similar count
1208 else
1211 else
1212 e_TextureFontPrintEx(mx - 68, y, IntToStr(Srv.Ping) + _lc[I_NET_SLIST_PING_MS], gStdFont, 255, 255, 255, 1);
1215 e_TextureFontPrintEx(mx - 68, y + 16, '< ' + IntToStr(Length(ST[I].Indices)) + ' >', gStdFont, 210, 210, 210, 1);
1217 // Game mode
1220 // Players
1221 e_TextureFontPrintEx(mx + 54, y, IntToStr(Srv.Players) + '/' + IntToStr(Srv.MaxPlayers), gStdFont, 255, 255, 255, 1);
1222 e_TextureFontPrintEx(mx + 54, y + 16, IntToStr(Srv.LocalPl) + '+' + IntToStr(Srv.Bots), gStdFont, 210, 210, 210, 1);
1224 // Version
1237 //==========================================================================
1238 //
1239 // g_Serverlist_GenerateTable
1240 //
1241 //==========================================================================
1243 var
1247 var
1249 begin
1252 Exit;
1254 begin
1256 continue;
1258 begin
1260 Exit;
1265 var
1267 begin
1275 var
1278 begin
1282 begin
1289 var
1292 begin
1296 begin
1302 begin
1305 Exit;
1307 begin
1310 begin
1316 end
1317 else
1318 begin
1331 //==========================================================================
1332 //
1333 // g_Serverlist_Control
1334 //
1335 //==========================================================================
1337 var
1340 begin
1342 Exit;
1349 begin
1357 Exit;
1360 // if there's a message on the screen,
1362 begin
1363 if e_KeyPressed(IK_RETURN) or e_KeyPressed(IK_KPRETURN) or e_KeyPressed(VK_FIRE) or e_KeyPressed(VK_OPEN) or
1364 e_KeyPressed(JOY0_ATTACK) or e_KeyPressed(JOY1_ATTACK) or e_KeyPressed(JOY2_ATTACK) or e_KeyPressed(JOY3_ATTACK) then
1366 Exit;
1370 e_KeyPressed(JOY0_ACTIVATE) or e_KeyPressed(JOY1_ACTIVATE) or e_KeyPressed(JOY2_ACTIVATE) or e_KeyPressed(JOY3_ACTIVATE) then
1371 begin
1373 begin
1376 g_Game_Draw;
1377 sys_Repaint;
1380 begin
1383 end
1384 else
1391 end
1392 else
1397 if e_KeyPressed(IK_RETURN) or e_KeyPressed(IK_KPRETURN) or e_KeyPressed(VK_FIRE) or e_KeyPressed(VK_OPEN) or
1398 e_KeyPressed(JOY0_ATTACK) or e_KeyPressed(JOY1_ATTACK) or e_KeyPressed(JOY2_ATTACK) or e_KeyPressed(JOY3_ATTACK) then
1399 begin
1401 begin
1404 begin
1412 Exit;
1413 end
1414 else
1419 Exit;
1421 end
1422 else
1426 e_KeyPressed(JOY0_DOWN) or e_KeyPressed(JOY1_DOWN) or e_KeyPressed(JOY2_DOWN) or e_KeyPressed(JOY3_DOWN) then
1427 begin
1429 begin
1437 e_KeyPressed(JOY0_UP) or e_KeyPressed(JOY1_UP) or e_KeyPressed(JOY2_UP) or e_KeyPressed(JOY3_UP) then
1438 begin
1440 begin
1449 e_KeyPressed(JOY0_RIGHT) or e_KeyPressed(JOY1_RIGHT) or e_KeyPressed(JOY2_RIGHT) or e_KeyPressed(JOY3_RIGHT) then
1450 begin
1452 begin
1460 e_KeyPressed(JOY0_LEFT) or e_KeyPressed(JOY1_LEFT) or e_KeyPressed(JOY2_LEFT) or e_KeyPressed(JOY3_LEFT) then
1461 begin
1463 begin
1464 if ST[slSelection].Current = 0 then ST[slSelection].Current := Length(ST[slSelection].Indices);
1483 (not e_KeyPressed(JOY0_UP)) and (not e_KeyPressed(JOY1_UP)) and (not e_KeyPressed(JOY2_UP)) and (not e_KeyPressed(JOY3_UP)) and
1484 (not e_KeyPressed(JOY0_DOWN)) and (not e_KeyPressed(JOY1_DOWN)) and (not e_KeyPressed(JOY2_DOWN)) and (not e_KeyPressed(JOY3_DOWN)) and
1485 (not e_KeyPressed(JOY0_LEFT)) and (not e_KeyPressed(JOY1_LEFT)) and (not e_KeyPressed(JOY2_LEFT)) and (not e_KeyPressed(JOY3_LEFT)) and
1486 (not e_KeyPressed(JOY0_RIGHT)) and (not e_KeyPressed(JOY1_RIGHT)) and (not e_KeyPressed(JOY2_RIGHT)) and (not e_KeyPressed(JOY3_RIGHT))
1487 then