⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sv_user.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
  if (size = 0) then
    size := 1;

  percent := (sv_client^.downloadcount * 100) div size;
  MSG_WriteByte(sv_client^.netchan.message, percent);
  SZ_Write(sv_client^.netchan.message, Pointer(Cardinal(sv_client^.download) + sv_client^.downloadcount - r), r);

  if (sv_client^.downloadcount <> sv_client^.downloadsize) then
    Exit;

  FS_FreeFile(sv_client^.download);
  sv_client^.download := nil;
end;

(* ==================
SV_BeginDownload_f
================== *)

procedure SV_BeginDownload_f;
var
  name: PChar;
  offset: Integer;
begin
  (*
  extern	cvar_t *allow_download;
  extern	cvar_t *allow_download_players;
  extern	cvar_t *allow_download_models;
  extern	cvar_t *allow_download_sounds;
  extern	cvar_t *allow_download_maps;
  extern	int		file_from_pak; // ZOID did file come from pak? *)
  offset := 0;

  name := Cmd_Argv(1);

  if (Cmd_Argc > 2) then
    offset := StrToInt(Cmd_Argv(2));    // downloaded offset

  { hacked by zoid to allow more conrol over download
    first off, no .. or global allow check }
  if ((strstr(name, '..') <> nil)
    or (not (allow_download.value <> 0))
    // leading dot is no good
    or (name^ = '.')
    // leading slash bad as well, must be in subdir
    or (name^ = '/')
    // next up, skin check
    or ((strncmp(name, 'players/', 6) = 0) and (not (allow_download_players.value <> 0)))
    // now models
    or ((strncmp(name, 'models/', 6) = 0) and (not (allow_download_models.value <> 0)))
    // now sounds
    or ((strncmp(name, 'sound/', 6) = 0) and (not (allow_download_sounds.value <> 0)))
    // now maps (note special case for maps, must not be in pak)
    or ((strncmp(name, 'maps/', 6) = 0) and (not (allow_download_maps.value <> 0)))
    // MUST be in a subdirectory
    or (strstr(name, '/') = nil)
    ) then
  begin                                 { don't allow anything with .. path }
    MSG_WriteByte(sv_client^.netchan.message, Integer(svc_download));
    MSG_WriteShort(sv_client^.netchan.message, -1);
    MSG_WriteByte(sv_client^.netchan.message, 0);
    Exit;
  end;

  if (sv_client^.download <> nil) then
    FS_FreeFile(sv_client^.download);

  sv_client^.downloadsize := FS_LoadFile(name, @sv_client^.download);
  sv_client^.downloadcount := offset;

  if (offset > sv_client^.downloadsize) then
    sv_client^.downloadcount := sv_client^.downloadsize;

  if (not (sv_client^.download <> nil)
    // special check for maps, if it came from a pak file, don't allow
    // download  ZOID
    or (strncmp(name, 'maps/', 5) = 0) and (file_from_pak <> 0)) then
  begin
    Com_DPrintf('Couldn''t download %s to %s'#10, [name, sv_client^.name]);
    if (sv_client^.download <> nil) then
    begin
      FS_FreeFile(sv_client^.download);
      sv_client^.download := nil;
    end;

    MSG_WriteByte(sv_client^.netchan.message, Integer(svc_download));
    MSG_WriteShort(sv_client^.netchan.message, -1);
    MSG_WriteByte(sv_client^.netchan.message, 0);
    Exit;
  end;

  SV_NextDownload_f;
  Com_DPrintf('Downloading %s to %s'#10, [name, sv_client^.name]);
end;

(* =================
SV_Disconnect_f

The client is going to disconnect, so remove the connection immediately
================= *)

procedure SV_Disconnect_f;
begin
  //	SV_EndRedirect ();
  SV_DropClient(sv_client);
end;

(* ==================
SV_ShowServerinfo_f

Dumps the serverinfo info string
================== *)

procedure SV_ShowServerinfo_f;
begin
  Info_Print(Cvar_Serverinfo_);
end;

procedure SV_Nextserver;
var
  v: PChar;
begin
  //ZOID, ss_pic can be nextserver'd in coop mode
  if (sv.state = ss_game) or ((sv.state = ss_pic) and (not (Cvar_VariableValue('coop') <> 0))) then
    Exit;                               // can't nextserver while playing a normal game

  Inc(svs.spawncount);                  // make sure another doesn't sneak in
  v := Cvar_VariableString('nextserver');
  if (v[0] = #0) then
    Cbuf_AddText('killserver'#10)
  else
  begin
    Cbuf_AddText(v);
    Cbuf_AddText(#10);
  end;
  Cvar_Set('nextserver', '');
end;

(* ==================
SV_Nextserver_f

A cinematic has completed or been aborted by a client, so move
to the next server,
================== *)

procedure SV_Nextserver_f;
begin
  if (StrToInt(Cmd_Argv(1)) <> svs.spawncount) then
  begin
    Com_DPrintf('Nextserver() from wrong level, from %s'#10, [sv_client^.name]);
    Exit;                               // leftover from last server
  end;

  Com_DPrintf('Nextserver() from %s'#10, [sv_client^.name]);

  SV_Nextserver;
end;

(* ==================
SV_ExecuteUserCommand
================== *)

procedure SV_ExecuteUserCommand(s: PChar);
var
  i: Integer;
begin
  Cmd_TokenizeString(s, true);
  sv_player := sv_client^.edict;

  //  SV_BeginRedirect (RD_CLIENT);

  i := 0;
  while (ucmds[i].name <> nil) do
  begin
    if (strcmp(Cmd_Argv(0), ucmds[i].name) = 0) then
    begin
      ucmds[i].func;
      Exit;
    end;
    Inc(i);
  end;

  if ((ucmds[i].name = nil) and (sv.state = ss_game)) then
    ge^.ClientCommand(sv_player);

  //  SV_EndRedirect ();
end;

(* ===========================================================================

USER CMD EXECUTION

=========================================================================== *)

procedure SV_ClientThink(cl: client_p; cmd: usercmd_p);
begin
  cl^.commandMsec := (cl^.commandMsec - cmd.msec);

  if (cl^.commandMsec < 0) and (sv_enforcetime^.value <> 0) then
  begin
    Com_DPrintf('commandMsec underflow from %s'#10, [cl^.name]);
    Exit;
  end;

  ge^.ClientThink(cl^.edict, cmd);
end;

(* ===================
SV_ExecuteClientMessage

The current net_message is parsed for the given client
=================== *)

procedure SV_ExecuteClientMessage(cl: client_p);
var
  c, net_drop, stringCmdCount, checksum, calculatedChecksum, checksumIndex,
    lastframe: Integer;
  s: PChar;
  nullcmd, oldest, oldcmd, newcmd: usercmd_t;
  move_issued: qboolean;
begin
  sv_client := cl;
  sv_player := sv_client^.edict;

  // only allow one move command
  move_issued := false;
  stringCmdCount := 0;

  while (True) do
  begin
    if (net_message.readcount > net_message.cursize) then
    begin
      Com_Printf('SV_ReadClientMessage: badread'#10, []);
      SV_DropClient(cl);
      Exit;
    end;

    c := MSG_ReadByte(net_message);
    if (c = -1) then
      Break;

    case clc_ops_e(c) of
      clc_nop: ;

      clc_userinfo:
        begin
          strncpy(cl^.userinfo, MSG_ReadString(net_message), (SizeOf(cl^.userinfo) - 1));
          SV_UserinfoChanged(cl);
        end;

      clc_move:
        begin
          if (move_issued) then
            Exit;                       { someone is trying to cheat... }

          move_issued := true;
          checksumIndex := net_message.readcount;
          checksum := MSG_ReadByte(net_message);
          lastframe := MSG_ReadLong(net_message);
          if (lastframe <> cl^.lastframe) then
          begin
            cl^.lastframe := lastframe;
            if (cl^.lastframe > 0) then
            begin
              cl^.frame_latency[cl^.lastframe and (LATENCY_COUNTS - 1)] :=
                svs.realtime - cl^.frames[cl^.lastframe and UPDATE_MASK].senttime;
            end;
          end;

          FillChar(nullcmd, SizeOf(nullcmd), 0);
          MSG_ReadDeltaUsercmd(net_message, nullcmd, oldest);
          MSG_ReadDeltaUsercmd(net_message, oldest, oldcmd);
          MSG_ReadDeltaUsercmd(net_message, oldcmd, newcmd);

          if (cl^.state <> cs_spawned) then
          begin
            cl^.lastframe := -1;
            Break;
          end;

          { if the checksum fails, ignore the rest of the packet }
          calculatedChecksum := COM_BlockSequenceCRCByte(
            Pointer(Cardinal(net_message.data) + checksumIndex + 1),
            net_message.readcount - checksumIndex - 1,
            cl.netchan.incoming_sequence);

          if (calculatedChecksum <> checksum) then
          begin
            Com_DPrintf('Failed command checksum for %s (%d != %d)/%d'#10,
              [cl.name, calculatedChecksum, checksum,
              cl.netchan.incoming_sequence]);
            Exit;
          end;

          if (sv_paused.value = 0) then
          begin
            net_drop := cl.netchan.dropped;
            if (net_drop < 20) then
            begin
              //if (net_drop > 2)

              //	Com_Printf ("drop %d\n", net_drop);
              while (net_drop > 2) do
              begin
                SV_ClientThink(cl, @cl.lastcmd);

                Dec(net_drop);
              end;

              if (net_drop > 1) then
                SV_ClientThink(cl, @oldest);

              if (net_drop > 0) then
                SV_ClientThink(cl, @oldcmd);

            end;
            SV_ClientThink(cl, @newcmd);
          end;

          cl.lastcmd := newcmd;
        end;

      clc_stringcmd:
        begin
          s := MSG_ReadString(net_message);

          { malicious users may try using too many string commands }
          Inc(stringCmdCount);
          if (stringCmdCount < MAX_STRINGCMDS) then
            SV_ExecuteUserCommand(s);

          if (cl^.state = cs_zombie) then
            Exit;                       { disconnect command }

        end;
    else
      Com_Printf('SV_ReadClientMessage: unknown command char'#10, []);
      SV_DropClient(cl);
      Exit;
    end;
  end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -