index ca7548344441114aa3f781aaf944813832536dad..ccaddfc87b2b29e1d2966f78d080aa30db6f7ed1 100644 (file)
-(* 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
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_fixedbuffer;
+uses sysutils, g_console;
-procedure g_Net_ClientMsgHandler(P: pENetPacket);
+// TODO: Unify this with g_Net_Host_HandlePacket() somehow? They're almost the same.
+procedure g_Net_Client_HandlePacket(P: pENetPacket; Handler: TNetClientMsgHandler);
var
- MID: Byte;
- B: Pointer;
+ MNext: Integer;
+ MSize: LongWord;
+ MHandled: Boolean = false;
+ NetMsg: TMsg;
+ Err: Boolean;
begin
- e_Raw_Seek(0);
-
- B := P^.data;
- if B = nil then Exit;
+ 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;
- MID := e_Raw_Read_Byte(B);
+ enet_packet_destroy(P);
+ //if Err
+ // then MC_MalformedPacket(S);
+end;
- case MID of
- NET_MSG_CHAT: MC_RECV_Chat(B);
- NET_MSG_GFX: MC_RECV_Effect(B);
- NET_MSG_SND: MC_RECV_Sound(B);
- NET_MSG_SCORE: MC_RECV_GameStats(B);
- NET_MSG_COOP: MC_RECV_CoopStats(B);
- NET_MSG_GEVENT: MC_RECV_GameEvent(B);
- NET_MSG_FLAG: MC_RECV_FlagEvent(B);
- NET_MSG_GSET: MC_RECV_GameSettings(B);
-
- NET_MSG_PLR: MC_RECV_PlayerCreate(B);
- NET_MSG_PLRPOS: MC_RECV_PlayerPos(B);
- NET_MSG_PLRSTA: MC_RECV_PlayerStats(B);
- NET_MSG_PLRDEL: MC_RECV_PlayerDelete(B);
- NET_MSG_PLRDMG: MC_RECV_PlayerDamage(B);
- NET_MSG_PLRDIE: MC_RECV_PlayerDeath(B);
- NET_MSG_PLRFIRE:MC_RECV_PlayerFire(B);
- NET_MSG_PLRSET: MC_RECV_PlayerSettings(B);
-
- NET_MSG_MSPAWN: MC_RECV_MonsterSpawn(B);
- NET_MSG_MPOS: MC_RECV_MonsterPos(B);
- NET_MSG_MSTATE: MC_RECV_MonsterState(B);
- NET_MSG_MSHOT: MC_RECV_MonsterShot(B);
- NET_MSG_MDEL: MC_RECV_MonsterDelete(B);
-
- NET_MSG_SHADD: MC_RECV_CreateShot(B);
- NET_MSG_SHPOS: MC_RECV_UpdateShot(B);
- NET_MSG_SHDEL: MC_RECV_DeleteShot(B);
-
- NET_MSG_ISPAWN: MC_RECV_ItemSpawn(B);
- NET_MSG_IDEL: MC_RECV_ItemDestroy(B);
-
- NET_MSG_PSTATE: MC_RECV_PanelState(B);
- NET_MSG_PTEX: MC_RECV_PanelTexture(B);
-
- NET_MSG_TSOUND: MC_RECV_TriggerSound(B);
- NET_MSG_TMUSIC: MC_RECV_TriggerMusic(B);
-
- NET_MSG_TIME_SYNC: MC_RECV_TimeSync(B);
- NET_MSG_VOTE_EVENT: MC_RECV_VoteEvent(B);
+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;
+
+ 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;
enet_packet_destroy(P);
+ if Err
+ then MH_MalformedPacket(S);
end;
-procedure g_Net_ClientLightMsgHandler(P: pENetPacket);
+
+function g_Net_ClientMsgHandler(NetMsg: TMsg): Boolean;
var
MID: Byte;
- B: Pointer;
+ Err: Boolean;
begin
- e_Raw_Seek(0);
-
- B := P^.data;
- if B = nil then Exit;
+ Result := True;
+ Err := False;
+ try
+ MID := NetMsg.ReadByte();
+ except
+ MID := 0;
+ Err := True;
+ end;
- MID := e_Raw_Read_Byte(B);
+ //if Err then begin MC_MalformedPacket(S); Exit; end;
case MID of
- NET_MSG_GEVENT: MC_RECV_GameEvent(B);
- NET_MSG_GSET: MC_RECV_GameSettings(B);
+ NET_MSG_CHAT: MC_RECV_Chat(NetMsg);
+ NET_MSG_GFX: MC_RECV_Effect(NetMsg);
+ NET_MSG_SND: MC_RECV_Sound(NetMsg);
+ NET_MSG_SCORE: MC_RECV_GameStats(NetMsg);
+ NET_MSG_COOP: MC_RECV_CoopStats(NetMsg);
+ 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);
+ NET_MSG_PLRSTA: MC_RECV_PlayerStats(NetMsg);
+ NET_MSG_PLRDEL: MC_RECV_PlayerDelete(NetMsg);
+ NET_MSG_PLRDMG: MC_RECV_PlayerDamage(NetMsg);
+ NET_MSG_PLRDIE: MC_RECV_PlayerDeath(NetMsg);
+ NET_MSG_PLRFIRE:MC_RECV_PlayerFire(NetMsg);
+ NET_MSG_PLRSET: MC_RECV_PlayerSettings(NetMsg);
+
+ NET_MSG_MSPAWN: MC_RECV_MonsterSpawn(NetMsg);
+ NET_MSG_MPOS: MC_RECV_MonsterPos(NetMsg);
+ NET_MSG_MSTATE: MC_RECV_MonsterState(NetMsg);
+ NET_MSG_MSHOT: MC_RECV_MonsterShot(NetMsg);
+ NET_MSG_MDEL: MC_RECV_MonsterDelete(NetMsg);
+
+ NET_MSG_SHADD: MC_RECV_CreateShot(NetMsg);
+ NET_MSG_SHPOS: MC_RECV_UpdateShot(NetMsg);
+ NET_MSG_SHDEL: MC_RECV_DeleteShot(NetMsg);
+
+ 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);
+
+ NET_MSG_TSOUND: MC_RECV_TriggerSound(NetMsg);
+ NET_MSG_TMUSIC: MC_RECV_TriggerMusic(NetMsg);
+
+ NET_MSG_TIME_SYNC: MC_RECV_TimeSync(NetMsg);
+ NET_MSG_VOTE_EVENT: MC_RECV_VoteEvent(NetMsg);
+
+ else
+ begin
+ Result := False;
+ g_Console_Add('unknown message ID: ' + IntToStr(MID));
+ end;
+ end;
+end;
- NET_MSG_PLR: if NetState <> NET_STATE_AUTH then MC_RECV_PlayerCreate(B);
- NET_MSG_PLRDEL: if NetState <> NET_STATE_AUTH then MC_RECV_PlayerDelete(B);
+function g_Net_ClientLightMsgHandler(NetMsg: TMsg): Boolean;
+var
+ MID: Byte;
+ Err: Boolean;
+begin
+ Result := True;
+ Err := False;
+ try
+ MID := NetMsg.ReadByte();
+ except
+ MID := 0;
+ Err := True;
end;
- enet_packet_destroy(P);
+ //if Err then begin MC_MalformedPacket(S); Exit; end;
+
+ case MID of
+ NET_MSG_GEVENT: MC_RECV_GameEvent(NetMsg);
+ NET_MSG_GSET: MC_RECV_GameSettings(NetMsg);
+
+ 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);
+
+ 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;
- B: Pointer;
+ Err: Boolean;
begin
- e_Raw_Seek(0);
-
- B := P^.data;
- if B = nil then Exit;
+ Result := True;
+ Err := False;
+ try
+ MID := NetMsg.ReadByte();
+ except
+ MID := 0;
+ Err := True;
+ end;
- MID := e_Raw_Read_Byte(B);
+ if Err then begin MH_MalformedPacket(S); Exit; end;
case MID of
- NET_MSG_INFO: MH_RECV_Info(S, B);
- NET_MSG_CHAT: MH_RECV_Chat(S, B);
- NET_MSG_REQFST: MH_RECV_FullStateRequest(S, B);
+ NET_MSG_INFO: MH_RECV_Info(S, NetMsg);
+ NET_MSG_CHAT: MH_RECV_Chat(S, NetMsg);
+ NET_MSG_REQFST: MH_RECV_FullStateRequest(S, NetMsg);
- NET_MSG_PLRPOS: MH_RECV_PlayerPos(S, B);
- NET_MSG_PLRSET: MH_RECV_PlayerSettings(S, B);
- NET_MSG_CHEAT: MH_RECV_CheatRequest(S, B);
+ NET_MSG_PLRPOS: MH_RECV_PlayerPos(S, NetMsg);
+ NET_MSG_PLRSET: MH_RECV_PlayerSettings(S, NetMsg);
+ NET_MSG_CHEAT: MH_RECV_CheatRequest(S, NetMsg);
- NET_MSG_RCON_AUTH: MH_RECV_RCONPassword(S, B);
- NET_MSG_RCON_CMD: MH_RECV_RCONCommand(S, B);
+ 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, B);
- NET_MSG_RES_REQUEST: MH_RECV_ResRequest(S, B);
+ //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, B);
+ NET_MSG_VOTE_EVENT: MH_RECV_Vote(S, NetMsg);
end;
-
- enet_packet_destroy(P);
end;
end.