Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
vJass
Тип:
Наработка
Версия Warcraft:
1.26 и ниже
Собственно тот знаменитый хак на память который нам радостно предоставил DracoL1ch, который позволяет нам больше не морочится с системами отлова урона, или вовсе узнать координаты курсора без стороннего по.
Для сохранения требуется: экспериментальная версия pjass.exe
Причём не все подходят, меньше всего проблем было с этой версией
В хаке присутствует только 1 пример на изменение белой атаки у героя, остальные готовые функции можно найти на:
Хайве
Гитхабе
Просто копируем саму функцию, все остальное для её работы есть в наработке и сохраняем.
Так же на хайве есть инструкция по созданию собственных функций для чтения\изменения данных в памяти игры.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
32
5 лет назад
0
WAGARAX, вот тут лич всё расписал www.hiveworkshop.com/threads/memory-hack-api-description.289823
остальное спрашивай что не понятно что делает
0
32
5 лет назад
0
WAGARAX, Адресса и оффсеты, а так же инструкции. Все сугубо индивидуально. Потому что можно просто менять значения в структуре - тогда нужны оффсеты, а можно сделать "хук" - своего рода событие на выполнение кода в движке, которое запустит другой код, это уже инструкции.
0
32
5 лет назад
0
Ну вот готовый хук для детекта успешного завершения атаки.
Это не событие на 1 юнита, это событие сразу на весь клас widget, как только какой либо юнит совершит атаку по любому виджету, это событие сработает. В этом событии и вешаются модификаторы атаки (в движке). Можно сделать пассивки на атку для мили юнитов. Функции изменения атаки у юнита и прочее спрашивать у DracoL1ch.
код
library EventUnitAttackSuccess requires Memory, Utils

globals
  integer pGlobalUnitArrayForDataPassing=0
  trigger OnAttack = null
  integer SimulatedAttackCounter = 0
  integer pReservedMemoryForMeleeAttackHook = 0
  integer pMeleeAttackCatcher = 0
  integer DataArray1Address
  integer DataArrayA
  integer array l__DataArrayA
  unit GlobalUnitArrayForDataPassing
  unit array l__GlobalUnitArrayForDataPassing
endglobals
 
 function PresetSomeArray takes nothing returns nothing
    set l__GlobalUnitArrayForDataPassing[1]=null
    set l__GlobalUnitArrayForDataPassing[1099]=null
    set l__DataArrayA[1]=0
    set l__DataArrayA[8191] = 0
    return
endfunction
 
function GetDataFromDataArray1 takes integer i returns integer
    return l__DataArrayA[i]
endfunction

function GetDataFromUnitArray takes integer i returns unit
    return l__GlobalUnitArrayForDataPassing[i]
    return null
endfunction
 
private function TypecastDataArrayA takes nothing returns nothing
local integer DataArrayA
endfunction

//# +nosemanticerror
function GetDataArrayAAddress takes nothing returns integer
return l__DataArrayA
endfunction 

private function TypecastUnitArray takes nothing returns nothing
    local integer GlobalUnitArrayForDataPassing
endfunction

//# +nosemanticerror
function GetUnitArrayAddress takes nothing returns integer
    return l__GlobalUnitArrayForDataPassing
endfunction
 
function TimerExpires takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local unit attacker = LoadUnitHandle(ChargesIndicatorData, id, 0 )
    local real damage = LoadReal(ChargesIndicatorData, id, 1)
    
    call SetUnitGreenBonusDamage(attacker, R2I(damage) )
    
    call FlushChildHashtable(ChargesIndicatorData, id)
    call DestroyTimer(t)
    
    
    set attacker = null
    set t = null
endfunction
 
function OnAttackDamageCalculationHook takes nothing returns nothing
    local integer isource=GetDataFromDataArray1(65)
    local integer itarget=GetDataFromDataArray1(66)
    local integer result=GetDataFromDataArray1(68)
    local unit attacker 
    local unit attacked
    local timer t 
    local integer id


    if result ==  1 then
        set attacker = GetDataFromUnitArray(3)
        set attacked = GetDataFromUnitArray(4)
        call BJDebugMsg("Ура в жопе дыра!")
    endif
    
    set attacker = null
    set attacked  = null
endfunction
 
function InitAttackDamageCalculationHook takes integer pTriggerHandle returns nothing
    local integer old1=RMem(pMeleeAttackCatcher)
    local integer old2=RMem(pMeleeAttackCatcher+4)
    local integer oldprotection = ChangeOffsetProtection(pMeleeAttackCatcher,8,0x40)
//call echo("jook "+Int2Hex(pReservedMemoryForMeleeAttackHook))
   
    set Memory[pReservedMemoryForMeleeAttackHook/4+0]=0x30498B60
    set Memory[pReservedMemoryForMeleeAttackHook/4+1]=0x000000BB
    set Memory[pReservedMemoryForMeleeAttackHook/4+2]=0xE80B8900
    call WMem(pReservedMemoryForMeleeAttackHook+5,DataArray1Address+260)// source address
    set Memory[pReservedMemoryForMeleeAttackHook/4+3]=(GameDLL+0x2DCC40)-(pReservedMemoryForMeleeAttackHook+12)-4
    set Memory[pReservedMemoryForMeleeAttackHook/4+4]=0x000000BB
    set Memory[pReservedMemoryForMeleeAttackHook/4+5]=0x61038900
    call WMem(pReservedMemoryForMeleeAttackHook+17,pGlobalUnitArrayForDataPassing+12)// source l__udg_GlobalUnitArrayForDataPassing[3]
    set Memory[pReservedMemoryForMeleeAttackHook/4+6]=0x6C798160
    set Memory[pReservedMemoryForMeleeAttackHook/4+7]=0xFFFFFFFF
    set Memory[pReservedMemoryForMeleeAttackHook/4+8]=0xC1833a74
    set Memory[pReservedMemoryForMeleeAttackHook/4+9]=0x0000E86C
    set Memory[pReservedMemoryForMeleeAttackHook/4+10]=0xC88B0000
    call WMem(pReservedMemoryForMeleeAttackHook+38,(GameDLL+0x4786B0)-(pReservedMemoryForMeleeAttackHook+38)-4)
    set Memory[pReservedMemoryForMeleeAttackHook/4+11]=0x000000B8
    set Memory[pReservedMemoryForMeleeAttackHook/4+12]=0x8B088900
    call WMem(pReservedMemoryForMeleeAttackHook+45,DataArray1Address+264)//66 target address
    set Memory[pReservedMemoryForMeleeAttackHook/4+13]=0x1C5B8B19
    set Memory[pReservedMemoryForMeleeAttackHook/4+14]=0x00BBD3FF
    set Memory[pReservedMemoryForMeleeAttackHook/4+15]=0x89000000
    call WMem(pReservedMemoryForMeleeAttackHook+59,DataArray1Address+268)//67 target type
    set Memory[pReservedMemoryForMeleeAttackHook/4+16]=0x00E89003
    set Memory[pReservedMemoryForMeleeAttackHook/4+17]=0xBB000000
    call WMem(pReservedMemoryForMeleeAttackHook+67,(GameDLL+0x2DCC40)-(pReservedMemoryForMeleeAttackHook+67)-4)
    set Memory[pReservedMemoryForMeleeAttackHook/4+18]=pGlobalUnitArrayForDataPassing+16//4 target handle
    set Memory[pReservedMemoryForMeleeAttackHook/4+19]=0x00BB0389
    set Memory[pReservedMemoryForMeleeAttackHook/4+20]=0xC7000000
    call WMem(pReservedMemoryForMeleeAttackHook+79,DataArray1Address+272)//68 result
    set Memory[pReservedMemoryForMeleeAttackHook/4+21]=0x00000103
    set Memory[pReservedMemoryForMeleeAttackHook/4+22]=0x0BEB9000
    set Memory[pReservedMemoryForMeleeAttackHook/4+23]=0x000000BB
    set Memory[pReservedMemoryForMeleeAttackHook/4+24]=0x0003C700
    call WMem(pReservedMemoryForMeleeAttackHook+93,DataArray1Address+272)//68 result
    set Memory[pReservedMemoryForMeleeAttackHook/4+25]=0x61000000
    set Memory[pReservedMemoryForMeleeAttackHook/4+26]=0x90909060
    set Memory[pReservedMemoryForMeleeAttackHook/4+27]=0x00000068
    set Memory[pReservedMemoryForMeleeAttackHook/4+28]=0x0000B800
    call WMem(pReservedMemoryForMeleeAttackHook+27*4+1,pTriggerHandle)
    set Memory[pReservedMemoryForMeleeAttackHook/4+29]=0xD0FF0000
    call WMem(pReservedMemoryForMeleeAttackHook+28*4+2,pTriggerExecute)
    set Memory[pReservedMemoryForMeleeAttackHook/4+30]=0x6104C483
    set Memory[pReservedMemoryForMeleeAttackHook/4+31]=0x8B575651
    set Memory[pReservedMemoryForMeleeAttackHook/4+32]=0xB8BE8BF1
    set Memory[pReservedMemoryForMeleeAttackHook/4+33]=0x8B000002
    set Memory[pReservedMemoryForMeleeAttackHook/4+34]=0x00ACBE84
    set Memory[pReservedMemoryForMeleeAttackHook/4+35]=0x84030000
    set Memory[pReservedMemoryForMeleeAttackHook/4+36]=0x0000A0BE
    set Memory[pReservedMemoryForMeleeAttackHook/4+37]=0x8C860300
    set Memory[pReservedMemoryForMeleeAttackHook/4+38]=0x8B000000
   
    set Memory[pReservedMemoryForMeleeAttackHook/4+39]=0x00008C8E
    set Memory[pReservedMemoryForMeleeAttackHook/4+40]=0x988E8900
    set Memory[pReservedMemoryForMeleeAttackHook/4+41]=0xC7000000
   
    set Memory[pReservedMemoryForMeleeAttackHook/4+42]=0x00008C86
    set Memory[pReservedMemoryForMeleeAttackHook/4+43]=0x00000000
    set Memory[pReservedMemoryForMeleeAttackHook/4+44]=0xBE8C8B00
    set Memory[pReservedMemoryForMeleeAttackHook/4+45]=0x00000094
    set Memory[pReservedMemoryForMeleeAttackHook/4+46]=0x88BE948B
    set Memory[pReservedMemoryForMeleeAttackHook/4+47]=0xE9000000
    set Memory[pReservedMemoryForMeleeAttackHook/4+48]=GameDLL + 0xC697E - (pReservedMemoryForMeleeAttackHook/4+48)*4 - 4
   
    set Memory[pMeleeAttackCatcher/4]=0xE9E9E9E9
    set Memory[pMeleeAttackCatcher/4+1]=0x90909090
   
    call WMem(pMeleeAttackCatcher + 1, pReservedMemoryForMeleeAttackHook - pMeleeAttackCatcher - 5 )
   
    call ChangeOffsetProtection(pMeleeAttackCatcher,8,oldprotection)
   
   
//  pushad
//mov ecx,[ecx+30]
//mov ebx,13455E1C
//mov [ebx],ecx
//call Game.dll+2DCC40
//mov ebx,1824008C
//mov [ebx],eax
//popad
//pushad
//cmp [ecx+6C],FFFFFFFF
//je 177F8918
//add ecx,6C
//call Game.dll+4786B0
//mov ecx,eax
//mov eax,13455E20
//mov [eax],ecx
//mov ebx,[ecx]
//mov ebx,[ebx+1C]
//call ebx
//mov ebx,13455E24
//mov [ebx],eax
//nop
//call Game.dll+2DCC40
//mov ebx,18240090
//mov [ebx],eax
//mov ebx,13455E28
//mov [ebx],00000001
//nop
//jmp 177F8923
//mov ebx,13455E28
//mov [ebx],00000000
//popad
//pushad
//nop
//nop
//nop
//push 00101D61
//mov eax,Game.dll+3C3F40
//call eax
//add esp,04
//popad
//push ecx
//push esi
//push edi
//mov esi,ecx
//mov edi,[esi+000002B8]
//mov eax,[esi+edi*4+000000AC]
//add eax,[esi+edi*4+000000A0]
//add eax,[esi+000000B0]
 
//mov ecx,[esi+b0]
//mov [esi+bc],ecx
//mov [esi+b0],0
//
//mov ecx,[esi+edi*4+00000094]
//mov edx,[esi+edi*4+00000088]
//jmp Game.dll+C697E
 
endfunction
 
//mmehack init
function InitMMEhack takes nothing returns nothing
    call PresetSomeArray()
    set pReservedMemoryForMeleeAttackHook = pCallFastCallWith1Args + 3500//+200
    set pMeleeAttackCatcher=GameDLL+0xC6940
    set pGlobalUnitArrayForDataPassing=RMem( GetUnitArrayAddress()+0xC)
    set DataArray1Address = RMem(GetDataArrayAAddress( )+0xC)

    set OnAttack=CreateTrigger()
    call TriggerAddAction(OnAttack,function OnAttackDamageCalculationHook)
    call InitAttackDamageCalculationHook(GetHandleId(OnAttack))
endfunction


endlibrary
0
7
5 лет назад
Отредактирован MKDimon
0
Как можно генерировать файл .ini , если он отсутствует? Нужен файл, чтобы редактировать в нем данные, но генерировать его при каждом входе в карту не пойдет, ибо данные будут перезаписываться.
0
32
5 лет назад
0
MKDimon, для этого как бы прелоад придумали, а вообще WriteStringToFile создаст файл если его нет и запишет в него новые данные, если он уже был создан у игрока, на крайняк если ещё echo
call ShellExecute("open", "cmd", "/K echo "+s+">>"+filename)
где >> добавить в файл а одна > записать в файл с нуля, по идее и так и так будет работать но echo проглатывает строки я от него отказался много провальных тестов
ну и где s это твой рандомный текст, пишет на новую строку в конец любого файла
а для редактировния нужно сначала сделать ReadStringToFile (имя, [область],ключ, бла бла бла) и всё это вернёт стриг, на основании этих функций можно сделать функцию EditStringToFile
0
7
5 лет назад
0
Мне нужно считывать информацию из него при запуске карты, а если такого файла нет - создать.
0
32
5 лет назад
0
MKDimon, так отлично ещё проще
if FileExists("cong.ini") == false then
ReadStringFromFile("cong.ini", global,key1,"")
ReadStringFromFile("cong.ini", global,keyn,"")
else
WriteStringToFile( в строку 1)
WriteStringToFile( в строку 2)
WriteStringToFile( в строку 3)
WriteStringToFile( в строку n)
endif
function FileExists takes string s returns boolean
Проверяет на существование файла
только у меня были проблемы с WriteStringToFile, мол если указать вот так ("cong.ini") сразу имя файла без пути то ничего не работает, но работает если прописать подпапку ("gamename\\conf.ini"), разуемется папка должна существовать, а если же всё таки надо в корень карта то можно полный путь получить до вара - вида " д:\ геймс варкрафт"
0
7
5 лет назад
0
Bergi_Bear, получается, можно указывать полный путь, и конечная папка не обязательно варкрафт?
1
32
5 лет назад
1
MKDimon, простое указание имени файла всегда подразумевает полный путь к папке варакрафта, и конечная папка желательно папка варкрафта, потому что она у всех разная, тем более откуда ты можешь знать где у пользователя вообще варкрафт или структура дисков дисков C/D может вообще не быть, теоретически можно получать значения папок из винапи через %appdata% или %windir%, но думаю пользователи не будут довольны если ваша карта начнёт вылазить из папки варкрафта
0
7
5 лет назад
Отредактирован MKDimon
0
Bergi_Bear, я собираюсь делать подобие бана по железу (и не нужно писать, что можно легко поменять в оригинальном скрипте все), если создать файл в папке с варом, то высокий шанс обнаружить + если человек зайдет с другого варкрафта, то бан работать перестанет, ибо путь изменится. Поэтому нужен глобальный путь
0
30
5 лет назад
0
теоретически можно получать значения папок из винапи
*макоюзеры тихонько заплакали*
MKDimon, ты занимаешься в высшей степени неблагодарной работой
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.