DEADSOFTWARE

Make autoswitch server-side. Add option to skip empty weapons by travi$
[d2df-sdl.git] / src / game / g_net.pas
index 95686fe911a14e226c33f234963369657a6954b1..edd6024a49af09237130e98d105a0d3d0948efb9 100644 (file)
@@ -21,7 +21,7 @@ uses
   e_log, e_msg, utils, ENet, Classes, md5, MAPDEF{$IFDEF USE_MINIUPNPC}, miniupnpc;{$ELSE};{$ENDIF}
 
 const
-  NET_PROTOCOL_VER = 187;
+  NET_PROTOCOL_VER = 188;
 
   NET_MAXCLIENTS = 24;
   NET_CHANS = 12;
@@ -161,8 +161,8 @@ var
   NetAutoBanPerm:  Boolean = True;
   NetAutoBanWarn:  Boolean = False;
 
-  NetAuthTimeout:   Integer = 36 * 15;
-  NetPacketTimeout: Integer = 36 * 30;
+  NetAuthTimeout:   Integer = 15 * 1000;
+  NetPacketTimeout: Integer = 30 * 1000;
 
   NetState:      Integer = NET_STATE_NONE;
 
@@ -345,7 +345,6 @@ begin
             e_KeyPressed(JOY3_JUMP)
 end;
 
-
 //**************************************************************************
 //
 // file transfer declaraions and host packet processor
@@ -1671,7 +1670,6 @@ procedure g_Net_Host_CheckTimeouts();
 var
   ID: Integer;
 begin
-  // auth timeout
   for ID := Low(NetClients) to High(NetClients) do
   begin
     with NetClients[ID] do
@@ -1680,17 +1678,63 @@ begin
       if (State = NET_STATE_AUTH) and (AuthTime > 0) and (AuthTime <= gTime) then
       begin
         g_Net_Penalize(@NetClients[ID], 'auth taking too long');
-        AuthTime := gTime + 18; // do it twice a second to give them a chance
+        AuthTime := gTime + 500; // do it twice a second to give them a chance
       end
       else if (State = NET_STATE_GAME) and (MsgTime > 0) and (MsgTime <= gTime) then
       begin
         g_Net_Penalize(@NetClients[ID], 'message timeout');
-        AuthTime := gTime + 18; // do it twice a second to give them a chance
+        AuthTime := gTime + 500; // do it twice a second to give them a chance
       end;
     end;
   end;
+end;
+
+procedure g_Net_Host_Disconnect_Client(ID: Integer; Force: Boolean = False);
+var
+  TP: TPlayer;
+  TC: pTNetClient;
+begin
+  TC := @NetClients[ID];
+  if (TC = nil) then Exit;
+  clearNetClient(NetClients[ID]);
+  if not (TC^.Used) then Exit;
 
+  TP := g_Player_Get(TC^.Player);
+
+  if TP <> nil then
+  begin
+    TP.Lives := 0;
+    TP.Kill(K_SIMPLEKILL, 0, HIT_DISCON);
+    g_Console_Add(Format(_lc[I_PLAYER_LEAVE], [TP.Name]), True);
+    e_WriteLog('NET: Client ' + TP.Name + ' [' + IntToStr(TC^.ID) + '] disconnected.', TMsgType.Notify);
+    g_Player_Remove(TP.UID);
+  end;
+
+  if (TC^.Peer^.data <> nil) then
+  begin
+    FreeMemory(TC^.Peer^.data);
+    TC^.Peer^.data := nil;
+  end;
 
+  if (Force) then
+    enet_peer_reset(TC^.Peer);
+
+  TC^.Used := False;
+  TC^.State := NET_STATE_NONE;
+  TC^.Peer := nil;
+  TC^.Player := 0;
+  TC^.Crimes := 0;
+  TC^.AuthTime := 0;
+  TC^.MsgTime := 0;
+  TC^.RequestedFullUpdate := False;
+  TC^.WaitForFirstSpawn := False;
+  TC^.NetOut[NET_UNRELIABLE].Free();
+  TC^.NetOut[NET_RELIABLE].Free();
+
+  g_Console_Add(_lc[I_NET_MSG] + Format(_lc[I_NET_MSG_HOST_DISC], [ID]));
+  Dec(NetClientCount);
+
+  if NetUseMaster then g_Net_Slist_ServerPlayerLeaves();
 end;
 
 
@@ -1700,7 +1744,6 @@ var
   Port: Word;
   ID: Integer;
   TC: pTNetClient;
-  TP: TPlayer;
 begin
   IP := '';
   Result := 0;
@@ -1811,41 +1854,7 @@ begin
       begin
         ID := Byte(NetEvent.peer^.data^);
         if ID > High(NetClients) then Exit;
-        clearNetClient(NetClients[ID]);
-        TC := @NetClients[ID];
-        if TC = nil then Exit;
-
-        if not (TC^.Used) then Exit;
-
-        TP := g_Player_Get(TC^.Player);
-
-        if TP <> nil then
-        begin
-          TP.Lives := 0;
-          TP.Kill(K_SIMPLEKILL, 0, HIT_DISCON);
-          g_Console_Add(Format(_lc[I_PLAYER_LEAVE], [TP.Name]), True);
-          e_WriteLog('NET: Client ' + TP.Name + ' [' + IntToStr(ID) + '] disconnected.', TMsgType.Notify);
-          g_Player_Remove(TP.UID);
-        end;
-
-        TC^.Used := False;
-        TC^.State := NET_STATE_NONE;
-        TC^.Peer := nil;
-        TC^.Player := 0;
-        TC^.Crimes := 0;
-        TC^.AuthTime := 0;
-        TC^.MsgTime := 0;
-        TC^.RequestedFullUpdate := False;
-        TC^.WaitForFirstSpawn := False;
-        TC^.NetOut[NET_UNRELIABLE].Free();
-        TC^.NetOut[NET_RELIABLE].Free();
-
-        FreeMemory(NetEvent.peer^.data);
-        NetEvent.peer^.data := nil;
-        g_Console_Add(_lc[I_NET_MSG] + Format(_lc[I_NET_MSG_HOST_DISC], [ID]));
-        Dec(NetClientCount);
-
-        if NetUseMaster then g_Net_Slist_ServerPlayerLeaves();
+        g_Net_Host_Disconnect_Client(ID);
       end;
     end;
   end;
@@ -2288,10 +2297,19 @@ var
   s: string;
 begin
   e_LogWritefln('NET: client #%u (cid #%u) triggered a penalty (%d/%d): %s',
-    [C^.ID, C^.Player, C^.Crimes, NetAutoBanLimit, Reason]);
+    [C^.ID, C^.Player, C^.Crimes + 1, NetAutoBanLimit, Reason]);
 
   if (NetAutoBanLimit <= 0) then Exit;
 
+  if (C^.Crimes >= NetAutoBanLimit) then
+  begin
+    // we have tried asking nicely before, now it is time to die
+    e_LogWritefln('NET: client #%u (cid #%u) force kicked',
+      [C^.ID, C^.Player]);
+    g_Net_Host_Disconnect_Client(C^.ID, True);
+    Exit;
+  end;
+
   Inc(C^.Crimes);
 
   if (NetAutoBanWarn) then
@@ -2565,8 +2583,8 @@ initialization
   conRegVar('sv_autoban_permanent', @NetAutoBanPerm, '', 'whether autobans are permanent');
   conRegVar('sv_autoban_warn', @NetAutoBanWarn, '', 'send warnings to the client when he triggers penalties');
 
-  conRegVar('sv_auth_timeout', @NetAuthTimeout, '', 'number of frames in which connecting clients must complete auth (0 = unlimited)');
-  conRegVar('sv_packet_timeout', @NetPacketTimeout, '', 'number of frames the client must idle to be kicked (0 = unlimited)');
+  conRegVar('sv_auth_timeout', @NetAuthTimeout, '', 'number of msec in which connecting clients must complete auth (0 = unlimited)');
+  conRegVar('sv_packet_timeout', @NetPacketTimeout, '', 'number of msec the client must idle to be kicked (0 = unlimited)');
 
   conRegVar('net_master_list', @NetMasterList, '', 'list of master servers');