[source] A delphi objectmanager component menu

Shout-Out

User Tag List

Results 1 to 3 of 3
  1. #1
    Därkness's Avatar Active Member
    Reputation
    22
    Join Date
    Jul 2009
    Posts
    113
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [source] A delphi objectmanager component

    Hey all, I was bored on a family holiday, and I discovered a bunch of saved tutorials on my netbook's hd, and the source of a my old half completed one, so I decided to give my object manager a rewrite.

    NOTES
    It was written in delphi 7, I tried to take advantage of oop like in this tut:

    http://www.mmowned.com/forums/world-...e-objects.html

    The descriptors etc are largely uncompleted as well as outdated because I only had old info and offsets, and I don't intend to finish the project because I have no gametime and my graphics card just fried (oh joys of life :S). The most important things such as the object arrays, localplayer, guid, most object's x and y position should be working though.

    USAGE AND DEVELOPMENT
    If you want to use this in your own project you are welcome to, however if you release it please give credit to me, I put this up just in case anyone wants to try learn from it, I personally wouldn't endorse my work, but I have commented it somewhat, and if you are familiar with classes and inheritance in delphi you should be able to follow what it does.

    To "Install" the object manager:
    - Create and save the .pas files (unit files) by copying the unit code that is down the bottom of this post, into notepad, and saving them as theunitsname.pas eg moduleWoWObjectManager.pas
    Add them as components to delphi:
    - Go to delphi
    - Click the component drop-down menu
    - Click install component
    - Either install them into an existing package (I did dclusr.dpk, the default) or new package NOTE YOU MUST INSTALL ALL 4 COMPONENTS.
    Now you can access the object manager component by adding moduleWoWObjectManager to your uses clause.

    To use the object manager:
    - With moduleWoWObjectManager in uses, create a new TWoWObjectManager
    eg as a global var
    Code:
    var
      ObjMgr: TWoWObjectManager;
    - Before use you must run the constructor method so
    Code:
    objmgr:= TWoWObjectManager.CreateObjMgr(Form1, FindWoWWindow, 250)
    where Form1 is the owner of objmgr, findwowwindow holds or returns the hwnd of the wow window, and 250 is the rate you want the object arrays to update at.
    - Now, with some luck, ObjMgr.GameObjects will hold all game objects, ObjMgr.PlayerObjects all player objects, etc. They auto update, take a look at the TWoWObjects to see the classes used for the arrays.

    Anyway heres the source:
    NOTE: o_GTTimer and UInt64Lib weren't created by me (duh)

    Code:
    unit UInt64Lib;
    {
      Unsigned 64 bit Integer support for Delphi 6 and Kylix.
      Copyright (c) 2002 by DelphiFactory Netherlands BV
    
      This unit provides to routines to convert between strings and unsigned
      64 bit integers.
    
      UInt64 range: 0..18446744073709551615
    
      Thanks to J.H.Plantenberg for the assembler part.
    
      For comments mail to:
      [email protected]
    }
    
    interface
    
    resourcestring
      SInvalidUInt64 = '''%s'' is not a valid UInt64 value';
    
    { The UInt64 type is declared as a strong typed Int64, since both compilers
      don't support unsigned 64 bit integers. This way you can at least do some
      calculations. }
    type
      UInt64 = type Int64;
    
    { StrToUInt64 converts the given string to an unsigned 64 bit integer value.
      If the string doesn't contain a valid value, an EConvertError exception is
      raised. }
    function StrToUInt64(const S: AnsiString): UInt64;
    
    { UInt64ToStr converts the given value to its decimal string representation. }
    function UInt64ToStr(Value: UInt64): string;
    
    implementation
    
    // For speed we are going to use the fact that long strings are
    // guaranteed to be null-terminated:
    {$R-} // Range checking must be disabled
    {$B-} // Do not perform complete boolean expression evaluations
    
    uses
      SysUtils;
    
    type
      _UInt64 = packed record   // Split the 64 bit into 2x32 bit
        Lo, Hi : LongWord;
      end;
    
    procedure RaiseEConvertError(const S: AnsiString);
    begin
      // raise an exception explaining the input string was invalid
      raise EConvertError.CreateResFmt(@SInvalidUInt64, [S]);
    end;
    
    function StrToUInt64(const S: AnsiString): UInt64;
    var
      I: LongWord;
      Dig: Integer;
      Digit : LongWord;
      Hi,Lo : LongWord;
    
    begin
      // check if S is empty (is nil pointer)
      if S = '' then
        RaiseEConvertError(S);
    
      // start at the first character
      I := 1;
    
      // trim leading spaces
      while S[I] = ' ' do
        Inc(I);
    
      if S[I] = '-' then // check for minus sign
        RaiseEConvertError(S);
    
      if S[I] = '+' then // check for plus sign
        Inc(I);
    
      // Check for hexidecimal string id:  '$' or '0x'
      if (S[I] = '$') or ((S[I] = '0') and (Upcase(S[I+1]) = 'X')) then
      begin
        // trim leading zero (if '0x' hex marker)
        if S[I] = '0' then
          Inc(I);
    
        // trim hex marker
        Inc(I);
    
        // Check if empty
        if S[I] = #0 then
          RaiseEConvertError(S);
    
        // init loop
        Dig := 0;
        Result := 0;
    
        // while not end of string
        while S[I] <> #0 do
        begin
          // try character convert
          case S[I] of
            '0'..'9': Dig := Ord(S[I]) -  Ord('0');
            'A'..'F': Dig := Ord(S[I]) - (Ord('A') - 10);
            'a'..'f': Dig := Ord(S[I]) - (Ord('a') - 10);
          else
            RaiseEConvertError(S)
          end;
    
          // still enough room in result?
          if Result shr 60 > 0 then
            RaiseEConvertError(S);
    
          // shift converted digit into result
          Result := Result shl 4 + Dig;
    
          // next char
          Inc(I);
        end;
      end
      else begin  // decimal unsigned 64 bit conversion
    
        // check if not empty
        if S[I] = #0 then
          RaiseEConvertError(S);
    
        Hi := 0;
        Lo := 0;
        while S[I] <> #0 do
        begin
          // Extract the digit from the string and convert it ASCII->Byte
          Digit := Ord(S[I]) xor Ord('0');
    
          // Some assembler to perform an unsigned 64 bit integer calculation.
          // This asm code runs in D6 and Kylix (PIC code).
          //  HiLo := (HiLo*10)+Digit
          asm
            push   esi               // save register
    
            // calculate: Hi * 10;
            mov    eax, Hi           // Load Hi
            mov    ecx, 10           // multiplier is 10
            mul    ecx               // EDX:EAX := EAX*ECX
            or     edx, edx          // Overflow?
            jnz    @TooBig           // yes -> bye bye
    
            // calculate: Lo * 10
            mov    esi, eax          // save Hi value
            mov    eax, Lo           // load Lo
            mul    ecx               // EDX:EAX := EAX*ECX
    
            // Combine Hi, Lo, and overflow of Lo to form HiLo result
            add    edx, esi          // EDX:EAX := HiLo*10
    
            // HiLo := HiLo + Digit
            add    eax, Digit        // EDX:EAX := HiLo+Digit
            adc    edx, 0            // check overflow
            jc     @TooBig           // yes -> bye bye
    
            // save HiLo
            mov    Hi, edx           // Hi := EDX
            mov    Lo, eax           // Lo := EAX
            jmp    @TheEnd           // successfull finish
          @TooBig:
            mov    Digit, 666        // something went wrong: invalidate Digit
          @TheEnd:
    
            pop    esi              // restore register
          end;
    
          // Check if digit was legal and if the previous calculation was a success
          if not (Digit in [0..9]) then
            RaiseEConvertError(S);
    
          // proceed to the next digit
          Inc(I);
        end;
        // Return HiLo as an unsigned 64 bit integer
        _UInt64(Result).Lo := Lo;
        _UInt64(Result).Hi := Hi;
      end;
    end;
    
    
    function UInt64ToStr(Value: UInt64): string;
    const
      BiggestUInt64Str = '18446744073709551615';
      MaxBCD = Length(BiggestUInt64Str);
    
    type
      TBCD = array[0..MaxBCD-1] of Integer; { Index 0 is highest BCD digit}
    
      procedure AddBCD(var BCD : TBCD; Pos,Value : Integer);
      begin
        Inc(BCD[Pos], Value);
        if BCD[Pos] > 9 then
        begin
          Dec(BCD[Pos],10);
          AddBCD(BCD,Pos-1, 1);
        end;
      end;
    
      procedure IncBCD(var A : TBCD; const B : TBCD);
      var
        I : Integer;
      begin
        for I := MaxBCD-1 downto 0 do
          AddBCD(A, I, B[I]);
      end;
    
    var
      ValueBCD : TBCD;
      BitValue : TBCD;
      Tmp : TBCD;
      I : Integer;
      Ofs : Integer;
    
    begin
      // default to zero
      FillChar(ValueBCD, SizeOf(ValueBCD), 0);
    
      // set bit value BCD. Lowest bit has value 1
      FillChar(BitValue, SizeOf(BitValue), 0);
      BitValue[MaxBCD-1] := 1;
    
      // check if there are bits available
      while Value <> 0 do
      begin
        // if current lowest bit is set
        //  Increment the BCD value with the current bit value
        if Value and 1 <> 0 then
          IncBCD(ValueBCD, BitValue);
    
        // proceed to the next bit
        Value := Value shr 1;
    
        // Double the BitValue
        Tmp := BitValue;
        IncBCD(BitValue, Tmp);
      end;
    
      // Find highest non zero decimal
      Ofs := 0;
      while (Ofs < MaxBCD) and (ValueBCD[Ofs] = 0) do
        Inc(Ofs);
    
      // check if any non zero decimals present
      if Ofs < MaxBCD then
      begin
        // convert BCD result to ASCII result
        SetLength(Result, MaxBCD-Ofs);
        I := Ofs;
        Repeat
          Result[I-Ofs+1] := Char(ValueBCD[I]+Ord('0'));
          Inc(I);
        until I > MaxBCD-1;
      end
      else
        Result := '0';  // nothing set -> value is '0'
    end;
    
    end.
    Code:
    {                                                       }
    {       GT Delphi Components                            }
    {       GT Threaded Timer                               }
    {                                                       }
    {       Copyright (c) GT Delphi Components              }
    {       http://www.gtdelphicomponents.gr                }
    {                                                       }
    {                                                       }
    
    unit o_GTTimer;
    
    interface
    
    uses
      Classes
      ;
    
    type
    {------------------------------------------------------------------------------}
      TgtTimer = class;
    {------------------------------------------------------------------------------}
     TgtTimerThread = class(TThread)
     private
       { Private declarations }
       FTimer : TgtTimer;
     protected
       { Protected declarations }
       procedure DoTimer;
     public
       { Public declarations }
       constructor Create(ATimer : TgtTimer);
       destructor  Destroy;override;
       procedure Execute;override;
     published
       { Published declarations}
     end;
    {------------------------------------------------------------------------------}
      TgtTimer = class(TComponent)
      private
        FEnabled: Boolean;
        FInterval: Cardinal;
        FOnTimer: TNotifyEvent;
        procedure SetEnabled(const Value: Boolean);
        procedure SetInterval(const Value: Cardinal);
        { Private declarations }
      protected
        { Protected declarations }
        FTimerThread : TgtTimerThread;
        procedure UpdateTimer;
      public
        { Public declarations }
        constructor Create(AOwner:TComponent);override;
        destructor  Destroy;override;
      published
        { Published declarations}
        property Enabled : Boolean  read FEnabled  write SetEnabled;
        property Interval: Cardinal read FInterval write SetInterval;
      published
        property OnTimer : TNotifyEvent read FOnTimer write FOnTimer;
      end;
    {------------------------------------------------------------------------------}
    
    implementation
    uses
       Windows
      ,SysUtils
      ;
    
    { TgtTimerThread }
    {------------------------------------------------------------------------------}
    constructor TgtTimerThread.Create(ATimer: TgtTimer);
    begin
      inherited Create(True);
      FreeOnTerminate := True;
      FTimer          := ATimer;
    end;
    {------------------------------------------------------------------------------}
    destructor TgtTimerThread.Destroy;
    begin
      inherited;
    end;
    {------------------------------------------------------------------------------}
    procedure TgtTimerThread.DoTimer;
    begin
      if Assigned(FTimer.OnTimer) then
        FTimer.OnTimer(FTimer);
    end;
    {------------------------------------------------------------------------------}
    procedure TgtTimerThread.Execute;
    begin
      while (not Self.Terminated) and (FTimer.Enabled) do
      begin
        WaitForSingleObject(Self.Handle,FTimer.Interval);
        Synchronize(DoTimer);
      end;
    end;
    {------------------------------------------------------------------------------}
    
    { TgtTimer }
    {------------------------------------------------------------------------------}
    constructor TgtTimer.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      FEnabled  := True;
      FInterval := 1000;
    end;
    {------------------------------------------------------------------------------}
    destructor TgtTimer.Destroy;
    begin
      inherited;
    end;
    {------------------------------------------------------------------------------}
    procedure TgtTimer.UpdateTimer;
    begin
      if Assigned(FTimerThread) then
      begin
        FTimerThread.Terminate;
        FTimerThread := nil;
      end;
      if Enabled then
      begin
        if FInterval > 0 then
        begin
          FTimerThread := TgtTimerThread.Create(Self);
          FTimerThread.Resume;
        end
        else
          Enabled := False;
      end;
    end;
    {------------------------------------------------------------------------------}
    
    //Getters - Setters\\
    {------------------------------------------------------------------------------}
    procedure TgtTimer.SetEnabled(const Value: Boolean);
    begin
      FEnabled := Value;
      UpdateTimer;
    end;
    {------------------------------------------------------------------------------}
    procedure TgtTimer.SetInterval(const Value: Cardinal);
    begin
      if Value <> FInterval then
      begin
        FInterval := Value;
        UpdateTimer;
      end;
    end;
    {------------------------------------------------------------------------------}
    
    end.
    Yer I know, this offset unit is both ugly, terrible and stuipid, I was cbf changing it once I started
    Code:
    unit moduleWoWOffsets;
    ///////////////////////////////////////////////////////////////////////////////
    //This unit contains offsets for all WoW modules. Very dodge way of doing it :S//
    ///////////////////////////////////////////////////////////////////////////////
    {To do:
     - Add FindPattern methods, for updateable currmgr
     - Possibly read currmanager straight from here.
    }
    
    interface
    
    type
      TWoWOffsets = Class
      published
        function ClientConnection: Cardinal;
        function CurrMgr: Cardinal;
        function FirstObject: Cardinal;
        function NextObject: Cardinal;
        function LocalGUID: Cardinal;
        function objGuid: Cardinal;
        function objType: Cardinal;
        function objXPosition: Cardinal;
        function objYPosition: Cardinal;
        function objZPosition: Cardinal;
        function objRotation: Cardinal;
        function objDescriptorFields: Cardinal;
        function crPitch1: Cardinal;/////////
        function crPitch2: Cardinal;/////////
        function crLevel: Cardinal;
        function crCurrentHealth: Cardinal;
        function crMaxHealth: Cardinal;
        function crCurrentMana: Cardinal;
        function crMaxMana: Cardinal;
        function crTargetGuid: Cardinal;
        function npcName1: Cardinal;
        function npcName2: Cardinal;
        function npcSummonedBy: Cardinal;
        function npcAttackingGuid: Cardinal;
        function plrCurrentRage: Cardinal;
        function plrCurrentEnergy: Cardinal;
        function plrMaxEnergy: Cardinal;
        function gmeName1: Cardinal;
        function gmeName2: Cardinal;
        function gmeXPosition: Cardinal;
        function gmeYPosition: Cardinal;
        function gmeZPosition: Cardinal;
        function gmedisplayId: Cardinal;
        function dynXPosition: Cardinal;
        function dynYPosition: Cardinal;
        function dynZPosition: Cardinal;
        function cpsXPosition: Cardinal;
        function cpsYPosition: Cardinal;
        function cpsZPosition: Cardinal;
      end;
    
    implementation
      {Object Manager Offsets}
      function TWoWOffsets.ClientConnection: Cardinal;
      begin
        result:= $C79CD8;  //00BB43F0
      end;
      function TWoWOffsets.CurrMgr: Cardinal;
      begin
        result := $2ED0;
      end;
      function TWoWOffsets.FirstObject : Cardinal;
      begin
        result:= $AC;
      end;
      function TWoWOffsets.NextObject : Cardinal;
      begin
        result:= $3C;
      end;
      function TWoWOffsets.LocalGUID : Cardinal;
      begin
        result:= $C0; //Offset from currmanager
      end;
    
      {Base object offsets}
      function TWoWOffsets.objGuid: Cardinal;
      begin
        result:= $30;
      end;
      function TWoWOffsets.objType: Cardinal;
      begin
        result:= $14;
      end;
      function TWoWOffsets.objXPosition: Cardinal;
      begin
        result:= $798;      //7D0
      end;
      function TWoWOffsets.objYPosition: Cardinal;
      begin
        result:=$79C; //$7D4;
      end;
      function TWoWOffsets.objZPosition: Cardinal;
      begin
        result:= $7A0; //$7D8;
      end;
      function TWoWOffsets.objRotation: Cardinal;
      begin
        result:= $7A8;
      end;
      function TWoWOffsets.objDescriptorFields: Cardinal;
      begin
        result:= $8;
      end;
    
      {Creature object offsets}
      function TWoWOffsets.crPitch1: Cardinal;/////////
      begin
        result:= $110;
      end;
      function TWoWOffsets.crPitch2: Cardinal;/////////
      begin
        result:= $20;
      end;
      function TWoWOffsets.crLevel: Cardinal;
      begin
        result:= $35 * 4;
      end;
      function TWoWOffsets.crCurrentHealth: Cardinal;
      begin
        result:= $17 * 4;
      end;
      function TWoWOffsets.crMaxHealth: Cardinal;
      begin
        result:= $1F * 4;
      end;
      function TWoWOffsets.crCurrentMana: Cardinal;
      begin
        result:= $18 * 4;
      end;
      function TWoWOffsets.crMaxMana: Cardinal;
      begin
        result:= $20 * 4;
      end;
      function TWoWOffsets.crTargetGuid: Cardinal;
      begin
        result:= $12 * 4;
      end;
    
      {NPC object offsets}
      function TWoWOffsets.npcName1: Cardinal;
      begin
        result:= $9B0;
      end;
      function TWoWOffsets.npcName2: Cardinal;
      begin
        result:= $3C;
      end;
      function TWoWOffsets.npcSummonedBy: Cardinal;
      begin
        result:= $E * 4;
      end;
      function TWoWOffsets.npcAttackingGuid: Cardinal;
      begin
        result:= $0A38;
      end;
    
      {Player object offsets}
      function TWoWOffsets.plrCurrentRage: Cardinal;
      begin
        result:= $19 * 4;
      end;
      function TWoWOffsets.plrCurrentEnergy: Cardinal;
      begin
        result:= $1B * 4;
      end;
      function TWoWOffsets.plrMaxEnergy: Cardinal;
      begin
        result:= $23 * 4;
      end;
    
      {Game object offsets}
      function TWoWOffsets.gmeName1: Cardinal;
      begin
        result:= $1f4;
      end;
      function TWoWOffsets.gmeName2: Cardinal;
      begin
        result:= $078;
      end;
      function TWoWOffsets.gmeXPosition: Cardinal;
      begin
        result:= $E8;
      end;
      function TWoWOffsets.gmeYPosition: Cardinal;
      begin
        result:= $EC;
      end;
      function TWoWOffsets.gmeZPosition: Cardinal;
      begin
        result:= $F0;
      end;
      function TWoWOffsets.gmedisplayId: Cardinal;
      begin
        result:= $8 * 4;
      end;
    
      {Dynamic object offsets}
      function TWoWOffsets.dynXPosition: Cardinal;
      begin
        result:= $B * 4;
      end;
      function TWoWOffsets.dynYPosition: Cardinal;
      begin
        result:= $C * 4;
      end;
      function TWoWOffsets.dynZPosition: Cardinal;
      begin
        result:= $D * 4;
      end;
    
      {Corpse object offsets}
      function TWoWOffsets.cpsXPosition: Cardinal;
      begin
        result:= $B * 4;
      end;
      function TWoWOffsets.cpsYPosition: Cardinal;
      begin
        result:= $C * 4;
      end;
      function TWoWOffsets.cpsZPosition: Cardinal;
      begin
        result:= $D * 4;
      end;
    
    end.
    Code:
    unit moduleWoWObjectManager;
    ///////////////////////////////////////////////////////////////////////////////
    //This unit contains the ObjectManager.                                      //
    //How to use:                                                                //
    //- Add unit to uses clause                                                  //
    //- Create new TWoWObjectManager using constructor CreateObjMgr              //
    //- Read the arrays of wowobjects, it self updates :D                        //
    ///////////////////////////////////////////////////////////////////////////////
    {To do:
     - Add more descriptors
     - Add items and containers
     - Make player data easily accessable
     - Do Aggro Radius
    }
    
    interface
    
    uses
      SysUtils, Classes, UInt64Lib, windows, o_GTTimer, Variants, moduleWoWOffsets, math;
    
    type
    {Master object, all others decending}
      TWoWObject = class
      private
      protected
      public
        BaseAddress: Cardinal;
        objType: Cardinal;
        objGUID: UInt64;
        constructor Create(BaseAdd: Cardinal);  //Loads all things that dont change
        function DescriptorFields: Cardinal;
        function xPosition: Single; virtual;
        function yPosition: Single; virtual;
        function zPosition: Single; virtual;
        function Rotation: Single; virtual;
      end;
    
    {Creature object, holds the procedures etc similar between
    creatures and players}
      TWoWCreature = class(TWoWObject)
      private
      protected
      public
        function Pitch: Single;
        function TargetGUID: Uint64;
        function Level: Integer;
        function CurrentHealth: Integer;
        function MaxHealth: Integer;
        function CurrentMana: Integer;
        function MaxMana: Integer;
        function HealthPercent: Real;
      end;
    
    {NPC object, decendant of creature object}
      TWoWNPC = class(TWoWCreature)
      private
      protected
      public
        function Name: String;
        function AttackingGUID: UInt64;
        function SummonedBy: UInt64;
        function GetAggroRadius(PlayersLevel: Integer): Integer;
      end;
    
    {Player object, decendant of creature object}
      TWoWPlayer = class(TWoWCreature)
      private
      protected
      public
        function CurrentRage: Integer;
        function MaxRage: Integer; //wait... didnt need this... always 100
        function CurrentEnergy: Integer;
        function MaxEnergy: Integer;
      end;
    
    {Game Object, nodes etc}
      TWoWGame = class(TWoWObject)
      private
      protected
      public
        function Name: String;
        function xPosition: Single; override;
        function yPosition: Single; override;
        function zPosition: Single; override;
        function DisplayID: Integer;
      end;
    
    {Dynamic Object, spells etc}
      TWoWDynamic = class(TWoWObject)
      private
      protected
      public
        function xPosition: Single; override;
        function yPosition: Single; override;
        function zPosition: Single; override;
      end;
    
    {Corpse Object, dead players etc}
      TWoWCorpse = class(TWoWObject)
      private
      protected
      public
      end;
    
    {END OF WOW OBJECTS, START OF OBJECT MANAGER TYPE DECLARATIONS}
    
      TWoWObjectManager = class(TComponent)
      private
        timerUpdate: TgtTimer;
        procedure LoadObjects;
        procedure timerUpdateOnTimer(Sender : TObject);
        function GetLocalPlayerIndex: Integer; //returns the index of the local player, use this later
        function GetLocalPlayer: TWoWPlayer;
      public
        GameObjects: Array of TWoWGame;
        PlayerObjects: Array of TWoWPlayer;
        NPCObjects: Array of TWoWNPC;
        DynamicObjects: Array of TWoWDynamic;
        CorpseObjects: Array of TWoWCorpse;
        property LocalPlayer: TWoWPlayer
          read GetLocalPlayer;
        constructor createObjMgr(AOwner: TComponent; wWindow: HWND; RefreshRate: Integer);
        function CurrMgr: Cardinal; //returns the currmgr
        function Count: integer;
      end;
    
    var
      WoWWindow: HWND;
      Offsets: TWoWOffsets;
    
    implementation
    
    
    ///////////////////////////////////////////////////////////////////////////////
    //Utility methods                                                            //
    //These methods are used in the various components in some way               //
    ///////////////////////////////////////////////////////////////////////////////
    
    {Sets the application privlieage level high enough to be able to read from wow l8r}
     function SetPrivilege(privilegeName: string; enable: boolean): boolean;
      var tpPrev,
          tp         : TTokenPrivileges;
          token      : THandle;
          dwRetLen   : DWord;
      begin
        result := False;
        OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, token);
        tp.PrivilegeCount := 1;
        if LookupPrivilegeValue(nil, pchar(privilegeName), tp.Privileges[0].LUID) then
        begin
          if enable then
            tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
          else
            tp.Privileges[0].Attributes := 0;
          dwRetLen := 0;
          result := AdjustTokenPrivileges(token, False, tp, SizeOf(tpPrev), tpPrev, dwRetLen);
        end;
        CloseHandle(token);
      end;
    
      function ReadCardinal(Address: Cardinal): Cardinal;
      {NOTE: Cardinal is an unsigned 32 bit integer}
      var
        bytesRead: Cardinal;
        Pid, PidHandle: Integer;
      begin
        bytesRead:= 0;
        GetWindowThreadProcessId(WoWWindow,@Pid);
        Pidhandle := OpenProcess(PROCESS_VM_READ,False,Pid);
        ReadProcessMemory(pidhandle, ptr(address), @result, 4, bytesRead);
        closehandle(Pidhandle);
      end;
    
      function ReadInt32(Address: Cardinal): Integer;
      var
        bytesRead: Cardinal;
        Pid, PidHandle: Integer;
      begin
        bytesRead:= 0;
        GetWindowThreadProcessId(WoWWindow,@Pid);
        Pidhandle := OpenProcess(PROCESS_VM_READ,False,Pid);
        ReadProcessMemory(pidhandle, ptr(address), @result, 4, bytesRead);
        closehandle(Pidhandle);
      end;
    
      function ReadUInt64(Address: Cardinal): UInt64;
      var
        bytesRead: Cardinal;
        Pid, PidHandle: Integer;
      begin
        bytesRead:= 0;
        GetWindowThreadProcessId(WoWWindow,@Pid);
        Pidhandle := OpenProcess(PROCESS_VM_READ,False,Pid);
        ReadProcessMemory(pidhandle, ptr(address), @result, 8, bytesRead);
        closehandle(Pidhandle);
      end;
    
      function ReadFloat(Address: Cardinal): Single;
      {32 bit float, use for reading coords etc}
      var
        bytesRead: Cardinal;
        Pid, PidHandle: Integer;
      begin
        bytesRead:= 0;
        GetWindowThreadProcessId(WoWWindow,@Pid);
        Pidhandle := OpenProcess(PROCESS_VM_READ,False,Pid);
        ReadProcessMemory(pidhandle, ptr(address), @result, 4, bytesRead);
        closehandle(Pidhandle);
      end;
    
      function ReadString(Address: Cardinal): String;
      begin
        result:= '';
      end;
    
    
    ///////////////////////////////////////////////////////////////////////////////
    //TWoWObject                                                                 //
    //Base component for all loaded objects.                                     //
    ///////////////////////////////////////////////////////////////////////////////
    
    constructor TWoWObject.Create(BaseAdd: Cardinal);
    {Load all info that doesnt change}
    begin
      BaseAddress:= BaseAdd;
      objType:= ReadCardinal(BaseAddress + Offsets.objType);
      objGUID:= ReadUInt64(BaseAddress + Offsets.objGuid);
    end;
    function TWoWObject.DescriptorFields: Cardinal;
    begin
      result:= ReadCardinal(BaseAddress + Offsets.objDescriptorFields);
    end;
    function TWoWObject.xPosition: Single;
    begin
      result:= ReadFloat(BaseAddress + Offsets.objXPosition);
    end;
    function TWoWObject.yPosition: Single;
    begin
      result:= ReadFloat(BaseAddress + Offsets.objYPosition);
    end;
    function TWoWObject.zPosition: Single;
    begin
      result:= ReadFloat(BaseAddress + Offsets.objZPosition);
    end;
    function TWoWObject.Rotation: Single;
    begin
      result:= ReadFloat(BaseAddress + Offsets.objRotation);
    end;
    
    ///////////////////////////////////////////////////////////////////////////////
    //TWoWCreature                                                               //
    //Decendant of TWoWObject                                                    //
    ///////////////////////////////////////////////////////////////////////////////
    
    function TWoWCreature.Pitch: Single;
    begin
      result:= ReadFloat(ReadCardinal(BaseAddress + Offsets.crPitch1) + Offsets.crPitch2);
    end;
    
    function TWoWCreature.TargetGUID: UInt64;
    begin
      result:= ReadUInt64(DescriptorFields + Offsets.crTargetGuid);
    end;
    
    function TWoWCreature.Level: Integer;
    begin
      result:= ReadInt32(DescriptorFields + offsets.crLevel);
    end;
    
    function TWoWCreature.CurrentHealth: Integer;
    begin
      result:= ReadInt32(DescriptorFields + Offsets.crCurrentHealth);
    end;
    
    function TWoWCreature.MaxHealth: Integer;
    begin
      result:= ReadInt32(DescriptorFields + Offsets.crMaxHealth);
    end;
    
    function TWoWCreature.CurrentMana: Integer;
    begin
      result:= ReadInt32(DescriptorFields + Offsets.crCurrentMana);
    end;
    
    function TWoWCreature.MaxMana: Integer;
    begin
      result:= ReadInt32(DescriptorFields + Offsets.crMaxMana);
    end;
    
    function TWoWCreature.HealthPercent: Real;
    begin
      result:= (CurrentHealth / MaxHealth) * 100;
    end;
    
    ///////////////////////////////////////////////////////////////////////////////
    //TWoWNPC                                                                    //
    //Decendant of TWoWCreature                                                  //
    ///////////////////////////////////////////////////////////////////////////////
    
    function TWoWNPC.Name: String;
    begin
      result:= ReadString(ReadCardinal(ReadCardinal(BaseAddress + Offsets.npcName1) + Offsets.npcName2));
    end;
    
    function TWoWNPC.AttackingGUID: UInt64;
    begin
      result:= ReadUInt64(BaseAddress + Offsets.npcAttackingGuid);
    end;
    
    function TWoWNPC.SummonedBy: UInt64;
    begin
      result:= ReadUInt64(DescriptorFields + Offsets.npcSummonedBy);
    end;
    
    function TWoWNPC.GetAggroRadius(PlayersLevel: Integer): Integer;
    {Return the aggro radius of this npc, finish later}
    begin
      result:= 0;
    end;
    
    ///////////////////////////////////////////////////////////////////////////////
    //TWoWPlayer                                                                 //
    //Decendant of TWoWCreature                                                  //
    ///////////////////////////////////////////////////////////////////////////////
    
    function TWoWPlayer.CurrentRage: Integer;
    var
      ragetemp: Real;
    begin
      ragetemp:= ReadInt32(DescriptorFields + Offsets.plrCurrentRage)/10;
      result:= Floor(RageTemp);
    end;
    
    function TWoWPlayer.MaxRage: Integer;
    begin
      result:= 100;
    end;
    
    function TWoWPlayer.CurrentEnergy: Integer;
    begin
      result:= ReadInt32(DescriptorFields + offsets.plrCurrentEnergy);
    end;
    
    function TWoWPlayer.MaxEnergy: Integer;
    begin
      result:= ReadInt32(DescriptorFields + Offsets.plrMaxEnergy);
    end;
    
    ///////////////////////////////////////////////////////////////////////////////
    //TWoWGame                                                                   //
    //Decendant of TWoWObject                                                    //
    ///////////////////////////////////////////////////////////////////////////////
    
    function TWoWGame.Name: String;
    begin
      result:= ReadString(ReadCardinal(BaseAddress + Offsets.gmeName1) + Offsets.gmeName2);
    end;
    
    function TWoWGame.xPosition: Single;
    begin
      result:= ReadFloat(BaseAddress + Offsets.gmeXPosition);
    end;
    
    function TWoWGame.yPosition: Single;
    begin
      result:= ReadFloat(BaseAddress + Offsets.gmeYPosition);
    end;
    
    function TWoWGame.zPosition: Single;
    begin
      result:= ReadFloat(BaseAddress + Offsets.gmeZPosition);
    end;
    
    function TWoWGame.DisplayID: Integer;
    begin
      result:= ReadInt32(DescriptorFields + Offsets.gmedisplayId);
    end;
    
    ///////////////////////////////////////////////////////////////////////////////
    //TWoWDynamic                                                                //
    //Decendant of TWoWObject                                                    //
    ///////////////////////////////////////////////////////////////////////////////
    
    function TWoWDynamic.xPosition: Single;
    begin
      result:= ReadFloat(DescriptorFields + Offsets.dynXPosition);
    end;
    
    function TWoWDynamic.yPosition: Single;
    begin
      result:= ReadFloat(DescriptorFields + Offsets.dynYPosition);
    end;
    
    function TWoWDynamic.zPosition: Single;
    begin
      result:= ReadFloat(DescriptorFields + Offsets.dynZPosition);
    end;
    
    ///////////////////////////////////////////////////////////////////////////////
    //TWoWCorpse                                                                 //
    //Decendant of TWoWObject                                                    //
    ///////////////////////////////////////////////////////////////////////////////
    
    ///////////////////////////////////////////////////////////////////////////////
    //TWoWObjectManager                                                          //
    //Component controlling object manager, self updating, uses object classes   //
    ///////////////////////////////////////////////////////////////////////////////
    
    function TWoWObjectManager.CurrMgr: Cardinal;
    {Returns the currmgr}
    begin
      result:=  readcardinal(Offsets.ClientConnection);
      result:= ReadCardinal(result + $2ED0);
      //result:= ReadCardinal(ReadCardinal(Offsets.ClientConnection)+ Offsets.CurrMgr);
    end;
    
    function TWoWObjectManager.Count: integer;
    {Returns the number of objects loaded}
    var
      NextObject: Cardinal;
      objType: Integer;
    begin
      NextObject:= ReadCardinal(CurrMgr + Offsets.FirstObject);      //Read the first object
      result:= 0;    //initialize result
      ObjType:= ReadInt32(NextObject + Offsets.objType);   //read the type of the first object
      //NOTE: if there is an object in the list, objType will = 1 to 7, fix for previous bug
      While (ObjType <= 7) and (ObjType > 0) do
      begin
        result:= result + 1;
        NextObject:= ReadCardinal(NextObject + Offsets.NextObject);
        ObjType:= ReadInt32(NextObject + Offsets.objType);  //read the type of nxtobject
      end;
    end;
    
    procedure TWoWObjectManager.LoadObjects;
    {Completly refreshes the object list, loading all the base addresses into their
    array by type}
    var
      objAddress, myType: Cardinal;
      ObjectCount, objIndex: Integer;
    begin
      //Clear arrays
      SetLength(GameObjects, 0);
      SetLength(PlayerObjects, 0);
      SetLength(NPCObjects, 0);
      SetLength(DynamicObjects, 0);
      SetLength(CorpseObjects, 0);
      ObjectCount:= Count;
      if (ObjectCount > 0) then //If is there any objects loaded?
      begin
        //Loop through the entire loaded list
        myType:= 0;
        objAddress:= 0;
        ObjAddress:= ReadCardinal(CurrMgr + Offsets.FirstObject);
        myType:= ReadCardinal(objAddress + Offsets.objType);
        for objIndex:= 0 to (ObjectCount-1) do
        begin
          case myType of   //Load a object into whatever array it belongs in
            3:  //NPCs
            begin
              SetLength(NPCObjects, (Length(NPCObjects)+1));
              NPCObjects[Length(NPCObjects)-1]:= TWoWNPC.Create(objAddress);
            end;
            4:  //Players
            begin
              SetLength(PlayerObjects, (Length(PlayerObjects)+1));
              PlayerObjects[Length(PlayerObjects)-1]:= TWoWPlayer.Create(objAddress);
            end;
            5:  //Gameobjects
            begin
              SetLength(GameObjects, (Length(GameObjects)+1));
              GameObjects[Length(GameObjects)-1]:= TWoWGame.Create(objAddress);
            end;
            6:  //dynamicobjects
            begin
              SetLength(DynamicObjects, (Length(DynamicObjects)+1));
              DynamicObjects[Length(DynamicObjects)-1]:= TWoWDynamic.Create(objAddress);
            end;
            7:  //Corpses
            begin
              SetLength(CorpseObjects, (Length(CorpseObjects)+1));
              CorpseObjects[Length(CorpseObjects)-1]:= TWoWCorpse.Create(objAddress);
            end;
          end; 
          ObjAddress:= ReadCardinal(objAddress + Offsets.NextObject);
          myType:= ReadCardinal(objAddress + Offsets.objType);
        end;
      end;
    end;
    
    procedure TWoWObjectManager.timerUpdateOnTimer(Sender : TObject);
    {TO DO: Add some way to check to see if the objmgr needs updating, then test to
    see if it is more efficient.}
    begin
      LoadObjects;
    end;
    
    constructor TWoWObjectManager.createObjMgr(AOwner: TComponent; wWindow: HWND; RefreshRate: Integer);
    begin
      //The TComponent create constructor
      {NOTE ABOUT TComponent: It isn't strictly neccesary however it has a method
      that destroys all children on close, and later could be used to make the
      component visual drag/drop able}
      self:= TWoWObjectManager.create(AOwner);
      SetPrivilege('SeDebugPrivilege', true); //sets privlige high enough to access wow
      WoWWindow:= wWindow;
      //First-run, load object list
      LoadObjects;
      //Create update loop. This loop runs every interval (the specified refreshRate), keeping the object lists up to date.
      timerUpdate:= TgtTimer.Create(Self);
      timerUpdate.OnTimer := timerUpdateOnTimer;  //the procedure that is run on timer
      timerUpdate.Interval:= RefreshRate; //x ms
      timerUpdate.Enabled := true;
    end;
    
    function TWoWObjectManager.GetLocalPlayerIndex: Integer;
    {Returns the index of the local player in the array}
    var
      LocalGUID: UInt64;//The GUID of the local player
      objIndex: Integer;
    begin
      //Find the local GUID
      LocalGUID:= ReadUInt64(CurrMgr + Offsets.LocalGUID);
      objIndex:= 0;
      result:= 0;
      for objIndex:= 0 to (Length(PlayerObjects) - 1) do
      begin
        if (PlayerObjects[objIndex].objGUID = LocalGUID) then
          result:= objIndex;
      end;
    end;
    
    function TWoWObjectManager.GetLocalPlayer: TWoWPlayer;
    begin
      result:= PlayerObjects[GetLocalPlayerIndex];
    end;
    
    end.

    "I shall call him Tufty," - Raest, Malazan Book of the Fallen.

    [source] A delphi objectmanager component
  2. #2
    KOS0937's Avatar Member
    Reputation
    18
    Join Date
    May 2008
    Posts
    129
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm not that fit with Delphi anymore, but why do you define
    Code:
    function ClientConnection: Cardinal;
    etc. instead of
    Code:
    const cardinal ClientConnection=$C79CD8;
    ???

    I don't really get this oO Defining a function to return a const value is not really a nice style of coding.

    Thanks anyway for sharing your code. Always appreciated =)

  3. #3
    Därkness's Avatar Active Member
    Reputation
    22
    Join Date
    Jul 2009
    Posts
    113
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by KOS0937 View Post
    I'm not that fit with Delphi anymore, but why do you define
    Code:
    function ClientConnection: Cardinal;
    etc. instead of
    Code:
    const cardinal ClientConnection=$C79CD8;
    ???

    I don't really get this oO Defining a function to return a const value is not really a nice style of coding.

    Thanks anyway for sharing your code. Always appreciated =)
    Because I was asleep :P

    "I shall call him Tufty," - Raest, Malazan Book of the Fallen.

Similar Threads

  1. Wow hack for 2.3.3 [Open Source] Delphi
    By robotkid in forum WoW Memory Editing
    Replies: 15
    Last Post: 05-23-2018, 10:53 PM
  2. Codename "oWo-Reader" (complete DELPHI Source for free)
    By VisioNOIR in forum WoW Memory Editing
    Replies: 21
    Last Post: 07-02-2012, 05:56 AM
  3. [Buying] Memory reader in Delphi - source code
    By lunex1225 in forum World of Warcraft Buy Sell Trade
    Replies: 1
    Last Post: 12-20-2010, 04:47 PM
  4. Delphi source for TLS
    By radegast in forum WoW Memory Editing
    Replies: 9
    Last Post: 03-23-2008, 08:36 PM
  5. [Bot:Source] Acidic Bot Source Code
    By =sinister= in forum World of Warcraft Bots and Programs
    Replies: 10
    Last Post: 07-03-2006, 05:38 PM
All times are GMT -5. The time now is 04:57 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search