DEADSOFTWARE

net: commented out old-style resource downloading handlers
[d2df-sdl.git] / src / game / g_netmsg.pas
index 6e825fe1215744d3b12123fc1045065e50d26a53..d8f8970c8ba6e950e29ec82975c1c9b2e8df8e33 100644 (file)
@@ -2,8 +2,7 @@
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, version 3 of the License ONLY.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -72,6 +71,30 @@ const
   NET_MSG_RES_REQUEST = 203;
   NET_MSG_RES_RESPONSE = 204;
 
+  // chunked file transfers
+  // it goes this way:
+  //   client requests file (FILE_REQUEST)
+  //   server sends file header info (FILE_HEADER)
+  //   client acks chunk -1 (CHUNK_ACK) to initiate transfer, or cancels (FILE_CANCEL)
+  //   server start sending data chunks (one at a time, waiting for an ACK for each one)
+  //   when client acks the last chunk, transfer is complete
+  // this scheme sux, of course; we can do better by spamming with unreliable unsequenced packets,
+  // and use client acks to drive server sends, but meh... let's do it this way first, and
+  // we can improve it later.
+
+  // client: request a file
+  NET_MSG_FILE_REQUEST = 210;
+  // server: file info response
+  NET_MSG_FILE_HEADER = 211;
+  // client: request transfer cancellation
+  // server: something went wrong, transfer cancelled, bomb out
+  NET_MSG_FILE_CANCEL = 212;
+  // server: file chunk data
+  NET_MSG_FILE_CHUNK_DATA = 213;
+  // client: file chunk ack
+  NET_MSG_FILE_CHUNK_ACK = 214;
+
+
   NET_CHAT_SYSTEM = 0;
   NET_CHAT_PLAYER = 1;
   NET_CHAT_TEAM   = 2;
@@ -109,6 +132,8 @@ const
   NET_EV_LMS_DRAW     = 16;
   NET_EV_KILLCOMBO    = 17;
   NET_EV_PLAYER_TOUCH = 18;
+  NET_EV_SECRET       = 19;
+  NET_EV_INTER_READY  = 20;
 
   NET_VE_STARTED      = 1;
   NET_VE_PASSED       = 2;
@@ -124,6 +149,7 @@ const
 
   NET_CHEAT_SUICIDE  = 1;
   NET_CHEAT_SPECTATE = 2;
+  NET_CHEAT_READY    = 3;
 
   NET_MAX_DIFFTIME = 5000 div 36;
 
@@ -137,8 +163,8 @@ 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_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
@@ -239,8 +265,9 @@ procedure MC_SEND_RCONPassword(Password: string);
 procedure MC_SEND_RCONCommand(Cmd: string);
 procedure MC_SEND_Vote(Start: Boolean = False; Command: string = 'a');
 // DOWNLOAD
-procedure MC_SEND_MapRequest();
-procedure MC_SEND_ResRequest(const resName: AnsiString);
+//procedure MC_SEND_MapRequest();
+//procedure MC_SEND_ResRequest(const resName: AnsiString);
+
 
 type
   TExternalResourceInfo = record
@@ -264,6 +291,9 @@ type
 function MapDataFromMsgStream(msgStream: TMemoryStream):TMapDataMsg;
 function ResDataFromMsgStream(msgStream: TMemoryStream):TResDataMsg;
 
+function IsValidFileName(const S: String): Boolean;
+function IsValidFilePath(const S: String): Boolean;
+
 implementation
 
 uses
@@ -510,6 +540,21 @@ begin
       else
         Pl.Spectate;
     end;
+    NET_CHEAT_READY:
+    begin
+      if gState <> STATE_INTERCUSTOM then Exit;
+      Pl.FReady := not Pl.FReady;
+      if Pl.FReady then
+      begin
+        MH_SEND_GameEvent(NET_EV_INTER_READY, Pl.UID, 'Y');
+        Inc(gInterReadyCount);
+      end
+      else
+      begin
+        MH_SEND_GameEvent(NET_EV_INTER_READY, Pl.UID, 'N');
+        Dec(gInterReadyCount);
+      end;
+    end;
   end;
 end;
 
@@ -711,6 +756,8 @@ begin
   begin
     MH_SEND_GameEvent(NET_EV_LMS_WARMUP, (gLMSRespawnTime - gTime) div 1000, 'N', ID);
   end;
+
+  g_Net_Flush();
 end;
 
 procedure MH_SEND_Info(ID: Byte);
@@ -1662,6 +1709,7 @@ begin
   case EvType of
     NET_EV_MAPSTART:
     begin
+      g_Res_received_map_start := true;
       gGameOn := False;
       g_Game_ClearLoading();
       g_Game_StopAllSounds(True);
@@ -1684,6 +1732,7 @@ begin
 
     NET_EV_MAPEND:
     begin
+      g_Res_received_map_start := true;
       gMissionFailed := EvNum <> 0;
       gExit := EXIT_ENDLEVELCUSTOM;
     end;
@@ -1831,6 +1880,21 @@ begin
         pl.Touch();
     end;
 
+    NET_EV_SECRET:
+    begin
+      pl := g_Player_Get(EvNum);
+      if pl <> nil then
+      begin
+        g_Console_Add(Format(_lc[I_PLAYER_SECRET], [pl.Name]), True);
+        g_Sound_PlayEx('SOUND_GAME_SECRET');
+      end;
+    end;
+
+    NET_EV_INTER_READY:
+    begin
+      pl := g_Player_Get(EvNum);
+      if pl <> nil then pl.FReady := (EvStr = 'Y');
+    end;
   end;
 end;
 
@@ -2544,12 +2608,13 @@ begin
   MPlaying := M.ReadByte() <> 0;
   MPos := M.ReadLongWord();
   MPaused := M.ReadByte() <> 0;
+  MPos := MPos+1; //k8: stfu, fpc!
 
   if MPlaying then
   begin
     gMusic.SetByName(MName);
     gMusic.Play(True);
-    gMusic.SetPosition(MPos);
+    // gMusic.SetPosition(MPos);
     gMusic.SpecPause := MPaused;
   end
   else
@@ -2770,20 +2835,13 @@ begin
   g_Net_Client_Send(True, NET_CHAN_CHAT);
 end;
 
-function isKeyPressed (key1: Word; key2: Word): Boolean;
-begin
-  if (key1 <> 0) and e_KeyPressed(key1) then begin result := true; exit; end;
-  if (key2 <> 0) and e_KeyPressed(key2) then begin result := true; exit; end;
-  result := false;
-end;
-
 procedure MC_SEND_PlayerPos();
 var
   kByte: Word;
   Predict: Boolean;
   strafeDir: Byte;
   WeaponSelect: Word = 0;
-  I: Integer;
+  i: Integer;
 begin
   if not gGameOn then Exit;
   if gPlayers = nil then Exit;
@@ -2796,62 +2854,80 @@ begin
   begin
     strafeDir := P1MoveButton shr 4;
     P1MoveButton := P1MoveButton and $0F;
-    with gGameControls.P1Control do
+
+    if gPlayerAction[0, ACTION_MOVELEFT] and (not gPlayerAction[0, ACTION_MOVERIGHT]) then
+      P1MoveButton := 1
+    else if (not gPlayerAction[0, ACTION_MOVELEFT]) and gPlayerAction[0, ACTION_MOVERIGHT] then
+      P1MoveButton := 2
+    else if (not gPlayerAction[0, ACTION_MOVELEFT]) and (not gPlayerAction[0, ACTION_MOVERIGHT]) then
+      P1MoveButton := 0;
+
+    // strafing
+    if gPlayerAction[0, ACTION_STRAFE] then
     begin
-           if isKeyPressed(KeyLeft, KeyLeft2) and (not isKeyPressed(KeyRight, KeyRight2)) then P1MoveButton := 1
-      else if (not isKeyPressed(KeyLeft, KeyLeft2)) and isKeyPressed(KeyRight, KeyRight2) then P1MoveButton := 2
-      else if (not isKeyPressed(KeyLeft, KeyLeft2)) and (not isKeyPressed(KeyRight, KeyRight2)) then P1MoveButton := 0;
+      // new strafe mechanics
+      if (strafeDir = 0) then
+        strafeDir := P1MoveButton; // start strafing
+      // now set direction according to strafe (reversed)
+      if (strafeDir = 2) then
+        gPlayer1.SetDirection(TDirection.D_LEFT)
+      else if (strafeDir = 1) then
+        gPlayer1.SetDirection(TDirection.D_RIGHT)
+    end
+    else
+    begin
+      strafeDir := 0; // not strafing anymore
+      if (P1MoveButton = 2) and gPlayerAction[0, ACTION_MOVELEFT] then
+        gPlayer1.SetDirection(TDirection.D_LEFT)
+      else if (P1MoveButton = 1) and gPlayerAction[0, ACTION_MOVERIGHT] then
+        gPlayer1.SetDirection(TDirection.D_RIGHT)
+      else if P1MoveButton <> 0 then
+        gPlayer1.SetDirection(TDirection(P1MoveButton-1));
+    end;
 
-      // strafing
-      if isKeyPressed(KeyStrafe, KeyStrafe2) then
-      begin
-        // new strafe mechanics
-        if (strafeDir = 0) then strafeDir := P1MoveButton; // start strafing
-        // now set direction according to strafe (reversed)
-             if (strafeDir = 2) then gPlayer1.SetDirection(TDirection.D_LEFT)
-        else if (strafeDir = 1) then gPlayer1.SetDirection(TDirection.D_RIGHT);
-      end
-      else
-      begin
-             if (P1MoveButton = 2) and isKeyPressed(KeyLeft, KeyLeft2) then gPlayer1.SetDirection(TDirection.D_LEFT)
-        else if (P1MoveButton = 1) and isKeyPressed(KeyRight, KeyRight2) then gPlayer1.SetDirection(TDirection.D_RIGHT)
-        else if P1MoveButton <> 0 then gPlayer1.SetDirection(TDirection(P1MoveButton-1));
-      end;
+    gPlayer1.ReleaseKeys;
+    if P1MoveButton = 1 then
+    begin
+      kByte := kByte or NET_KEY_LEFT;
+      if Predict then gPlayer1.PressKey(KEY_LEFT, 10000);
+    end;
+    if P1MoveButton = 2 then
+    begin
+      kByte := kByte or NET_KEY_RIGHT;
+      if Predict then gPlayer1.PressKey(KEY_RIGHT, 10000);
+    end;
+    if gPlayerAction[0, ACTION_LOOKUP] then
+    begin
+      kByte := kByte or NET_KEY_UP;
+      gPlayer1.PressKey(KEY_UP, 10000);
+    end;
+    if gPlayerAction[0, ACTION_LOOKDOWN] then
+    begin
+      kByte := kByte or NET_KEY_DOWN;
+      gPlayer1.PressKey(KEY_DOWN, 10000);
+    end;
+    if gPlayerAction[0, ACTION_JUMP] then
+    begin
+      kByte := kByte or NET_KEY_JUMP;
+      // gPlayer1.PressKey(KEY_JUMP, 10000); // TODO: Make a prediction option
+    end;
+    if gPlayerAction[0, ACTION_ATTACK] then kByte := kByte or NET_KEY_FIRE;
+    if gPlayerAction[0, ACTION_ACTIVATE] then kByte := kByte or NET_KEY_OPEN;
+    if gPlayerAction[0, ACTION_WEAPNEXT] then kByte := kByte or NET_KEY_NW;
+    if gPlayerAction[0, ACTION_WEAPPREV] then kByte := kByte or NET_KEY_PW;
 
-      gPlayer1.ReleaseKeys;
-      if P1MoveButton = 1 then
-      begin
-        kByte := kByte or NET_KEY_LEFT;
-        if Predict then gPlayer1.PressKey(KEY_LEFT, 10000);
-      end;
-      if P1MoveButton = 2 then
-      begin
-        kByte := kByte or NET_KEY_RIGHT;
-        if Predict then gPlayer1.PressKey(KEY_RIGHT, 10000);
-      end;
-      if isKeyPressed(KeyUp, KeyUp2) then
-      begin
-        kByte := kByte or NET_KEY_UP;
-        gPlayer1.PressKey(KEY_UP, 10000);
-      end;
-      if isKeyPressed(KeyDown, KeyDown2) then
-      begin
-        kByte := kByte or NET_KEY_DOWN;
-        gPlayer1.PressKey(KEY_DOWN, 10000);
-      end;
-      if isKeyPressed(KeyJump, KeyJump2) then
+    gPlayerAction[0, ACTION_WEAPNEXT] := False; // HACK, remove after readyweaon&pendinweapon implementation
+    gPlayerAction[0, ACTION_WEAPPREV] := False; // HACK, remove after readyweaon&pendinweapon implementation
+
+    for i := WP_FIRST to WP_LAST do
+    begin
+      if gSelectWeapon[0, i] then
       begin
-        kByte := kByte or NET_KEY_JUMP;
-        // gPlayer1.PressKey(KEY_JUMP, 10000); // TODO: Make a prediction option
-      end;
-      if isKeyPressed(KeyFire, KeyFire2) then kByte := kByte or NET_KEY_FIRE;
-      if isKeyPressed(KeyOpen, KeyOpen2) then kByte := kByte or NET_KEY_OPEN;
-      if isKeyPressed(KeyNextWeapon, KeyNextWeapon2) then kByte := kByte or NET_KEY_NW;
-      if isKeyPressed(KeyPrevWeapon, KeyPrevWeapon2) then kByte := kByte or NET_KEY_PW;
-      for I := 0 to High(KeyWeapon) do
-        if isKeyPressed(KeyWeapon[I], KeyWeapon2[I]) then
-          WeaponSelect := WeaponSelect or Word(1 shl I);
+        WeaponSelect := WeaponSelect or Word(1 shl i);
+        gSelectWeapon[0, i] := False
+      end
     end;
+
     // fix movebutton state
     P1MoveButton := P1MoveButton or (strafeDir shl 4);
   end
@@ -3054,6 +3130,7 @@ begin
   Result := True;
 end;
 
+{
 procedure MC_SEND_MapRequest();
 begin
   NetOut.Write(Byte(NET_MSG_MAP_REQUEST));
@@ -3069,8 +3146,8 @@ end;
 
 procedure MH_RECV_MapRequest(C: pTNetClient; var M: TMsg);
 var
-  payload: AByte;
   peer: pENetPeer;
+  payload: AByte;
   mapDataMsg: TMapDataMsg;
 begin
   e_WriteLog('NET: Received map request from ' +
@@ -3116,5 +3193,7 @@ begin
     g_Net_SendData(payload, peer, True, NET_CHAN_DOWNLOAD);
   end;
 end;
+}
+
 
 end.