summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: f9af3a4)
raw | patch | inline | side by side (parent: f9af3a4)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Sun, 13 Oct 2019 01:32:38 +0000 (04:32 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Sun, 13 Oct 2019 01:34:19 +0000 (04:34 +0300) |
use blocking connections only in server list query. we don't need
to block at map loading, or in any other place, because we can
simply schedule update, and send them when master is available.
to block at map loading, or in any other place, because we can
simply schedule update, and send them when master is available.
src/game/g_game.pas | patch | blob | history | |
src/game/g_net.pas | patch | blob | history | |
src/game/g_netmaster.pas | patch | blob | history |
diff --git a/src/game/g_game.pas b/src/game/g_game.pas
index 2b827412980e5292b5ecd3db459292af8ed0c734..963496aab5b49eddfb4779dda2ef1f7e9d14674b 100644 (file)
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
if NetUseMaster then
begin
- if gTime >= NetTimeToMaster then
+ if (gTime >= NetTimeToMaster) or g_Net_Slist_IsConnectionInProgress then
begin
- if (NetMHost = nil) or (NetMPeer = nil) then
- begin
- g_Net_Slist_Connect(false); // non-blocking connection to the master
- end;
-
+ if (not g_Net_Slist_IsConnectionActive) then g_Net_Slist_Connect(false); // non-blocking connection to the master
g_Net_Slist_Update;
NetTimeToMaster := gTime + NetMasterRate;
end;
// Ìàñòåðñåðâåð
if NetUseMaster then
begin
- if (NetMHost = nil) or (NetMPeer = nil) then
- begin
- // let the connection be blocking here, why not?
- g_Net_Slist_Connect();
- end;
+ if (not g_Net_Slist_IsConnectionActive) then g_Net_Slist_Connect(false); // non-blocking connection to the master
g_Net_Slist_Update;
end;
begin
NetUseMaster := StrToIntDef(P[1], Byte(NetUseMaster)) > 0;
if g_Game_IsServer and g_Game_IsNet then
+ begin
if NetUseMaster then
begin
- if NetMPeer = nil then g_Net_Slist_Connect();
+ if (not g_Net_Slist_IsConnectionActive) then g_Net_Slist_Connect(false); // non-blocking connection to the master
g_Net_Slist_Update();
end
else
- if NetMPeer <> nil then
- g_Net_Slist_Disconnect();
+ begin
+ if (not g_Net_Slist_IsConnectionActive) then g_Net_Slist_Disconnect();
+ end;
+ end;
end;
g_Console_Add(cmd + ' = ' + IntToStr(Byte(NetUseMaster)));
diff --git a/src/game/g_net.pas b/src/game/g_net.pas
index 391e09c520a6f6513ecfe6c52a9377c2009a4bc8..4deca1e4c2f65356a7a2ebfcb886a0480bfb9aef 100644 (file)
--- a/src/game/g_net.pas
+++ b/src/game/g_net.pas
NetPeer := nil;
NetHost := nil;
- NetMPeer := nil;
- NetMHost := nil;
+ g_Net_Slist_Disconnect(false); // do not spam console
NetMyID := -1;
NetPlrUID1 := -1;
NetPlrUID2 := -1;
end;
clearNetClients(false); // don't clear array
- if (NetMPeer <> nil) and (NetMHost <> nil) then g_Net_Slist_Disconnect;
+ if (g_Net_Slist_IsConnectionActive) then g_Net_Slist_Disconnect;
if NetPongSock <> ENET_SOCKET_NULL then
enet_socket_destroy(NetPongSock);
index 925b910241c91bcdda8a5a4e2f7e645441c7fe5a..01d5d67ce153aec648034a1e37a373b8ad178d31 100644 (file)
--- a/src/game/g_netmaster.pas
+++ b/src/game/g_netmaster.pas
TNetServerTable = array of TNetServerRow;
var
- NetMHost: pENetHost = nil;
- NetMPeer: pENetPeer = nil;
-
slCurrent: TNetServerList = nil;
slTable: TNetServerTable = nil;
slWaitStr: string = '';
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_Update (immediateSend: Boolean=true);
procedure g_Net_Slist_Remove();
function g_Net_Slist_Connect(blocking: Boolean=True): Boolean;
procedure g_Net_Slist_Check();
-procedure g_Net_Slist_Disconnect();
+procedure g_Net_Slist_Disconnect (spamConsole: Boolean=true);
procedure g_Net_Slist_WriteInfo();
+function g_Net_Slist_IsConnectionActive (): Boolean; // returns `false` if totally disconnected
+function g_Net_Slist_IsConnectionInProgress (): Boolean;
+
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);
wadreader;
var
- NetMEvent: ENetEvent;
- slSelection: Byte = 0;
- slFetched: Boolean = False;
- slDirPressed: Boolean = False;
- slReadUrgent: Boolean = False;
+ NetMHost: pENetHost = nil;
+ NetMPeer: pENetPeer = nil;
+ NetMEvent: ENetEvent;
+ slSelection: Byte = 0;
+ 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`
+ NetUpdatePending: Boolean = false;
-function GetTimerMS(): Int64;
+
+function GetTimerMS (): Int64;
begin
Result := GetTimer() {div 1000};
end;
+
+// returns `false` if totally disconnected
+function g_Net_Slist_IsConnectionActive (): Boolean;
+begin
+ result := (NetMHost <> nil) and (NetMPeer <> nil);
+end;
+
+
+function g_Net_Slist_IsConnectionInProgress (): Boolean;
+begin
+ if (NetMHost = nil) or (NetMPeer = nil) then begin result := false; exit; end;
+ result := (not NetHostConnected);
+end;
+
+
+// should be called only if host/peer is here
+// returns `false` if not connected/dead
+function ProcessPendingConnection (): Boolean;
+var
+ ct: Int64;
+begin
+ result := false;
+ if (NetMHost = nil) or (NetMPeer = nil) then exit;
+ // are we waiting for connection?
+ if (not NetHostConnected) then
+ begin
+ // check for connection event
+ if (enet_host_service(NetMHost, @NetMEvent, 0) > 0) then
+ begin
+ if (NetMEvent.kind = ENET_EVENT_TYPE_CONNECT) then
+ begin
+ NetHostConnected := true;
+ if NetUpdatePending then g_Net_Slist_Update(false);
+ g_Console_Add(_lc[I_NET_MSG]+_lc[I_NET_SLIST_CONN]);
+ result := true;
+ exit;
+ end;
+ if (NetMEvent.kind = ENET_EVENT_TYPE_RECEIVE) then enet_packet_destroy(NetMEvent.packet);
+ end;
+ // check for connection timeout
+ if (not NetHostConnected) then
+ begin
+ ct := GetTimerMS();
+ if (ct < NetHostConReqTime) or (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(false);
+ end;
+ exit;
+ end;
+ end;
+ result := true;
+end;
+
+
procedure PingServer(var S: TNetServer; Sock: ENetSocket);
var
Buf: ENetBuffer;
NetOut.Write(Byte(NetPassword <> ''));
end;
-procedure g_Net_Slist_Update;
+
+procedure g_Net_Slist_Update (immediateSend: Boolean=true);
var
P: pENetPacket;
- ct: Int64;
begin
- if (NetMHost = nil) or (NetMPeer = nil) then exit;
-
- // we are waiting for connection
- if (not NetHostConnected) then
+ if not ProcessPendingConnection() 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;
+ NetUpdatePending := g_Net_Slist_IsConnectionInProgress();
+ exit;
end;
+ NetUpdatePending := false;
+
NetOut.Clear();
NetOut.Write(Byte(NET_MMSG_UPD));
NetOut.Write(NetAddr.port);
P := enet_packet_create(NetOut.Data, NetOut.CurSize, Cardinal(ENET_PACKET_FLAG_RELIABLE));
enet_peer_send(NetMPeer, NET_MCHAN_UPD, P);
- enet_host_flush(NetMHost);
+ if (immediateSend) then enet_host_flush(NetMHost);
NetOut.Clear();
end;
var
P: pENetPacket;
begin
- if (NetMHost = nil) or (NetMPeer = nil) or (not NetHostConnected) then Exit;
+ if not ProcessPendingConnection() then exit;
+
NetOut.Clear();
NetOut.Write(Byte(NET_MMSG_DEL));
NetOut.Write(NetAddr.port);
delay: Integer;
begin
Result := False;
+
+ if g_Net_Slist_IsConnectionActive then
+ begin
+ if not blocking then exit;
+ g_Net_Slist_Disconnect(false);
+ end;
+
NetHostConnected := False; // just in case
NetHostConReqTime := 0; // just in case
+ NetUpdatePending := false;
NetMHost := enet_host_create(nil, 1, NET_MCHANS, 0, 0);
if (NetMHost = nil) then
NetMHost := nil;
NetHostConnected := False;
NetHostConReqTime := 0;
+ NetUpdatePending := false;
end
else
begin
end;
end;
-procedure g_Net_Slist_Disconnect;
+procedure g_Net_Slist_Disconnect (spamConsole: Boolean=true);
begin
if (NetMHost = nil) and (NetMPeer = nil) then Exit;
- if NetMode = NET_SERVER then g_Net_Slist_Remove;
+ if (NetMode = NET_SERVER) and (NetHostConnected) then g_Net_Slist_Remove;
enet_peer_disconnect(NetMPeer, 0);
enet_host_flush(NetMHost);
NetMHost := nil;
NetHostConnected := False;
NetHostConReqTime := 0;
+ NetUpdatePending := false;
- g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_SLIST_DISC]);
+ if (spamConsole) then 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) or (not NetHostConnected) then Exit;
+ if not ProcessPendingConnection() then exit;
+
+ if (NetUpdatePending) then g_Net_Slist_Update(false);
while (enet_host_service(NetMHost, @NetMEvent, 0) > 0) do
begin
NetMHost := nil;
NetHostConnected := False;
NetHostConReqTime := 0;
+ NetUpdatePending := false;
Break;
end
else