DEADSOFTWARE

game: fix screenshot size
[d2df-sdl.git] / src / game / g_nethandler.pas
index 78221ab00b9b1780efe8014d84f580cdf047226f..4dc52a395c6152a05cd3c8cbc2581831b1ead811 100644 (file)
@@ -1,9 +1,8 @@
-(* Copyright (C)  DooM 2D:Forever Developers
+(* Copyright (C)  Doom 2D: Forever Developers
  *
  * 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
@@ -18,25 +17,103 @@ unit g_nethandler;
 
 interface
 
-uses g_net, g_netmsg, ENet;
+uses e_msg, g_net, g_netmsg, ENet;
 
-procedure g_Net_ClientMsgHandler(P: pENetPacket);
-procedure g_Net_ClientLightMsgHandler(P: pENetPacket);
-procedure g_Net_HostMsgHandler(S: pTNetClient; P: pENetPacket);
+type
+  TNetClientMsgHandler = function (M: TMsg): Boolean;
+  TNetHostMsgHandler = function (S: pTNetClient; M: TMsg): Boolean;
+
+procedure g_Net_Client_HandlePacket(P: pENetPacket; Handler: TNetClientMsgHandler);
+procedure g_Net_Host_HandlePacket(S: pTNetClient; P: pENetPacket; Handler: TNetHostMsgHandler);
+
+function g_Net_ClientMsgHandler(NetMsg: TMsg): Boolean;
+function g_Net_ClientLightMsgHandler(NetMsg: TMsg): Boolean;
+function g_Net_HostMsgHandler(S: pTNetClient; NetMsg: TMsg): Boolean;
 
 implementation
 
-uses e_msg;
+uses sysutils, g_console;
 
-procedure g_Net_ClientMsgHandler(P: pENetPacket);
+procedure g_Net_Client_HandlePacket(P: pENetPacket; Handler: TNetClientMsgHandler);
 var
-  MID: Byte;
+  MNext: Integer;
+  MSize: LongWord;
+  MHandled: Boolean = false;
+  NetMsg: TMsg;
+  Err: Boolean;
+begin
+  if not NetMsg.Init(P^.data, P^.dataLength, True) then
+    Exit;
+
+  Err := False;
+  MNext := 0;
+
+  while (NetMsg.BytesLeft() > 0) and (not Err) do
+  begin
+    try
+      MSize := NetMsg.ReadLongWord();
+      MNext := NetMsg.ReadCount + MSize;
+      MHandled := Handler(NetMsg); // TODO: maybe do something with this bool
+      NetMsg.Seek(MNext);
+    except
+      Err := True;
+    end;
+  end;
+
+  MHandled := not MHandled; //k8: stfu, fpc!
+
+  enet_packet_destroy(P);
+  //if Err then begin MC_MalformedPacket(S); Exit; end;
+end;
+
+procedure g_Net_Host_HandlePacket(S: pTNetClient; P: pENetPacket; Handler: TNetHostMsgHandler);
+var
+  MNext: Integer;
+  MSize: LongWord;
+  MHandled: Boolean = false;
   NetMsg: TMsg;
+  Err: Boolean;
 begin
   if not NetMsg.Init(P^.data, P^.dataLength, True) then
     Exit;
 
-  MID := NetMsg.ReadByte();
+  Err := False;
+  MNext := 0;
+
+  while (NetMsg.BytesLeft() > 0) and (not Err) do
+  begin
+    try
+      MSize := NetMsg.ReadLongWord();
+      MNext := NetMsg.ReadCount + MSize;
+      MHandled := Handler(S, NetMsg); // TODO: maybe do something with this bool
+      NetMsg.Seek(MNext);
+    except
+      Err := True;
+    end;
+  end;
+
+  MHandled := not MHandled; //k8: stfu, fpc!
+
+  enet_packet_destroy(P);
+  if Err then begin MH_MalformedPacket(S); Exit; end;
+end;
+
+
+function g_Net_ClientMsgHandler(NetMsg: TMsg): Boolean;
+var
+  MID: Byte;
+  Err: Boolean;
+begin
+  Result := True;
+  Err := False;
+  try
+    MID := NetMsg.ReadByte();
+  except
+    MID := 0;
+    Err := True;
+  end;
+
+  //if Err then begin MC_MalformedPacket(S); Exit; end;
 
   case MID of
     NET_MSG_CHAT:   MC_RECV_Chat(NetMsg);
@@ -47,6 +124,7 @@ begin
     NET_MSG_GEVENT: MC_RECV_GameEvent(NetMsg);
     NET_MSG_FLAG:   MC_RECV_FlagEvent(NetMsg);
     NET_MSG_GSET:   MC_RECV_GameSettings(NetMsg);
+    NET_MSG_FLAGPOS:MC_RECV_FlagPos(NetMsg);
 
     NET_MSG_PLR:    MC_RECV_PlayerCreate(NetMsg);
     NET_MSG_PLRPOS: MC_RECV_PlayerPos(NetMsg);
@@ -69,6 +147,7 @@ begin
 
     NET_MSG_ISPAWN: MC_RECV_ItemSpawn(NetMsg);
     NET_MSG_IDEL:   MC_RECV_ItemDestroy(NetMsg);
+    NET_MSG_IPOS:   MC_RECV_ItemPos(NetMsg);
 
     NET_MSG_PSTATE: MC_RECV_PanelState(NetMsg);
     NET_MSG_PTEX:   MC_RECV_PanelTexture(NetMsg);
@@ -78,20 +157,30 @@ begin
 
     NET_MSG_TIME_SYNC:  MC_RECV_TimeSync(NetMsg);
     NET_MSG_VOTE_EVENT: MC_RECV_VoteEvent(NetMsg);
-  end;
 
-  enet_packet_destroy(P);
+    else
+    begin
+      Result := False;
+      g_Console_Add('unknown message ID: ' + IntToStr(MID));
+    end;
+  end;
 end;
 
-procedure g_Net_ClientLightMsgHandler(P: pENetPacket);
+function g_Net_ClientLightMsgHandler(NetMsg: TMsg): Boolean;
 var
   MID: Byte;
-  NetMsg: TMsg;
+  Err: Boolean;
 begin
-  if not NetMsg.Init(P^.data, P^.dataLength, True) then
-    Exit;
+  Result := True;
+  Err := False;
+  try
+    MID := NetMsg.ReadByte();
+  except
+    MID := 0;
+    Err := True;
+  end;
 
-  MID := NetMsg.ReadByte();
+  //if Err then begin MC_MalformedPacket(S); Exit; end;
 
   case MID of
     NET_MSG_GEVENT: MC_RECV_GameEvent(NetMsg);
@@ -99,20 +188,26 @@ begin
 
     NET_MSG_PLR:    if NetState <> NET_STATE_AUTH then MC_RECV_PlayerCreate(NetMsg);
     NET_MSG_PLRDEL: if NetState <> NET_STATE_AUTH then MC_RECV_PlayerDelete(NetMsg);
-  end;
 
-  enet_packet_destroy(P);
+    else Result := False;
+  end;
 end;
 
-procedure g_Net_HostMsgHandler(S: pTNetClient; P: pENetPacket);
+function g_Net_HostMsgHandler(S: pTNetClient; NetMsg: TMsg): Boolean;
 var
   MID: Byte;
-  NetMsg: TMsg;
+  Err: Boolean;
 begin
-  if not NetMsg.Init(P^.data, P^.dataLength, True) then
-    Exit;
+  Result := True;
+  Err := False;
+  try
+    MID := NetMsg.ReadByte();
+  except
+    MID := 0;
+    Err := True;
+  end;
 
-  MID := NetMsg.ReadByte();
+  if Err then begin MH_MalformedPacket(S); Exit; end;
 
   case MID of
     NET_MSG_INFO: MH_RECV_Info(S, NetMsg);
@@ -126,13 +221,11 @@ begin
     NET_MSG_RCON_AUTH: MH_RECV_RCONPassword(S, NetMsg);
     NET_MSG_RCON_CMD:  MH_RECV_RCONCommand(S, NetMsg);
 
-    NET_MSG_MAP_REQUEST: MH_RECV_MapRequest(S, NetMsg);
-    NET_MSG_RES_REQUEST: MH_RECV_ResRequest(S, NetMsg);
+    //NET_MSG_MAP_REQUEST: MH_RECV_MapRequest(S, NetMsg);
+    //NET_MSG_RES_REQUEST: MH_RECV_ResRequest(S, NetMsg);
 
     NET_MSG_VOTE_EVENT: MH_RECV_Vote(S, NetMsg);
   end;
-
-  enet_packet_destroy(P);
 end;
 
 end.