X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_netmaster.pas;h=925b910241c91bcdda8a5a4e2f7e645441c7fe5a;hb=8ab76228a45f13481cc1162b6d84cb3bdb50b9c6;hp=e8a80d691c12c1b7493940081ec72f3eb7a5becd;hpb=d48e70deea1b12aaea9d0543dfe5f1bac9787177;p=d2df-sdl.git diff --git a/src/game/g_netmaster.pas b/src/game/g_netmaster.pas index e8a80d6..925b910 100644 --- a/src/game/g_netmaster.pas +++ b/src/game/g_netmaster.pas @@ -2,8 +2,7 @@ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * the Free Software Foundation, version 3 of the License ONLY. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -55,8 +54,8 @@ type TNetServerTable = array of TNetServerRow; var - NetMHost: pENetHost = nil; - NetMPeer: pENetPeer = nil; + NetMHost: pENetHost = nil; + NetMPeer: pENetPeer = nil; slCurrent: TNetServerList = nil; slTable: TNetServerTable = nil; @@ -70,7 +69,7 @@ procedure g_Net_Slist_Set(IP: string; Port: Word); function g_Net_Slist_Fetch(var SL: TNetServerList): Boolean; procedure g_Net_Slist_Update(); procedure g_Net_Slist_Remove(); -function g_Net_Slist_Connect(): Boolean; +function g_Net_Slist_Connect(blocking: Boolean=True): Boolean; procedure g_Net_Slist_Check(); procedure g_Net_Slist_Disconnect(); procedure g_Net_Slist_WriteInfo(); @@ -79,6 +78,9 @@ procedure g_Serverlist_GenerateTable(SL: TNetServerList; var ST: TNetServerTable procedure g_Serverlist_Draw(var SL: TNetServerList; var ST: TNetServerTable); procedure g_Serverlist_Control(var SL: TNetServerList; var ST: TNetServerTable); +function GetTimerMS(): Int64; + + implementation uses @@ -92,6 +94,10 @@ var slFetched: Boolean = False; slDirPressed: Boolean = False; slReadUrgent: Boolean = False; + // inside the game, calling `g_Net_Slist_Connect()` is disasterous, as it is blocking. + // so we'll use this variable to indicate if "connected" event is received. + NetHostConnected: Boolean = false; + NetHostConReqTime: Int64 = 0; // to timeout `connect` function GetTimerMS(): Int64; begin @@ -383,11 +389,40 @@ end; procedure g_Net_Slist_Update; var - P: pENetPacket; - + ct: Int64; begin - if (NetMHost = nil) or (NetMPeer = nil) then Exit; + if (NetMHost = nil) or (NetMPeer = nil) then exit; + + // we are waiting for connection + if (not NetHostConnected) then + begin + // check for connection packet + if (enet_host_service(NetMHost, @NetMEvent, 0) > 0) then + begin + if NetMEvent.kind = ENET_EVENT_TYPE_CONNECT then + begin + NetHostConnected := True; + g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_SLIST_CONN]); + end + else + begin + if NetMEvent.kind = ENET_EVENT_TYPE_RECEIVE then enet_packet_destroy(NetMEvent.packet); + end; + end; + // check for connection timeout + if (not NetHostConnected) then + begin + ct := GetTimerMS(); + if (ct-NetHostConReqTime >= 3000) then + begin + // do not spam with error messages, it looks like the master is down + //g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_SLIST_ERROR], True); + g_Net_Slist_Disconnect(); + exit; + end; + end; + end; NetOut.Clear(); NetOut.Write(Byte(NET_MMSG_UPD)); @@ -406,7 +441,7 @@ procedure g_Net_Slist_Remove; var P: pENetPacket; begin - if (NetMHost = nil) or (NetMPeer = nil) then Exit; + if (NetMHost = nil) or (NetMPeer = nil) or (not NetHostConnected) then Exit; NetOut.Clear(); NetOut.Write(Byte(NET_MMSG_DEL)); NetOut.Write(NetAddr.port); @@ -418,9 +453,13 @@ begin NetOut.Clear(); end; -function g_Net_Slist_Connect: Boolean; +function g_Net_Slist_Connect (blocking: Boolean=True): Boolean; +var + delay: Integer; begin Result := False; + NetHostConnected := False; // just in case + NetHostConReqTime := 0; // just in case NetMHost := enet_host_create(nil, 1, NET_MCHANS, 0, 0); if (NetMHost = nil) then @@ -438,10 +477,12 @@ begin Exit; end; - if (enet_host_service(NetMHost, @NetMEvent, 3000) > 0) then + if (blocking) then delay := 3000 else delay := 0; + if (enet_host_service(NetMHost, @NetMEvent, delay) > 0) then if NetMEvent.kind = ENET_EVENT_TYPE_CONNECT then begin Result := True; + NetHostConnected := True; g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_SLIST_CONN]); Exit; end @@ -449,10 +490,22 @@ begin if NetMEvent.kind = ENET_EVENT_TYPE_RECEIVE then enet_packet_destroy(NetMEvent.packet); - g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_SLIST_ERROR], True); + if (blocking) then + begin + g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_SLIST_ERROR], True); - NetMHost := nil; - NetMPeer := nil; + if NetMPeer <> nil then enet_peer_reset(NetMPeer); + if NetMHost <> nil then enet_host_destroy(NetMHost); + NetMPeer := nil; + NetMHost := nil; + NetHostConnected := False; + NetHostConReqTime := 0; + end + else + begin + NetHostConReqTime := GetTimerMS(); + g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_SLIST_WCONN]); + end; end; procedure g_Net_Slist_Disconnect; @@ -469,13 +522,15 @@ begin NetMPeer := nil; NetMHost := nil; + NetHostConnected := False; + NetHostConReqTime := 0; g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_SLIST_DISC]); end; procedure g_Net_Slist_Check; begin - if (NetMHost = nil) or (NetMPeer = nil) then Exit; + if (NetMHost = nil) or (NetMPeer = nil) or (not NetHostConnected) then Exit; while (enet_host_service(NetMHost, @NetMEvent, 0) > 0) do begin @@ -486,6 +541,8 @@ begin if NetMHost <> nil then enet_host_destroy(NetMHost); NetMPeer := nil; NetMHost := nil; + NetHostConnected := False; + NetHostConReqTime := 0; Break; end else @@ -785,7 +842,7 @@ begin Exit; end; - // if there's a message on the screen, + // if there's a message on the screen, if not slReadUrgent and (slUrgent <> '') then begin if e_KeyPressed(IK_RETURN) or e_KeyPressed(IK_KPRETURN) or e_KeyPressed(VK_FIRE) or e_KeyPressed(VK_OPEN) or