Перейти к содержанию

MasterGH

Ветераны
  • Постов

    2 999
  • Зарегистрирован

  • Победитель дней

    129

Сообщения, опубликованные MasterGH

  1. Опишите ещё плз как в 6.1 встроенными средствами трейнер сгенерировать, если скрипты и адреса уже найдены и написаны...

    Akama, не уже ли ты не сможешь разобраться "методом тыка" как генерировать трейнер в CE 6.1, если уже есть таблица? Лучше задавай конкретные вопросы...

    У тебя, наверно, есть один большой скрипт и несколько адресов активации. Ну в генерируемом трейнере укажи хот-кеи на большой скрипт - "клавиша Inc", на остальные - другие клавиши. И ничего сложного...

  2. Я что-то потерялся в дебрях вызовов и упёрся в аргумент функции "location_manager().update_positions". Эта функция постоянно работает с позициями.... Внизу есть другая функция, которая может вызывать "подставляемые" функции. Одну функцию может вызвать для бота и совершенно другую для пользователя. По какому принципу это делается нет времени разбирать, т.к. похоже это надолго. Всё-таки надо было ставить бряк на изменение курсора или на клик. Но для этого париться с хуками directX, на это тоже надо какое-то время.

    Но у меня есть не плохие новости. Есть же уже готовая таблица Recifense - ещё тот Гуру по таким случаям.


    ===========================================
    Total War - Shogun 2
    Game Version : 1.00
    Script Version: 1.0
    CE Version : 6.0
    GM, Ammo, Gold, MP, MSO
    23-Mar-2011
    By Recifense

    ===========================================
    Total War - Shogun 2
    Game Version : 1.00
    Script Version: 1.0
    CE Version : 6.0
    GM, Ammo, Gold, MP, MSO
    23-Mar-2011
    By Recifense
    ===========================================
    1) God Mode: For all Units and Ships
    2) Unlimited Ammo (Arrows, Bombs, etc)
    3) Unlimited Movement Points (Army on campaign)
    4) Recover troop size when Army moves (Army on campaign)
    5) Minimum Gold (On campaign)
    6) Player's Current Gold (On campaign)
    7) Skill points of selected army's general (On Campaign)

    }

    [ENABLE]
    //=========================================
    // Check if script is compatible to this game version
    // If false the script will not be loaded

    assert(Shogun2.dll+00a63e50,55 8b ec 83 e4 f8)
    assert(Shogun2.dll+00c7e770,55 8b ec 83 e4 f8)
    assert(Shogun2.dll+01199dc3,8b b7 34 01 00 00)
    assert(Shogun2.dll+009e7af3,f3 0f 11 86 40 0f 00 00)
    assert(Shogun2.dll+00cf54e0,51 8b 8f a0 03 00 00)
    assert(Shogun2.dll+011cb77d,89 8e b0 00 00 00)
    assert(Shogun2.dll+00b560d7,8b 43 40)
    assert(Shogun2.dll+0046df80,?? ?? 6c 04 00 00)
    assert(Shogun2.dll+011ad6bc,?? ?? 0c 1c 00 00)

    //=========================================
    alloc(MyCode,1024)
    //=========================================
    // Declaration section
    label(_GodMode)
    label(_GodM00)
    label(_GodM01)
    label(_BackGM)
    label(_ExitGM)
    label(_GodMode1)
    label(_GodM10)
    label(_GodM11)
    label(_BackGM1)
    label(_ExitGM1)
    label(_MonSel)
    label(_BackMS)
    label(_MonAmmo)
    label(_MonA0)
    label(_MonA1)
    label(_BackMA)
    label(_ExitMA)
    label(_GodModeS)
    label(_BackGMS)
    label(_ExitGMS)
    label(_MonSelShip)
    label(_BackMSS)
    label(_ExitMSS)
    label(_GodModeSH)
    label(_BackGMSH)
    label(_ExitGMSH)
    label(_MonGold)
    label(_BackMG)
    label(_ExitMG)
    label(_MonMP)
    label(_MonM0)
    label(_BackMM)
    label(_ExitMM)
    label(_MonSelOfficer)
    label(_BackMSO)
    label(_ExitMSO)
    label(pSel)
    label(pGold)
    label(pOfficer)
    label(iEnableGM)
    label(iEnableGM1)
    label(iEnableGM2)
    label(iEnableGMS)
    label(iEnableMA)
    label(iEnableQR)
    label(iEnableMG)
    label(iEnableMM)
    label(iEnableMTS)
    label(iPlayerID)
    label(iMinGold)
    label(iEAX)
    label(iCount0)
    label(iCount1)
    label(iCount2)
    label(iCount3)
    label(iCountS)

    registersymbol(MyCode)
    registersymbol(pSel)
    registersymbol(pGold)
    registersymbol(pOfficer)
    registersymbol(iEnableGM)
    registersymbol(iEnableGM1)
    registersymbol(iEnableGM2)
    registersymbol(iEnableGMS)
    registersymbol(iEnableMA)
    registersymbol(iEnableQR)
    registersymbol(iEnableMG)
    registersymbol(iEnableMM)
    registersymbol(iEnableMTS)
    registersymbol(iMinGold)
    registersymbol(iPlayerID)
    registersymbol(iCount0)
    registersymbol(iCount1)
    registersymbol(iCount2)
    registersymbol(iCount3)
    registersymbol(iCountS)

    //=========================================
    MyCode:
    //=========================================
    _GodMode:
    mov [iEAX],eax // Save EAX

    mov eax,[esp+04] // Get Unit

    mov eax,[eax+00000204] // Get pTroop
    test eax,eax
    jnz _GodM00 // Jump if the pointer is null

    mov eax,[eax+0000020c] // Get pShip
    test eax,eax
    jz _ExitGM // Jump if the pointer is null

    mov al,[eax+0000111f] // Get pCommon
    cmp al,[iPlayerID] // Is it a Player's Troop ?
    jne _ExitGM // Jump if false

    inc dword ptr [iCount0]

    cmp dword ptr [iEnableGM],0
    je _ExitGM // Jump if feature is disabled

    jmp _GodM01
    //=====
    _GodM00:
    mov eax,[eax+00000294] // Get pPlayerInfo
    test eax,eax
    jz _ExitGM // Jump if the pointer is null

    mov eax,[eax+04] // Get playerID
    cmp eax,[iPlayerID] // Is it a Player's Troop ?
    jne _ExitGM // Jump if false

    inc dword ptr [iCount1]

    cmp dword ptr [iEnableGM],0
    je _ExitGM // Jump if feature is disabled

    _GodM01:
    mov eax,[iEAX] // Restore EAX
    ret 0004 // Avoid routine
    //-----
    _ExitGM:
    mov eax,[iEAX] // Restore EAX

    push ebp // Original code
    mov ebp,esp // Original code
    and esp,f8 // Original code
    jmp _BackGM // Back to main code

    //=========================================
    _GodMode1:
    mov [iEAX],eax // Save EAX

    mov eax,[ecx+00000204] // Get pTroop
    test eax,eax
    jnz _GodM10 // Jump if the pointer is not null

    mov eax,[ecx+0000020c] // Get pShip
    test eax,eax
    jz _ExitGM1 // Jump if the pointer is null
    // Ship Crew
    mov al,[eax+0000111f] // Get pCommon
    cmp al,[iPlayerID] // Is it a Player's Troop ?
    jne _ExitGM1 // Jump if false

    inc dword ptr [iCount2]

    cmp dword ptr [iEnableGM],0
    je _ExitGM1 // Jump if feature is disabled
    jmp _GodM11
    //Land Soldiers
    _GodM10:
    mov eax,[eax+00000294] // Get pPlayerInfo
    test eax,eax
    jz _ExitGM1 // Jump if the pointer is null

    mov eax,[eax+04] // Get playerID
    cmp eax,[iPlayerID] // Is it a Player's Troop ?
    jne _ExitGM1 // Jump if false

    inc dword ptr [iCount3]

    cmp dword ptr [iEnableGM],0
    je _ExitGM1 // Jump if feature is disabled

    _GodM11:
    mov eax,[iEAX] // Restore EAX
    ret 0004 // Avoid routine
    //-----
    _ExitGM1:
    mov eax,[iEAX] // Restore EAX

    push ebp // Original code
    mov ebp,esp // Original code
    and esp,f8 // Original code
    jmp _BackGM1 // Back to main code

    //=========================================
    _MonSel:
    mov esi,[edi+00000134] // Original code
    mov [pSel],esi
    jmp _BackMS // Back to main code

    //=========================================
    _MonAmmo:
    mov eax,[esi+00000294] // Get pPlayerInfo
    test eax,eax
    jz _ExitMA // Jump if the pointer is null

    mov eax,[eax+04] // Get playerID
    cmp eax,[iPlayerID] // Is it a Player's Troop ?
    jne _ExitMA // Jump if false

    cmp dword ptr [iEnableMA],0
    je _MonA0 // Jump if feature is disabled

    cvtsi2ss xmm0,[esi+00000F44] // Get Maximum Ammo

    _MonA0:
    cmp dword ptr [iEnableQR],0
    je _ExitMA // Jump if feature is disabled

    cmp dword ptr [esi+00000dbc],#15
    jle _MonA1

    mov dword ptr [esi+00000dbc],#15

    _MonA1:
    cmp dword ptr [esi+00000dc0],#15
    jle _ExitMA

    mov dword ptr [esi+00000dc0],#15

    _ExitMA:
    comiss xmm1,xmm0 // Update EFLAGS
    movss [esi+00000F40],xmm0 // Original code
    jmp _BackMA // Back to main code

    //=========================================
    _GodModeS:
    mov [iEAX],eax // Save EAX

    mov eax,[edi+0000020c] // Get pShip
    test eax,eax
    jz _ExitGMS // Jump if the pointer is null

    mov al,[eax+0000111f] // Get pCommon
    cmp al,[iPlayerID] // Is it a Player's Troop ?
    jne _ExitGMS // Jump if false

    inc dword ptr [iCountS]

    cmp dword ptr [iEnableGM],0
    je _ExitGMS // Jump if feature is disabled

    mov eax,[iEAX] // Restore EAX
    ret // Avoid routine
    //-----
    _ExitGMS:
    mov eax,[iEAX] // Restore EAX

    push ecx // Original code
    mov ecx,[edi+000003A0] // Original code
    jmp _BackGMS // Back to main code

    //=========================================
    // Card under cursor
    _MonSelShip:
    mov [pSel],ecx

    _ExitMSS:
    mov [esi+000000B0],ecx // Original code
    jmp _BackMSS // Back to main code

    //=========================================
    // Ship Hull
    _GodModeSH:
    mov eax,[ebx+24] // Get pShip
    test eax,eax
    jz _ExitGMSH // Jump if the pointer is null

    mov al,[eax+0000111f] // Get pCommon
    cmp al,[iPlayerID] // Is it a Player's Troop ?
    jne _ExitGMSH // Jump if false

    cmp dword ptr [iEnableGM],0
    je _ExitGMSH // Jump if feature is disabled

    mov eax,[ebx+1c] // Get max HP
    mov [ebx+40],eax // Update cur HP

    xor edi,edi // value2decrease = 0

    _ExitGMSH:
    mov eax,[ebx+40] // Original code
    sub eax,edi // Original code
    jmp _BackGMSH // Back to main code

    //=========================================
    // RTS Gold
    _MonGold:
    mov eax,[ecx+0000048c] // Get pointer to info
    test eax,eax
    jz _ExitMG // Jump if null pointer

    mov eax,[eax+24] // Get pointer to uPlayerID
    test eax,eax
    jz _ExitMG // Jump if null pointer

    mov eax,[eax]
    cmp eax,006c0070
    jne _ExitMG // Jump if it's an AI

    mov eax,[ecx+00000470] // Get pointer to player
    mov [pGold],eax

    cmp dword ptr [iEnableMG],0
    je _ExitMG // Jump if feature is disabled

    mov eax,[iMinGold]
    cmp eax,[ecx+0000046C]
    jle _ExitMG

    mov [ecx+0000046C],eax // Update gold

    _ExitMG:
    mov eax,[ecx+0000046C] // Original code
    jmp _BackMG // Back to main code

    //=========================================
    // RTS Troop Movement Points/Size
    _MonMP:
    push ecx

    mov ecx,[eax+44] // Get pointer to Owner
    cmp ecx,[pGold] // Is it a player's troop?
    jne _ExitMM

    cmp dword ptr [iEnableMM],0
    je _MonM0 // Jump if feature is disabled

    xor edi,edi // value2decrease = 0

    _MonM0:
    cmp dword ptr [iEnableMTS],0
    je _ExitMM // Jump if feature is disabled

    mov ecx,[eax+50] // Get troop maximum size
    mov [eax+4c],ecx // Update current size

    _ExitMM:
    pop ecx

    sub edx,edi // Original code
    mov [eax+6C],edx // Original code
    jmp _BackMM // Back to main code

    //=========================================
    // RTS Selected Officer
    _MonSelOfficer:
    mov [pOfficer],eax

    _ExitMSO:
    cmp [eax+00001C0C],ebx // Original code
    jmp _BackMSO // Back to main code

    //=========================================
    // Variables
    iEnableGM:
    dd 1
    iEnableGM1:
    dd 0
    iEnableGM2:
    dd 1
    iEnableMA:
    dd 1
    iEnableQR:
    dd 1
    iEnableGMS:
    dd 1
    iEnableMG:
    dd 1
    iEnableMM:
    dd 1
    iEnableMTS:
    dd 1
    pSel:
    dd 0
    pGold:
    dd 0
    pOfficer:
    dd 0
    iPlayerID:
    dd 1
    iEAX:
    dd 0
    iCount0:
    dd 0
    iCount1:
    dd 0
    iCount2:
    dd 0
    iCount3:
    dd 0
    iCountS:
    dd 0
    iMinGold:
    dd #50000

    //=========================================
    // Hacking Points
    Shogun2.dll+00a63e50:
    jmp _GodMode
    nop
    _BackGM:

    Shogun2.dll+00c7e770:
    jmp _GodMode1
    nop
    _BackGM1:

    Shogun2.dll+01199dc3:
    jmp _MonSel
    nop
    _BackMS:

    Shogun2.dll+009e7af3:
    jmp _MonAmmo
    nop
    nop
    nop
    _BackMA:

    Shogun2.dll+00cf54e0:
    jmp _GodModeS
    nop
    nop
    _BackGMS:

    Shogun2.dll+011cb77d:
    jmp _MonSelShip
    nop
    _BackMSS:

    Shogun2.dll+00b560d7:
    jmp _GodModeSH
    _BackGMSH:

    Shogun2.dll+0046df80:
    jmp _MonGold
    nop
    _BackMG:

    Shogun2.dll+0026a5e0:
    jmp _MonMP
    _BackMM:

    Shogun2.dll+011ad6bc:
    jmp _MonSelOfficer
    nop
    _BackMSO:

    //=========================================
    // Original Codes
    [DISABLE]
    Shogun2.dll+00a63e50:
    push ebp
    mov ebp,esp
    and esp,f8

    Shogun2.dll+00c7e770:
    push ebp
    mov ebp,esp
    and esp,f8

    Shogun2.dll+01199dc3:
    mov esi,[edi+00000134]

    Shogun2.dll+009e7af3:
    movss [esi+00000F40],xmm0

    Shogun2.dll+00cf54e0:
    push ecx
    mov ecx,[edi+000003A0]

    Shogun2.dll+011cb77d:
    mov [esi+000000B0],ecx

    Shogun2.dll+00b560d7:
    mov eax,[ebx+40]
    sub eax,edi

    Shogun2.dll+0046df80:
    mov eax,[ecx+0000046C]

    Shogun2.dll+0026a5e0:
    sub edx,edi
    mov [eax+6C],edx

    Shogun2.dll+011ad6bc:
    cmp [eax+00001C0C],ebx

    unregistersymbol(MyCode)
    unregistersymbol(pSel)
    unregistersymbol(pGold)
    unregistersymbol(pOfficer)
    unregistersymbol(iEnableGM)
    unregistersymbol(iEnableGM1)
    unregistersymbol(iEnableGM2)
    unregistersymbol(iEnableGMS)
    unregistersymbol(iEnableMA)
    unregistersymbol(iEnableQR)
    unregistersymbol(iEnableMG)
    unregistersymbol(iEnableMM)
    unregistersymbol(iEnableMTS)
    unregistersymbol(iMinGold)
    unregistersymbol(iPlayerID)
    unregistersymbol(iCount0)
    unregistersymbol(iCount1)
    unregistersymbol(iCount2)
    unregistersymbol(iCount3)
    unregistersymbol(iCountS)

    dealloc(MyCode)

    {

    Как видно по смещению +0x44, я об этом смещение уже писал почему-то указатель на pGold (вроде как золото) Пользователя является уже критерием принадлежности войскам. Вообще-то странно кажется это корявые названия указателей.


    // RTS Troop Movement Points/Size
    _MonMP:
    push ecx

    mov ecx,[eax+44] // Get pointer to Owner
    cmp ecx,[pGold] // Is it a player's troop?
    jne _ExitMM

    cmp dword ptr [iEnableMM],0
    je _MonM0 // Jump if feature is disabled

    xor edi,edi // value2decrease = 0

    _MonM0:
    cmp dword ptr [iEnableMTS],0
    je _ExitMM // Jump if feature is disabled

    mov ecx,[eax+50] // Get troop maximum size
    mov [eax+4c],ecx // Update current size

    _ExitMM:
    pop ecx

    sub edx,edi // Original code
    mov [eax+6C],edx // Original code
    jmp _BackMM // Back to main code

    Напоминаю, что это инъекция в эту функцию:


    {
    int result; // eax@1
    char *v3; // ecx@1
    int v4; // esi@1
    int v5; // eax@2
    int v6; // edx@2

    v3 = (char *)this + 148;
    v4 = *((_DWORD *)v3 + 5);
    for ( result = v4 + 4 * *((_DWORD *)v3 + 4); // начальное значения для начала цикла
    v4 != result; // условие выполнение цикла пока истино v4 != result
    result = *((_DWORD *)v3 + 5) + 4 * *((_DWORD *)v3 + 4) ) // действие при каждой повторении цикла
    {

    v5 = **(_DWORD **)v4; // v5 = адрес группы (v5 теперь является подгруппой *this)
    v6 = *(_DWORD *)(v5 + 0x6C); // v6 = разрешённых шагов для группы v5

    if ( v6 <= a2 ) // если разрешённых шагов меньше например 3, когда попытка пойти на 5, то
    *(_DWORD *)(v5 + 0x6C) = 0; // присвоить v5 перемещение 0
    else // иначе
    *(_DWORD *)(v5 + 0x6C) = v6 - a2; // присворить v5 разность между разршенными шагами и "сделанными"

    *(_DWORD *)(v5 + 0x898) = -1; // какое-то интересное смещение +0x898, что означает точно не понятно.
    // по карайне мере понятно, что оно стаиться в -1, когда v5 было установленно
    // кол-во разрешённых шагов

    v4 += 4; // перебираем следующую группу
    }
    return result;
    }
    int __thiscall sub_10654450(void *this, int a2)

    Всё-таки я выскажусь по этой таблице - громоздка, запутанная и неудобная. Надо было пользоваться обвёрткой Lua, как я это делал в теме по Lua...

  3. Ликбез.

    На карте Мира могут быть войска Пользователя и ботов. За Пользователя играет Пользователь, за остальных компьютер.

    Все войска Пользователя разделим на Армии в составе которой есть руководитель. Именно Армии мы можем передвигать на карте Мира.

    Армию можно делить на отряды по классам: конница, лучники и т.п.

    Каждый отряд имеет коэффициент усталости. От него зависит дальность хода. Таким образом в Армии быстрые отряды не могут идти дальше чем медленные отряды.

    Итак, когда Пользователь передвигает Армию, то код игры смотрит принадлежит ли Армия пользователю, если нет, то идти не разрешается, если да, то код игры перебирает отряды и двигает их на расстояние указанное пользователем с вычетом сделанных ходов ранее и вычитом усталости самого уставшего отряда. Если вы что-то не поняли или запутались просто поиграйте в игру и всё поймете. Конница не может оставить лучников в армии, если двигается вся армия...

    Путь Вхождений моего героя из глубины вверх.

    Три функции ниже связаны с объектом пользователя или бота и параметром а2 - шагов сколько Армия должна сделать. Именно Армия. При чём неавжно какая армия. И в этих трёх функция не определяется сравнение с Армией пользователя или Бота. Да и важно понимать, что псевдокод может отображать не все параметры передаваемые в функцию.


    int __thiscall sub_10654450(void *this, int a2)
    {
    int result; // eax@1
    char *v3; // ecx@1
    int v4; // esi@1
    int v5; // eax@2
    int v6; // edx@2

    v3 = (char *)this + 148;
    v4 = *((_DWORD *)v3 + 5);
    // цикл на запись ходо для отрядов
    for ( result = v4 + 4 * *((_DWORD *)v3 + 4); v4 != result; result = *((_DWORD *)v3 + 5) + 4 * *((_DWORD *)v3 + 4) )
    {
    v5 = **(_DWORD **)v4; // v5 - отряд в Армии
    v6 = *(_DWORD *)(v5 + 0x6C);
    if ( v6 <= a2 )
    *(_DWORD *)(v5 + 0x6C) = 0;
    else
    *(_DWORD *)(v5 + 0x6C) = v6 - a2; // Запись вычитанных шагов shogun2.dll+68DEB2
    *(_DWORD *)(v5 + 0x898) = -1;
    v4 += 4;
    }
    return result;
    }


    int __thiscall sub_1068B2D0(void *this, int a2)
    {
    int result; // eax@1
    int i; // edi@1
    int v4; // esi@1
    void *v5; // edi@1
    int v6; // eax@2

    v5 = this;
    (*(void (__stdcall **)(int))(*(_DWORD *)this + 152))(v5, a2); // MasterGH Вхождение 4 в sub_10654450 shogun2.dll+68B2e4
    v4 = *((_DWORD *)v5 + 32);
    result = *((_DWORD *)v5 + 31);
    for ( i = v4 + 4 * result; v4 != i; v4 += 4 )
    {
    v6 = (*(int (**)(void))(***(_DWORD ***)v4 + 20))() - a2;
    _ECX = 0;
    __asm { sets cl }
    result = (*(int (__stdcall **)(int))(***(_DWORD ***)v4 + 40))((_ECX - 1) & v6);
    }
    return result;
    }


    void __thiscall sub_103BB8B0(int this, int a2)
    {
    int v2; // edi@1
    int v3; // esi@1
    int v4; // eax@2
    int v5; // ecx@5
    int v6; // eax@7

    v2 = a2;
    v3 = this;
    if ( a2 )
    {
    v4 = *(_DWORD *)(this + 700);
    if ( v4 && *(_DWORD *)v4 )
    {
    if ( v4 )
    v5 = *(_DWORD *)v4;
    else
    v5 = 0;
    v6 = sub_104E7A10(v5);
    if ( a2 >= 0 )
    {
    if ( v6 < a2 )
    v2 = v6;
    }
    else
    {
    v2 = 0;
    }
    sub_1068B2D0(v3, v2); // MasterGh вхождение 3 (в sub_1068B2D0) shogun2.dll+3bb900
    *(_DWORD *)(v3 + 28) = (*(int (__thiscall **)(int))(*(_DWORD *)v3 + 20))(v3);
    }
    else
    {
    sub_103670F0(a2);
    }
    }
    }



    int __thiscall sub_103D8D20(int this)
    {
    int result; // eax@1
    int v2; // edi@1
    __int16 v4; // cx@1
    int v6; // eax@1
    int v8; // eax@2
    int v9; // ecx@2
    int v10; // eax@2

    _ESI = this;
    v4 = *(_WORD *)(this + 60);
    __asm { movq xmm0, qword ptr [esi+24h] }
    v6 = *(_DWORD *)(_ESI + 44);
    __asm
    {
    movq qword ptr [esi+40h], xmm0
    xorps xmm0, xmm0
    }
    *(_WORD *)(_ESI + 76) = v4;
    *(_DWORD *)(_ESI + 72) = v6;
    __asm
    {
    movss dword ptr [esi+54h], xmm0
    movss dword ptr [esi+50h], xmm0
    }
    result = sub_100E0B70(_ESI);
    v2 = result;
    if ( result )
    {
    // _ESI - это армия, а (result + 28) это расстояние хода при этом в структуре _ESI уже записаны координаты перемещения
    (*(void (__stdcall **)(_DWORD))(*(_DWORD *)_ESI + 40))(*(_DWORD *)(_ESI, result + 28)); // MasterGH вхождение 2 ()sub_103BB8B0 shogun2.dll+3D8D61
    (**(void (__thiscall ***)(_DWORD, _DWORD))v2)(v2, 1);
    v10 = *(_DWORD *)(_ESI + 96);
    v9 = *(_DWORD *)v10;
    *(_DWORD *)v10 = **(_DWORD **)v10;
    v8 = *(_DWORD *)(_ESI + 96);
    if ( *(_DWORD *)v8 )
    {
    *(_DWORD *)(*(_DWORD *)v8 + 4) = v8;
    result = sub_10F4F0A0(v9);
    }
    else
    {
    *(_DWORD *)(_ESI + 92) = v8;
    result = sub_10F4F0A0(v9);
    }
    }
    return result;
    }


    int __userpurge sub_10255060<eax>(int a1<ecx>, double a2<st0>, int a3, int a4, char a5)
    {
    int v5; // eax@1
    char v7; // zf@4
    int v8; // ecx@8
    int v9; // ecx@10
    char v10; // bl@12
    int v11; // edi@14
    int v12; // ecx@15
    int v13; // ecx@17
    void (__thiscall *v14)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // edx@17
    int result; // eax@19
    int v16; // eax@20
    int v17; // edx@20
    int v18; // ecx@20
    int v19; // ebx@23
    void (__thiscall *v20)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // edx@27
    __int16 v26; // cx@28
    __int16 v29; // dx@29
    int v30; // eax@29
    int v31; // ecx@29
    int (__thiscall *v32)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // edx@30
    char v33; // al@31
    char v34; // zf@32
    int v35; // ecx@38
    int v36; // eax@40
    char v37; // al@44
    int v38; // ecx@44
    int v39; // edx@44
    int v40; // eax@44
    int v42; // ecx@44
    int v43; // edx@44
    int v47; // eax@45
    int v48; // ecx@49
    int v49; // edx@49
    int v50; // eax@49
    int v52; // ecx@49
    int v53; // edx@49
    char v57; // al@52
    int v58; // eax@63
    char v59; // zf@63
    int v60; // edi@64
    int v61; // eax@70
    int v62; // edi@74
    int v63; // ecx@83
    int v64; // ebx@83
    int v65; // eax@90
    int v66; // eax@91
    int v68; // eax@94
    int v69; // eax@95
    int v70; // eax@97
    int v71; // edi@97
    int v72; // eax@100
    int v73; // ebx@101
    int v74; // eax@103
    int v77; // eax@105
    int v78; // ebx@105
    int v79; // edi@105
    int v80; // eax@108
    int v81; // edx@108
    int (__thiscall *v82)(_DWORD); // eax@108
    int v83; // eax@108
    int v86; // eax@110
    int v90; // eax@116
    int v91; // eax@117
    int v92; // ecx@120
    __int16 v94; // dx@120
    int v95; // eax@120
    int v96; // ecx@120
    int v98; // ecx@121
    void (__thiscall *v100)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // edx@121
    int v101; // ecx@121
    signed int v102; // ecx@122
    signed int v107; // edi@134
    int v112; // ecx@141
    int *v113; // eax@145
    int v114; // eax@146
    int *v115; // eax@149
    int v116; // eax@150
    int v117; // eax@152
    int v118; // edi@152
    int v119; // eax@155
    int v120; // ebx@156
    int v121; // eax@158
    int v122; // eax@160
    int v123; // ebx@160
    int v124; // edi@160
    int v125; // eax@163
    int v126; // edx@163
    int (*v127)(void); // eax@163
    int v128; // eax@163
    int v129; // eax@164
    int v134; // ecx@173
    int v135; // eax@173
    __int16 v136; // dx@173
    int v137; // ecx@173
    void (__thiscall *v138)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // edx@173
    int v139; // ecx@173
    int v144; // edi@176
    int v150; // eax@177
    int v151; // eax@178
    int v152; // ecx@180
    int v153; // ecx@181
    int v154; // eax@184
    int v155; // eax@185
    int v156; // eax@188
    int v157; // edx@189
    int v158; // eax@191
    int v159; // eax@191
    int v160; // eax@192
    int v161; // eax@194
    char v162; // bl@197
    void (__thiscall *v163)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // edx@201
    int v164; // edi@202
    int v165; // eax@202
    int v166; // ecx@203
    char v168; // zf@207
    int v172; // eax@211
    __int16 v174; // cx@211
    int v175; // edx@211
    int v176; // eax@211
    int v178; // eax@213
    __int16 v179; // cx@213
    int v182; // eax@214
    __int16 v183; // dx@214
    int v189; // ecx@220
    __int16 v190; // dx@220
    char v191; // al@221
    int v192; // ebx@221
    int v194; // ecx@222
    int v198; // eax@227
    signed int v199; // edi@230
    int v200; // eax@232
    int v201; // ecx@233
    int v202; // ecx@239
    int v204; // edx@244
    int v209; // edx@246
    int v213; // ecx@247
    int v214; // esi@251
    void (__thiscall *v215)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // edx@255
    char v219; // [sp-8h] [bp-B4h]@44
    signed int v220; // [sp-4h] [bp-B0h]@27
    char v221; // [sp+0h] [bp-ACh]@27
    char v222; // [sp+4h] [bp-A8h]@44
    __int64 v223; // [sp+8h] [bp-A4h]@27
    __int64 v224; // [sp+10h] [bp-9Ch]@27
    int *v225; // [sp+18h] [bp-94h]@44
    __int64 v226; // [sp+28h] [bp-84h]@4
    __int64 v227; // [sp+30h] [bp-7Ch]@28
    __int64 v228; // [sp+38h] [bp-74h]@19
    __int64 v229; // [sp+40h] [bp-6Ch]@27
    __int64 v230; // [sp+48h] [bp-64h]@19
    int v231; // [sp+50h] [bp-5Ch]@222
    int v232; // [sp+54h] [bp-58h]@28
    int v233[2]; // [sp+58h] [bp-54h]@34
    int v234[2]; // [sp+60h] [bp-4Ch]@28
    int v235; // [sp+68h] [bp-44h]@28
    int v236; // [sp+6Ch] [bp-40h]@28
    int v237; // [sp+70h] [bp-3Ch]@17
    int v238; // [sp+74h] [bp-38h]@17
    __int64 v239; // [sp+78h] [bp-34h]@28
    int v240; // [sp+80h] [bp-2Ch]@29
    __int64 v241; // [sp+84h] [bp-28h]@14
    float v242; // [sp+8Ch] [bp-20h]@29
    __int64 v243; // [sp+90h] [bp-1Ch]@93
    int v244; // [sp+98h] [bp-14h]@93
    __int64 v245; // [sp+9Ch] [bp-10h]@110
    int v246; // [sp+A4h] [bp-8h]@110
    int v247; // [sp+A8h] [bp-4h]@2

    _ESI = a1;
    v5 = *(_DWORD *)(*(_DWORD *)(a1 + 32) + 692);
    if ( v5 )
    v247 = *(_DWORD *)v5;
    else
    v247 = 0;
    v7 = *(_BYTE *)(a1 + 124) == 0;
    BYTE4(v226) = 0;
    if ( !v7 )
    {
    if ( !(unsigned __int8)sub_1061F3E0(a1 + 128) )
    {
    BYTE4(v226) = 1;
    *(_BYTE *)(_ESI + 124) = 0;
    }
    if ( *(_BYTE *)(_ESI + 124) )
    {
    v215 = *(void (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)_ESI + 32);
    v232 = 0;
    v233[0] = 0;
    v215(_ESI, 2, &v232, 0, 0);
    LOBYTE(v228) = 0;
    HIDWORD(v228) = 0;
    v230 = 17179869188i64;
    result = a3;
    *(_DWORD *)a3 = 2;
    LABEL_256:
    __asm
    {
    movq xmm0, [esp+90h+var_74]
    movq qword ptr [eax+4], xmm0
    }
    v229 = 51539607552i64;
    __asm
    {
    movq xmm0, [esp+90h+var_6C]
    movq qword ptr [eax+0Ch], xmm0
    movq xmm0, qword ptr [esp+2Ch]
    movq qword ptr [eax+14h], xmm0
    }
    *(_DWORD *)(result + 28) = 15;
    return result;
    }
    }
    v8 = *(_DWORD *)(_ESI + 156);
    if ( v8 )
    (*(void (**)(void))(*(_DWORD *)v8 + 12))();
    v9 = *(_DWORD *)(_ESI + 156);
    v10 = v9 && !(unsigned __int8)(*(int (**)(void))(*(_DWORD *)v9 + 16))();
    v11 = sub_100E0B70(_ESI);
    LODWORD(v241) = v11;
    if ( v10 )
    {
    sub_105B9910((char *)&v226 + 4, 0, 0);
    v12 = *(_DWORD *)(_ESI + 156);
    if ( v12 )
    {
    (**(void (***)(void))v12)();
    sub_101B70A0(*(_DWORD *)(_ESI + 156));
    }
    *(_DWORD *)(_ESI + 156) = 0;
    (*(void (__thiscall **)(int, _DWORD))(*(_DWORD *)_ESI + 28))(_ESI, 0);
    v14 = *(void (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)_ESI + 32);
    v237 = 0;
    v238 = 0;
    v14(_ESI, 1, &v237, 0, 0);
    v13 = *(_DWORD *)(_ESI + 156);
    if ( v13 )
    {
    (**(void (***)(void))v13)();
    sub_101B70A0(*(_DWORD *)(_ESI + 156));
    *(_DWORD *)(_ESI + 156) = 0;
    }
    LOBYTE(v228) = 0;
    HIDWORD(v228) = 0;
    v230 = 17179869188i64;
    result = a3;
    *(_DWORD *)a3 = 1;
    goto LABEL_256;
    }
    v16 = *(_DWORD *)(_ESI + 92);
    v18 = *(_DWORD *)(_ESI + 96);
    v17 = 0;
    if ( v16 == v18 )
    goto LABEL_259;
    do
    {
    v16 = *(_DWORD *)(v16 + 4);
    ++v17;
    }
    while ( v16 != v18 );
    if ( v17 )
    v19 = *(_DWORD *)(*(_DWORD *)(_ESI + 92) + 8);
    else
    LABEL_259:
    v19 = 0;
    if ( sub_100E0B70(_ESI) == v19 && !*(_DWORD *)(_ESI + 156) )
    {
    (*(void (__stdcall **)(_DWORD))(*(_DWORD *)_ESI + 28))(0);
    v20 = *(void (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)_ESI + 32);
    v237 = 0;
    v238 = 0;
    v20(_ESI, 1, &v237, 0, 0);
    LOBYTE(v228) = 0;
    HIDWORD(v228) = 0;
    __asm { movq xmm0, [esp+90h+var_74] }
    v230 = 17179869188i64;
    _EAX = &v221;
    __asm { movq qword ptr [eax], xmm0 }
    v229 = 51539607552i64;
    __asm
    {
    movq xmm0, [esp+0ACh+var_6C]
    movq qword ptr [eax+8], xmm0
    movq xmm0, qword ptr [esp+48h]
    }
    v220 = 1;
    __asm { movq qword ptr [eax+10h], xmm0 }
    sub_100E6380(a3, v220, *(__int64 *)&v221, v223, v224, 15);
    return a3;
    }
    v26 = *(_WORD *)(_ESI + 60);
    __asm { movq xmm0, qword ptr [esi+24h] }
    _EBX = _ESI + 36;
    v235 = *(_DWORD *)(_ESI + 44);
    WORD2(v227) = v26;
    __asm { movq qword ptr [esp+90h+var_4C], xmm0 }
    (*(void (__thiscall **)(int, int *))(*(_DWORD *)v11 + 32))(v11, &v232);
    HIDWORD(v239) = (*(int (__thiscall **)(int, _DWORD))(*(_DWORD *)v11 + 36))(v11, *(_DWORD *)(_ESI + 32));
    BYTE3(v236) = 0;
    if ( BYTE4(v226) )
    {
    __asm { movq xmm0, qword ptr [esi+80h] }
    v29 = *(_WORD *)(_ESI + 140);
    v30 = *(_DWORD *)(_ESI + 144);
    v235 = *(_DWORD *)(_ESI + 136);
    v31 = *(_DWORD *)(_ESI + 148);
    __asm
    {
    movq qword ptr [esp+90h+var_4C], xmm0
    movss xmm0, dword ptr [esi+98h]
    }
    WORD2(v227) = v29;
    HIDWORD(v239) = v30;
    __asm { movss [esp+90h+var_20], xmm0 }
    v240 = v31;
    }
    else
    {
    v32 = *(int (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)v11 + 64);
    ++*(_DWORD *)(v11 + 36);
    v240 = v32(v11, a4, v234, (char *)&v227 + 4, (char *)&v236 + 3);
    (*(void (__thiscall **)(int))(*(_DWORD *)v11 + 44))(v11);
    v242 = a2;
    }
    v33 = sub_10571DF0(v234, _ESI + 36);
    if ( !v33 || (v34 = WORD2(v227) == *(_WORD *)(_ESI + 60), BYTE4(v241) = 0, !v34) )
    BYTE4(v241) = 1;
    v233[1] = 0;
    BYTE4(v226) = HIDWORD(v239) != 12;
    if ( !BYTE3(v236) )
    goto LABEL_61;
    if ( !(HIDWORD(v239) != 12) )
    goto LABEL_68;
    if ( v33 || v240 != 2 )
    {
    LABEL_61:
    if ( !BYTE4(v226) || v240 == 3 )
    goto LABEL_68;
    goto LABEL_63;
    }
    v35 = *(_DWORD *)(_ESI + 32);
    if ( *(_BYTE *)(v35 + 419) )
    {
    if ( *(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(v35 + 396) + 8) + 5420) + 160) == _ESI )
    {
    v36 = ((int (*)(void))sub_101F4F90)();
    LOBYTE(v36) = !(_BYTE)v36 && (v36 = sub_1026C750(*(_DWORD *)(_ESI + 32)), !(_BYTE)v36);
    v38 = *(_DWORD *)(_ESI + 32);
    v39 = *(_DWORD *)(*(_DWORD *)(v38 + 396) + 8);
    *(float *)&v225 = 3.402823466385289e38;
    HIDWORD(v224) = v36;
    v40 = sub_1042BF80(v38, v39);
    __asm { movq xmm0, qword ptr [esp+98h+var_4C] }
    v42 = v235;
    v43 = *(_DWORD *)(_ESI + 44);
    LODWORD(v224) = v40;
    _EAX = &v222;
    __asm
    {
    movq qword ptr [eax], xmm0
    movq xmm0, qword ptr [ebx]
    }
    HIDWORD(v223) = v42;
    _EAX = &v219;
    __asm { movq qword ptr [eax], xmm0 }
    v37 = sub_1060ADE0(v219, v220, v43, v222, v223, HIDWORD(v223), v224, HIDWORD(v224), (char)v225);
    }
    else
    {
    v47 = ((int (*)(void))sub_101F4F90)();
    LOBYTE(v47) = !(_BYTE)v47 && (v47 = sub_1026C750(*(_DWORD *)(_ESI + 32)), !(_BYTE)v47);
    v48 = *(_DWORD *)(_ESI + 32);
    v49 = *(_DWORD *)(*(_DWORD *)(v48 + 396) + 8);
    *(float *)&v225 = 3.402823466385289e38;
    HIDWORD(v224) = v47;
    v50 = sub_1042BF80(v48, v49);
    __asm { movq xmm0, qword ptr [esp+98h+var_4C] }
    v52 = v235;
    v53 = *(_DWORD *)(_ESI + 44);
    LODWORD(v224) = v50;
    _EAX = &v222;
    __asm
    {
    movq qword ptr [eax], xmm0
    movq xmm0, qword ptr [ebx]
    }
    HIDWORD(v223) = v52;
    _EAX = &v219;
    __asm { movq qword ptr [eax], xmm0 }
    v37 = sub_10157500(v219, v220, v53, v222, v223, HIDWORD(v223), v224, HIDWORD(v224), (char)v225);
    }
    BYTE4(v226) = v37;
    if ( !v37 )
    {
    if ( v232 )
    {
    v57 = sub_10697F40(*(_DWORD *)(_ESI + 32), v232, 3.402823466385289e38);
    }
    else
    {
    if ( !v233[0] )
    goto LABEL_68;
    v57 = sub_10206660(*(_DWORD *)(_ESI + 32), v233[0], 3.402823466385289e38);
    }
    LABEL_60:
    BYTE4(v226) = v57;
    goto LABEL_61;
    }
    }
    else
    {
    BYTE4(v226) = sub_106BA160(_ESI, _ESI + 36, (int)v234, 3.402823466385289e38);
    if ( !BYTE4(v226) )
    {
    if ( v232 )
    {
    v57 = sub_103B31E0(_ESI, *(_DWORD *)(_ESI + 32), v232, 3.402823466385289e38);
    }
    else
    {
    if ( !v233[0] )
    goto LABEL_68;
    v57 = sub_10678EA0(_ESI, *(_DWORD *)(_ESI + 32), v233[0], 3.402823466385289e38);
    }
    goto LABEL_60;
    }
    }
    LABEL_63:
    v59 = (unsigned __int8)(*(int (**)(void))(*(_DWORD *)v241 + 4))() == 0;
    v58 = *(_DWORD *)(_ESI + 156);
    if ( v59 )
    {
    v225 = &v233[1];
    HIDWORD(v224) = HIDWORD(v241);
    }
    else
    {
    v60 = HIDWORD(v241);
    v237 = 0;
    v238 = 0;
    BYTE4(v226) = sub_10559C70(_ESI, v234, HIDWORD(v239), &v237, v58, SBYTE4(v241), &v233[1]);
    if ( BYTE4(v226) )
    goto LABEL_68;
    v58 = *(_DWORD *)(_ESI + 156);
    v225 = &v233[1];
    HIDWORD(v224) = v60;
    }
    BYTE4(v226) = sub_10144A00(_ESI, v234, HIDWORD(v239), &v232, v58, HIDWORD(v224), v225);
    LABEL_68:
    if ( !BYTE4(v241) )
    goto LABEL_221;
    if ( (unsigned __int8)sub_10571DF0(v234, _ESI + 36) )
    goto LABEL_114;
    v61 = *(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8);
    if ( *(_DWORD *)(*(_DWORD *)(v61 + 5420) + 160) != _ESI )
    {
    if ( v233[1] == 3 )
    {
    v92 = v235;
    __asm { movq xmm0, qword ptr [esp+90h+var_4C] }
    v94 = WORD2(v227);
    v95 = HIDWORD(v239);
    __asm { movq qword ptr [esi+80h], xmm0 }
    *(_DWORD *)(_ESI + 136) = v92;
    v96 = v240;
    *(_WORD *)(_ESI + 140) = v94;
    *(_DWORD *)(_ESI + 144) = v95;
    *(_DWORD *)(_ESI + 148) = v96;
    LABEL_121:
    __asm { movss xmm0, [esp+90h+var_20] }
    v100 = *(void (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)_ESI + 32);
    v225 = 0;
    HIDWORD(v224) = 0;
    LODWORD(v224) = &v232;
    HIDWORD(v223) = 2;
    v101 = _ESI;
    *(_BYTE *)(_ESI + 124) = 1;
    __asm { movss dword ptr [esi+98h], xmm0 }
    v100(v101, HIDWORD(v223), v224, HIDWORD(v224), v225);
    LOBYTE(v228) = 0;
    HIDWORD(v228) = 0;
    v98 = 0;
    v230 = 17179869188i64;
    _EAX = &v221;
    v220 = 2;
    goto LABEL_122;
    }
    if ( v233[1] != 1 && (v233[1] != 2 || (unsigned __int8)sub_106AC630(*(_DWORD *)(v61 + 5428))) )
    goto LABEL_114;
    __asm
    {
    movq xmm0, qword ptr [esp+90h+var_4C]
    movq [esp+90h+var_1C], xmm0
    }
    v244 = v235;
    if ( v233[1] == 1
    && !(unsigned __int8)(*(int (__thiscall **)(_DWORD, __int64 *))(*(_DWORD *)v241 + 60))(v241, &v243) )
    {
    BYTE4(v226) = 0;
    goto LABEL_114;
    }
    v225 = *(int **)(_ESI + 32);
    sub_103CCAB0(v225);
    if ( *(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8) + 5420) + 160)
    || v233[1] == 1 && !(unsigned __int8)sub_100C9AB0(&v243, HIDWORD(v239)) )
    {
    __asm { movq xmm0, qword ptr [esp+90h+var_4C] }
    v134 = v235;
    v135 = HIDWORD(v239);
    v136 = WORD2(v227);
    v225 = 0;
    __asm
    {
    movq qword ptr [esi+80h], xmm0
    movss xmm0, [esp+94h+var_20]
    }
    *(_DWORD *)(_ESI + 136) = v134;
    v137 = v240;
    *(_DWORD *)(_ESI + 144) = v135;
    HIDWORD(v224) = 0;
    *(_WORD *)(_ESI + 140) = v136;
    v138 = *(void (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)_ESI + 32);
    LODWORD(v224) = &v232;
    *(_DWORD *)(_ESI + 148) = v137;
    HIDWORD(v223) = 2;
    v139 = _ESI;
    *(_BYTE *)(_ESI + 124) = 1;
    __asm { movss dword ptr [esi+98h], xmm0 }
    v138(v139, HIDWORD(v223), v224, HIDWORD(v224), v225);
    LOBYTE(v228) = 0;
    HIDWORD(v228) = 0;
    __asm { movq xmm0, [esp+90h+var_74] }
    v229 = 51539607552i64;
    v230 = 17179869188i64;
    _EAX = &v221;
    __asm
    {
    movq qword ptr [eax], xmm0
    movq xmm0, [esp+0ACh+var_6C]
    movq qword ptr [eax+8], xmm0
    movq xmm0, qword ptr [esp+48h]
    }
    v220 = 2;
    __asm { movq qword ptr [eax+10h], xmm0 }
    sub_100E6380(a3, v220, *(__int64 *)&v221, v223, v224, 15);
    sub_103D7930(v238);
    return a3;
    }
    sub_103D7930(v238);
    v107 = 2;
    if ( v233[1] == 2 )
    {
    if ( v232 )
    {
    _EAX = sub_101FFC00(v232);
    __asm
    {
    movq xmm0, qword ptr [eax]
    movq [esp+90h+var_1C], xmm0
    }
    v244 = *(_DWORD *)(_EAX + 8);
    }
    else
    {
    if ( v233[0] )
    {
    _EAX = (*(int (**)(void))(*(_DWORD *)v233[0] + 72))();
    __asm
    {
    movq xmm0, qword ptr [eax]
    movq [esp+90h+var_1C], xmm0
    }
    v244 = *(_DWORD *)(_EAX + 8);
    }
    }
    if ( (unsigned __int8)sub_101F4F90(*(_DWORD *)(_ESI + 32))
    || (unsigned __int8)sub_1026C750(*(_DWORD *)(_ESI + 32)) )
    {
    v112 = *(_DWORD *)(_ESI + 156);
    if ( !v112 || (unsigned __int8)(*(int (**)(void))(*(_DWORD *)v112 + 44))() )
    {
    if ( !(dword_119076D8 & 2) )
    {
    dword_119076D8 |= 2u;
    dword_119076BC = 0;
    dword_119076C0 = 0;
    dword_119076C4 = 0;
    atexit(sub_11338E60);
    }
    v113 = *(int **)(*(_DWORD *)(_ESI + 32) + 692);
    if ( v113 )
    v114 = *v113;
    else
    v114 = 0;
    v237 = v114;
    sub_1008A5C0(&v237);
    if ( v232 )
    {
    v115 = *(int **)(v232 + 692);
    if ( v115 )
    v116 = *v115;
    else
    v116 = 0;
    v237 = v116;
    sub_1008A5C0(&v237);
    v118 = *(_DWORD *)(_ESI + 32);
    v237 = v232;
    v117 = *(_DWORD *)(v232 + 692);
    if ( v117 )
    LODWORD(v227) = *(_DWORD *)v117;
    else
    LODWORD(v227) = 0;
    v119 = *(_DWORD *)(v118 + 692);
    if ( v119 )
    v120 = *(_DWORD *)v119;
    else
    v120 = 0;
    v121 = (*(int (__thiscall **)(int))(*(_DWORD *)_ESI + 36))(_ESI);
    sub_1061B980(v120, v227, v118, v237, &unk_119076B8, v121);
    }
    else
    {
    if ( v233[0] )
    {
    v237 = (*(int (**)(void))(*(_DWORD *)v233[0] + 16))();
    sub_1008A5C0(&v237);
    v124 = *(_DWORD *)(_ESI + 32);
    v122 = *(_DWORD *)(v124 + 692);
    v123 = v233[0];
    if ( v122 )
    LODWORD(v227) = *(_DWORD *)v122;
    else
    LODWORD(v227) = 0;
    v125 = (*(int (__thiscall **)(int))(*(_DWORD *)_ESI + 36))(_ESI);
    v126 = *(_DWORD *)v123;
    v225 = (int *)v125;
    v127 = *(int (**)(void))(v126 + 16);
    HIDWORD(v224) = &unk_119076B8;
    LODWORD(v224) = v123;
    HIDWORD(v223) = v124;
    v128 = v127();
    sub_10505740(v227, v128, HIDWORD(v223), v224, HIDWORD(v224), v225);
    }
    }
    v129 = *(_DWORD *)(_ESI + 156);
    __asm
    {
    movq xmm0, qword ptr [esp+90h+var_4C]
    movq [esp+90h+var_10], xmm0
    }
    v246 = v235;
    if ( v129 )
    {
    if ( *(_DWORD *)(v129 + 8) )
    {
    _EAX = sub_10628480(&v237);
    __asm
    {
    movq xmm0, qword ptr [eax]
    movq [esp+90h+var_10], xmm0
    }
    v246 = *(_DWORD *)(_EAX + 8);
    }
    }
    sub_10197970(&v243, &v245, &unk_119076B8);
    dword_119076C0 = 0;
    v107 = 2;
    }
    }
    }
    sub_1060F240(_ESI, &v243, v233[1]);
    if ( !(unsigned __int8)(*(int (**)(void))(*(_DWORD *)v241 + 4))()
    || v233[1] != v107
    || (unsigned __int8)sub_101F4F90(*(_DWORD *)(_ESI + 32))
    || (unsigned __int8)sub_1026C750(*(_DWORD *)(_ESI + 32)) )
    goto LABEL_114;
    goto LABEL_172;
    }
    if ( !BYTE4(v226) )
    goto LABEL_114;
    if ( v233[1] == 3 || !v233[1] )
    {
    sub_100FF540(_ESI);
    goto LABEL_114;
    }
    v62 = v241;
    if ( (unsigned __int8)(*(int (__thiscall **)(_DWORD))(*(_DWORD *)v241 + 4))(v241) && v233[1] == 2 )
    {
    if ( (unsigned __int8)sub_101F4F90(*(_DWORD *)(_ESI + 32)) || (unsigned __int8)sub_1026C750(*(_DWORD *)(_ESI + 32)) )
    {
    if ( !(unsigned __int8)sub_105B8700(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8) + 5428)) )
    goto LABEL_81;
    if ( sub_104034F0(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8) + 5428)) != *(_DWORD *)(_ESI + 32) )
    {
    v62 = v241;
    goto LABEL_81;
    }
    }
    LABEL_172:
    *(_BYTE *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8) + 5420) + 180) = 1;
    goto LABEL_114;
    }
    LABEL_81:
    if ( (unsigned __int8)sub_101F4F90(*(_DWORD *)(_ESI + 32)) || (unsigned __int8)sub_1026C750(*(_DWORD *)(_ESI + 32)) )
    {
    v63 = *(_DWORD *)(_ESI + 156);
    v64 = 0;
    if ( !v63 || (unsigned __int8)(*(int (**)(void))(*(_DWORD *)v63 + 44))() )
    {
    if ( (v233[1] == 2 || (unsigned __int8)(*(int (__thiscall **)(int))(*(_DWORD *)v62 + 4))(v62))
    && (unsigned __int8)sub_105FD3D0(2) )
    {
    if ( !(dword_119076D8 & 1) )
    {
    dword_119076D8 |= 1u;
    dword_119076CC = 0;
    dword_119076D0 = 0;
    dword_119076D4 = 0;
    atexit(sub_11338E80);
    }
    v65 = *(_DWORD *)(*(_DWORD *)(_ESI + 32) + 692);
    if ( v65 )
    v66 = *(_DWORD *)v65;
    else
    v66 = 0;
    LODWORD(v227) = v66;
    sub_1008A5C0(&v227);
    __asm
    {
    movq xmm0, qword ptr [esp+90h+var_4C]
    movq [esp+90h+var_1C], xmm0
    }
    v244 = v235;
    if ( v232 )
    {
    v68 = *(_DWORD *)(v232 + 692);
    if ( v68 )
    v69 = *(_DWORD *)v68;
    else
    v69 = 0;
    LODWORD(v227) = v69;
    sub_1008A5C0(&v227);
    v71 = *(_DWORD *)(_ESI + 32);
    v237 = v232;
    v70 = *(_DWORD *)(v232 + 692);
    if ( v70 )
    LODWORD(v227) = *(_DWORD *)v70;
    else
    LODWORD(v227) = 0;
    v72 = *(_DWORD *)(v71 + 692);
    if ( v72 )
    v73 = *(_DWORD *)v72;
    else
    v73 = 0;
    v74 = (*(int (__thiscall **)(_DWORD))(*(_DWORD *)_ESI + 36))(_ESI);
    sub_1061B980(v73, v227, v71, v237, &unk_119076C8, v74);
    _EAX = sub_101FFC00(v232);
    __asm
    {
    movq xmm0, qword ptr [eax]
    movq [esp+90h+var_1C], xmm0
    }
    v244 = *(_DWORD *)(_EAX + 8);
    }
    else
    {
    if ( !v233[0] )
    {
    LABEL_110:
    v86 = *(_DWORD *)(_ESI + 156);
    __asm
    {
    movq xmm0, qword ptr [esp+90h+var_4C]
    movq [esp+90h+var_10], xmm0
    }
    v246 = v235;
    if ( v86 != v64 )
    {
    if ( *(_DWORD *)(v86 + 8) != v64 )
    {
    _EAX = sub_10628480(&v237);
    __asm
    {
    movq xmm0, qword ptr [eax]
    movq [esp+90h+var_10], xmm0
    }
    v246 = *(_DWORD *)(_EAX + 8);
    }
    }
    sub_10197970(&v243, &v245, &unk_119076C8);
    dword_119076D0 = v64;
    goto LABEL_114;
    }
    v237 = (*(int (**)(void))(*(_DWORD *)v233[0] + 16))();
    sub_1008A5C0(&v237);
    v78 = *(_DWORD *)(_ESI + 32);
    v77 = *(_DWORD *)(v78 + 692);
    v79 = v233[0];
    if ( v77 )
    LODWORD(v227) = *(_DWORD *)v77;
    else
    LODWORD(v227) = 0;
    v80 = (*(int (__thiscall **)(_DWORD))(*(_DWORD *)_ESI + 36))(_ESI);
    v81 = *(_DWORD *)v79;
    v225 = (int *)v80;
    HIDWORD(v224) = &unk_119076C8;
    LODWORD(v224) = v79;
    v82 = *(int (__thiscall **)(_DWORD))(v81 + 16);
    HIDWORD(v223) = v78;
    v83 = v82(v79);
    sub_10505740(v227, v83, HIDWORD(v223), v224, HIDWORD(v224), v225);
    _EAX = (*(int (**)(void))(*(_DWORD *)v233[0] + 72))();
    __asm
    {
    movq xmm0, qword ptr [eax]
    movq [esp+90h+var_1C], xmm0
    }
    v244 = *(_DWORD *)(_EAX + 8);
    }
    v64 = 0;
    goto LABEL_110;
    }
    }
    }
    LABEL_114:
    if ( (unsigned __int8)(*(int (__thiscall **)(_DWORD))(*(_DWORD *)_ESI + 36))(_ESI) )
    {
    if ( !(unsigned __int8)sub_10571DF0(v234, _ESI + 36) )
    {
    v90 = *(_DWORD *)(*(_DWORD *)(_ESI + 32) + 692);
    if ( v90 )
    v91 = *(_DWORD *)v90;
    else
    v91 = 0;
    if ( !(unsigned __int8)sub_10453D70(v91) )
    {
    __asm
    {
    movss xmm0, ds:dword_113C3980
    cvtsi2ss xmm1, [esp+90h+var_4C+4]
    mulss xmm1, xmm0
    movss [esp+90h+var_3C], xmm1
    cvtsi2ss xmm1, [esp+90h+var_44]
    mulss xmm1, xmm0
    movss [esp+90h+var_38], xmm1
    }
    v144 = sub_104CA9E0(&v237);
    if ( v144 )
    {
    v150 = *(_DWORD *)(*(_DWORD *)(_ESI + 32) + 692);
    if ( v150 )
    v151 = *(_DWORD *)v150;
    else
    v151 = 0;
    v152 = *(_DWORD *)(v144 + 248);
    if ( v152 )
    v153 = *(_DWORD *)v152;
    else
    v153 = 0;
    if ( (unsigned __int8)sub_105DE830(v153, v151) )
    {
    v154 = *(_DWORD *)(v144 + 248);
    if ( v154 )
    v155 = *(_DWORD *)v154;
    else
    v155 = 0;
    if ( !(unsigned __int8)sub_10453D70(v155) )
    {
    v156 = *(_DWORD *)(v144 + 248);
    if ( v156 )
    v157 = *(_DWORD *)v156;
    else
    v157 = 0;
    v159 = sub_103573E0(v157);
    sub_10643AA0(v159);
    v158 = *(_DWORD *)(*(_DWORD *)(_ESI + 32) + 692);
    if ( v158 )
    v160 = *(_DWORD *)v158;
    else
    v160 = 0;
    v161 = sub_103573E0(v160);
    sub_10643AA0(v161);
    }
    }
    }
    }
    }
    }
    v225 = *(int **)(_ESI + 32);
    sub_105403B0(v225);
    (*(void (__thiscall **)(int, _DWORD))(*(_DWORD *)_ESI + 28))(_ESI, 0);
    LOBYTE(v227) = 0;
    if ( (unsigned __int8)sub_101758E0(v234, _ESI) )
    {
    BYTE4(v226) = 0;
    LOBYTE(v227) = 1;
    }
    v162 = 0;
    if ( sub_10D28370(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8) + 5428) + 84) != 1 )
    {
    if ( !BYTE4(v226) )
    goto LABEL_200;
    if ( (unsigned __int8)sub_1061F3E0(v234) )
    {
    v172 = v235;
    __asm { movq xmm0, qword ptr [esp+90h+var_4C] }
    v174 = WORD2(v227);
    v175 = HIDWORD(v239);
    __asm { movq qword ptr [esi+80h], xmm0 }
    *(_DWORD *)(_ESI + 136) = v172;
    v176 = v240;
    *(_WORD *)(_ESI + 140) = v174;
    *(_DWORD *)(_ESI + 144) = v175;
    *(_DWORD *)(_ESI + 148) = v176;
    goto LABEL_121;
    }
    if ( a5 )
    {
    __asm { movq xmm0, qword ptr [esi+24h] }
    v178 = *(_DWORD *)(_ESI + 44);
    *(float *)(_ESI + 84) = *(float *)(_ESI + 80);
    v179 = *(_WORD *)(_ESI + 60);
    __asm { movq qword ptr [esi+40h], xmm0 }
    *(_DWORD *)(_ESI + 72) = v178;
    *(_WORD *)(_ESI + 76) = v179;
    }
    __asm { movq xmm0, qword ptr [esp+90h+var_4C] }
    v182 = v235;
    v183 = WORD2(v227);
    __asm
    {
    movq qword ptr [esi+24h], xmm0
    movss xmm0, [esp+90h+var_20]
    }
    *(_DWORD *)(_ESI + 44) = v182;
    *(_WORD *)(_ESI + 60) = v183;
    *(_DWORD *)(_ESI + 172) = 0;
    _EAX = *(_DWORD *)(_ESI + 156);
    __asm { movss dword ptr [esi+50h], xmm0 }
    if ( _EAX )
    {
    __asm { comiss xmm0, dword ptr [eax+0Ch] }
    if ( !(_CF | _ZF) )
    __asm { movss dword ptr [eax+0Ch], xmm0 }
    }
    if ( *(_BYTE *)(_ESI + 62) == 1 || v240 == 2 || v240 == 3 )
    {
    __asm { movq xmm0, qword ptr [esi+24h] }
    v189 = *(_DWORD *)(_ESI + 44);
    *(float *)(_ESI + 84) = *(float *)(_ESI + 80);
    v190 = *(_WORD *)(_ESI + 60);
    __asm { movq qword ptr [esi+40h], xmm0 }
    *(_BYTE *)(_ESI + 62) = 0;
    *(_DWORD *)(_ESI + 72) = v189;
    *(_WORD *)(_ESI + 76) = v190;
    }
    LABEL_221:
    v192 = v241;
    v191 = (*(int (__thiscall **)(_DWORD))(*(_DWORD *)v241 + 4))(v241);
    if ( v191 ) // MASTERGH возможно ключевой момент, возможно условия выделеная ли Армия пользователя?
    {
    while ( 1 ) //mastergh возможно цикл когда Выделена Армия пользователя
    {
    (*(void (__thiscall **)(int, __int64 *))(*(_DWORD *)v192 + 16))(v192, &v228);
    __asm { movq xmm0, [esp+90h+var_74] }
    v194 = v231;
    _EAX = &v221;
    __asm
    {
    movq qword ptr [eax], xmm0
    movq xmm0, [esp+0ACh+var_6C]
    movq qword ptr [eax+8], xmm0
    movq xmm0, qword ptr [esp+48h]
    movq qword ptr [eax+10h], xmm0
    }
    sub_10339480(v221, *(_DWORD *)&v222, v223, HIDWORD(v223), v224, HIDWORD(v224), v194);
    if ( !HIDWORD(v230) )
    {
    v102 = v231;
    _EAX = &v221;
    v220 = 3;
    goto LABEL_123;
    }
    if ( (_BYTE)v228 )
    {
    __asm { movq xmm0, [esp+90h+var_74] }
    v204 = v231;
    _EAX = &v221;
    __asm
    {
    movq qword ptr [eax], xmm0
    movq xmm0, [esp+0ACh+var_6C]
    movq qword ptr [eax+8], xmm0
    movq xmm0, qword ptr [esp+48h]
    movq qword ptr [eax+10h], xmm0
    }
    v225 = (int *)v204;
    v220 = 4;
    goto LABEL_124; LABEL_230; // masterGH - выход на LABEL_124
    }
    if ( HIDWORD(v230) == 3 )
    {
    sub_103D8D20(_ESI); // mastergh - кщё функция
    v102 = v231;
    _EAX = &v221;
    v220 = 5;
    goto LABEL_123; // masterGH - выход на LABEL_123
    }
    if ( HIDWORD(v230) == 1 || HIDWORD(v229) != 12 )
    break;
    sub_103D8D20(_ESI); // mastergh (1 вхождение) (в sub_103D8D20) : shogun2.dll+25635e
    v198 = sub_100E0B70(_ESI);
    v192 = v198;
    if ( v198 && !(unsigned __int8)(*(int (__thiscall **)(int))(*(_DWORD *)v198 + 4))(v198) )
    {
    v191 = v192 == sub_1031A3A0(_ESI);
    goto LABEL_230; // masterGH - выход на LABEL_230
    }
    }
    sub_103D8D20(_ESI); // mastergh функция
    __asm { movq xmm0, [esp+90h+var_74] }
    v209 = v231;
    _EAX = &v221;
    __asm
    {
    movq qword ptr [eax], xmm0
    movq xmm0, [esp+0ACh+var_6C]
    movq qword ptr [eax+8], xmm0
    movq xmm0, qword ptr [esp+48h]
    movq qword ptr [eax+10h], xmm0
    }
    v225 = (int *)v209;
    v220 = 6;
    goto LABEL_124; // mastergh выход на LABEL_124
    }
    LABEL_230:
    v199 = 0;
    if ( v191 )
    v199 = 1;
    v200 = sub_1031A3A0(_ESI);
    if ( v192 == v200 )
    {
    v201 = *(_DWORD *)(_ESI + 156);
    if ( v201 )
    {
    v200 = (*(int (**)(void))(*(_DWORD *)v201 + 20))();
    if ( (_BYTE)v200 )
    v199 = 1;
    }
    }
    if ( BYTE4(v241) || v199 == 1 )
    {
    LOBYTE(v200) = BYTE4(v241) == 0;
    (*(void (__thiscall **)(int, signed int, int *, int, _DWORD))(*(_DWORD *)_ESI + 32))(_ESI, v199, &v232, v200, 0);
    }
    v202 = *(_DWORD *)(_ESI + 156);
    if ( v202 && (unsigned __int8)(*(int (**)(void))(*(_DWORD *)v202 + 4))() )
    {
    if ( (unsigned __int8)sub_101B70A0(*(_DWORD *)(_ESI + 156)) )
    *(_DWORD *)(_ESI + 156) = 0;
    }
    else
    {
    v213 = *(_DWORD *)(_ESI + 156);
    if ( !v213 || (unsigned __int8)(*(int (**)(void))(*(_DWORD *)v213 + 16))() )
    {
    if ( v192 == sub_1031A3A0(_ESI) )
    {
    v214 = *(_DWORD *)(_ESI + 156);
    if ( v214 )
    {
    if ( (unsigned __int8)(*(int (__thiscall **)(int))(*(_DWORD *)v214 + 24))(v214) )
    v199 = 1;
    }
    }
    }
    else
    {
    sub_101B70A0(*(_DWORD *)(_ESI + 156));
    *(_DWORD *)(_ESI + 156) = 0;
    }
    }
    HIDWORD(v228) = 0;
    v98 = 0;
    v230 = 17179869188i64;
    _EAX = &v221;
    LOBYTE(v228) = 0;
    v220 = v199;
    LABEL_122:
    LODWORD(v229) = v98;
    v102 = 15;
    HIDWORD(v229) = 12;
    LABEL_123:
    __asm
    {
    movq xmm0, [esp+0B0h+var_74]
    movq qword ptr [eax], xmm0
    movq xmm0, [esp+0B0h+var_6C]
    movq qword ptr [eax+8], xmm0
    movq xmm0, qword ptr [esp+4Ch]
    movq qword ptr [eax+10h], xmm0
    }
    *((_DWORD *)_EAX + 6) = v102;
    LABEL_124:
    sub_100E6380(a3, v220, *(__int64 *)&v221, v223, v224, v225);
    return a3;
    }
    v162 = 1;
    LABEL_200:
    sub_1059DCD0(
    (char *)&v226 + 4,
    0,
    v227,
    *(_BYTE *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8) + 5420) + 61),
    0);
    if ( BYTE5(v226) )
    {
    v163 = *(void (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)_ESI + 32);
    v225 = 0;
    HIDWORD(v224) = 0;
    LODWORD(v224) = &v232;
    HIDWORD(v223) = 0;
    }
    else
    {
    v164 = *(_DWORD *)_ESI + 32;
    v165 = sub_105B8700(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8) + 5428));
    v163 = *(void (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))v164;
    v225 = (int *)v165;
    HIDWORD(v224) = 0;
    LODWORD(v224) = &v232;
    HIDWORD(v223) = 1;
    }
    v163(_ESI, HIDWORD(v223), v224, HIDWORD(v224), v225);
    v166 = *(_DWORD *)(_ESI + 156);
    if ( v166 )
    (**(void (***)(void))v166)();
    if ( !v162 )
    {
    v225 = *(int **)(_ESI + 32);
    sub_100554B0(v225);
    }
    HIDWORD(v228) = 0;
    LOBYTE(v228) = 0;
    __asm { movq xmm0, [esp+90h+var_74] }
    v168 = BYTE5(v226) == 0;
    v229 = 51539607552i64;
    v230 = 17179869188i64;
    _EAX = &v221;
    __asm
    {
    movq qword ptr [eax], xmm0
    movq xmm0, [esp+0ACh+var_6C]
    movq qword ptr [eax+8], xmm0
    movq xmm0, qword ptr [esp+48h]
    movq qword ptr [eax+10h], xmm0
    }
    v225 = (int *)15;
    if ( v168 )
    {
    sub_100E6380(a3, 1, *(__int64 *)&v221, v223, v224, v225);
    result = a3;
    }
    else
    {
    sub_100E6380(a3, 0, *(__int64 *)&v221, v223, v224, v225);
    result = a3;
    }
    return result;
    }

    Осталось только проверить в отладке моё предположение о том выделен лы был игрок. Но это я сделаю не сегодня.

  4. Это в теории его должны применять в большинстве. На практике могут и не писать такую поддержку, а могут даже наоборот "перестараться" и добавить опцию включения и отключения аппаратного курсора для мышки. Насколько я предполагаю если эта поддержка выключения, то клики будут обрабатываться стандартно от сообщений обрабатываемых в функции привязанной к окну....

    По теме...

    Перевел я на псевдокод функцию уменьшающие шаги:

    int __thiscall sub_10654450(void *this, int a2)

    void *this - указатель на некоторую структуру Пользователя или бота

    int a2 - кол-во шагов которое желает выполнить *this

    return - наверно значение ошибки...

    Функция перебирает группы привязанные к *this и отнимает шаги перемещения.

    Эта функция находиться в окрестностях адреса вычитания очков перещения:

    Shogun2.dll+68DEB2 - 89 50 6C - mov [eax+6C],edx


    int __thiscall sub_10654450(void *this, int a2)
    {
    int result; // eax@1
    char *v3; // ecx@1
    int v4; // esi@1
    int v5; // eax@2
    int v6; // edx@2

    v3 = (char *)this + 148;
    v4 = *((_DWORD *)v3 + 5);
    for ( result = v4 + 4 * *((_DWORD *)v3 + 4); // начальное значения для начала цикла
    v4 != result; // условие выполнение цикла пока истино v4 != result
    result = *((_DWORD *)v3 + 5) + 4 * *((_DWORD *)v3 + 4) ) // действие при каждой повторении цикла
    {

    v5 = **(_DWORD **)v4; // v5 = адрес группы (v5 теперь является подгруппой *this)
    v6 = *(_DWORD *)(v5 + 0x6C); // v6 = разрешённых шагов для группы v5

    if ( v6 <= a2 ) // если разрешённых шагов меньше например 3, когда попытка пойти на 5, то
    *(_DWORD *)(v5 + 0x6C) = 0; // присвоить v5 перемещение 0
    else // иначе
    *(_DWORD *)(v5 + 0x6C) = v6 - a2; // присворить v5 разность между разршенными шагами и "сделанными"

    *(_DWORD *)(v5 + 0x898) = -1; // какое-то интересное смещение +0x898, что означает точно не понятно.
    // по карайне мере понятно, что оно стаиться в -1, когда v5 было установленно
    // кол-во разрешённых шагов

    v4 += 4; // перебираем следующую группу
    }
    return result;
    }

    Переписываем функцию так, чтобы она давала шаги отряду вместо того чтобы забирать их.


    int __thiscall Cheat_SetPointMove(void *unit, int a2)
    {
    int result; // eax@1
    char *v3; // ecx@1
    int v4; // esi@1
    int v5; // eax@2
    int v6; // edx@2

    v3 = (char *)unit + 148;
    v4 = *((_DWORD *)v3 + 5);
    for ( result = v4 + 4 * *((_DWORD *)v3 + 4);
    v4 != result;
    result = *((_DWORD *)v3 + 5) + 4 * *((_DWORD *)v3 + 4) )
    {

    v5 = **(_DWORD **)v4;
    v6 = *(_DWORD *)(v5 + 0x6C);

    if ( v6 <= 1000000 )
    *(_DWORD *)(v5 + 0x6C) = a2;

    *(_DWORD *)(v5 + 0x898) = -1;

    v4 += 4;
    }
    return result;
    }

    Эта функция обязательно пригодиться, когда при инициализации чита нужно чтобы сарзу всем героям Пользователя дать необходимое кол-во очков например 500000.

    void units = GetPlayerObjects();

    Cheat_SetPointMove(void &units, 500000);

    Дальше нужно не вызывать функцию sub_10654450 если units принадлежит не Player.

    Для этого нужно изменить sub_10654450:


    int __thiscall sub_10654450(void *this, int a2)
    {
    int result; // eax@1
    char *v3; // ecx@1
    int v4; // esi@1
    int v5; // eax@2
    int v6; // edx@2

    // инъекция пвсевод-кода
    void playerUnits = GetPlayerObjects();
    if (playerUnits==this)
    {
    Cheat_SetPointMove(playerUnits,500000)
    return;
    }
    //=====================

    v3 = (char *)this + 148;
    v4 = *((_DWORD *)v3 + 5);
    for ( result = v4 + 4 * *((_DWORD *)v3 + 4); // начальное значения для начала цикла
    v4 != result; // условие выполнение цикла пока истино v4 != result
    result = *((_DWORD *)v3 + 5) + 4 * *((_DWORD *)v3 + 4) ) // действие при каждой повторении цикла
    {

    v5 = **(_DWORD **)v4; // v5 = адрес группы (v5 теперь является подгруппой *this)
    v6 = *(_DWORD *)(v5 + 0x6C); // v6 = разрешённых шагов для группы v5

    if ( v6 <= a2 ) // если разрешённых шагов меньше например 3, когда попытка пойти на 5, то
    *(_DWORD *)(v5 + 0x6C) = 0; // присвоить v5 перемещение 0
    else // иначе
    *(_DWORD *)(v5 + 0x6C) = v6 - a2; // присворить v5 разность между разршенными шагами и "сделанными"

    *(_DWORD *)(v5 + 0x898) = -1; // какое-то интересное смещение +0x898, что означает точно не понятно.
    // по карайне мере понятно, что оно стаиться в -1, когда v5 было установленно
    // кол-во разрешённых шагов

    v4 += 4; // перебираем следующую группу
    }
    return result;
    }

    Чтобы функцию перевести на машинныкод, лучше скопироват старую в машинном коде и изменить её.

    Дальше исследовать пока нет времени. Надо идти вверх по call-ам и разобраться с указателем ecx передаваемым в функцию sub_10654450... Фактически мы должны дойти до развилки имеет ли право идти игрок. Там должен быть код определения игрока. Если это игрок, если его очки хода больше 0, то разрешить ему перемещение.

    Возможно, будет сложно. Например, один поток который собирает сообщение от ДайректИнпут запишет некоторой новое событие в в некотурую очередь собщений о том что надо пердвинуть отряд, а другой поток будет читать эту очередь...

    Ладно, дальше будет видно.

    Что касается вопросов по OllyDbg.

    OllyDbg видимо снёс Xipho. Поэтому этот вопрос прямо к нему :) у нас была OllyShadow.

    Иногда OllyDbg не может обрабатывать инструкции и неизбежно придётся перезагружать процесс игры. И это касается трейсинга. Возможно не повезло. А возможно стоит поставить игнор исключений в настройках. Долго об этом писать.

    movq вообще интресная инструкция связанная с глюками. Если например она работать с адресом не кратным "как это говорят параграфу", то что-то будет нестабильное... Я думаю если можно как-то в трейсинге отметить что такой-то участок не трейсить, то предлагаю это сделать.

    По пункту два. Это обычное явление... более прокомментировать как решить проблему с трассировкой не могу, т.к. без понятия.

  5. Как написал Xipho по этому скрипту нет ответа почему именно такие смещения прибавляются к регистрам. Эти смещения я когда-то давно искал в отладчике реверсингом совместно со сканером памяти.

    Суть в том что по выражению [[core.dll+00155744h]+350h]+43Ch находится указатель на адрес здоровья героя. И если этот адрес совпадает с eax на участке кода куда была сделана инъекция, то записать в этот адрес 250 очков здоровь. Если этого не сделать, то все игроки будут бессмертными.

    Но что здесь неправильно, а то что имея полноценный указатель чуть более правильнее записывать в него данные без сравнения.

    Именно эту запись нужно делать циклически

    [[[core.dll+0x00155744]+0x350]+0x43C] = 250 

    Вот так...


    push ebx
    mov ebx,[core.dll+00155744]
    mov ebx,[ebx+350]
    mov byte ptr [ebx+43C],#250
    pop ebx
    originalcode:
    mov ecx,[eax]
    mov edx,[esp+04]
    ....

  6. Откуда такая информация что в большинстве? :) Лично я в Дисайплс 3 когда-то давно именно таким способом что-то делал и всё работало. На Чемаксе мои посты есть по этому поводу. И никаких хуков на ДайректИнпут я не ставил.

    //bronis, по заданному вопросу отвечу позже

  7. Может быть и нет разницы...

    Какое у тебя сообщение вылазит из этих:

    .rdata:1001C308 aUsingGameVer_0 db 'Using game version 1.0.1',0
    .rdata:1001C308 ; DATA XREF: sub_100050D0:loc_10005176o
    .rdata:1001C321 align 4
    .rdata:1001C324 aInitialization db 'Initialization failed -- Unknown game version',0
    .rdata:1001C324 ; DATA XREF: sub_100050D0+99o
    .rdata:1001C352 align 4
    .rdata:1001C354 ; char aFailedToDetect[]
    .rdata:1001C354 aFailedToDetect db 'Failed to detect game version',0
    .rdata:1001C354 ; DATA XREF: sub_100050D0:loc_10005152o
    .rdata:1001C372 align 4
    .rdata:1001C374 ; char aUsingGameVersi[]
    .rdata:1001C374 aUsingGameVersi db 'Using game version 1.0.2',0
    .rdata:1001C374 ; DATA XREF: sub_100050D0+5Bo
    .rdata:1001C38D align 10h
    .rdata:1001C390 ; char aAutoDetectingG[]
    .rdata:1001C390 aAutoDetectingG db 'Auto detecting game version',0
    .rdata:1001C390 ; DATA XREF: sub_100050D0+2Do
    .rdata:1001C3AC ; char aProcessBaseAdd[]
    .rdata:1001C3AC aProcessBaseAdd db 'Process base address: 0x%x',0

    Наверно, это "Failed to detect game version" ?

    ----------------

    Меня что-то глюкнуло. Оказывается *.Lib файл это файл содержащий информацию экспорта и импорта относительно ScriptHook.dll описания. Файл нужен для компоновщика чтобы построить SampleCustom.dll корректно работающего с функциями ScriptHook.dll.

  8. Сложно сказать в этом духе или в другом... Смотря как разработчики код игры написали. То что на видео, это сравнение данных структур. Можно не стесняться и брать мног структур. Своего героя, пару ботов из твоей команды и по паре ботов из двух других команд... Определяешь группы и ищешь чем они отличаются. Если найдёшь отличие, то сможешь сделать "фильтр" для совершения какого-то действия...

  9. Приаттач твою SampleCustom.dll в архиве в посте. Что-то я свою SampleCustom.dll собрать не могу из-за ошибок в настройках проекта портированного на VS2010. Завтра я проверю её под отладкой.

    ---

    Да и кстати в АА-скриптах CE есть команда "LOADLIBRARY(filename)". Попробуй её. Нужно заранее приаттачить процесс игры. В filename указать полный путь.

  10. По поводу указателей, которые ты привёл на картинке я знаю что они меняются с перезапуском игры. Я не акцентировал внимание на это. Это просто небольшая зацепка для дальнейших поисков статичных указателей и "постоянных фильтров". Но пока я не попробовал метод об определении кто свой, а кто чужой с помощью бряка на щелок мышки, лучше с фильтрами не возиться. Я попробую завтра.

    Как ставить бряк на клик мышью?!

    25.png

    Тут полная статья о клике на кнопку, хотя не важно на что кликать... Но лучше чтобы я это сделал, потому что у меня опыта больше. Так что до завтра.

  11. Если про GTAIV, то для компиляции своей dll-ки нужен файл "ScriptHook.lib", а ScriptHook.dll не требуется.

    В примере проекта из SVN (на который я указывал ссылку) этот файл ScriptHook.libимеется.

    Можно скомпилировать пример из SVN например SampleCustom, получится SampleCustom.dll. Её кладём в директории игры и используем асилоадер или просто загружаем эту SampleCustom.dll через Cheat Engine загрузчик без выполнения каких-либо определённых функций в ней. Активируем клавиши и играем со спавном. Разве не так должно быть? Просто я этого не делал, поэтому точно не знаю.


  12. // Обработчик события клика мышки
    void OnBtnClick(object sender, MouseArgs args)
    {
    GameObject gameObject = nil;
    // Выбираем объект под курсором мышки

    gameObject = GetObjectFromMouse(args.x, args.y, argz.z);
    if (gameObject == nil) // если объекта нет, то проверить был ли выделен объект поьзователя
    {
    // Последний выделенныйобъект
    gameObject = GetlastSelectGameObj();

    // Если объект пользователя (!!! вот в этом месте определяется что групаа принадлежит пользователю)
    if (IsUser(gameObject))
    {
    // то попытаться перенести объект, в данном случае "объект это отряд войска"
    // в этой функции, где-то там будет проверка на оставшиеся ходы и вычет ходов из остальных отрядов
    TryMove(gameObject,args.x, args.y, argz.z);

    }
    // Если объект не пользователя, то выход

    return;
    }

    seelct(gameObject); // подсветка объекта
    //...
    }

    void TryMove(gameObject,args.x, args.y, argz.z)
    {
    //...
    group = gameObject as GroupClass;
    //...

    if (group.move(args.x, args.y, argz.z))
    {
    anyGroup = getGroups(group)
    anyGroup.decreaseMove(group.lastMove)
    }
    // ...
    }

    В отладчике надо найти то место, где я отметил восклицательными знаками. Там где выясняется может ли отряд ходить потому что принадлежит пользователю.

    В OllyDbg надо поставить бряк на обработку щелчка мышки... один бряк поставить на запись очков передвижения... Сделать автоматический трейс по ретам до последнего бряка, и затем отпустить процесс чтобы узнать пересечение участков... и тогда должны выйти под call-ом. Посомтрим выше и должны увидеть код условия о передвижения отряда который принадлежит только нашему герою. написал в теории как смог... Я проверю эту теорию, когда выделю на это время...

  13. Попробуй искать цепочку указателей свою и 2-х чужих машин, и затем сравнивать структуры указателей в Cheat Engine "dessect data" из меню дизассемблера. Как это делается есть в статье про Медал Тотал Вар на нашем сайте. Ещё поищи англоязычные статьи Geri по Cheat Engine. Вот одна. У него даже должно быть видео, вроде, по сравнениям структур.

  14. О, неплохо ты в этом во всём шаришь...

    Я установил эту игру, думал быстро разберусь, а не тут-то было (сейчас дел навалом, может быть на недели попробую копнуть).

    Вот что я предполагаю:

    Пользователь:
    Группа1 юнитов на карте:
    Unit_ID:
    + ..:
    +44: одинаковый указатель для "Пользователя"
    +6c: очки действия
    // либо здесь конец структуры
    _+B8: одинаковый указатель для "Пользователя"
    // либо здесь конец структуры

    Группа2 юнитов на карте:
    Unit_ID:
    + ..:
    +44: одинаковый указатель для "Пользователя"
    +6c: очки действия
    // либо здесь конец структуры
    _+B8: одинаковый указатель для "Пользователя"
    // либо здесь конец структуры

    ....
    ГруппаN юнитов на карте:
    Unit_ID:
    + ..:
    +44: одинаковый указатель для "Пользователя"
    +6c: очки действия
    // либо здесь конец структуры
    _+B8: одинаковый указатель для "Пользователя"
    // либо здесь конец структуры

    БотN:
    Группа1 юнитов на карте:
    Unit_ID:
    + ..:
    +44: одинаковый указатель для БотN
    +6c: очки действия
    // либо здесь конец структуры
    _+B8: одинаковый указатель для БотN
    // либо здесь конец структуры

    Группа2 юнитов на карте:
    Unit_ID:
    + ..:
    +44: одинаковый указатель для БотN
    +6c: очки действия
    // либо здесь конец структуры
    _+B8: одинаковый указатель для БотN
    // либо здесь конец структуры

    ....
    ГруппаN юнитов на карте:
    Unit_ID:
    + ..:
    +44: одинаковый указатель для БотN
    +6c: очки действия
    // либо здесь конец структуры
    _+B8: одинаковый указатель для БотN
    // либо здесь конец структуры

    Одна инструкция

    Shogun2.dll+68DEB2 - 89 50 6C 		- mov [eax+6C],edx

    работает со всеми адресами ОД (очками действия). У меня много мыслей как поступить дальше, но пока я ничего писать не буду, т.к. могу запутать. Да, и предполагаю, что указатель в виде скобок написать не получиться, потому что его часть по идее может рассчитываться функцией с логическим условием. Например, перебирать такие-то элементы в пока не дойдём до конца массива и возвратить количество элементов в массиве.

    Если одна группа сдвинулась на шаг, то очки хода у остальных отнимаются.


    if (group.move)
    {
    anyGroup = getGroups(group)
    anyGroup.decreaseMove(group.lastMove)
    }

    Я уверен, что должен быть почти такой код, а это значит, что скорее всего надо больше внимания обращать на функции и её аргументы. Т.е. надо искать по всему стеку в моменты бряков такие функции , которые работают с группой после хода одной группы... Лучше не заморачиваться с указателямя, а заморачиваться с функциями в дереве вызовов...

  15. local te_health = getTableEntry("health")

    function CECheckbox1Change(sender)
    if ( checkbox_getState(sender)== 1 ) then
    memoryrecord_setValue(te_health, "100")
    memoryrecord_freeze(te_health, 0)
    else
    memoryrecord_setValue(te_health, "99")
    memoryrecord_unfreeze(te_health)
    end
    end

    Поглядывай сюда, тут могут быть подсказки о том какие функции тебе использовать. Тебе пригодиться. Когда я писал для тебя код я смотрел, только туда )

  16. local te_health = getTableEntry("health")

    function CECheckbox1Change(sender)
    if ( checkbox_getState(sender) )
    memoryrecord_freeze(te_health, 0) //0=freeze, 1=allow increase, 2=allow decrease
    else
    memoryrecord_unfreeze(te_health)
    end
    end

    В этом примере предварительно нужно установить записываемое значение заморозки в главной таблице Cheat Engine. Будет ли этот код работать без ошибок не знаю, тебе надо проверить.

  17. Чтобы побыстрее ответить я напишу кратко, а если будут вопросы, то задавай.

    1. Сначала создаём форму в IDE Cheat Engine.

    2. На неё бросаем чекБокс.

    3. Заходим во вкладку Events и создаём событие напротив onchange двойным кликом по соседнему полю.

    И ты увидишь:

    function CECheckbox1Change(sender)

    end

    Если задача записывать в адрес разные значения при активации и деактивации чексбокса, то написать надо следующее.

    function CECheckbox1Change(sender)
    if ( checkbox_getState(sender) )
    // запись в адрес
    else
    // запись в адрес
    end
    end

    Затем надо нажать Execute Script и закрыть IDE, закрыв панель инструментов. Так останется одна форма с чекбоксом. Ну а дальше проверяешь, работает или нет активируя чекбокс.

  18. Ну, вот ещё информация. Поискал я ответы в Интернете и нашёл. Просто я знал, что моддинг к GTA очень развивается...

    На странице SVN "проекта по созданию модов" есть функция создания машины.

    Ссылка для скачивания для клиента SVN:

    http://gta4modding.googlecode.com/svn/trunk/

    static void CreateCar(u32 nameHash, f32 x, f32 y, f32 z, Vehicle *pVehicle, b8 unknownTrue) { 

    NativeInvoke::Invoke<scriptVoid>("CREATE_CAR", nameHash, x, y, z, pVehicle, unknownTrue);
    }

    Эта функция как и другие, как очевидно, используются для модинга.

    Ну и ещё есть одна:

    static void GetCarModel(Vehicle vehicle, eModel *pValue) { 
    NativeInvoke::Invoke<NATIVE_GET_CAR_MODEL, ScriptVoid>(vehicle, pValue);
    }

    Разберёмся, что требуется для создания машины и как работает GetCarModel. Т.е. мы разберём технологию спавна "на поверхности", но не так глубоко как хотелось бы. Пока мне не понятно как эта инфа была кем-то сотсавлена и изучена. Одно понятно, что этот человек действительно Гуру создания модов, а читов и подавно. Могу его только сильно уважать. Его никнейм Aru.

    Все машины в первую очередь создаются по скриптам(на самом деле это что-то вроде своего языка программирования в опкодах), а затем уже машинным кодом.

    Вот пример из GTAIV создания машины, скрипт декомпилирован из особых опкодов(составленных разработчиками игр) в текстовый формат:

    .native HAS_MODEL_LOADED // in=1, out=1
    .iftrue
    PushD 8
    Var
    RefGet
    PushD 9
    Var
    PushD 0
    Add
    RefGet
    PushD 9
    Var
    PushD 4
    Add
    RefGet
    PushD 9
    Var
    PushD 8
    Add
    RefGet
    PushD 23
    LocalVar
    PushD 1
    .native CREATE_CAR // in=6, out=0

    Вот более понятный вид,но уже из Санд-Андреас:

    Загружаем модель машины, проверяем что она загрузилась, размещаем модель в игре:

    :Createcar
    wait 0
    Model.Load(#SULTAN)

    :Createcar_3
    wait 100
    if
    Model.Available(#SULTAN).
    jf @Createcar_3
    $9 = Car.Create(#SULTAN, 2488.917, -1658.0735, 13.3549)
    0229: set_car $9 color_to 31 0

    Функции ниже это обвертки C++ или Паскальные:

    Разберём параметры функций (источник "Seemann")

    static void GetCarModel(Vehicle vehicle, eModel *pValue) { 
    NativeInvoke::Invoke<NATIVE_GET_CAR_MODEL, ScriptVoid>(vehicle, pValue);
    }

    //Vehicle vehicle : хендл машины
    //eModel *pValue : переменная-приемник, куда будет записано ID модели.

    значения параметров косвенно можно определить по названию функции. Если функция называется GetCarModel (в переводе получить модель машины), значит должно быть как минимум 2 параметра:

    1. хендл машины и

    2. переменная-приемник, куда будет записано ID модели.

    Хендл машины - это переменная с ее "именем", позволяющим отличить от другой машины. Хендл получается как раз из следующей функции:

    CreateCar. Её параметры можно понять по названию:

    static void CreateCar(u32 nameHash, f32 x, f32 y, f32 z, Vehicle *pVehicle, b8 unknownTrue) { 

    NativeInvoke::Invoke<scriptVoid>("CREATE_CAR", nameHash, x, y, z, pVehicle, unknownTrue);
    }

    //u32 nameHash : хэш имени модели (http://www.gtamodding.com/index.php?title=List_of_models_hashes), например Например, для

    //AMBULANCE хэш равен 1171614426 или 0x45D56ADA
    //f32 x, f32 y, f32 z : это координаты места, где будет создана машина. Например, 100.10 -986.12 55.0
    //Vehicle *pVehicle : Переменная с типом Vehicle, в которую будет записан хендл созданной машины (см. выше)
    //b8 unknownTrue : Неизвестный параметр. В оригинальных скриптах всегда равен 1 или True.

    Пример вызова функций на Паскале:


    var
    _mycar:Vehicle;
    _mymodel: u32;

    CreateCar(1171614426, 100.10, -986.12, 55.0, _mycar, true);

    Можно догадаться чему будет равен результат теперь:

    GetCarModel(_mycar; _mymodel);

    Более подробно как я уже писал смотрим:

    GTAModding.ru Wiki - ссылка

    обсуждение вопроса создания машины (там в основном Паскаль): ссылка

    хеши (или уникальные ID) моделей: здесь

    ------------

    Вопрос о том можно ли подобное создать на Cheat Engine. Ответ да, можно... Есть сложные пути, а есть и простые. О сложных путях было написано уже до этого поста. А простой путь это найти необходииые Lua- модули с описанием CreateCar. Вызывать эту функцию из LUA-Engine...

    -------------

    А вот пример, от самого Aru (там есть и спавн машины и другие читы:)


    #include "Scripting.h"
    #include "../ScriptHook/Log.h"

    #include <windows.h>

    // Pull in all our scripting functions/types
    using namespace Scripting;

    CustomFiberThread::CustomFiberThread()
    {
    // Give your own name here!
    SetName("CustomFiberThread");
    }

    // Some helper functions

    Player CustomFiberThread::GetPlayer()
    {
    Player playerIndex = ConvertIntToPlayerIndex(GetPlayerId());
    return playerIndex;
    }

    Scripting::Ped CustomFiberThread::GetPlayerPed()
    {
    Ped ped;
    GetPlayerChar(GetPlayer(), &ped);
    return ped;
    }


    void CustomFiberThread::SpawnCar(eModel model)
    {
    RequestModel(model);

    while(!HasModelLoaded(model))
    {
    Wait(0);
    }

    LogInfo("Car model available... spawning it!");

    Ped ped = GetPlayerPed();

    Vehicle vehicle;
    f32 x,y,z;

    GetCharCoordinates(ped, &x, &y, &z);

    CreateCar(model, x, y, z, &vehicle, true);

    MarkModelAsNoLongerNeeded(model);

    }

    void CustomFiberThread::ChangePlayerSkin(eModel model)
    {
    RequestModel(model);

    while(!HasModelLoaded(model))
    {
    Wait(0);
    }

    LogInfo("Skin model available... spawning it!");

    eInteriorRoomKey roomKey;

    GetKeyForCharInRoom(GetPlayerPed(), &roomKey);

    ChangePlayerModel(GetPlayer(), model);

    SetRoomForCharByKey(GetPlayerPed(), roomKey);

    MarkModelAsNoLongerNeeded(model);

    }

    void CustomFiberThread::TeleportToWaypoint(Scripting::Ped &ped)
    {
    Blip b = GetFirstBlipInfoId(BLIP_WAYPOINT);
    if(b.IsValid())
    {
    Vector3 v;
    GetBlipCoords(b, &v);

    LogInfo("Teleporting to %f, %f", v.X, v.Y);

    // Thanks to Prince-Link for this magical Z coord detection code...
    SetCharCoordinates(ped, v.X, v.Y, v.Z);
    while(v.Z == 0.0f) // The chance that ground Z is 0.0 _exactly_ is really small
    {
    GetGroundZFor3DCoord(v.X, v.Y, 1000, &v.Z);
    Wait(0);
    }

    SetCharCoordinates(ped, v.X, v.Y, v.Z);
    }
    else
    {
    LogError("No way point found to teleport to.");
    }

    }


    // The real script

    void CustomFiberThread::RunScript()
    {
    // This is a fiber thread, so we use an loop to run the contents of this script.
    // The thread will terminate when we return from this function.

    while(IsThreadAlive())
    {

    if ((GetAsyncKeyState(VK_F4) & 1) != 0)
    {
    LogInfo("Teleporting player to way point");

    TeleportToWaypoint( GetPlayerPed() );
    }
    else if ((GetAsyncKeyState(VK_F5) & 1) != 0)
    {
    LogInfo("Spawning a random car");

    Vehicle vehicle;
    u32 modelHash;
    ScriptAny unknown;

    f32 x,y,z;
    GetCharCoordinates(GetPlayerPed(), &x, &y, &z);

    GetRandomCarModelInMemory(1, &modelHash, &unknown);
    CreateCar(modelHash, x, y, z, &vehicle, true);
    }
    else if ((GetAsyncKeyState(VK_F6) & 1) != 0)
    {
    LogInfo("Granting player $1000");

    AddScore(GetPlayer(), 1000);
    }
    else if ((GetAsyncKeyState(VK_F7) & 1) != 0)
    {
    LogInfo("Requested a MODEL_BANSHEE spawn");

    SpawnCar(MODEL_BANSHEE);
    }
    else if ((GetAsyncKeyState(VK_F8) & 1) != 0)
    {
    LogInfo("Changing the player skin");

    ChangePlayerSkin(MODEL_IG_JOHNNYBIKER);
    }
    else if ((GetAsyncKeyState(VK_F9) & 1) != 0)
    {
    LogInfo("Changing the player skin back to Niko's");

    ChangePlayerSkin(MODEL_PLAYER);
    }

    // Call Wait() so we can process other scripts/game code
    // You must call Wait(...) in your loop code for a fiber thread!
    Wait(100);

    }


    }

    #include "CustomFiberThread.h"

    Данный код компилируется в модуль dll. При аттаче этого модуля к процессу игры (можно сделать и с помощью Cheat Engine), можно активировать hot-keys и тем самым включать читы. Для спавна машины надо нажать F7. Скрипты Aru можно найти в Интернете.


    {
    RequestModel(model); // создать модель машины, укажите model - машины, например MODEL_BANSHEE, другие модели ищите в исходниках Aru
    while(!HasModelLoaded(model)) // дождаться когда модель инициализируется
    {
    Wait(0);
    }
    LogInfo("Car model available... spawning it!"); // лог
    Ped ped = GetPlayerPed(); // получить описатель главного героя

    Vehicle vehicle; // создать какой-то описатель
    f32 x,y,z; // координаты

    GetCharCoordinates(ped, &x, &y, &z); // получить координаты героя
    CreateCar(model, x, y, z, &vehicle, true); // создать машину и возвратить vehicle, если он пригодиться позже
    MarkModelAsNoLongerNeeded(model); // с моделью машины уже отработали, надо её отметить как ненужную
    }
    void CustomFiberThread::SpawnCar(eModel model)

  19. А чем Вас видео не устроило : "Взлом денег Mafia 2 Обман денег и создание скрипта", а также "Devil May Cry 4 Бесконечное здоровье и убийство с одного удара." Может быть что-то не понятно или Вы просто не посмотрели? Все видео находится в соответствующем разделе форума. ZOCKIR-у, если увидит это сообщение за видео ещё раз спасибо лично от меня.

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.