DEADSOFTWARE

replaced e_fixedbuffer with e_msg
authorfgsfds <pvt.fgsfds@gmail.com>
Sun, 20 Aug 2017 01:44:59 +0000 (04:44 +0300)
committerfgsfds <pvt.fgsfds@gmail.com>
Sun, 20 Aug 2017 01:44:59 +0000 (04:44 +0300)
src/engine/e_fixedbuffer.pas [deleted file]
src/engine/e_msg.pas [new file with mode: 0644]
src/game/Doom2DF.dpr
src/game/g_game.pas
src/game/g_net.pas
src/game/g_nethandler.pas
src/game/g_netmaster.pas
src/game/g_netmsg.pas

diff --git a/src/engine/e_fixedbuffer.pas b/src/engine/e_fixedbuffer.pas
deleted file mode 100644 (file)
index 5b80d7f..0000000
+++ /dev/null
@@ -1,322 +0,0 @@
-(* 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *)
-{$INCLUDE ../shared/a_modes.inc}
-unit e_fixedbuffer;
-
-interface
-
-uses md5;
-
-const
-  BUF_SIZE = 65536;
-
-type
-  TBuffer = record
-    Data: array [0..BUF_SIZE] of Byte; // îäèí áàéò ñâåðõó íà âñÿêèé ñëó÷àé
-    ReadPos: Cardinal;
-    WritePos: Cardinal;
-    Len: Cardinal;
-  end;
-  pTBuffer = ^TBuffer;
-
-var
-  RawPos: Cardinal = 0;
-
-procedure e_Buffer_Clear(B: pTBuffer);
-
-
-procedure e_Buffer_Write_Generic(B: pTBuffer; var V; N: Cardinal);
-procedure e_Buffer_Read_Generic(B: pTBuffer; var V; N: Cardinal);
-
-
-procedure e_Buffer_Write(B: pTBuffer; V: Char); overload;
-
-procedure e_Buffer_Write(B: pTBuffer; V: Byte); overload;
-procedure e_Buffer_Write(B: pTBuffer; V: Word); overload;
-procedure e_Buffer_Write(B: pTBuffer; V: LongWord); overload;
-
-procedure e_Buffer_Write(B: pTBuffer; V: ShortInt); overload;
-procedure e_Buffer_Write(B: pTBuffer; V: SmallInt); overload;
-procedure e_Buffer_Write(B: pTBuffer; V: LongInt); overload;
-procedure e_Buffer_Write(B: pTBuffer; V: Int64); overload;
-
-procedure e_Buffer_Write(B: pTBuffer; V: string); overload;
-
-procedure e_Buffer_Write(B: pTBuffer; V: TMD5Digest); overload;
-
-
-function  e_Buffer_Read_Char(B: pTBuffer): Char;
-
-function  e_Buffer_Read_Byte(B: pTBuffer): Byte;
-function  e_Buffer_Read_Word(B: pTBuffer): Word;
-function  e_Buffer_Read_LongWord(B: pTBuffer): LongWord;
-
-function  e_Buffer_Read_ShortInt(B: pTBuffer): ShortInt;
-function  e_Buffer_Read_SmallInt(B: pTBuffer): SmallInt;
-function  e_Buffer_Read_LongInt(B: pTBuffer): LongInt;
-function  e_Buffer_Read_Int64(B: pTBuffer): Int64;
-
-function  e_Buffer_Read_String(B: pTBuffer): string;
-
-function  e_Buffer_Read_MD5(B: pTBuffer): TMD5Digest;
-
-
-procedure e_Raw_Read_Generic(P: Pointer; var V; N: Cardinal);
-
-function  e_Raw_Read_Char(P: Pointer): Char;
-
-function  e_Raw_Read_Byte(P: Pointer): Byte;
-function  e_Raw_Read_Word(P: Pointer): Word;
-function  e_Raw_Read_LongWord(P: Pointer): LongWord;
-
-function  e_Raw_Read_ShortInt(P: Pointer): ShortInt;
-function  e_Raw_Read_SmallInt(P: Pointer): SmallInt;
-function  e_Raw_Read_LongInt(P: Pointer): LongInt;
-
-function  e_Raw_Read_String(P: Pointer): string;
-
-function  e_Raw_Read_MD5(P: Pointer): TMD5Digest;
-
-procedure e_Raw_Seek(I: Cardinal);
-
-implementation
-
-uses SysUtils, BinEditor;
-
-procedure e_Buffer_Clear(B: pTBuffer);
-begin
-  B^.WritePos := 0;
-  B^.ReadPos := 0;
-  B^.Len := 0;
-end;
-
-
-procedure e_Buffer_Write_Generic(B: pTBuffer; var V; N: Cardinal);
-begin
-  if (B^.WritePos + N >= BUF_SIZE) then Exit;
-  if (B^.WritePos + N > B^.Len) then
-    B^.Len := B^.WritePos + N + 1;
-
-  CopyMemory(Pointer(NativeUInt(Addr(B^.Data)) + B^.WritePos),
-             @V, N);
-
-  B^.WritePos := B^.WritePos + N;
-end;
-procedure e_Buffer_Read_Generic(B: pTBuffer; var V; N: Cardinal);
-begin
-  if (B^.ReadPos + N >= BUF_SIZE) then Exit;
-
-  CopyMemory(@V, Pointer(NativeUInt(Addr(B^.Data)) + B^.ReadPos), N);
-
-  B^.ReadPos := B^.ReadPos + N;
-end;
-
-
-procedure e_Buffer_Write(B: pTBuffer; V: Char); overload;
-begin
-  e_Buffer_Write_Generic(B, V, 1);
-end;
-
-procedure e_Buffer_Write(B: pTBuffer; V: Byte); overload;
-begin
-  e_Buffer_Write_Generic(B, V, 1);
-end;
-procedure e_Buffer_Write(B: pTBuffer; V: Word); overload;
-begin
-  e_Buffer_Write_Generic(B, V, 2);
-end;
-procedure e_Buffer_Write(B: pTBuffer; V: LongWord); overload;
-begin
-  e_Buffer_Write_Generic(B, V, 4);
-end;
-
-procedure e_Buffer_Write(B: pTBuffer; V: ShortInt); overload;
-begin
-  e_Buffer_Write_Generic(B, V, 1);
-end;
-procedure e_Buffer_Write(B: pTBuffer; V: SmallInt); overload;
-begin
-  e_Buffer_Write_Generic(B, V, 2);
-end;
-procedure e_Buffer_Write(B: pTBuffer; V: LongInt); overload;
-begin
-  e_Buffer_Write_Generic(B, V, 4);
-end;
-procedure e_Buffer_Write(B: pTBuffer; V: Int64); overload;
-begin
-  e_Buffer_Write_Generic(B, V, 8);
-end;
-
-procedure e_Buffer_Write(B: pTBuffer; V: string); overload;
-var
-  Len: Byte;
-  P: Cardinal;
-begin
-  Len := Length(V);
-  e_Buffer_Write_Generic(B, Len, 1);
-
-  if (Len = 0) then Exit;
-
-  P := B^.WritePos + Len;
-  if (P >= BUF_SIZE) then
-  begin
-    Len := BUF_SIZE - B^.WritePos;
-    P := BUF_SIZE;
-  end;
-
-  if (P > B^.Len) then B^.Len := P;
-
-  CopyMemory(Pointer(NativeUInt(Addr(B^.Data)) + B^.WritePos),
-             @V[1], Len);
-
-  B^.WritePos := P;
-end;
-
-procedure e_Buffer_Write(B: pTBuffer; V: TMD5Digest); overload;
-var
-  I: Integer;
-begin
-  for I := 0 to 15 do
-    e_Buffer_Write(B, V[I]);
-end;
-
-
-function e_Buffer_Read_Char(B: pTBuffer): Char;
-begin
-  e_Buffer_Read_Generic(B, Result, 1);
-end;
-
-function e_Buffer_Read_Byte(B: pTBuffer): Byte;
-begin
-  e_Buffer_Read_Generic(B, Result, 1);
-end;
-function e_Buffer_Read_Word(B: pTBuffer): Word;
-begin
-  e_Buffer_Read_Generic(B, Result, 2);
-end;
-function e_Buffer_Read_LongWord(B: pTBuffer): LongWord;
-begin
-  e_Buffer_Read_Generic(B, Result, 4);
-end;
-
-function e_Buffer_Read_ShortInt(B: pTBuffer): ShortInt;
-begin
-  e_Buffer_Read_Generic(B, Result, 1);
-end;
-function e_Buffer_Read_SmallInt(B: pTBuffer): SmallInt;
-begin
-  e_Buffer_Read_Generic(B, Result, 2);
-end;
-function e_Buffer_Read_LongInt(B: pTBuffer): LongInt;
-begin
-  e_Buffer_Read_Generic(B, Result, 4);
-end;
-function e_Buffer_Read_Int64(B: pTBuffer): Int64;
-begin
-  e_Buffer_Read_Generic(B, Result, 8);
-end;
-
-function e_Buffer_Read_String(B: pTBuffer): string;
-var
-  Len: Byte;
-begin
-  Len := e_Buffer_Read_Byte(B);
-  Result := '';
-  if Len = 0 then Exit;
-
-  if B^.ReadPos + Len > B^.Len then
-    Len := B^.Len - B^.ReadPos;
-
-  SetLength(Result, Len);
-  CopyMemory(@Result[1], Pointer(NativeUInt(Addr(B^.Data)) + B^.ReadPos), Len);
-
-  B^.ReadPos := B^.ReadPos + Len;
-end;
-
-function e_Buffer_Read_MD5(B: pTBuffer): TMD5Digest;
-var
-  I: Integer;
-begin
-  for I := 0 to 15 do
-    Result[I] := e_Buffer_Read_Byte(B);
-end;
-
-procedure e_Raw_Read_Generic(P: Pointer; var V; N: Cardinal);
-begin
-  CopyMemory(@V, Pointer(NativeUInt(P) + RawPos), N);
-
-  RawPos := RawPos + N;
-end;
-
-function e_Raw_Read_Char(P: Pointer): Char;
-begin
-  e_Raw_Read_Generic(P, Result, 1);
-end;
-
-function e_Raw_Read_Byte(P: Pointer): Byte;
-begin
-  e_Raw_Read_Generic(P, Result, 1);
-end;
-function e_Raw_Read_Word(P: Pointer): Word;
-begin
-  e_Raw_Read_Generic(P, Result, 2);
-end;
-function e_Raw_Read_LongWord(P: Pointer): LongWord;
-begin
-  e_Raw_Read_Generic(P, Result, 4);
-end;
-
-function e_Raw_Read_ShortInt(P: Pointer): ShortInt;
-begin
-  e_Raw_Read_Generic(P, Result, 1);
-end;
-function e_Raw_Read_SmallInt(P: Pointer): SmallInt;
-begin
-  e_Raw_Read_Generic(P, Result, 2);
-end;
-function e_Raw_Read_LongInt(P: Pointer): LongInt;
-begin
-  e_Raw_Read_Generic(P, Result, 4);
-end;
-
-function e_Raw_Read_String(P: Pointer): string;
-var
-  Len: Byte;
-begin
-  Len := e_Raw_Read_Byte(P);
-  Result := '';
-  if Len = 0 then Exit;
-
-  SetLength(Result, Len);
-  CopyMemory(@Result[1], Pointer(NativeUInt(P) + RawPos), Len);
-
-  RawPos := RawPos + Len;
-end;
-
-function e_Raw_Read_MD5(P: Pointer): TMD5Digest;
-var
-  I: Integer;
-begin
-  for I := 0 to 15 do
-    Result[I] := e_Raw_Read_Byte(P);
-end;
-
-procedure e_Raw_Seek(I: Cardinal);
-begin
-  RawPos := I;
-end;
-
-end.
diff --git a/src/engine/e_msg.pas b/src/engine/e_msg.pas
new file mode 100644 (file)
index 0000000..04efb5d
--- /dev/null
@@ -0,0 +1,296 @@
+(* 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *)
+{$INCLUDE ../shared/a_modes.inc}
+unit e_msg;
+
+interface
+
+uses md5;
+
+type
+  TMsg = record
+    Data: Pointer;
+    Overflow: Boolean;
+    MaxSize: Integer;
+    CurSize: Integer;
+    ReadCount: Integer;
+    Bit: Integer;
+    OwnMemory: Boolean;
+
+    function Init(V: Pointer; N: Integer; Full: Boolean = False): Boolean;
+    procedure Alloc(N: Integer);
+    procedure Clear();
+    procedure Free();
+    procedure CopyFrom(var From: TMsg; V: Pointer; N: Integer);
+    function Allocated(): Boolean;
+    function AssignBuffer(P: Pointer; N: Integer; Full: Boolean = False): Boolean;
+
+    procedure BeginReading();
+    function ReadData(V: Pointer; N: Integer): Integer;
+    function ReadChar(): Char;
+    function ReadByte(): Byte;
+    function ReadWord(): Word;
+    function ReadLongWord(): LongWord;
+    function ReadShortInt(): ShortInt;
+    function ReadSmallInt(): SmallInt;
+    function ReadLongInt(): LongInt;
+    function ReadInt64(): Int64;
+    function ReadString(): String;
+    function ReadMD5(): TMD5Digest;
+
+    procedure WriteData(V: Pointer; N: Integer);
+    procedure Write(V: Byte); overload;
+    procedure Write(V: Word); overload;
+    procedure Write(V: LongWord); overload;
+    procedure Write(V: ShortInt); overload;
+    procedure Write(V: SmallInt); overload;
+    procedure Write(V: LongInt); overload;
+    procedure Write(V: Int64); overload;
+    procedure Write(V: String); overload;
+    procedure Write(V: TMD5Digest); overload;
+  end;
+
+type
+  pTMsg = ^TMsg;
+
+implementation
+
+uses SysUtils, e_log;
+
+function TMsg.Init(V: Pointer; N: Integer; Full: Boolean = False): Boolean;
+begin
+  Overflow := False;
+  if Full then CurSize := N else CurSize := 0;
+  ReadCount := 0;
+  Bit := 0;
+  MaxSize := N;
+  Data := V;
+  OwnMemory := False;
+  Result := (N > 0) and (V <> nil);
+end;
+
+procedure TMsg.Alloc(N: Integer);
+var
+  P: Pointer;
+begin
+  P := GetMem(N);
+  if P = nil then
+    raise Exception.Create('TMsg.Alloc: no mem');
+  Init(P, N);
+  OwnMemory := True;
+end;
+
+procedure TMsg.Free();
+begin
+  if not OwnMemory then
+    raise Exception.Create('TMsg.Free: called on borrowed memory');
+  OwnMemory := False;
+  FreeMem(Data);
+  Data := nil;
+  MaxSize := 0;
+end;
+
+procedure TMsg.Clear();
+begin
+  CurSize := 0;
+  ReadCount := 0;
+  Overflow := False;
+  Bit := 0;
+end;
+
+function TMsg.Allocated(): Boolean;
+begin
+  Result := OwnMemory;
+end;
+
+procedure TMsg.CopyFrom(var From: TMsg; V: Pointer; N: Integer);
+begin
+  if N < From.CurSize then
+    raise Exception.Create('TMsg.Copy: can''t copy into a smaller TMsg');
+  Move(From, Self, SizeOf(TMsg));
+  Data := V;
+  Move(From.Data^, Data^, From.CurSize);
+end;
+
+function TMsg.AssignBuffer(P: Pointer; N: Integer; Full: Boolean = False): Boolean;
+begin
+  if OwnMemory then Self.Free();
+  Clear();
+  Data := P;
+  MaxSize := N;
+  if Full then CurSize := N;
+  Result := (N > 0) and (P <> nil);
+end;
+
+procedure TMsg.WriteData(V: Pointer; N: Integer);
+begin
+  if CurSize + N > MaxSize then
+  begin
+    Overflow := True;
+    raise Exception.Create('TMsg.WriteData: buffer overrun!');
+    Exit;
+  end;
+  Move(V^, (Data + CurSize)^, N);
+  CurSize := CurSize + N;
+end;
+
+procedure TMsg.Write(V: Byte); overload;
+begin
+  WriteData(@V, 1);
+end;
+
+procedure TMsg.Write(V: Word); overload;
+begin
+  WriteData(@V, 2);
+end;
+
+procedure TMsg.Write(V: LongWord); overload;
+begin
+  WriteData(@V, 4);
+end;
+
+procedure TMsg.Write(V: ShortInt); overload;
+begin
+  WriteData(@V, 2);
+end;
+
+procedure TMsg.Write(V: SmallInt); overload;
+begin
+  WriteData(@V, 1);
+end;
+
+procedure TMsg.Write(V: LongInt); overload;
+begin
+  WriteData(@V, 4);
+end;
+
+procedure TMsg.Write(V: Int64); overload;
+begin
+  WriteData(@V, 8);
+end;
+
+procedure TMsg.Write(V: AnsiString); overload;
+var
+  I: Integer;
+begin
+  // TODO: Write(Word(Length(V)));
+  Write(Byte(Length(V)));
+  for I := 1 to High(V) do
+    Write(Byte(V[I]));
+end;
+
+procedure TMsg.Write(V: TMD5Digest); overload;
+var
+  I: Integer;
+begin
+  for I := 0 to 15 do
+    Write(V[I]);
+end;
+
+procedure TMsg.BeginReading();
+begin
+  ReadCount := 0;
+  Bit := 0;
+end;
+
+function TMsg.ReadData(V: Pointer; N: Integer): Integer;
+begin
+  Result := 0;
+  if ReadCount + N > CurSize then
+  begin
+    // TODO: maybe partial reads?
+    ReadCount := CurSize + 1;
+    raise Exception.Create('TMsg.ReadData: buffer overrun!');
+    Exit;
+  end;
+  Move((Data + ReadCount)^, V^, N);
+  ReadCount := ReadCount + N;
+  Result := N;
+end;
+
+function TMsg.ReadChar(): Char;
+begin
+  Result := #0;
+  ReadData(@Result, 1);
+end;
+
+function TMsg.ReadByte(): Byte;
+begin
+  Result := 0;
+  ReadData(@Result, 1);
+end;
+
+function TMsg.ReadWord(): Word;
+begin
+  Result := 0;
+  ReadData(@Result, 2);
+end;
+
+function TMsg.ReadLongWord(): LongWord;
+begin
+  Result := 0;
+  ReadData(@Result, 4);
+end;
+
+function TMsg.ReadShortInt(): ShortInt;
+begin
+  Result := 0;
+  ReadData(@Result, 2);
+end;
+
+function TMsg.ReadSmallInt(): SmallInt;
+begin
+  Result := 0;
+  ReadData(@Result, 1);
+end;
+
+function TMsg.ReadLongInt(): LongInt;
+begin
+  Result := 0;
+  ReadData(@Result, 4);
+end;
+
+function TMsg.ReadInt64(): Int64;
+begin
+  Result := 0;
+  ReadData(@Result, 8);
+end;
+
+function TMsg.ReadString(): string;
+var
+  I: Integer;
+  L: Byte;
+begin
+  Result := '';
+  // TODO: L := ReadWord();
+  L := ReadByte();
+  if (L > 0) and (L <> Byte(-1)) then
+  begin
+    SetLength(Result, L);
+    for I := 1 to L do
+      Result[I] := ReadChar();
+  end;
+end;
+
+function TMsg.ReadMD5(): TMD5Digest;
+var
+  I: Integer;
+begin
+  for I := 0 to 15 do
+    Result[I] := ReadByte();
+end;
+
+end.
index 72e2c3b425508cb0a4f58f9a3b3b4be2fea84d8f..26fd58b6f710824959569c7b5f9c7240797f64e9 100644 (file)
@@ -52,7 +52,7 @@ uses
   e_log in '../engine/e_log.pas',
   e_sound in '../engine/e_sound.pas',
   e_texture in '../engine/e_texture.pas',
-  e_fixedbuffer in '../engine/e_fixedbuffer.pas',
+  e_msg in '../engine/e_msg.pas',
   utils in '../shared/utils.pas',
   xstreams in '../shared/xstreams.pas',
   sfs in '../sfs/sfs.pas',
index 2a52eccfb90dd8b19c144ee23530224f9684315a..c09158d4428909d9041a06e6ea7b2b505f0f56ad 100644 (file)
@@ -327,7 +327,7 @@ uses
   g_playermodel, g_gfx, g_options, g_weapons, Math,
   g_triggers, MAPDEF, g_monsters, e_sound, CONFIG,
   BinEditor, g_language, g_net, SDL,
-  ENet, e_fixedbuffer, g_netmsg, g_netmaster, GL, GLExt,
+  ENet, e_msg, g_netmsg, g_netmaster, GL, GLExt,
   utils, sfs;
 
 
@@ -3740,6 +3740,7 @@ var
   State: Byte;
   OuterLoop: Boolean;
   newResPath: string;
+  InMsg: TMsg;
 begin
   g_Game_Free();
 
@@ -3787,27 +3788,28 @@ begin
       if (NetEvent.kind = ENET_EVENT_TYPE_RECEIVE) then
       begin
         Ptr := NetEvent.packet^.data;
-        e_Raw_Seek(0);
+        if not InMsg.Init(Ptr, NetEvent.packet^.dataLength, True) then
+          continue;
 
-        MID := e_Raw_Read_Byte(Ptr);
+        MID := InMsg.ReadByte();
 
         if (MID = NET_MSG_INFO) and (State = 0) then
         begin
-          NetMyID := e_Raw_Read_Byte(Ptr);
-          NetPlrUID1 := e_Raw_Read_Word(Ptr);
+          NetMyID := InMsg.ReadByte();
+          NetPlrUID1 := InMsg.ReadWord();
 
-          WadName := e_Raw_Read_String(Ptr);
-          Map := e_Raw_Read_String(Ptr);
+          WadName := InMsg.ReadString();
+          Map := InMsg.ReadString();
 
-          gWADHash := e_Raw_Read_MD5(Ptr);
+          gWADHash := InMsg.ReadMD5();
 
-          gGameSettings.GameMode := e_Raw_Read_Byte(Ptr);
+          gGameSettings.GameMode := InMsg.ReadByte();
           gSwitchGameMode := gGameSettings.GameMode;
-          gGameSettings.GoalLimit := e_Raw_Read_Word(Ptr);
-          gGameSettings.TimeLimit := e_Raw_Read_Word(Ptr);
-          gGameSettings.MaxLives := e_Raw_Read_Byte(Ptr);
-          gGameSettings.Options := e_Raw_Read_LongWord(Ptr);
-          T := e_Raw_Read_LongWord(Ptr);
+          gGameSettings.GoalLimit := InMsg.ReadWord();
+          gGameSettings.TimeLimit := InMsg.ReadWord();
+          gGameSettings.MaxLives := InMsg.ReadByte();
+          gGameSettings.Options := InMsg.ReadLongWord();
+          T := InMsg.ReadLongWord();
 
           newResPath := g_Res_SearchSameWAD(MapsDir, WadName, gWADHash);
           if newResPath = '' then
index 1de6e98d237e9846b8f0393c53490a2a22213740..576e8772f39b2f2016e6c94670704cafe6079661 100644 (file)
@@ -19,7 +19,7 @@ unit g_net;
 interface
 
 uses
-  e_log, e_fixedbuffer, ENet, Classes;
+  e_log, e_msg, ENet, Classes;
 
 const
   NET_PROTOCOL_VER = 171;
@@ -43,7 +43,7 @@ const
   NET_SERVER = 1;
   NET_CLIENT = 2;
 
-  NET_BUFSIZE = 65536;
+  NET_BUFSIZE = $FFFF;
 
   NET_EVERYONE = -1;
 
@@ -116,7 +116,7 @@ var
   NetClientIP:   string = '127.0.0.1';
   NetClientPort: Word   = 25666;
 
-  NetIn, NetOut: TBuffer;
+  NetIn, NetOut: TMsg;
 
   NetClients:     array of TNetClient;
   NetClientCount: Byte = 0;
@@ -248,8 +248,8 @@ var
   IPstr: string;
   IP: LongWord;
 begin
-  e_Buffer_Clear(@NetIn);
-  e_Buffer_Clear(@NetOut);
+  NetIn.Clear();
+  NetOut.Clear();
   SetLength(NetClients, 0);
   NetPeer := nil;
   NetHost := nil;
@@ -282,8 +282,8 @@ end;
 
 procedure g_Net_Cleanup();
 begin
-  e_Buffer_Clear(@NetIn);
-  e_Buffer_Clear(@NetOut);
+  NetIn.Clear();
+  NetOut.Clear();
 
   SetLength(NetClients, 0);
   NetClientCount := 0;
@@ -373,7 +373,7 @@ begin
   end;
 
   NetMode := NET_SERVER;
-  e_Buffer_Clear(@NetOut);
+  NetOut.Clear();
 
   if NetDump then
     g_Net_DumpStart();
@@ -433,14 +433,14 @@ begin
     if ID > High(NetClients) then Exit;
     if NetClients[ID].Peer = nil then Exit;
 
-    P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, F);
+    P := enet_packet_create(NetOut.Data, NetOut.CurSize, F);
     if not Assigned(P) then Exit;
 
     enet_peer_send(NetClients[ID].Peer, Chan, P);
   end
   else
   begin
-    P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, F);
+    P := enet_packet_create(NetOut.Data, NetOut.CurSize, F);
     if not Assigned(P) then Exit;
 
     enet_host_broadcast(NetHost, Chan, P);
@@ -448,7 +448,7 @@ begin
 
   if NetDump then g_Net_DumpSendBuffer();
   g_Net_Flush();
-  e_Buffer_Clear(@NetOut);
+  NetOut.Clear();
 end;
 
 procedure g_Net_Host_CheckPings();
@@ -474,22 +474,22 @@ begin
   begin
     ClTime := Int64(Addr(Ping[2])^);
 
-    e_Buffer_Clear(@NetOut);
-    e_Buffer_Write(@NetOut, Byte(Ord('D')));
-    e_Buffer_Write(@NetOut, Byte(Ord('F')));
-    e_Buffer_Write(@NetOut, ClTime);
+    NetOut.Clear();
+    NetOut.Write(Byte(Ord('D')));
+    NetOut.Write(Byte(Ord('F')));
+    NetOut.Write(ClTime);
     g_Net_Slist_WriteInfo();
     NPl := 0;
     if gPlayer1 <> nil then Inc(NPl);
     if gPlayer2 <> nil then Inc(NPl);
-    e_Buffer_Write(@NetOut, NPl);
-    e_Buffer_Write(@NetOut, gNumBots);
+    NetOut.Write(NPl);
+    NetOut.Write(gNumBots);
 
-    Buf.data := Addr(NetOut.Data[0]);
-    Buf.dataLength := NetOut.WritePos;
+    Buf.data := NetOut.Data;
+    Buf.dataLength := NetOut.CurSize;
     enet_socket_send(NetPongSock, @ClAddr, @Buf, 1);
 
-    e_Buffer_Clear(@NetOut);
+    NetOut.Clear();
   end;
 end;
 
@@ -663,13 +663,13 @@ begin
   else
     F := 0;
 
-  P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, F);
+  P := enet_packet_create(NetOut.Data, NetOut.CurSize, F);
   if not Assigned(P) then Exit;
 
   enet_peer_send(NetPeer, Chan, P);
   if NetDump then g_Net_DumpSendBuffer();
   g_Net_Flush();
-  e_Buffer_Clear(@NetOut);
+  NetOut.Clear();
 end;
 
 function g_Net_Client_Update(): enet_size_t;
@@ -777,7 +777,7 @@ begin
       begin
         g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_MSG_CLIENT_DONE]);
         NetMode := NET_CLIENT;
-        e_Buffer_Clear(@NetOut);
+        NetOut.Clear();
         enet_peer_timeout(NetPeer, ENET_PEER_TIMEOUT_LIMIT * 2, ENET_PEER_TIMEOUT_MINIMUM * 2, ENET_PEER_TIMEOUT_MAXIMUM * 2);
         NetClientIP := IP;
         NetClientPort := Port;
@@ -810,15 +810,11 @@ function IpToStr(IP: LongWord): string;
 var
   Ptr: Pointer;
 begin
-  Result := '';
   Ptr := Addr(IP);
-
-  e_Raw_Seek(0);
-  Result := Result + IntToStr(e_Raw_Read_Byte(Ptr)) + '.';
-  Result := Result + IntToStr(e_Raw_Read_Byte(Ptr)) + '.';
-  Result := Result + IntToStr(e_Raw_Read_Byte(Ptr)) + '.';
-  Result := Result + IntToStr(e_Raw_Read_Byte(Ptr));
-  e_Raw_Seek(0);
+  Result :=          IntToStr(PByte(Ptr + 0)^) + '.';
+  Result := Result + IntToStr(PByte(Ptr + 1)^) + '.';
+  Result := Result + IntToStr(PByte(Ptr + 2)^) + '.';
+  Result := Result + IntToStr(PByte(Ptr + 3)^);
 end;
 
 function StrToIp(IPstr: string; var IP: LongWord): Boolean;
@@ -1085,9 +1081,9 @@ end;
 procedure g_Net_DumpSendBuffer();
 begin
   writeInt(NetDumpFile, gTime);
-  writeInt(NetDumpFile, LongWord(NetOut.Len));
+  writeInt(NetDumpFile, LongWord(NetOut.CurSize));
   writeInt(NetDumpFile, Byte(1));
-  NetDumpFile.WriteBuffer(NetOut.Data[0], NetOut.Len);
+  NetDumpFile.WriteBuffer(NetOut.Data^, NetOut.CurSize);
 end;
 
 procedure g_Net_DumpRecvBuffer(Buf: penet_uint8; Len: LongWord);
@@ -1105,4 +1101,14 @@ begin
   NetDumpFile := nil;
 end;
 
+initialization
+
+  NetIn.Alloc(NET_BUFSIZE);
+  NetOut.Alloc(NET_BUFSIZE);
+
+finalization
+
+  NetIn.Free();
+  NetOut.Free();
+
 end.
index ca7548344441114aa3f781aaf944813832536dad..78221ab00b9b1780efe8014d84f580cdf047226f 100644 (file)
@@ -26,60 +26,58 @@ procedure g_Net_HostMsgHandler(S: pTNetClient; P: pENetPacket);
 
 implementation
 
-uses e_fixedbuffer;
+uses e_msg;
 
 procedure g_Net_ClientMsgHandler(P: pENetPacket);
 var
   MID: Byte;
-  B: Pointer;
+  NetMsg: TMsg;
 begin
-  e_Raw_Seek(0);
+  if not NetMsg.Init(P^.data, P^.dataLength, True) then
+    Exit;
 
-  B := P^.data;
-  if B = nil then Exit;
-
-  MID := e_Raw_Read_Byte(B);
+  MID := NetMsg.ReadByte();
 
   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);
+    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_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_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);
   end;
 
   enet_packet_destroy(P);
@@ -88,21 +86,19 @@ end;
 procedure g_Net_ClientLightMsgHandler(P: pENetPacket);
 var
   MID: Byte;
-  B: Pointer;
+  NetMsg: TMsg;
 begin
-  e_Raw_Seek(0);
-
-  B := P^.data;
-  if B = nil then Exit;
+  if not NetMsg.Init(P^.data, P^.dataLength, True) then
+    Exit;
 
-  MID := e_Raw_Read_Byte(B);
+  MID := NetMsg.ReadByte();
 
   case MID of
-    NET_MSG_GEVENT: MC_RECV_GameEvent(B);
-    NET_MSG_GSET:   MC_RECV_GameSettings(B);
+    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(B);
-    NET_MSG_PLRDEL: if NetState <> NET_STATE_AUTH then MC_RECV_PlayerDelete(B);
+    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);
@@ -111,31 +107,29 @@ end;
 procedure g_Net_HostMsgHandler(S: pTNetClient; P: pENetPacket);
 var
   MID: Byte;
-  B: Pointer;
+  NetMsg: TMsg;
 begin
-  e_Raw_Seek(0);
-
-  B := P^.data;
-  if B = nil then Exit;
+  if not NetMsg.Init(P^.data, P^.dataLength, True) then
+    Exit;
 
-  MID := e_Raw_Read_Byte(B);
+  MID := NetMsg.ReadByte();
 
   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);
index 86d727e93b1963fb9e51004de844f16b11597717..4b9573d99a9ee476f8b57bec618f9a972f8e2a7d 100644 (file)
@@ -72,7 +72,7 @@ procedure g_Serverlist_Control(var SL: TNetServerList);
 implementation
 
 uses
-  SysUtils, e_fixedbuffer, e_input, e_graphics, e_log, g_window, g_net, g_console,
+  SysUtils, e_msg, e_input, e_graphics, e_log, g_window, g_net, g_console,
   g_map, g_game, g_sound, g_textures, g_gui, g_menu, g_options, g_language, wadreader;
 
 var
@@ -113,6 +113,7 @@ var
   T: Int64;
   Sock: ENetSocket;
   Buf: ENetBuffer;
+  InMsg: TMsg;
   SvAddr: ENetAddress;
 begin
   Result := False;
@@ -127,10 +128,12 @@ begin
   e_WriteLog('Fetching serverlist...', MSG_NOTIFY);
   g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_SLIST_FETCH]);
 
-  e_Buffer_Clear(@NetOut);
-  e_Buffer_Write(@NetOut, Byte(NET_MMSG_GET));
+  NetOut.Clear();
+  NetOut.Write(Byte(NET_MMSG_GET));
+  e_WriteLog('Wr ' + IntToStr(PByte(NetOut.Data)^) + ' !.', MSG_NOTIFY);
+  e_WriteLog('Wr ' + IntToStr(NetOut.CurSize) + ' !.', MSG_NOTIFY);
 
-  P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, Cardinal(ENET_PACKET_FLAG_RELIABLE));
+  P := enet_packet_create(NetOut.Data, NetOut.CurSize, Cardinal(ENET_PACKET_FLAG_RELIABLE));
   enet_peer_send(NetMPeer, NET_MCHAN_MAIN, P);
   enet_host_flush(NetMHost);
 
@@ -138,12 +141,14 @@ begin
   begin
     if NetMEvent.kind = ENET_EVENT_TYPE_RECEIVE then
     begin
-      e_Raw_Seek(0);
-      MID := e_Raw_Read_Byte(NetMEvent.packet^.data);
+      if not InMsg.Init(NetMEvent.packet^.data, NetMEvent.packet^.dataLength, True) then continue;
+
+      MID := InMsg.ReadByte();
+      e_WriteLog('Retrieved ' + IntToStr(MID) + ' !.', MSG_NOTIFY);
 
       if MID <> NET_MMSG_GET then continue;
 
-      Cnt := e_Raw_Read_Byte(NetMEvent.packet^.data);
+      Cnt := InMsg.ReadByte();
       e_WriteLog('Retrieved ' + IntToStr(Cnt) + ' server(s).', MSG_NOTIFY);
       g_Console_Add(_lc[I_NET_MSG] + Format(_lc[I_NET_SLIST_RETRIEVED], [Cnt]), True);
       //writeln('BOO!');
@@ -155,15 +160,15 @@ begin
         for I := 0 to Cnt - 1 do
         begin
           SL[I].Number := I;
-          SL[I].IP := e_Raw_Read_String(NetMEvent.packet^.data);
-          SL[I].Port := e_Raw_Read_Word(NetMEvent.packet^.data);
-          SL[I].Name := e_Raw_Read_String(NetMEvent.packet^.data);
-          SL[I].Map := e_Raw_Read_String(NetMEvent.packet^.data);
-          SL[I].GameMode := e_Raw_Read_Byte(NetMEvent.packet^.data);
-          SL[I].Players := e_Raw_Read_Byte(NetMEvent.packet^.data);
-          SL[I].MaxPlayers := e_Raw_Read_Byte(NetMEvent.packet^.data);
-          SL[I].Protocol := e_Raw_Read_Byte(NetMEvent.packet^.data);
-          SL[I].Password := e_Raw_Read_Byte(NetMEvent.packet^.data) = 1;
+          SL[I].IP := InMsg.ReadString();
+          SL[I].Port := InMsg.ReadWord();
+          SL[I].Name := InMsg.ReadString();
+          SL[I].Map := InMsg.ReadString();
+          SL[I].GameMode := InMsg.ReadByte();
+          SL[I].Players := InMsg.ReadByte();
+          SL[I].MaxPlayers := InMsg.ReadByte();
+          SL[I].Protocol := InMsg.ReadByte();
+          SL[I].Password := InMsg.ReadByte() = 1;
           enet_address_set_host(Addr(SL[I].PingAddr), PChar(Addr(SL[I].IP[1])));
           SL[I].Ping := -1;
           SL[I].PingAddr.port := SL[I].Port + 1;
@@ -176,7 +181,7 @@ begin
   end;
 
   g_Net_Slist_Disconnect;
-  e_Buffer_Clear(@NetOut);
+  NetOut.Clear();
 
   if Length(SL) = 0 then Exit;
 
@@ -189,23 +194,24 @@ begin
 
   T := GetTimerMS();
 
-  e_Buffer_Clear(@NetIn);
-  Buf.data := Addr(NetIn.Data);
-  Buf.dataLength := Length(NetIn.Data);
+  InMsg.Alloc(NET_BUFSIZE);
+  Buf.data := InMsg.Data;
+  Buf.dataLength := InMsg.MaxSize;
   Cnt := 0;
   while Cnt < Length(SL) do
   begin
     if GetTimerMS() - T > 500 then break;
 
-    e_Buffer_Clear(@NetIn);
+    InMsg.Clear();
 
     RX := enet_socket_receive(Sock, @SvAddr, @Buf, 1);
     if RX <= 0 then continue;
-    NetIn.Len := RX + 1;
-    NetIn.ReadPos := 0;
+    InMsg.CurSize := RX;
+
+    InMsg.BeginReading();
 
-    if e_Buffer_Read_Char(@NetIn) <> 'D' then continue;
-    if e_Buffer_Read_Char(@NetIn) <> 'F' then continue;
+    if InMsg.ReadChar() <> 'D' then continue;
+    if InMsg.ReadChar() <> 'F' then continue;
 
     for I := Low(SL) to High(SL) do
       if (SL[I].PingAddr.host = SvAddr.host) and
@@ -213,23 +219,24 @@ begin
       begin
         with SL[I] do
         begin
-          Ping := e_Buffer_Read_Int64(@NetIn);
+          Ping := InMsg.ReadInt64();
           Ping := GetTimerMS() - Ping;
-          Name := e_Buffer_Read_String(@NetIn);
-          Map := e_Buffer_Read_String(@NetIn);
-          GameMode := e_Buffer_Read_Byte(@NetIn);
-          Players := e_Buffer_Read_Byte(@NetIn);
-          MaxPlayers := e_Buffer_Read_Byte(@NetIn);
-          Protocol := e_Buffer_Read_Byte(@NetIn);
-          Password := e_Buffer_Read_Byte(@NetIn) = 1;
-          LocalPl := e_Buffer_Read_Byte(@NetIn);
-          Bots := e_Buffer_Read_Word(@NetIn);
+          Name := InMsg.ReadString();
+          Map := InMsg.ReadString();
+          GameMode := InMsg.ReadByte();
+          Players := InMsg.ReadByte();
+          MaxPlayers := InMsg.ReadByte();
+          Protocol := InMsg.ReadByte();
+          Password := InMsg.ReadByte() = 1;
+          LocalPl := InMsg.ReadByte();
+          Bots := InMsg.ReadWord();
         end;
         Inc(Cnt);
         break;
       end;
   end;
 
+  InMsg.Free();
   enet_socket_destroy(Sock);
 end;
 
@@ -241,18 +248,18 @@ begin
   Wad := g_ExtractWadNameNoPath(gMapInfo.Map);
   Map := g_ExtractFileName(gMapInfo.Map);
 
-  e_Buffer_Write(@NetOut, NetServerName);
+  NetOut.Write(NetServerName);
 
-  e_Buffer_Write(@NetOut, Wad + ':\' + Map);
-  e_Buffer_Write(@NetOut, gGameSettings.GameMode);
+  NetOut.Write(Wad + ':\' + Map);
+  NetOut.Write(gGameSettings.GameMode);
 
   Cli := NetClientCount;
-  e_Buffer_Write(@NetOut, Cli);
+  NetOut.Write(Cli);
 
-  e_Buffer_Write(@NetOut, NetMaxClients);
+  NetOut.Write(NetMaxClients);
 
-  e_Buffer_Write(@NetOut, Byte(NET_PROTOCOL_VER));
-  e_Buffer_Write(@NetOut, Byte(NetPassword <> ''));
+  NetOut.Write(Byte(NET_PROTOCOL_VER));
+  NetOut.Write(Byte(NetPassword <> ''));
 end;
 
 procedure g_Net_Slist_Update;
@@ -263,17 +270,17 @@ var
 begin
   if (NetMHost = nil) or (NetMPeer = nil) then Exit;
 
-  e_Buffer_Clear(@NetOut);
-  e_Buffer_Write(@NetOut, Byte(NET_MMSG_UPD));
-  e_Buffer_Write(@NetOut, NetAddr.port);
+  NetOut.Clear();
+  NetOut.Write(Byte(NET_MMSG_UPD));
+  NetOut.Write(NetAddr.port);
 
   g_Net_Slist_WriteInfo();
 
-  P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, Cardinal(ENET_PACKET_FLAG_RELIABLE));
+  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);
-  e_Buffer_Clear(@NetOut);
+  NetOut.Clear();
 end;
 
 procedure g_Net_Slist_Remove;
@@ -281,15 +288,15 @@ var
   P: pENetPacket;
 begin
   if (NetMHost = nil) or (NetMPeer = nil) then Exit;
-  e_Buffer_Clear(@NetOut);
-  e_Buffer_Write(@NetOut, Byte(NET_MMSG_DEL));
-  e_Buffer_Write(@NetOut, NetAddr.port);
+  NetOut.Clear();
+  NetOut.Write(Byte(NET_MMSG_DEL));
+  NetOut.Write(NetAddr.port);
 
-  P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, Cardinal(ENET_PACKET_FLAG_RELIABLE));
+  P := enet_packet_create(NetOut.Data, NetOut.CurSize, Cardinal(ENET_PACKET_FLAG_RELIABLE));
   enet_peer_send(NetMPeer, NET_MCHAN_MAIN, P);
 
   enet_host_flush(NetMHost);
-  e_Buffer_Clear(@NetOut);
+  NetOut.Clear();
 end;
 
 function g_Net_Slist_Connect: Boolean;
index a60f95fe10e2e313b1fd2512029fe5db397c2527..7499fc260112bda3621a18db0fcb416f737d0a21 100644 (file)
@@ -18,7 +18,7 @@ unit g_netmsg;
 
 interface
 
-uses g_net, g_triggers, Classes, SysUtils, md5;
+uses e_msg, g_net, g_triggers, Classes, SysUtils, md5;
 
 const
   NET_MSG_INFO   = 100;
@@ -129,17 +129,17 @@ const
 
 // HOST MESSAGES
 
-procedure MH_RECV_Info(C: pTNetClient; P: Pointer);
-procedure MH_RECV_Chat(C: pTNetClient; P: Pointer);
-procedure MH_RECV_FullStateRequest(C: pTNetClient; P: Pointer);
-function  MH_RECV_PlayerPos(C: pTNetClient; P: Pointer): Word;
-procedure MH_RECV_PlayerSettings(C: pTNetClient; P: Pointer);
-procedure MH_RECV_CheatRequest(C: pTNetClient; P: Pointer);
-procedure MH_RECV_RCONPassword(C: pTNetClient; P: Pointer);
-procedure MH_RECV_RCONCommand(C: pTNetClient; P: Pointer);
-procedure MH_RECV_MapRequest(C: pTNetClient; P: Pointer);
-procedure MH_RECV_ResRequest(C: pTNetClient; P: Pointer);
-procedure MH_RECV_Vote(C: pTNetClient; P: Pointer);
+procedure MH_RECV_Info(C: pTNetClient; var M: TMsg);
+procedure MH_RECV_Chat(C: pTNetClient; var M: TMsg);
+procedure MH_RECV_FullStateRequest(C: pTNetClient; var M: TMsg);
+function  MH_RECV_PlayerPos(C: pTNetClient; var M: TMsg): Word;
+procedure MH_RECV_PlayerSettings(C: pTNetClient; var M: TMsg);
+procedure MH_RECV_CheatRequest(C: pTNetClient; var M: TMsg);
+procedure MH_RECV_RCONPassword(C: pTNetClient; var M: TMsg);
+procedure MH_RECV_RCONCommand(C: pTNetClient; var M: TMsg);
+procedure MH_RECV_MapRequest(C: pTNetClient; var M: TMsg);
+procedure MH_RECV_ResRequest(C: pTNetClient; var M: TMsg);
+procedure MH_RECV_Vote(C: pTNetClient; var M: TMsg);
 
 // GAME
 procedure MH_SEND_Everything(CreatePlayers: Boolean = False; ID: Integer = NET_EVERYONE);
@@ -189,45 +189,45 @@ procedure MH_SEND_VoteEvent(EvType: Byte;
 // CLIENT MESSAGES //
 
 // GAME
-procedure MC_RECV_Chat(P: Pointer);
-procedure MC_RECV_Effect(P: Pointer);
-procedure MC_RECV_Sound(P: Pointer);
-procedure MC_RECV_GameStats(P: Pointer);
-procedure MC_RECV_CoopStats(P: Pointer);
-procedure MC_RECV_GameEvent(P: Pointer);
-procedure MC_RECV_FlagEvent(P: Pointer);
-procedure MC_RECV_GameSettings(P: Pointer);
+procedure MC_RECV_Chat(var M: TMsg);
+procedure MC_RECV_Effect(var M: TMsg);
+procedure MC_RECV_Sound(var M: TMsg);
+procedure MC_RECV_GameStats(var M: TMsg);
+procedure MC_RECV_CoopStats(var M: TMsg);
+procedure MC_RECV_GameEvent(var M: TMsg);
+procedure MC_RECV_FlagEvent(var M: TMsg);
+procedure MC_RECV_GameSettings(var M: TMsg);
 // PLAYER
-function  MC_RECV_PlayerCreate(P: Pointer): Word;
-function  MC_RECV_PlayerPos(P: Pointer): Word;
-function  MC_RECV_PlayerStats(P: Pointer): Word;
-function  MC_RECV_PlayerDelete(P: Pointer): Word;
-function  MC_RECV_PlayerDamage(P: Pointer): Word;
-function  MC_RECV_PlayerDeath(P: Pointer): Word;
-function  MC_RECV_PlayerFire(P: Pointer): Word;
-procedure MC_RECV_PlayerSettings(P: Pointer);
+function  MC_RECV_PlayerCreate(var M: TMsg): Word;
+function  MC_RECV_PlayerPos(var M: TMsg): Word;
+function  MC_RECV_PlayerStats(var M: TMsg): Word;
+function  MC_RECV_PlayerDelete(var M: TMsg): Word;
+function  MC_RECV_PlayerDamage(var M: TMsg): Word;
+function  MC_RECV_PlayerDeath(var M: TMsg): Word;
+function  MC_RECV_PlayerFire(var M: TMsg): Word;
+procedure MC_RECV_PlayerSettings(var M: TMsg);
 // ITEM
-procedure MC_RECV_ItemSpawn(P: Pointer);
-procedure MC_RECV_ItemDestroy(P: Pointer);
+procedure MC_RECV_ItemSpawn(var M: TMsg);
+procedure MC_RECV_ItemDestroy(var M: TMsg);
 // PANEL
-procedure MC_RECV_PanelTexture(P: Pointer);
-procedure MC_RECV_PanelState(P: Pointer);
+procedure MC_RECV_PanelTexture(var M: TMsg);
+procedure MC_RECV_PanelState(var M: TMsg);
 // MONSTER
-procedure MC_RECV_MonsterSpawn(P: Pointer);
-procedure MC_RECV_MonsterPos(P: Pointer);
-procedure MC_RECV_MonsterState(P: Pointer);
-procedure MC_RECV_MonsterShot(P: Pointer);
-procedure MC_RECV_MonsterDelete(P: Pointer);
+procedure MC_RECV_MonsterSpawn(var M: TMsg);
+procedure MC_RECV_MonsterPos(var M: TMsg);
+procedure MC_RECV_MonsterState(var M: TMsg);
+procedure MC_RECV_MonsterShot(var M: TMsg);
+procedure MC_RECV_MonsterDelete(var M: TMsg);
 // SHOT
-procedure MC_RECV_CreateShot(P: Pointer);
-procedure MC_RECV_UpdateShot(P: Pointer);
-procedure MC_RECV_DeleteShot(P: Pointer);
+procedure MC_RECV_CreateShot(var M: TMsg);
+procedure MC_RECV_UpdateShot(var M: TMsg);
+procedure MC_RECV_DeleteShot(var M: TMsg);
 // TRIGGER
-procedure MC_RECV_TriggerSound(P: Pointer);
-procedure MC_RECV_TriggerMusic(P: Pointer);
+procedure MC_RECV_TriggerSound(var M: TMsg);
+procedure MC_RECV_TriggerMusic(var M: TMsg);
 // MISC
-procedure MC_RECV_TimeSync(P: Pointer);
-procedure MC_RECV_VoteEvent(P: Pointer);
+procedure MC_RECV_TimeSync(var M: TMsg);
+procedure MC_RECV_VoteEvent(var M: TMsg);
 // SERVICE
 procedure MC_SEND_Info(Password: string);
 procedure MC_SEND_Chat(Txt: string; Mode: Byte);
@@ -267,7 +267,7 @@ function ResDataFromMsgStream(msgStream: TMemoryStream):TResDataMsg;
 implementation
 
 uses
-  Math, ENet, e_input, e_fixedbuffer, e_graphics, e_log,
+  Math, ENet, e_input, e_graphics, e_log,
   g_textures, g_gfx, g_sound, g_console, g_basic, g_options, g_main,
   g_game, g_player, g_map, g_panel, g_items, g_weapons, g_phys, g_gui,
   g_language, g_monsters, g_netmaster, utils, wadreader, MAPDEF;
@@ -295,7 +295,7 @@ const
 
 // GAME
 
-procedure MH_RECV_Chat(C: pTNetClient; P: Pointer);
+procedure MH_RECV_Chat(C: pTNetClient; var M: TMsg);
 var
   Txt: string;
   Mode: Byte;
@@ -305,8 +305,8 @@ begin
   PID := C^.Player;
   Pl := g_Player_Get(PID);
 
-  Txt := e_Raw_Read_String(P);
-  Mode := e_Raw_Read_Byte(P);
+  Txt := M.ReadString();
+  Mode := M.ReadByte();
   if (Mode = NET_CHAT_SYSTEM) then
     Mode := NET_CHAT_PLAYER; // prevent sending system messages from clients
   if (Mode = NET_CHAT_TEAM) and (not gGameSettings.GameMode in [GM_TDM, GM_CTF]) then
@@ -318,7 +318,7 @@ begin
     MH_SEND_Chat(Pl.Name + ': ' + Txt, Mode, IfThen(Mode = NET_CHAT_TEAM, Pl.Team, NET_EVERYONE));
 end;
 
-procedure MH_RECV_Info(C: pTNetClient; P: Pointer);
+procedure MH_RECV_Info(C: pTNetClient; var M: TMsg);
 var
   Ver, PName, Model, Pw: string;
   R, G, B, T: Byte;
@@ -326,14 +326,14 @@ var
   Color: TRGB;
   I: Integer;
 begin
-  Ver := e_Raw_Read_String(P);
-  Pw := e_Raw_Read_String(P);
-  PName := e_Raw_Read_String(P);
-  Model := e_Raw_Read_String(P);
-  R := e_Raw_Read_Byte(P);
-  G := e_Raw_Read_Byte(P);
-  B := e_Raw_Read_Byte(P);
-  T := e_Raw_Read_Byte(P);
+  Ver := M.ReadString();
+  Pw := M.ReadString();
+  PName := M.ReadString();
+  Model := M.ReadString();
+  R := M.ReadByte();
+  G := M.ReadByte();
+  B := M.ReadByte();
+  T := M.ReadByte();
 
   if Ver <> GAME_VERSION then
   begin
@@ -418,7 +418,7 @@ begin
   if NetUseMaster then g_Net_Slist_Update;
 end;
 
-procedure MH_RECV_FullStateRequest(C: pTNetClient; P: Pointer);
+procedure MH_RECV_FullStateRequest(C: pTNetClient; var M: TMsg);
 begin
   if gGameOn then
     MH_SEND_Everything((C^.State = NET_STATE_AUTH), C^.ID)
@@ -428,7 +428,7 @@ end;
 
 // PLAYER
 
-function  MH_RECV_PlayerPos(C: pTNetClient; P: Pointer): Word;
+function  MH_RECV_PlayerPos(C: pTNetClient; var M: TMsg): Word;
 var
   Dir, i: Byte;
   WeaponSelect: Word;
@@ -440,7 +440,7 @@ begin
   Result := 0;
   if not gGameOn then Exit;
 
-  GT := e_Raw_Read_LongWord(P);
+  GT := M.ReadLongWord();
   PID := C^.Player;
   Pl := g_Player_Get(PID);
   if Pl = nil then
@@ -451,9 +451,9 @@ begin
   with Pl do
   begin
     NetTime := GT;
-    kByte := e_Raw_Read_Word(P);
-    Dir := e_Raw_Read_Byte(P);
-    WeaponSelect := e_Raw_Read_Word(P);
+    kByte := M.ReadWord();
+    Dir := M.ReadByte();
+    WeaponSelect := M.ReadWord();
     //e_WriteLog(Format('R:ws=%d', [WeaponSelect]), MSG_WARNING);
     if Direction <> TDirection(Dir) then
       JustTeleported := False;
@@ -490,7 +490,7 @@ begin
   // MH_SEND_PlayerPos(False, PID, C^.ID);
 end;
 
-procedure MH_RECV_CheatRequest(C: pTNetClient; P: Pointer);
+procedure MH_RECV_CheatRequest(C: pTNetClient; var M: TMsg);
 var
   CheatKind: Byte;
   Pl: TPlayer;
@@ -498,7 +498,7 @@ begin
   Pl := g_Player_Get(C^.Player);
   if Pl = nil then Exit;
 
-  CheatKind := e_Raw_Read_Byte(P);
+  CheatKind := M.ReadByte();
 
   case CheatKind of
     NET_CHEAT_SUICIDE:
@@ -513,7 +513,7 @@ begin
   end;
 end;
 
-procedure MH_RECV_PlayerSettings(C: pTNetClient; P: Pointer);
+procedure MH_RECV_PlayerSettings(C: pTNetClient; var M: TMsg);
 var
   TmpName: string;
   TmpModel: string;
@@ -521,12 +521,12 @@ var
   TmpTeam: Byte;
   Pl: TPlayer;
 begin
-  TmpName := e_Raw_Read_String(P);
-  TmpModel := e_Raw_Read_String(P);
-  TmpColor.R := e_Raw_Read_Byte(P);
-  TmpColor.G := e_Raw_Read_Byte(P);
-  TmpColor.B := e_Raw_Read_Byte(P);
-  TmpTeam := e_Raw_Read_Byte(P);
+  TmpName := M.ReadString();
+  TmpModel := M.ReadString();
+  TmpColor.R := M.ReadByte();
+  TmpColor.G := M.ReadByte();
+  TmpColor.B := M.ReadByte();
+  TmpTeam := M.ReadByte();
 
   Pl := g_Player_Get(C^.Player);
   if Pl = nil then Exit;
@@ -550,11 +550,11 @@ end;
 
 // RCON
 
-procedure MH_RECV_RCONPassword(C: pTNetClient; P: Pointer);
+procedure MH_RECV_RCONPassword(C: pTNetClient; var M: TMsg);
 var
   Pwd: string;
 begin
-  Pwd := e_Raw_Read_String(P);
+  Pwd := M.ReadString();
   if not NetAllowRCON then Exit;
   if Pwd = NetRCONPassword then
   begin
@@ -565,11 +565,11 @@ begin
     MH_SEND_GameEvent(NET_EV_RCON, NET_RCON_PWBAD, 'N', C^.ID);
 end;
 
-procedure MH_RECV_RCONCommand(C: pTNetClient; P: Pointer);
+procedure MH_RECV_RCONCommand(C: pTNetClient; var M: TMsg);
 var
   Cmd: string;
 begin
-  Cmd := e_Raw_Read_String(P);
+  Cmd := M.ReadString();
   if not NetAllowRCON then Exit;
   if not C^.RCONAuth then
   begin
@@ -581,15 +581,15 @@ end;
 
 // MISC
 
-procedure MH_RECV_Vote(C: pTNetClient; P: Pointer);
+procedure MH_RECV_Vote(C: pTNetClient; var M: TMsg);
 var
   Start: Boolean;
   Name, Command: string;
   Need: Integer;
   Pl: TPlayer;
 begin
-  Start := e_Raw_Read_Byte(P) <> 0;
-  Command := e_Raw_Read_String(P);
+  Start := M.ReadByte() <> 0;
+  Command := M.ReadString();
 
   Pl := g_Player_Get(C^.Player);
   if Pl = nil then Exit;
@@ -760,20 +760,20 @@ var
 begin
   Map := g_ExtractFileName(gMapInfo.Map);
 
-  e_Buffer_Clear(@NetOut);
-
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_INFO));
-  e_Buffer_Write(@NetOut, ID);
-  e_Buffer_Write(@NetOut, NetClients[ID].Player);
-  e_Buffer_Write(@NetOut, gGameSettings.WAD);
-  e_Buffer_Write(@NetOut, Map);
-  e_Buffer_Write(@NetOut, gWADHash);
-  e_Buffer_Write(@NetOut, gGameSettings.GameMode);
-  e_Buffer_Write(@NetOut, gGameSettings.GoalLimit);
-  e_Buffer_Write(@NetOut, gGameSettings.TimeLimit);
-  e_Buffer_Write(@NetOut, gGameSettings.MaxLives);
-  e_Buffer_Write(@NetOut, gGameSettings.Options);
-  e_Buffer_Write(@NetOut, gTime);
+  NetOut.Clear();
+
+  NetOut.Write(Byte(NET_MSG_INFO));
+  NetOut.Write(ID);
+  NetOut.Write(NetClients[ID].Player);
+  NetOut.Write(gGameSettings.WAD);
+  NetOut.Write(Map);
+  NetOut.Write(gWADHash);
+  NetOut.Write(gGameSettings.GameMode);
+  NetOut.Write(gGameSettings.GoalLimit);
+  NetOut.Write(gGameSettings.TimeLimit);
+  NetOut.Write(gGameSettings.MaxLives);
+  NetOut.Write(gGameSettings.Options);
+  NetOut.Write(gTime);
 
   g_Net_Host_Send(ID, True, NET_CHAN_SERVICE);
 end;
@@ -794,9 +794,9 @@ begin
       if (gPlayers[i] <> nil) and (gPlayers[i].FClientID >= 0) and
          (gPlayers[i].Team = ID) then
       begin
-        e_Buffer_Write(@NetOut, Byte(NET_MSG_CHAT));
-        e_Buffer_Write(@NetOut, Txt);
-        e_Buffer_Write(@NetOut, Mode);
+        NetOut.Write(Byte(NET_MSG_CHAT));
+        NetOut.Write(Txt);
+        NetOut.Write(Mode);
         g_Net_Host_Send(gPlayers[i].FClientID, True, NET_CHAN_CHAT);
       end;
     Team := ID;
@@ -804,9 +804,9 @@ begin
   end
   else
   begin
-    e_Buffer_Write(@NetOut, Byte(NET_MSG_CHAT));
-    e_Buffer_Write(@NetOut, Txt);
-    e_Buffer_Write(@NetOut, Mode);
+    NetOut.Write(Byte(NET_MSG_CHAT));
+    NetOut.Write(Txt);
+    NetOut.Write(Mode);
     g_Net_Host_Send(ID, True, NET_CHAN_CHAT);
   end;
 
@@ -850,27 +850,27 @@ end;
 
 procedure MH_SEND_Effect(X, Y: Integer; Ang: SmallInt; Kind: Byte; ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_GFX));
-  e_Buffer_Write(@NetOut, Kind);
-  e_Buffer_Write(@NetOut, X);
-  e_Buffer_Write(@NetOut, Y);
-  e_Buffer_Write(@NetOut, Ang);
+  NetOut.Write(Byte(NET_MSG_GFX));
+  NetOut.Write(Kind);
+  NetOut.Write(X);
+  NetOut.Write(Y);
+  NetOut.Write(Ang);
 
   g_Net_Host_Send(ID, False, NET_CHAN_GAME);
 end;
 
 procedure MH_SEND_Sound(X, Y: Integer; Name: string; Pos: Boolean = True; ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_SND));
-  e_Buffer_Write(@NetOut, Name);
+  NetOut.Write(Byte(NET_MSG_SND));
+  NetOut.Write(Name);
   if Pos then
   begin
-    e_Buffer_Write(@NetOut, Byte(1));
-    e_Buffer_Write(@NetOut, X);
-    e_Buffer_Write(@NetOut, Y);
+    NetOut.Write(Byte(1));
+    NetOut.Write(X);
+    NetOut.Write(Y);
   end
   else
-    e_Buffer_Write(@NetOut, Byte(0));
+    NetOut.Write(Byte(0));
 
   g_Net_Host_Send(ID, False, NET_CHAN_GAME);
 end;
@@ -879,16 +879,16 @@ procedure MH_SEND_CreateShot(Proj: LongInt; ID: Integer = NET_EVERYONE);
 begin
   if (Shots = nil) or (Proj < 0) or (Proj > High(Shots)) then Exit;
 
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_SHADD));
-  e_Buffer_Write(@NetOut, Proj);
-  e_Buffer_Write(@NetOut, Shots[Proj].ShotType);
-  e_Buffer_Write(@NetOut, Shots[Proj].Target);
-  e_Buffer_Write(@NetOut, Shots[Proj].SpawnerUID);
-  e_Buffer_Write(@NetOut, Shots[Proj].Timeout);
-  e_Buffer_Write(@NetOut, Shots[Proj].Obj.X);
-  e_Buffer_Write(@NetOut, Shots[Proj].Obj.Y);
-  e_Buffer_Write(@NetOut, Shots[Proj].Obj.Vel.X);
-  e_Buffer_Write(@NetOut, Shots[Proj].Obj.Vel.Y);
+  NetOut.Write(Byte(NET_MSG_SHADD));
+  NetOut.Write(Proj);
+  NetOut.Write(Shots[Proj].ShotType);
+  NetOut.Write(Shots[Proj].Target);
+  NetOut.Write(Shots[Proj].SpawnerUID);
+  NetOut.Write(Shots[Proj].Timeout);
+  NetOut.Write(Shots[Proj].Obj.X);
+  NetOut.Write(Shots[Proj].Obj.Y);
+  NetOut.Write(Shots[Proj].Obj.Vel.X);
+  NetOut.Write(Shots[Proj].Obj.Vel.Y);
 
   g_Net_Host_Send(ID, True, NET_CHAN_SHOTS);
 end;
@@ -897,40 +897,40 @@ procedure MH_SEND_UpdateShot(Proj: LongInt; ID: Integer = NET_EVERYONE);
 begin
   if (Shots = nil) or (Proj < 0) or (Proj > High(Shots)) then Exit;
 
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_SHPOS));
-  e_Buffer_Write(@NetOut, Proj);
-  e_Buffer_Write(@NetOut, Shots[Proj].Obj.X);
-  e_Buffer_Write(@NetOut, Shots[Proj].Obj.Y);
-  e_Buffer_Write(@NetOut, Shots[Proj].Obj.Vel.X);
-  e_Buffer_Write(@NetOut, Shots[Proj].Obj.Vel.Y);
+  NetOut.Write(Byte(NET_MSG_SHPOS));
+  NetOut.Write(Proj);
+  NetOut.Write(Shots[Proj].Obj.X);
+  NetOut.Write(Shots[Proj].Obj.Y);
+  NetOut.Write(Shots[Proj].Obj.Vel.X);
+  NetOut.Write(Shots[Proj].Obj.Vel.Y);
 
   g_Net_Host_Send(ID, False, NET_CHAN_SHOTS);
 end;
 
 procedure MH_Send_DeleteShot(Proj: LongInt; X, Y: LongInt; Loud: Boolean = True; ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_SHDEL));
-  e_Buffer_Write(@NetOut, Proj);
-  e_Buffer_Write(@NetOut, Byte(Loud));
-  e_Buffer_Write(@NetOut, X);
-  e_Buffer_Write(@NetOut, Y);
+  NetOut.Write(Byte(NET_MSG_SHDEL));
+  NetOut.Write(Proj);
+  NetOut.Write(Byte(Loud));
+  NetOut.Write(X);
+  NetOut.Write(Y);
 
   g_Net_Host_Send(ID, True, NET_CHAN_SHOTS);
 end;
 
 procedure MH_SEND_GameStats(ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_SCORE));
+  NetOut.Write(Byte(NET_MSG_SCORE));
   if gGameSettings.GameMode in [GM_TDM, GM_CTF] then
   begin
-    e_Buffer_Write(@NetOut, gTeamStat[TEAM_RED].Goals);
-    e_Buffer_Write(@NetOut, gTeamStat[TEAM_BLUE].Goals);
+    NetOut.Write(gTeamStat[TEAM_RED].Goals);
+    NetOut.Write(gTeamStat[TEAM_BLUE].Goals);
   end
   else
     if gGameSettings.GameMode = GM_COOP then
     begin
-      e_Buffer_Write(@NetOut, gCoopMonstersKilled);
-      e_Buffer_Write(@NetOut, gCoopSecretsFound);
+      NetOut.Write(gCoopMonstersKilled);
+      NetOut.Write(gCoopSecretsFound);
     end;
 
   g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT);
@@ -938,58 +938,58 @@ end;
 
 procedure MH_SEND_CoopStats(ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_COOP));
-  e_Buffer_Write(@NetOut, gTotalMonsters);
-  e_Buffer_Write(@NetOut, gSecretsCount);
-  e_Buffer_Write(@NetOut, gCoopTotalMonstersKilled);
-  e_Buffer_Write(@NetOut, gCoopTotalSecretsFound);
-  e_Buffer_Write(@NetOut, gCoopTotalMonsters);
-  e_Buffer_Write(@NetOut, gCoopTotalSecrets);
+  NetOut.Write(Byte(NET_MSG_COOP));
+  NetOut.Write(gTotalMonsters);
+  NetOut.Write(gSecretsCount);
+  NetOut.Write(gCoopTotalMonstersKilled);
+  NetOut.Write(gCoopTotalSecretsFound);
+  NetOut.Write(gCoopTotalMonsters);
+  NetOut.Write(gCoopTotalSecrets);
 end;
 
 procedure MH_SEND_GameEvent(EvType: Byte; EvNum: Integer = 0; EvStr: string = 'N'; ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_GEVENT));
-  e_Buffer_Write(@NetOut, EvType);
-  e_Buffer_Write(@NetOut, EvNum);
-  e_Buffer_Write(@NetOut, EvStr);
-  e_Buffer_Write(@NetOut, Byte(gLastMap));
-  e_Buffer_Write(@NetOut, gTime);
+  NetOut.Write(Byte(NET_MSG_GEVENT));
+  NetOut.Write(EvType);
+  NetOut.Write(EvNum);
+  NetOut.Write(EvStr);
+  NetOut.Write(Byte(gLastMap));
+  NetOut.Write(gTime);
   if (EvType = NET_EV_MAPSTART) and (Pos(':\', EvStr) > 0) then
   begin
-    e_Buffer_Write(@NetOut, Byte(1));
-    e_Buffer_Write(@NetOut, gWADHash);
+    NetOut.Write(Byte(1));
+    NetOut.Write(gWADHash);
   end else
-    e_Buffer_Write(@NetOut, Byte(0));
+    NetOut.Write(Byte(0));
 
   g_Net_Host_Send(ID, True, NET_CHAN_SERVICE);
 end;
 
 procedure MH_SEND_FlagEvent(EvType: Byte; Flag: Byte; PID: Word; Quiet: Boolean = False; ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_FLAG));
-  e_Buffer_Write(@NetOut, EvType);
-  e_Buffer_Write(@NetOut, Flag);
-  e_Buffer_Write(@NetOut, Byte(Quiet));
-  e_Buffer_Write(@NetOut, PID);
-  e_Buffer_Write(@NetOut, gFlags[Flag].State);
-  e_Buffer_Write(@NetOut, gFlags[Flag].CaptureTime);
-  e_Buffer_Write(@NetOut, gFlags[Flag].Obj.X);
-  e_Buffer_Write(@NetOut, gFlags[Flag].Obj.Y);
-  e_Buffer_Write(@NetOut, gFlags[Flag].Obj.Vel.X);
-  e_Buffer_Write(@NetOut, gFlags[Flag].Obj.Vel.Y);
+  NetOut.Write(Byte(NET_MSG_FLAG));
+  NetOut.Write(EvType);
+  NetOut.Write(Flag);
+  NetOut.Write(Byte(Quiet));
+  NetOut.Write(PID);
+  NetOut.Write(gFlags[Flag].State);
+  NetOut.Write(gFlags[Flag].CaptureTime);
+  NetOut.Write(gFlags[Flag].Obj.X);
+  NetOut.Write(gFlags[Flag].Obj.Y);
+  NetOut.Write(gFlags[Flag].Obj.Vel.X);
+  NetOut.Write(gFlags[Flag].Obj.Vel.Y);
 
   g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT);
 end;
 
 procedure MH_SEND_GameSettings(ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_GSET));
-  e_Buffer_Write(@NetOut, gGameSettings.GameMode);
-  e_Buffer_Write(@NetOut, gGameSettings.GoalLimit);
-  e_Buffer_Write(@NetOut, gGameSettings.TimeLimit);
-  e_Buffer_Write(@NetOut, gGameSettings.MaxLives);
-  e_Buffer_Write(@NetOut, gGameSettings.Options);
+  NetOut.Write(Byte(NET_MSG_GSET));
+  NetOut.Write(gGameSettings.GameMode);
+  NetOut.Write(gGameSettings.GoalLimit);
+  NetOut.Write(gGameSettings.TimeLimit);
+  NetOut.Write(gGameSettings.MaxLives);
+  NetOut.Write(gGameSettings.Options);
 
   g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT);
 end;
@@ -1003,15 +1003,15 @@ begin
   P := g_Player_Get(PID);
   if P = nil then Exit;
 
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_PLR));
-  e_Buffer_Write(@NetOut, PID);
-  e_Buffer_Write(@NetOut, P.Name);
+  NetOut.Write(Byte(NET_MSG_PLR));
+  NetOut.Write(PID);
+  NetOut.Write(P.Name);
 
-  e_Buffer_Write(@NetOut, P.FActualModelName);
-  e_Buffer_Write(@NetOut, P.FColor.R);
-  e_Buffer_Write(@NetOut, P.FColor.G);
-  e_Buffer_Write(@NetOut, P.FColor.B);
-  e_Buffer_Write(@NetOut, P.Team);
+  NetOut.Write(P.FActualModelName);
+  NetOut.Write(P.FColor.R);
+  NetOut.Write(P.FColor.G);
+  NetOut.Write(P.FColor.B);
+  NetOut.Write(P.Team);
 
   g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT)
 end;
@@ -1025,16 +1025,16 @@ begin
   if Pl = nil then Exit;
   if Pl.FDummy then Exit;
 
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_PLRPOS));
-  e_Buffer_Write(@NetOut, gTime);
-  e_Buffer_Write(@NetOut, PID);
+  NetOut.Write(Byte(NET_MSG_PLRPOS));
+  NetOut.Write(gTime);
+  NetOut.Write(PID);
 
   kByte := 0;
 
   with Pl do
   begin
-    e_Buffer_Write(@NetOut, FPing);
-    e_Buffer_Write(@NetOut, FLoss);
+    NetOut.Write(FPing);
+    NetOut.Write(FLoss);
     if IsKeyPressed(KEY_CHAT) then
       kByte := NET_KEY_CHAT
     else
@@ -1047,14 +1047,14 @@ begin
       if JustTeleported then kByte := kByte or NET_KEY_FORCEDIR;
     end;
 
-    e_Buffer_Write(@NetOut, kByte);
-    if Direction = D_LEFT then e_Buffer_Write(@NetOut, Byte(0)) else e_Buffer_Write(@NetOut, Byte(1));
-    e_Buffer_Write(@NetOut, GameX);
-    e_Buffer_Write(@NetOut, GameY);
-    e_Buffer_Write(@NetOut, GameVelX);
-    e_Buffer_Write(@NetOut, GameVelY);
-    e_Buffer_Write(@NetOut, GameAccelX);
-    e_Buffer_Write(@NetOut, GameAccelY);
+    NetOut.Write(kByte);
+    if Direction = D_LEFT then NetOut.Write(Byte(0)) else NetOut.Write(Byte(1));
+    NetOut.Write(GameX);
+    NetOut.Write(GameY);
+    NetOut.Write(GameVelX);
+    NetOut.Write(GameVelY);
+    NetOut.Write(GameAccelX);
+    NetOut.Write(GameAccelY);
   end;
 
   g_Net_Host_Send(ID, Reliable, NET_CHAN_PLAYERPOS);
@@ -1068,49 +1068,49 @@ begin
   P := g_Player_Get(PID);
   if P = nil then Exit;
 
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_PLRSTA));
-  e_Buffer_Write(@NetOut, PID);
+  NetOut.Write(Byte(NET_MSG_PLRSTA));
+  NetOut.Write(PID);
 
   with P do
   begin
-    e_Buffer_Write(@NetOut, Byte(Live));
-    e_Buffer_Write(@NetOut, Byte(GodMode));
-    e_Buffer_Write(@NetOut, Health);
-    e_Buffer_Write(@NetOut, Armor);
-    e_Buffer_Write(@NetOut, Air);
-    e_Buffer_Write(@NetOut, JetFuel);
-    e_Buffer_Write(@NetOut, Lives);
-    e_Buffer_Write(@NetOut, Team);
+    NetOut.Write(Byte(Live));
+    NetOut.Write(Byte(GodMode));
+    NetOut.Write(Health);
+    NetOut.Write(Armor);
+    NetOut.Write(Air);
+    NetOut.Write(JetFuel);
+    NetOut.Write(Lives);
+    NetOut.Write(Team);
 
     for I := WP_FIRST to WP_LAST do
-      e_Buffer_Write(@NetOut, Byte(FWeapon[I]));
+      NetOut.Write(Byte(FWeapon[I]));
 
     for I := A_BULLETS to A_HIGH do
-      e_Buffer_Write(@NetOut, FAmmo[I]);
+      NetOut.Write(FAmmo[I]);
 
     for I := A_BULLETS to A_HIGH do
-      e_Buffer_Write(@NetOut, FMaxAmmo[I]);
+      NetOut.Write(FMaxAmmo[I]);
 
     for I := MR_SUIT to MR_MAX do
-      e_Buffer_Write(@NetOut, LongWord(FMegaRulez[I]));
+      NetOut.Write(LongWord(FMegaRulez[I]));
 
-    e_Buffer_Write(@NetOut, Byte(R_ITEM_BACKPACK in FRulez));
-    e_Buffer_Write(@NetOut, Byte(R_KEY_RED in FRulez));
-    e_Buffer_Write(@NetOut, Byte(R_KEY_GREEN in FRulez));
-    e_Buffer_Write(@NetOut, Byte(R_KEY_BLUE in FRulez));
-    e_Buffer_Write(@NetOut, Byte(R_BERSERK in FRulez));
+    NetOut.Write(Byte(R_ITEM_BACKPACK in FRulez));
+    NetOut.Write(Byte(R_KEY_RED in FRulez));
+    NetOut.Write(Byte(R_KEY_GREEN in FRulez));
+    NetOut.Write(Byte(R_KEY_BLUE in FRulez));
+    NetOut.Write(Byte(R_BERSERK in FRulez));
 
-    e_Buffer_Write(@NetOut, Frags);
-    e_Buffer_Write(@NetOut, Death);
+    NetOut.Write(Frags);
+    NetOut.Write(Death);
 
-    e_Buffer_Write(@NetOut, CurrWeap);
+    NetOut.Write(CurrWeap);
 
-    e_Buffer_Write(@NetOut, Byte(FSpectator));
-    e_Buffer_Write(@NetOut, Byte(FGhost));
-    e_Buffer_Write(@NetOut, Byte(FPhysics));
-    e_Buffer_Write(@NetOut, Byte(FNoRespawn));
-    e_Buffer_Write(@NetOut, Byte(FJetpack));
-    e_Buffer_Write(@NetOut, FFireTime);
+    NetOut.Write(Byte(FSpectator));
+    NetOut.Write(Byte(FGhost));
+    NetOut.Write(Byte(FPhysics));
+    NetOut.Write(Byte(FNoRespawn));
+    NetOut.Write(Byte(FJetpack));
+    NetOut.Write(FFireTime);
   end;
 
   g_Net_Host_Send(ID, True, NET_CHAN_PLAYER);
@@ -1118,46 +1118,46 @@ end;
 
 procedure MH_SEND_PlayerDamage(PID: Word; Kind: Byte; Attacker, Value: Word; VX, VY: Integer; ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_PLRDMG));
-  e_Buffer_Write(@NetOut, PID);
-  e_Buffer_Write(@NetOut, Kind);
-  e_Buffer_Write(@NetOut, Attacker);
-  e_Buffer_Write(@NetOut, Value);
-  e_Buffer_Write(@NetOut, VX);
-  e_Buffer_Write(@NetOut, VY);
+  NetOut.Write(Byte(NET_MSG_PLRDMG));
+  NetOut.Write(PID);
+  NetOut.Write(Kind);
+  NetOut.Write(Attacker);
+  NetOut.Write(Value);
+  NetOut.Write(VX);
+  NetOut.Write(VY);
 
   g_Net_Host_Send(ID, False, NET_CHAN_PLAYER);
 end;
 
 procedure MH_SEND_PlayerDeath(PID: Word; KillType, DeathType: Byte; Attacker: Word; ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_PLRDIE));
-  e_Buffer_Write(@NetOut, PID);
-  e_Buffer_Write(@NetOut, KillType);
-  e_Buffer_Write(@NetOut, DeathType);
-  e_Buffer_Write(@NetOut, Attacker);
+  NetOut.Write(Byte(NET_MSG_PLRDIE));
+  NetOut.Write(PID);
+  NetOut.Write(KillType);
+  NetOut.Write(DeathType);
+  NetOut.Write(Attacker);
 
   g_Net_Host_Send(ID, True, NET_CHAN_PLAYER);
 end;
 
 procedure MH_SEND_PlayerFire(PID: Word; Weapon: Byte; X, Y, AX, AY: Integer; ShotID: Integer = -1; ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_PLRFIRE));
-  e_Buffer_Write(@NetOut, PID);
-  e_Buffer_Write(@NetOut, Weapon);
-  e_Buffer_Write(@NetOut, X);
-  e_Buffer_Write(@NetOut, Y);
-  e_Buffer_Write(@NetOut, AX);
-  e_Buffer_Write(@NetOut, AY);
-  e_Buffer_Write(@NetOut, ShotID);
+  NetOut.Write(Byte(NET_MSG_PLRFIRE));
+  NetOut.Write(PID);
+  NetOut.Write(Weapon);
+  NetOut.Write(X);
+  NetOut.Write(Y);
+  NetOut.Write(AX);
+  NetOut.Write(AY);
+  NetOut.Write(ShotID);
 
   g_Net_Host_Send(ID, True, NET_CHAN_SHOTS);
 end;
 
 procedure MH_SEND_PlayerDelete(PID: Word; ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_PLRDEL));
-  e_Buffer_Write(@NetOut, PID);
+  NetOut.Write(Byte(NET_MSG_PLRDEL));
+  NetOut.Write(PID);
 
   g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT);
 end;
@@ -1169,17 +1169,17 @@ begin
   Pl := g_Player_Get(PID);
   if Pl = nil then Exit;
 
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_PLRSET));
-  e_Buffer_Write(@NetOut, PID);
-  e_Buffer_Write(@NetOut, Pl.Name);
+  NetOut.Write(Byte(NET_MSG_PLRSET));
+  NetOut.Write(PID);
+  NetOut.Write(Pl.Name);
   if Mdl = '' then
-    e_Buffer_Write(@NetOut, Pl.Model.Name)
+    NetOut.Write(Pl.Model.Name)
   else
-    e_Buffer_Write(@NetOut, Mdl);
-  e_Buffer_Write(@NetOut, Pl.FColor.R);
-  e_Buffer_Write(@NetOut, Pl.FColor.G);
-  e_Buffer_Write(@NetOut, Pl.FColor.B);
-  e_Buffer_Write(@NetOut, Pl.Team);
+    NetOut.Write(Mdl);
+  NetOut.Write(Pl.FColor.R);
+  NetOut.Write(Pl.FColor.G);
+  NetOut.Write(Pl.FColor.B);
+  NetOut.Write(Pl.Team);
 
   g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT);
 end;
@@ -1192,25 +1192,25 @@ var
 begin
   it := g_ItemByIdx(IID);
 
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_ISPAWN));
-  e_Buffer_Write(@NetOut, IID);
-  e_Buffer_Write(@NetOut, Byte(Quiet));
-  e_Buffer_Write(@NetOut, it.ItemType);
-  e_Buffer_Write(@NetOut, Byte(it.Fall));
-  e_Buffer_Write(@NetOut, Byte(it.Respawnable));
-  e_Buffer_Write(@NetOut, it.Obj.X);
-  e_Buffer_Write(@NetOut, it.Obj.Y);
-  e_Buffer_Write(@NetOut, it.Obj.Vel.X);
-  e_Buffer_Write(@NetOut, it.Obj.Vel.Y);
+  NetOut.Write(Byte(NET_MSG_ISPAWN));
+  NetOut.Write(IID);
+  NetOut.Write(Byte(Quiet));
+  NetOut.Write(it.ItemType);
+  NetOut.Write(Byte(it.Fall));
+  NetOut.Write(Byte(it.Respawnable));
+  NetOut.Write(it.Obj.X);
+  NetOut.Write(it.Obj.Y);
+  NetOut.Write(it.Obj.Vel.X);
+  NetOut.Write(it.Obj.Vel.Y);
 
   g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
 end;
 
 procedure MH_SEND_ItemDestroy(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_IDEL));
-  e_Buffer_Write(@NetOut, IID);
-  e_Buffer_Write(@NetOut, Byte(Quiet));
+  NetOut.Write(Byte(NET_MSG_IDEL));
+  NetOut.Write(IID);
+  NetOut.Write(Byte(Quiet));
 
   g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
 end;
@@ -1242,13 +1242,13 @@ begin
 
   with TP do
   begin
-    e_Buffer_Write(@NetOut, Byte(NET_MSG_PTEX));
-    e_Buffer_Write(@NetOut, PType);
-    e_Buffer_Write(@NetOut, PID);
-    e_Buffer_Write(@NetOut, FCurTexture);
-    e_Buffer_Write(@NetOut, FCurFrame);
-    e_Buffer_Write(@NetOut, FCurFrameCount);
-    e_Buffer_Write(@NetOut, AnimLoop);
+    NetOut.Write(Byte(NET_MSG_PTEX));
+    NetOut.Write(PType);
+    NetOut.Write(PID);
+    NetOut.Write(FCurTexture);
+    NetOut.Write(FCurFrame);
+    NetOut.Write(FCurFrameCount);
+    NetOut.Write(AnimLoop);
   end;
 
   g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
@@ -1277,13 +1277,13 @@ begin
       Exit;
   end;
 
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_PSTATE));
-  e_Buffer_Write(@NetOut, PType);
-  e_Buffer_Write(@NetOut, PID);
-  e_Buffer_Write(@NetOut, Byte(TP.Enabled));
-  e_Buffer_Write(@NetOut, TP.LiftType);
-  e_Buffer_Write(@NetOut, TP.X);
-  e_Buffer_Write(@NetOut, TP.Y);
+  NetOut.Write(Byte(NET_MSG_PSTATE));
+  NetOut.Write(PType);
+  NetOut.Write(PID);
+  NetOut.Write(Byte(TP.Enabled));
+  NetOut.Write(TP.LiftType);
+  NetOut.Write(TP.X);
+  NetOut.Write(TP.Y);
 
   g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
 end;
@@ -1295,22 +1295,22 @@ begin
   if gTriggers = nil then Exit;
   if T.Sound = nil then Exit;
 
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_TSOUND));
-  e_Buffer_Write(@NetOut, T.ClientID);
-  e_Buffer_Write(@NetOut, Byte(T.Sound.IsPlaying));
-  e_Buffer_Write(@NetOut, LongWord(T.Sound.GetPosition));
-  e_Buffer_Write(@NetOut, T.SoundPlayCount);
+  NetOut.Write(Byte(NET_MSG_TSOUND));
+  NetOut.Write(T.ClientID);
+  NetOut.Write(Byte(T.Sound.IsPlaying));
+  NetOut.Write(LongWord(T.Sound.GetPosition));
+  NetOut.Write(T.SoundPlayCount);
 
   g_Net_Host_Send(ID, True);
 end;
 
 procedure MH_SEND_TriggerMusic(ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_TMUSIC));
-  e_Buffer_Write(@NetOut, gMusic.Name);
-  e_Buffer_Write(@NetOut, Byte(gMusic.IsPlaying));
-  e_Buffer_Write(@NetOut, LongWord(gMusic.GetPosition));
-  e_Buffer_Write(@NetOut, Byte(gMusic.SpecPause or gMusic.IsPaused));
+  NetOut.Write(Byte(NET_MSG_TMUSIC));
+  NetOut.Write(gMusic.Name);
+  NetOut.Write(Byte(gMusic.IsPlaying));
+  NetOut.Write(LongWord(gMusic.GetPosition));
+  NetOut.Write(Byte(gMusic.SpecPause or gMusic.IsPaused));
 
   g_Net_Host_Send(ID, True);
 end;
@@ -1327,22 +1327,22 @@ begin
 
   with M do
   begin
-    e_Buffer_Write(@NetOut, Byte(NET_MSG_MSPAWN));
-    e_Buffer_Write(@NetOut, UID);
-    e_Buffer_Write(@NetOut, MonsterType);
-    e_Buffer_Write(@NetOut, MonsterState);
-    e_Buffer_Write(@NetOut, MonsterAnim);
-    e_Buffer_Write(@NetOut, MonsterTargetUID);
-    e_Buffer_Write(@NetOut, MonsterTargetTime);
-    e_Buffer_Write(@NetOut, MonsterBehaviour);
-    e_Buffer_Write(@NetOut, MonsterSleep);
-    e_Buffer_Write(@NetOut, MonsterHealth);
-    e_Buffer_Write(@NetOut, MonsterAmmo);
-    e_Buffer_Write(@NetOut, GameX);
-    e_Buffer_Write(@NetOut, GameY);
-    e_Buffer_Write(@NetOut, GameVelX);
-    e_Buffer_Write(@NetOut, GameVelY);
-    e_Buffer_Write(@NetOut, Byte(GameDirection));
+    NetOut.Write(Byte(NET_MSG_MSPAWN));
+    NetOut.Write(UID);
+    NetOut.Write(MonsterType);
+    NetOut.Write(MonsterState);
+    NetOut.Write(MonsterAnim);
+    NetOut.Write(MonsterTargetUID);
+    NetOut.Write(MonsterTargetTime);
+    NetOut.Write(MonsterBehaviour);
+    NetOut.Write(MonsterSleep);
+    NetOut.Write(MonsterHealth);
+    NetOut.Write(MonsterAmmo);
+    NetOut.Write(GameX);
+    NetOut.Write(GameY);
+    NetOut.Write(GameVelX);
+    NetOut.Write(GameVelY);
+    NetOut.Write(Byte(GameDirection));
   end;
 
   g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
@@ -1355,16 +1355,16 @@ begin
   M := g_Monsters_Get(UID);
   if M = nil then Exit;
 
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_MPOS));
-  e_Buffer_Write(@NetOut, UID);
+  NetOut.Write(Byte(NET_MSG_MPOS));
+  NetOut.Write(UID);
 
   with M do
   begin
-    e_Buffer_Write(@NetOut, GameX);
-    e_Buffer_Write(@NetOut, GameY);
-    e_Buffer_Write(@NetOut, GameVelX);
-    e_Buffer_Write(@NetOut, GameVelY);
-    e_Buffer_Write(@NetOut, Byte(GameDirection));
+    NetOut.Write(GameX);
+    NetOut.Write(GameY);
+    NetOut.Write(GameVelX);
+    NetOut.Write(GameVelY);
+    NetOut.Write(Byte(GameDirection));
   end;
 
   g_Net_Host_Send(ID, False, NET_CHAN_MONSTERPOS);
@@ -1377,21 +1377,21 @@ begin
   M := g_Monsters_Get(UID);
   if M = nil then Exit;
 
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_MSTATE));
-  e_Buffer_Write(@NetOut, UID);
+  NetOut.Write(Byte(NET_MSG_MSTATE));
+  NetOut.Write(UID);
 
   with M do
   begin
-    e_Buffer_Write(@NetOut, MonsterState);
-    e_Buffer_Write(@NetOut, ForcedAnim);
-    e_Buffer_Write(@NetOut, MonsterTargetUID);
-    e_Buffer_Write(@NetOut, MonsterTargetTime);
-    e_Buffer_Write(@NetOut, MonsterSleep);
-    e_Buffer_Write(@NetOut, MonsterHealth);
-    e_Buffer_Write(@NetOut, MonsterAmmo);
-    e_Buffer_Write(@NetOut, MonsterPain);
-    e_Buffer_Write(@NetOut, Byte(AnimIsReverse));
-    e_Buffer_Write(@NetOut, FFireTime);
+    NetOut.Write(MonsterState);
+    NetOut.Write(ForcedAnim);
+    NetOut.Write(MonsterTargetUID);
+    NetOut.Write(MonsterTargetTime);
+    NetOut.Write(MonsterSleep);
+    NetOut.Write(MonsterHealth);
+    NetOut.Write(MonsterAmmo);
+    NetOut.Write(MonsterPain);
+    NetOut.Write(Byte(AnimIsReverse));
+    NetOut.Write(FFireTime);
   end;
 
   g_Net_Host_Send(ID, True, NET_CHAN_MONSTER);
@@ -1399,12 +1399,12 @@ end;
 
 procedure MH_SEND_MonsterShot(UID: Word; X, Y, VX, VY: Integer; ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_MSHOT));
-  e_Buffer_Write(@NetOut, UID);
-  e_Buffer_Write(@NetOut, X);
-  e_Buffer_Write(@NetOut, Y);
-  e_Buffer_Write(@NetOut, VX);
-  e_Buffer_Write(@NetOut, VY);
+  NetOut.Write(Byte(NET_MSG_MSHOT));
+  NetOut.Write(UID);
+  NetOut.Write(X);
+  NetOut.Write(Y);
+  NetOut.Write(VX);
+  NetOut.Write(VY);
 
   g_Net_Host_Send(ID, True, NET_CHAN_MONSTER);
 end;
@@ -1416,8 +1416,8 @@ begin
   M := g_Monsters_Get(UID);
   if M = nil then Exit;
 
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_MDEL));
-  e_Buffer_Write(@NetOut, UID);
+  NetOut.Write(Byte(NET_MSG_MDEL));
+  NetOut.Write(UID);
 
   g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
 end;
@@ -1426,8 +1426,8 @@ end;
 
 procedure MH_SEND_TimeSync(Time: LongWord; ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_TIME_SYNC));
-  e_Buffer_Write(@NetOut, Time);
+  NetOut.Write(Byte(NET_MSG_TIME_SYNC));
+  NetOut.Write(Time);
 
   g_Net_Host_Send(ID, False, NET_CHAN_SERVICE);
 end;
@@ -1437,12 +1437,12 @@ procedure MH_SEND_VoteEvent(EvType: Byte;
                             IntArg1: SmallInt = 0; IntArg2: SmallInt = 0;
                             ID: Integer = NET_EVERYONE);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_VOTE_EVENT));
-  e_Buffer_Write(@NetOut, EvType);
-  e_Buffer_Write(@NetOut, IntArg1);
-  e_Buffer_Write(@NetOut, IntArg2);
-  e_Buffer_Write(@NetOut, StrArg1);
-  e_Buffer_Write(@NetOut, StrArg2);
+  NetOut.Write(Byte(NET_MSG_VOTE_EVENT));
+  NetOut.Write(EvType);
+  NetOut.Write(IntArg1);
+  NetOut.Write(IntArg2);
+  NetOut.Write(StrArg1);
+  NetOut.Write(StrArg2);
 
   g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT);
 end;
@@ -1451,13 +1451,13 @@ end;
 
 // GAME
 
-procedure MC_RECV_Chat(P: Pointer);
+procedure MC_RECV_Chat(var M: TMsg);
 var
   Txt: string;
   Mode: Byte;
 begin
-  Txt := e_Raw_Read_String(P);
-  Mode := e_Raw_Read_Byte(P);
+  Txt := M.ReadString();
+  Mode := M.ReadByte();
 
   if Mode <> NET_CHAT_SYSTEM then
   begin
@@ -1480,7 +1480,7 @@ begin
     g_Console_Add(Txt, True);
 end;
 
-procedure MC_RECV_Effect(P: Pointer);
+procedure MC_RECV_Effect(var M: TMsg);
 var
   Kind: Byte;
   X, Y: Integer;
@@ -1489,10 +1489,10 @@ var
   ID: LongWord;
 begin
   if not gGameOn then Exit;
-  Kind := e_Raw_Read_Byte(P);
-  X := e_Raw_Read_LongInt(P);
-  Y := e_Raw_Read_LongInt(P);
-  Ang := e_Raw_Read_SmallInt(P);
+  Kind := M.ReadByte();
+  X := M.ReadLongInt();
+  Y := M.ReadLongInt();
+  Ang := M.ReadSmallInt();
 
   case Kind of
     NET_GFX_SPARK:
@@ -1584,40 +1584,40 @@ begin
   end;
 end;
 
-procedure MC_RECV_Sound(P: Pointer);
+procedure MC_RECV_Sound(var M: TMsg);
 var
   Name: string;
   X, Y: Integer;
   Pos: Boolean;
 begin
-  Name := e_Raw_Read_String(P);
-  Pos := e_Raw_Read_Byte(P) <> 0;
+  Name := M.ReadString();
+  Pos := M.ReadByte() <> 0;
   if Pos then
   begin
-    X := e_Raw_Read_LongInt(P);
-    Y := e_Raw_Read_LongInt(P);
+    X := M.ReadLongInt();
+    Y := M.ReadLongInt();
     g_Sound_PlayExAt(Name, X, Y);
   end
   else
     g_Sound_PlayEx(Name);
 end;
 
-procedure MC_RECV_CreateShot(P: Pointer);
+procedure MC_RECV_CreateShot(var M: TMsg);
 var
   I, X, Y, XV, YV: Integer;
   Timeout: LongWord;
   Target, Spawner: Word;
   ShType: Byte;
 begin
-  I := e_Raw_Read_LongInt(P);
-  ShType := e_Raw_Read_Byte(P);
-  Target := e_Raw_Read_Word(P);
-  Spawner := e_Raw_Read_Word(P);
-  Timeout := e_Raw_Read_LongWord(P);
-  X := e_Raw_Read_LongInt(P);
-  Y := e_Raw_Read_LongInt(P);
-  XV := e_Raw_Read_LongInt(P);
-  YV := e_Raw_Read_LongInt(P);
+  I := M.ReadLongInt();
+  ShType := M.ReadByte();
+  Target := M.ReadWord();
+  Spawner := M.ReadWord();
+  Timeout := M.ReadLongWord();
+  X := M.ReadLongInt();
+  Y := M.ReadLongInt();
+  XV := M.ReadLongInt();
+  YV := M.ReadLongInt();
 
   I := g_Weapon_CreateShot(I, ShType, Spawner, Target, X, Y, XV, YV);
   if (Shots <> nil) and (I <= High(Shots)) then
@@ -1627,15 +1627,15 @@ begin
   end;
 end;
 
-procedure MC_RECV_UpdateShot(P: Pointer);
+procedure MC_RECV_UpdateShot(var M: TMsg);
 var
   I, TX, TY, TXV, TYV: Integer;
 begin
-  I := e_Raw_Read_LongInt(P);
-  TX := e_Raw_Read_LongInt(P);
-  TY := e_Raw_Read_LongInt(P);
-  TXV := e_Raw_Read_LongInt(P);
-  TYV := e_Raw_Read_LongInt(P);
+  I := M.ReadLongInt();
+  TX := M.ReadLongInt();
+  TY := M.ReadLongInt();
+  TXV := M.ReadLongInt();
+  TYV := M.ReadLongInt();
 
   if (Shots <> nil) and (I <= High(Shots)) then
     with (Shots[i]) do
@@ -1647,46 +1647,46 @@ begin
     end;
 end;
 
-procedure MC_RECV_DeleteShot(P: Pointer);
+procedure MC_RECV_DeleteShot(var M: TMsg);
 var
   I, X, Y: Integer;
   L: Boolean;
 begin
   if not gGameOn then Exit;
-  I := e_Raw_Read_LongInt(P);
-  L := (e_Raw_Read_Byte(P) <> 0);
-  X := e_Raw_Read_LongInt(P);
-  Y := e_Raw_Read_LongInt(P);
+  I := M.ReadLongInt();
+  L := (M.ReadByte() <> 0);
+  X := M.ReadLongInt();
+  Y := M.ReadLongInt();
 
   g_Weapon_DestroyShot(I, X, Y, L);
 end;
 
-procedure MC_RECV_GameStats(P: Pointer);
+procedure MC_RECV_GameStats(var M: TMsg);
 begin
   if gGameSettings.GameMode in [GM_TDM, GM_CTF] then
   begin
-    gTeamStat[TEAM_RED].Goals := e_Raw_Read_SmallInt(P);
-    gTeamStat[TEAM_BLUE].Goals := e_Raw_Read_SmallInt(P);
+    gTeamStat[TEAM_RED].Goals := M.ReadSmallInt();
+    gTeamStat[TEAM_BLUE].Goals := M.ReadSmallInt();
   end
   else
     if gGameSettings.GameMode = GM_COOP then
     begin
-      gCoopMonstersKilled := e_Raw_Read_Word(P);
-      gCoopSecretsFound := e_Raw_Read_Word(P);
+      gCoopMonstersKilled := M.ReadWord();
+      gCoopSecretsFound := M.ReadWord();
     end;
 end;
 
-procedure MC_RECV_CoopStats(P: Pointer);
+procedure MC_RECV_CoopStats(var M: TMsg);
 begin
-  gTotalMonsters := e_Raw_Read_LongInt(P);
-  gSecretsCount := e_Raw_Read_LongInt(P);
-  gCoopTotalMonstersKilled := e_Raw_Read_Word(P);
-  gCoopTotalSecretsFound := e_Raw_Read_Word(P);
-  gCoopTotalMonsters := e_Raw_Read_Word(P);
-  gCoopTotalSecrets := e_Raw_Read_Word(P);
+  gTotalMonsters := M.ReadLongInt();
+  gSecretsCount := M.ReadLongInt();
+  gCoopTotalMonstersKilled := M.ReadWord();
+  gCoopTotalSecretsFound := M.ReadWord();
+  gCoopTotalMonsters := M.ReadWord();
+  gCoopTotalSecrets := M.ReadWord();
 end;
 
-procedure MC_RECV_GameEvent(P: Pointer);
+procedure MC_RECV_GameEvent(var M: TMsg);
 var
   EvType: Byte;
   EvNum: Integer;
@@ -1700,16 +1700,16 @@ var
   cnt: Byte;
 begin
   FillChar(EvHash, Sizeof(EvHash), 0);
-  EvType := e_Raw_Read_Byte(P);
-  EvNum := e_Raw_Read_LongInt(P);
-  EvStr := e_Raw_Read_String(P);
-  gLastMap := e_Raw_Read_Byte(P) <> 0;
+  EvType := M.ReadByte();
+  EvNum := M.ReadLongInt();
+  EvStr := M.ReadString();
+  gLastMap := M.ReadByte() <> 0;
   if gLastMap and (gGameSettings.GameMode = GM_COOP) then gStatsOff := True;
   gStatsPressed := True;
-  EvTime := e_Raw_Read_LongWord(P);
-  BHash := e_Raw_Read_Byte(P) <> 0;
+  EvTime := M.ReadLongWord();
+  BHash := M.ReadByte() <> 0;
   if BHash then
-    EvHash := e_Raw_Read_MD5(P);
+    EvHash := M.ReadMD5();
 
   gTime := EvTime;
 
@@ -1888,7 +1888,7 @@ begin
   end;
 end;
 
-procedure MC_RECV_FlagEvent(P: Pointer);
+procedure MC_RECV_FlagEvent(var M: TMsg);
 var
   PID: Word;
   Pl: TPlayer;
@@ -1897,20 +1897,20 @@ var
   Quiet: Boolean;
   s, ts: string;
 begin
-  EvType := e_Raw_Read_Byte(P);
-  Fl := e_Raw_Read_Byte(P);
+  EvType := M.ReadByte();
+  Fl := M.ReadByte();
 
   if Fl = FLAG_NONE then Exit;
 
-  Quiet := (e_Raw_Read_Byte(P) <> 0);
-  PID := e_Raw_Read_Word(P);
+  Quiet := (M.ReadByte() <> 0);
+  PID := M.ReadWord();
 
-  gFlags[Fl].State := e_Raw_Read_Byte(P);
-  gFlags[Fl].CaptureTime := e_Raw_Read_LongWord(P);
-  gFlags[Fl].Obj.X := e_Raw_Read_LongInt(P);
-  gFlags[Fl].Obj.Y := e_Raw_Read_LongInt(P);
-  gFlags[Fl].Obj.Vel.X := e_Raw_Read_LongInt(P);
-  gFlags[Fl].Obj.Vel.Y := e_Raw_Read_LongInt(P);
+  gFlags[Fl].State := M.ReadByte();
+  gFlags[Fl].CaptureTime := M.ReadLongWord();
+  gFlags[Fl].Obj.X := M.ReadLongInt();
+  gFlags[Fl].Obj.Y := M.ReadLongInt();
+  gFlags[Fl].Obj.Vel.X := M.ReadLongInt();
+  gFlags[Fl].Obj.Vel.Y := M.ReadLongInt();
 
   Pl := g_Player_Get(PID);
   if (Pl = nil) and
@@ -1995,18 +1995,18 @@ begin
   end;
 end;
 
-procedure MC_RECV_GameSettings(P: Pointer);
+procedure MC_RECV_GameSettings(var M: TMsg);
 begin
-  gGameSettings.GameMode := e_Raw_Read_Byte(P);
-  gGameSettings.GoalLimit := e_Raw_Read_Word(P);
-  gGameSettings.TimeLimit := e_Raw_Read_Word(P);
-  gGameSettings.MaxLives := e_Raw_Read_Byte(P);
-  gGameSettings.Options := e_Raw_Read_LongWord(P);
+  gGameSettings.GameMode := M.ReadByte();
+  gGameSettings.GoalLimit := M.ReadWord();
+  gGameSettings.TimeLimit := M.ReadWord();
+  gGameSettings.MaxLives := M.ReadByte();
+  gGameSettings.Options := M.ReadLongWord();
 end;
 
 // PLAYER
 
-function MC_RECV_PlayerCreate(P: Pointer): Word;
+function MC_RECV_PlayerCreate(var M: TMsg): Word;
 var
   PID, DID: Word;
   PName, Model: string;
@@ -2014,15 +2014,15 @@ var
   T: Byte;
   Pl: TPlayer;
 begin
-  PID := e_Raw_Read_Word(P);
+  PID := M.ReadWord();
   Pl := g_Player_Get(PID);
 
-  PName := e_Raw_Read_String(P);
-  Model := e_Raw_Read_String(P);
-  Color.R := e_Raw_Read_Byte(P);
-  Color.G := e_Raw_Read_Byte(P);
-  Color.B := e_Raw_Read_Byte(P);
-  T := e_Raw_Read_Byte(P);
+  PName := M.ReadString();
+  Model := M.ReadString();
+  Color.R := M.ReadByte();
+  Color.G := M.ReadByte();
+  Color.B := M.ReadByte();
+  T := M.ReadByte();
 
   Result := 0;
   if (PID <> NetPlrUID1) and (PID <> NetPlrUID2) then
@@ -2055,7 +2055,7 @@ begin
   Result := PID;
 end;
 
-function MC_RECV_PlayerPos(P: Pointer): Word;
+function MC_RECV_PlayerPos(var M: TMsg): Word;
 var
   GT: LongWord;
   PID: Word;
@@ -2066,7 +2066,7 @@ var
 begin
   Result := 0;
 
-  GT := e_Raw_Read_LongWord(P);
+  GT := M.ReadLongWord();
   if GT < gTime - NET_MAX_DIFFTIME then
   begin
     gTime := GT;
@@ -2074,7 +2074,7 @@ begin
   end;
   gTime := GT;
 
-  PID := e_Raw_Read_Word(P);
+  PID := M.ReadWord();
   Pl := g_Player_Get(PID);
 
   if Pl = nil then Exit;
@@ -2083,13 +2083,13 @@ begin
 
   with Pl do
   begin
-    FPing := e_Raw_Read_Word(P);
-    FLoss := e_Raw_Read_Byte(P);
-    kByte := e_Raw_Read_Word(P);
-    Dir := e_Raw_Read_Byte(P);
+    FPing := M.ReadWord();
+    FLoss := M.ReadByte();
+    kByte := M.ReadWord();
+    Dir := M.ReadByte();
 
-    TmpX := e_Raw_Read_LongInt(P);
-    TmpY := e_Raw_Read_LongInt(P);
+    TmpX := M.ReadLongInt();
+    TmpY := M.ReadLongInt();
 
     ReleaseKeys;
 
@@ -2107,16 +2107,16 @@ begin
     if ((Pl <> gPlayer1) and (Pl <> gPlayer2)) or LongBool(kByte and NET_KEY_FORCEDIR) then
       SetDirection(TDirection(Dir));
 
-    GameVelX := e_Raw_Read_LongInt(P);
-    GameVelY := e_Raw_Read_LongInt(P);
-    GameAccelX := e_Raw_Read_LongInt(P);
-    GameAccelY := e_Raw_Read_LongInt(P);
+    GameVelX := M.ReadLongInt();
+    GameVelY := M.ReadLongInt();
+    GameAccelX := M.ReadLongInt();
+    GameAccelY := M.ReadLongInt();
     SetLerp(TmpX, TmpY);
     if NetForcePlayerUpdate then Update();
   end;
 end;
 
-function MC_RECV_PlayerStats(P: Pointer): Word;
+function MC_RECV_PlayerStats(var M: TMsg): Word;
 var
   PID: Word;
   Pl: TPlayer;
@@ -2124,7 +2124,7 @@ var
   OldJet: Boolean;
   NewTeam: Byte;
 begin
-  PID := e_Raw_Read_Word(P);
+  PID := M.ReadWord();
   Pl := g_Player_Get(PID);
   Result := 0;
   if Pl = nil then
@@ -2132,45 +2132,45 @@ begin
 
   with Pl do
   begin
-    Live := (e_Raw_Read_Byte(P) <> 0);
-    GodMode := (e_Raw_Read_Byte(P) <> 0);
-    Health := e_Raw_Read_LongInt(P);
-    Armor := e_Raw_Read_LongInt(P);
-    Air := e_Raw_Read_LongInt(P);
-    JetFuel := e_Raw_Read_LongInt(P);
-    Lives := e_Raw_Read_Byte(P);
-    NewTeam := e_Raw_Read_Byte(P);
+    Live := (M.ReadByte() <> 0);
+    GodMode := (M.ReadByte() <> 0);
+    Health := M.ReadLongInt();
+    Armor := M.ReadLongInt();
+    Air := M.ReadLongInt();
+    JetFuel := M.ReadLongInt();
+    Lives := M.ReadByte();
+    NewTeam := M.ReadByte();
 
     for I := WP_FIRST to WP_LAST do
-      FWeapon[I] := (e_Raw_Read_Byte(P) <> 0);
+      FWeapon[I] := (M.ReadByte() <> 0);
 
     for I := A_BULLETS to A_HIGH do
-      FAmmo[I] := e_Raw_Read_Word(P);
+      FAmmo[I] := M.ReadWord();
 
     for I := A_BULLETS to A_HIGH do
-      FMaxAmmo[I] := e_Raw_Read_Word(P);
+      FMaxAmmo[I] := M.ReadWord();
 
     for I := MR_SUIT to MR_MAX do
-      FMegaRulez[I] := e_Raw_Read_LongWord(P);
+      FMegaRulez[I] := M.ReadLongWord();
 
     FRulez := [];
-    if (e_Raw_Read_Byte(P) <> 0) then
+    if (M.ReadByte() <> 0) then
       FRulez := FRulez + [R_ITEM_BACKPACK];
-    if (e_Raw_Read_Byte(P) <> 0) then
+    if (M.ReadByte() <> 0) then
       FRulez := FRulez + [R_KEY_RED];
-    if (e_Raw_Read_Byte(P) <> 0) then
+    if (M.ReadByte() <> 0) then
       FRulez := FRulez + [R_KEY_GREEN];
-    if (e_Raw_Read_Byte(P) <> 0) then
+    if (M.ReadByte() <> 0) then
       FRulez := FRulez + [R_KEY_BLUE];
-    if (e_Raw_Read_Byte(P) <> 0) then
+    if (M.ReadByte() <> 0) then
       FRulez := FRulez + [R_BERSERK];
 
-    Frags := e_Raw_Read_LongInt(P);
-    Death := e_Raw_Read_LongInt(P);
+    Frags := M.ReadLongInt();
+    Death := M.ReadLongInt();
 
-    SetWeapon(e_Raw_Read_Byte(P));
+    SetWeapon(M.ReadByte());
 
-    FSpectator := e_Raw_Read_Byte(P) <> 0;
+    FSpectator := M.ReadByte() <> 0;
     if FSpectator then
     begin
       if Pl = gPlayer1 then
@@ -2191,12 +2191,12 @@ begin
       if (gPlayer2 = nil) and (gLMSPID2 > 0) then
         gPlayer2 := g_Player_Get(gLMSPID2);
     end;
-    FGhost := e_Raw_Read_Byte(P) <> 0;
-    FPhysics := e_Raw_Read_Byte(P) <> 0;
-    FNoRespawn := e_Raw_Read_Byte(P) <> 0;
+    FGhost := M.ReadByte() <> 0;
+    FPhysics := M.ReadByte() <> 0;
+    FNoRespawn := M.ReadByte() <> 0;
     OldJet := FJetpack;
-    FJetpack := e_Raw_Read_Byte(P) <> 0;
-    FFireTime := e_Raw_Read_LongInt(P);
+    FJetpack := M.ReadByte() <> 0;
+    FFireTime := M.ReadLongInt();
     if OldJet and not FJetpack then
       JetpackOff
     else if not OldJet and FJetpack then
@@ -2208,7 +2208,7 @@ begin
   Result := PID;
 end;
 
-function MC_RECV_PlayerDamage(P: Pointer): Word;
+function MC_RECV_PlayerDamage(var M: TMsg): Word;
 var
   PID: Word;
   Pl: TPlayer;
@@ -2218,15 +2218,15 @@ var
 begin
   Result := 0;
   if not gGameOn then Exit;
-  PID := e_Raw_Read_Word(P);
+  PID := M.ReadWord();
   Pl := g_Player_Get(PID);
   if Pl = nil then Exit;
 
-  Kind := e_Raw_Read_Byte(P);
-  Attacker := e_Raw_Read_Word(P);
-  Value := e_Raw_Read_Word(P);
-  VX := e_Raw_Read_Word(P);
-  VY := e_Raw_Read_Word(P);
+  Kind := M.ReadByte();
+  Attacker := M.ReadWord();
+  Value := M.ReadWord();
+  VX := M.ReadWord();
+  VY := M.ReadWord();
 
   with Pl do
     Damage(Value, Attacker, VX, VY, Kind);
@@ -2234,7 +2234,7 @@ begin
   Result := PID;
 end;
 
-function MC_RECV_PlayerDeath(P: Pointer): Word;
+function MC_RECV_PlayerDeath(var M: TMsg): Word;
 var
   PID: Word;
   Pl: TPlayer;
@@ -2243,13 +2243,13 @@ var
 begin
   Result := 0;
   if not gGameOn then Exit;
-  PID := e_Raw_Read_Word(P);
+  PID := M.ReadWord();
   Pl := g_Player_Get(PID);
   if Pl = nil then Exit;
 
-  KillType := e_Raw_Read_Byte(P);
-  DeathType := e_Raw_Read_Byte(P);
-  Attacker := e_Raw_Read_Word(P);
+  KillType := M.ReadByte();
+  DeathType := M.ReadByte();
+  Attacker := M.ReadWord();
 
   with Pl do
   begin
@@ -2258,12 +2258,12 @@ begin
   end;
 end;
 
-function MC_RECV_PlayerDelete(P: Pointer): Word;
+function MC_RECV_PlayerDelete(var M: TMsg): Word;
 var
   PID: Word;
   Pl: TPlayer;
 begin
-  PID := e_Raw_Read_Word(P);
+  PID := M.ReadWord();
   Pl := g_Player_Get(PID);
   Result := 0;
   if Pl = nil then Exit;
@@ -2276,7 +2276,7 @@ begin
   Result := PID;
 end;
 
-function MC_RECV_PlayerFire(P: Pointer): Word;
+function MC_RECV_PlayerFire(var M: TMsg): Word;
 var
   PID: Word;
   Weap: Byte;
@@ -2286,22 +2286,22 @@ var
 begin
   Result := 0;
   if not gGameOn then Exit;
-  PID := e_Raw_Read_Word(P);
+  PID := M.ReadWord();
   Pl := g_Player_Get(PID);
   if Pl = nil then Exit;
 
-  Weap := e_Raw_Read_Byte(P);
-  X := e_Raw_Read_LongInt(P);
-  Y := e_Raw_Read_LongInt(P);
-  AX := e_Raw_Read_LongInt(P);
-  AY := e_Raw_Read_LongInt(P);
-  SHID := e_Raw_Read_LongInt(P);
+  Weap := M.ReadByte();
+  X := M.ReadLongInt();
+  Y := M.ReadLongInt();
+  AX := M.ReadLongInt();
+  AY := M.ReadLongInt();
+  SHID := M.ReadLongInt();
 
   with Pl do
     if Live then NetFire(Weap, X, Y, AX, AY, SHID);
 end;
 
-procedure MC_RECV_PlayerSettings(P: Pointer);
+procedure MC_RECV_PlayerSettings(var M: TMsg);
 var
   TmpName: string;
   TmpModel: string;
@@ -2310,16 +2310,16 @@ var
   Pl: TPlayer;
   PID: Word;
 begin
-  PID := e_Raw_Read_Word(P);
+  PID := M.ReadWord();
   Pl := g_Player_Get(PID);
   if Pl = nil then Exit;
 
-  TmpName := e_Raw_Read_String(P);
-  TmpModel := e_Raw_Read_String(P);
-  TmpColor.R := e_Raw_Read_Byte(P);
-  TmpColor.G := e_Raw_Read_Byte(P);
-  TmpColor.B := e_Raw_Read_Byte(P);
-  TmpTeam := e_Raw_Read_Byte(P);
+  TmpName := M.ReadString();
+  TmpModel := M.ReadString();
+  TmpColor.R := M.ReadByte();
+  TmpColor.G := M.ReadByte();
+  TmpColor.B := M.ReadByte();
+  TmpTeam := M.ReadByte();
 
   if (gGameSettings.GameMode in [GM_TDM, GM_CTF]) and (Pl.Team <> TmpTeam) then
   begin
@@ -2343,7 +2343,7 @@ end;
 
 // ITEM
 
-procedure MC_RECV_ItemSpawn(P: Pointer);
+procedure MC_RECV_ItemSpawn(var M: TMsg);
 var
   ID: Word;
   AID: DWord;
@@ -2354,15 +2354,15 @@ var
   it: PItem;
 begin
   if not gGameOn then Exit;
-  ID := e_Raw_Read_Word(P);
-  Quiet := e_Raw_Read_Byte(P) <> 0;
-  T := e_Raw_Read_Byte(P);
-  Fall := e_Raw_Read_Byte(P) <> 0;
-  {Resp :=} e_Raw_Read_Byte(P);
-  X := e_Raw_Read_LongInt(P);
-  Y := e_Raw_Read_LongInt(P);
-  VX := e_Raw_Read_LongInt(P);
-  VY := e_Raw_Read_LongInt(P);
+  ID := M.ReadWord();
+  Quiet := M.ReadByte() <> 0;
+  T := M.ReadByte();
+  Fall := M.ReadByte() <> 0;
+  {Resp :=} M.ReadByte();
+  X := M.ReadLongInt();
+  Y := M.ReadLongInt();
+  VX := M.ReadLongInt();
+  VY := M.ReadLongInt();
 
   g_Items_Create(X, Y, T, Fall, False, False, ID);
 
@@ -2382,14 +2382,14 @@ begin
   end;
 end;
 
-procedure MC_RECV_ItemDestroy(P: Pointer);
+procedure MC_RECV_ItemDestroy(var M: TMsg);
 var
   ID: Word;
   Quiet: Boolean;
 begin
   if not gGameOn then Exit;
-  ID := e_Raw_Read_Word(P);
-  Quiet := e_Raw_Read_Byte(P) <> 0;
+  ID := M.ReadWord();
+  Quiet := M.ReadByte() <> 0;
 
   if not g_ItemValidId(ID) then exit;
 
@@ -2400,7 +2400,7 @@ end;
 
 // PANEL
 
-procedure MC_RECV_PanelTexture(P: Pointer);
+procedure MC_RECV_PanelTexture(var M: TMsg);
 var
   TP: TPanel;
   PType: Word;
@@ -2409,12 +2409,12 @@ var
   Loop, Cnt: Byte;
 begin
   if not gGameOn then Exit;
-  PType := e_Raw_Read_Word(P);
-  ID := e_Raw_Read_LongWord(P);
-  Tex := e_Raw_Read_LongInt(P);
-  Fr := e_Raw_Read_LongInt(P);
-  Cnt := e_Raw_Read_Byte(P);
-  Loop := e_Raw_Read_Byte(P);
+  PType := M.ReadWord();
+  ID := M.ReadLongWord();
+  Tex := M.ReadLongInt();
+  Fr := M.ReadLongInt();
+  Cnt := M.ReadByte();
+  Loop := M.ReadByte();
 
   TP := nil;
 
@@ -2453,7 +2453,7 @@ begin
       TP.NextTexture(Loop);
 end;
 
-procedure MC_RECV_PanelState(P: Pointer);
+procedure MC_RECV_PanelState(var M: TMsg);
 var
   ID: LongWord;
   E: Boolean;
@@ -2462,12 +2462,12 @@ var
   X, Y: Integer;
 begin
   if not gGameOn then Exit;
-  PType := e_Raw_Read_Word(P);
-  ID := e_Raw_Read_LongWord(P);
-  E := (e_Raw_Read_Byte(P) <> 0);
-  Lift := e_Raw_Read_Byte(P);
-  X := e_Raw_Read_LongInt(P);
-  Y := e_Raw_Read_LongInt(P);
+  PType := M.ReadWord();
+  ID := M.ReadLongWord();
+  E := (M.ReadByte() <> 0);
+  Lift := M.ReadByte();
+  X := M.ReadLongInt();
+  Y := M.ReadLongInt();
 
   case PType of
     PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR:
@@ -2495,7 +2495,7 @@ end;
 
 // TRIGGERS
 
-procedure MC_RECV_TriggerSound(P: Pointer);
+procedure MC_RECV_TriggerSound(var M: TMsg);
 var
   SPlaying: Boolean;
   SPos, SID: LongWord;
@@ -2505,10 +2505,10 @@ begin
   if not gGameOn then Exit;
   if gTriggers = nil then Exit;
 
-  SID := e_Raw_Read_LongWord(P);
-  SPlaying := e_Raw_Read_Byte(P) <> 0;
-  SPos := e_Raw_Read_LongWord(P);
-  SCount := e_Raw_Read_LongInt(P);
+  SID := M.ReadLongWord();
+  SPlaying := M.ReadByte() <> 0;
+  SPos := M.ReadLongWord();
+  SCount := M.ReadLongInt();
 
   for I := Low(gTriggers) to High(gTriggers) do
     if gTriggers[I].TriggerType = TRIGGER_SOUND then
@@ -2530,7 +2530,7 @@ begin
         end;
 end;
 
-procedure MC_RECV_TriggerMusic(P: Pointer);
+procedure MC_RECV_TriggerMusic(var M: TMsg);
 var
   MName: string;
   MPlaying: Boolean;
@@ -2539,10 +2539,10 @@ var
 begin
   if not gGameOn then Exit;
 
-  MName := e_Raw_Read_String(P);
-  MPlaying := e_Raw_Read_Byte(P) <> 0;
-  MPos := e_Raw_Read_LongWord(P);
-  MPaused := e_Raw_Read_Byte(P) <> 0;
+  MName := M.ReadString();
+  MPlaying := M.ReadByte() <> 0;
+  MPos := M.ReadLongWord();
+  MPaused := M.ReadByte() <> 0;
 
   if MPlaying then
   begin
@@ -2557,41 +2557,41 @@ end;
 
 // MONSTERS
 
-procedure MC_RECV_MonsterSpawn(P: Pointer);
+procedure MC_RECV_MonsterSpawn(var M: TMsg);
 var
   ID: Word;
   MType, MState, MDir, MAnim, MBehav: Byte;
   X, Y, VX, VY, MTargTime, MHealth, MAmmo, MSleep: Integer;
   MTarg: Word;
-  M: TMonster;
+  Mon: TMonster;
 begin
-  ID := e_Raw_Read_Word(P);
-  M := g_Monsters_Get(ID);
-  if M <> nil then
+  ID := M.ReadWord();
+  Mon := g_Monsters_Get(ID);
+  if Mon <> nil then
     Exit;
 
-  MType := e_Raw_Read_Byte(P);
-  MState := e_Raw_Read_Byte(P);
-  MAnim := e_Raw_Read_Byte(P);
-  MTarg := e_Raw_Read_Word(P);
-  MTargTime := e_Raw_Read_LongInt(P);
-  MBehav := e_Raw_Read_Byte(P);
-  MSleep := e_Raw_Read_LongInt(P);
-  MHealth := e_Raw_Read_LongInt(P);
-  MAmmo := e_Raw_Read_LongInt(P);
-
-  X := e_Raw_Read_LongInt(P);
-  Y := e_Raw_Read_LongInt(P);
-  VX := e_Raw_Read_LongInt(P);
-  VY := e_Raw_Read_LongInt(P);
-  MDir := e_Raw_Read_Byte(P);
+  MType := M.ReadByte();
+  MState := M.ReadByte();
+  MAnim := M.ReadByte();
+  MTarg := M.ReadWord();
+  MTargTime := M.ReadLongInt();
+  MBehav := M.ReadByte();
+  MSleep := M.ReadLongInt();
+  MHealth := M.ReadLongInt();
+  MAmmo := M.ReadLongInt();
+
+  X := M.ReadLongInt();
+  Y := M.ReadLongInt();
+  VX := M.ReadLongInt();
+  VY := M.ReadLongInt();
+  MDir := M.ReadByte();
 
   g_Monsters_Create(MType, X, Y, TDirection(MDir), False, ID);
-  M := g_Monsters_Get(ID);
-  if M = nil then
+  Mon := g_Monsters_Get(ID);
+  if Mon = nil then
     Exit;
 
-  with M do
+  with Mon do
   begin
     GameX := X;
     GameY := Y;
@@ -2612,51 +2612,51 @@ begin
   end;
 end;
 
-procedure MC_RECV_MonsterPos(P: Pointer);
+procedure MC_RECV_MonsterPos(var M: TMsg);
 var
-  M: TMonster;
+  Mon: TMonster;
   ID: Word;
 begin
-  ID := e_Raw_Read_Word(P);
-  M := g_Monsters_Get(ID);
-  if M = nil then
+  ID := M.ReadWord();
+  Mon := g_Monsters_Get(ID);
+  if Mon = nil then
     Exit;
 
-  with M do
+  with Mon do
   begin
-    GameX := e_Raw_Read_LongInt(P);
-    GameY := e_Raw_Read_LongInt(P);
-    GameVelX := e_Raw_Read_LongInt(P);
-    GameVelY := e_Raw_Read_LongInt(P);
-    GameDirection := TDirection(e_Raw_Read_Byte(P));
+    GameX := M.ReadLongInt();
+    GameY := M.ReadLongInt();
+    GameVelX := M.ReadLongInt();
+    GameVelY := M.ReadLongInt();
+    GameDirection := TDirection(M.ReadByte());
     positionChanged(); // this updates spatial accelerators
   end;
 end;
 
-procedure MC_RECV_MonsterState(P: Pointer);
+procedure MC_RECV_MonsterState(var M: TMsg);
 var
   ID: Integer;
   MState, MFAnm: Byte;
-  M: TMonster;
+  Mon: TMonster;
   AnimRevert: Boolean;
 begin
-  ID := e_Raw_Read_Word(P);
-  M := g_Monsters_Get(ID);
-  if M = nil then Exit;
+  ID := M.ReadWord();
+  Mon := g_Monsters_Get(ID);
+  if Mon = nil then Exit;
 
-  MState := e_Raw_Read_Byte(P);
-  MFAnm := e_Raw_Read_Byte(P);
+  MState := M.ReadByte();
+  MFAnm := M.ReadByte();
 
-  with M do
+  with Mon do
   begin
-    MonsterTargetUID := e_Raw_Read_Word(P);
-    MonsterTargetTime := e_Raw_Read_LongInt(P);
-    MonsterSleep := e_Raw_Read_LongInt(P);
-    MonsterHealth := e_Raw_Read_LongInt(P);
-    MonsterAmmo := e_Raw_Read_LongInt(P);
-    MonsterPain := e_Raw_Read_LongInt(P);
-    AnimRevert := e_Raw_Read_Byte(P) <> 0;
-    FFireTime := e_Raw_Read_LongInt(P);
+    MonsterTargetUID := M.ReadWord();
+    MonsterTargetTime := M.ReadLongInt();
+    MonsterSleep := M.ReadLongInt();
+    MonsterHealth := M.ReadLongInt();
+    MonsterAmmo := M.ReadLongInt();
+    MonsterPain := M.ReadLongInt();
+    AnimRevert := M.ReadByte() <> 0;
+    FFireTime := M.ReadLongInt();
     RevertAnim(AnimRevert);
 
     if MonsterState <> MState then
@@ -2677,60 +2677,58 @@ begin
   end;
 end;
 
-procedure MC_RECV_MonsterShot(P: Pointer);
+procedure MC_RECV_MonsterShot(var M: TMsg);
 var
   ID: Integer;
-  M: TMonster;
+  Mon: TMonster;
   X, Y, VX, VY: Integer;
 begin
-  ID := e_Raw_Read_Word(P);
+  ID := M.ReadWord();
 
-  M := g_Monsters_Get(ID);
-  if M = nil then Exit;
+  Mon := g_Monsters_Get(ID);
+  if Mon = nil then Exit;
 
-  X := e_Raw_Read_LongInt(P);
-  Y := e_Raw_Read_LongInt(P);
-  VX := e_Raw_Read_LongInt(P);
-  VY := e_Raw_Read_LongInt(P);
+  X := M.ReadLongInt();
+  Y := M.ReadLongInt();
+  VX := M.ReadLongInt();
+  VY := M.ReadLongInt();
 
-  M.ClientAttack(X, Y, VX, VY);
+  Mon.ClientAttack(X, Y, VX, VY);
 end;
 
-procedure MC_RECV_MonsterDelete(P: Pointer);
+procedure MC_RECV_MonsterDelete(var M: TMsg);
 var
   ID: Integer;
-  M, mon: TMonster;
+  Mon: TMonster;
 begin
-  ID := e_Raw_Read_Word(P);
-  M := g_Monsters_Get(ID);
-  if M = nil then Exit;
-
-  mon := g_Mons_ByIdx(ID);
-  mon.SetState(5);
-  mon.MonsterRemoved := True;
+  ID := M.ReadWord();
+  Mon := g_Monsters_Get(ID);
+  if Mon = nil then Exit;
+  Mon.SetState(5);
+  Mon.MonsterRemoved := True;
 end;
 
-procedure MC_RECV_TimeSync(P: Pointer);
+procedure MC_RECV_TimeSync(var M: TMsg);
 var
   Time: LongWord;
 begin
-  Time := e_Raw_Read_LongWord(P);
+  Time := M.ReadLongWord();
 
   if gState = STATE_INTERCUSTOM then
     gServInterTime := Min(Time, 255);
 end;
 
-procedure MC_RECV_VoteEvent(P: Pointer);
+procedure MC_RECV_VoteEvent(var M: TMsg);
 var
   EvID: Byte;
   Str1, Str2: string;
   Int1, Int2: SmallInt;
 begin
-  EvID := e_Raw_Read_Byte(P);
-  Int1 := e_Raw_Read_SmallInt(P);
-  Int2 := e_Raw_Read_SmallInt(P);
-  Str1 := e_Raw_Read_String(P);
-  Str2 := e_Raw_Read_String(P);
+  EvID := M.ReadByte();
+  Int1 := M.ReadSmallInt();
+  Int2 := M.ReadSmallInt();
+  Str1 := M.ReadString();
+  Str2 := M.ReadString();
 
   case EvID of
     NET_VE_STARTED:
@@ -2750,26 +2748,26 @@ end;
 
 procedure MC_SEND_Info(Password: string);
 begin
-  e_Buffer_Clear(@NetOut);
+  NetOut.Clear();
 
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_INFO));
-  e_Buffer_Write(@NetOut, GAME_VERSION);
-  e_Buffer_Write(@NetOut, Password);
-  e_Buffer_Write(@NetOut, gPlayer1Settings.Name);
-  e_Buffer_Write(@NetOut, gPlayer1Settings.Model);
-  e_Buffer_Write(@NetOut, gPlayer1Settings.Color.R);
-  e_Buffer_Write(@NetOut, gPlayer1Settings.Color.G);
-  e_Buffer_Write(@NetOut, gPlayer1Settings.Color.B);
-  e_Buffer_Write(@NetOut, gPlayer1Settings.Team);
+  NetOut.Write(Byte(NET_MSG_INFO));
+  NetOut.Write(GAME_VERSION);
+  NetOut.Write(Password);
+  NetOut.Write(gPlayer1Settings.Name);
+  NetOut.Write(gPlayer1Settings.Model);
+  NetOut.Write(gPlayer1Settings.Color.R);
+  NetOut.Write(gPlayer1Settings.Color.G);
+  NetOut.Write(gPlayer1Settings.Color.B);
+  NetOut.Write(gPlayer1Settings.Team);
 
   g_Net_Client_Send(True, NET_CHAN_SERVICE);
 end;
 
 procedure MC_SEND_Chat(Txt: string; Mode: Byte);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_CHAT));
-  e_Buffer_Write(@NetOut, Txt);
-  e_Buffer_Write(@NetOut, Mode);
+  NetOut.Write(Byte(NET_MSG_CHAT));
+  NetOut.Write(Txt);
+  NetOut.Write(Mode);
 
   g_Net_Client_Send(True, NET_CHAN_CHAT);
 end;
@@ -2862,11 +2860,11 @@ begin
   else
     kByte := NET_KEY_CHAT;
 
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_PLRPOS));
-  e_Buffer_Write(@NetOut, gTime);
-  e_Buffer_Write(@NetOut, kByte);
-  e_Buffer_Write(@NetOut, Byte(gPlayer1.Direction));
-  e_Buffer_Write(@NetOut, WeaponSelect);
+  NetOut.Write(Byte(NET_MSG_PLRPOS));
+  NetOut.Write(gTime);
+  NetOut.Write(kByte);
+  NetOut.Write(Byte(gPlayer1.Direction));
+  NetOut.Write(WeaponSelect);
   //e_WriteLog(Format('S:ws=%d', [WeaponSelect]), MSG_WARNING);
   g_Net_Client_Send(True, NET_CHAN_PLAYERPOS);
 
@@ -2876,50 +2874,50 @@ end;
 
 procedure MC_SEND_Vote(Start: Boolean = False; Command: string = 'a');
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_VOTE_EVENT));
-  e_Buffer_Write(@NetOut, Byte(Start));
-  e_Buffer_Write(@NetOut, Command);
+  NetOut.Write(Byte(NET_MSG_VOTE_EVENT));
+  NetOut.Write(Byte(Start));
+  NetOut.Write(Command);
   g_Net_Client_Send(True, NET_CHAN_IMPORTANT);
 end;
 
 procedure MC_SEND_PlayerSettings();
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_PLRSET));
-  e_Buffer_Write(@NetOut, gPlayer1Settings.Name);
-  e_Buffer_Write(@NetOut, gPlayer1Settings.Model);
-  e_Buffer_Write(@NetOut, gPlayer1Settings.Color.R);
-  e_Buffer_Write(@NetOut, gPlayer1Settings.Color.G);
-  e_Buffer_Write(@NetOut, gPlayer1Settings.Color.B);
-  e_Buffer_Write(@NetOut, gPlayer1Settings.Team);
+  NetOut.Write(Byte(NET_MSG_PLRSET));
+  NetOut.Write(gPlayer1Settings.Name);
+  NetOut.Write(gPlayer1Settings.Model);
+  NetOut.Write(gPlayer1Settings.Color.R);
+  NetOut.Write(gPlayer1Settings.Color.G);
+  NetOut.Write(gPlayer1Settings.Color.B);
+  NetOut.Write(gPlayer1Settings.Team);
 
   g_Net_Client_Send(True, NET_CHAN_IMPORTANT);
 end;
 
 procedure MC_SEND_FullStateRequest();
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_REQFST));
+  NetOut.Write(Byte(NET_MSG_REQFST));
 
   g_Net_Client_Send(True, NET_CHAN_SERVICE);
 end;
 
 procedure MC_SEND_CheatRequest(Kind: Byte);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_CHEAT));
-  e_Buffer_Write(@NetOut, Kind);
+  NetOut.Write(Byte(NET_MSG_CHEAT));
+  NetOut.Write(Kind);
 
   g_Net_Client_Send(True, NET_CHAN_IMPORTANT);
 end;
 procedure MC_SEND_RCONPassword(Password: string);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_RCON_AUTH));
-  e_Buffer_Write(@NetOut, Password);
+  NetOut.Write(Byte(NET_MSG_RCON_AUTH));
+  NetOut.Write(Password);
 
   g_Net_Client_Send(True, NET_CHAN_SERVICE);
 end;
 procedure MC_SEND_RCONCommand(Cmd: string);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_RCON_CMD));
-  e_Buffer_Write(@NetOut, Cmd);
+  NetOut.Write(Byte(NET_MSG_RCON_CMD));
+  NetOut.Write(Cmd);
 
   g_Net_Client_Send(True, NET_CHAN_SERVICE);
 end;
@@ -3060,18 +3058,18 @@ end;
 
 procedure MC_SEND_MapRequest();
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_MAP_REQUEST));
+  NetOut.Write(Byte(NET_MSG_MAP_REQUEST));
   g_Net_Client_Send(True, NET_CHAN_IMPORTANT);
 end;
 
 procedure MC_SEND_ResRequest(const resName: AnsiString);
 begin
-  e_Buffer_Write(@NetOut, Byte(NET_MSG_RES_REQUEST));
-  e_Buffer_Write(@NetOut, resName);
+  NetOut.Write(Byte(NET_MSG_RES_REQUEST));
+  NetOut.Write(resName);
   g_Net_Client_Send(True, NET_CHAN_IMPORTANT);
 end;
 
-procedure MH_RECV_MapRequest(C: pTNetClient; P: Pointer);
+procedure MH_RECV_MapRequest(C: pTNetClient; var M: TMsg);
 var
   payload: AByte;
   peer: pENetPeer;
@@ -3091,14 +3089,14 @@ begin
   mapDataMsg.ExternalResources := nil;
 end;
 
-procedure MH_RECV_ResRequest(C: pTNetClient; P: Pointer);
+procedure MH_RECV_ResRequest(C: pTNetClient; var M: TMsg);
 var
   payload: AByte;
   peer: pENetPeer;
   FileName: String;
   resDataMsg: TResDataMsg;
 begin
-  FileName := ExtractFileName(e_Raw_Read_String(P));
+  FileName := ExtractFileName(M.ReadString());
   e_WriteLog('NET: Received res request: ' + FileName +
              ' from ' + DecodeIPV4(C.Peer.address.host), MSG_NOTIFY);