2005. július 20., szerda

Anti Cheat code in savegame files


Problem/Question/Abstract:

Quick way to make Anti Cheat code in save game files using RandSeed

Answer:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

const
  NUM_CLUES = 50;
type
  Counter = Integer;
  TGameRec = record
    GameName: string[20];
    AnswerFound: array[1..NUM_CLUES] of boolean;
  end;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
uses
  INIFiles;

var
  GameRec: tGameRec;
  IniFileName: string;
  TheINI: TIniFile;

  { =============================================== }

procedure InitGameRec(var G: TGameRec);
var
  C: Counter;
begin
  with G do
  begin
    GameName := 'A Funny Test Game';
    for C := 1 to NUM_CLUES do
      AnswerFound[C] := false;
  end;
end;
{ =============================================== }

function AntiCheatString(R: TGameRec): string;
var
  aSeed: LongInt;
  S: string;
  C: counter;
begin
  S := '';
  aSeed := 999; // or somwthing else
  for C := 1 to length(R.GameName) do
    aSeed := aSeed + ord(R.GameName[C]);
  for C := 1 to NUM_CLUES do
    if R.AnswerFound[C] then
      aSeed := aSeed + 333 // or somwthing else
    else
      aSeed := aSeed + 666; // or somwthing else
  RandSeed := aSeed;
  for C := 1 to 50 do
    S := S + chr(random(26) + ord('A'));
  result := S;
end;
{ =============================================== }

procedure SaveINI;
var
  R: TGameRec;
  C: counter;
  S: string;
begin
  TheINI := TIniFile.Create(IniFileName);
  R := GameRec;
  TheINI.WriteString('Files', 'EXE File Name', ParamStr(0));
  TheIni.WriteString('Files', 'INI File Name', IniFileName);
  TheIni.WriteString('Game', 'Name', R.GameName);
  S := AntiCheatString(R);
  TheINI.WriteString('Anti Cheat Section', 'Code', S);
  for C := 1 to NUM_CLUES do
  begin
    S := 'Clue Number ' + IntToStr(C);
    TheINI.WriteBool('Clues', S, R.AnswerFound[C]);
  end;
  TheINI.Free;
end;
{ =============================================== }

function ReadINIOK: boolean;
var
  R: TGameRec;
  C: counter;
  aCode,
    S: string;
begin

  TheINI := TIniFile.Create(IniFileName);
  R.GameName := TheINI.ReadString('Game', 'Name', 'Not Found');
  for C := 1 to NUM_CLUES do
  begin
    S := 'Clue Number ' + IntToStr(C);
    R.AnswerFound[C] := theINI.ReadBool('Clues', S, false);
  end;
  aCode := TheINI.ReadString('Anti Cheat Section', 'Code', 'Cheat');
  TheINI.Free;

  S := AntiCheatString(R);
  result := (S = aCode);
end;
{ =============================================== }

procedure TForm1.FormCreate(Sender: TObject);
begin
  IniFileName := ExtractFileDir(paramStr(0)) + '\' + 'Test.ini';
  if not FileExists(IniFileName) then // save for 1st ever run
  begin
    InitGameRec(GameRec);
    SaveINI;
  end;
  if ReadINIOK then
    ShowMessage('Ini File OK')
  else
    ShowMessage('Ini File is no good');
end;

end.

Nincsenek megjegyzések:

Megjegyzés küldése