,

Хак на память Warcraft3

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


Просмотров: 51 366



» Лучшие комментарии


NazarPunk #551 - 3 месяца назад 0
Bergi_Bear, а можно вообще написать свой лаунчер и хранить в карте .dll, как дота на айкапе)
PT153 #552 - 3 месяца назад 0
Можно сделать свою игру.
Bergi_Bear #553 - 3 месяца назад 0
NazarPunk, зачем лаунчер, надо чтобы на гарене работало, сделать своё это слишком просто "да и не интересно"
quq_CCCP #554 - 3 месяца назад 0
NazarPunk:
Bergi_Bear, а можно вообще написать свой лаунчер и хранить в карте .dll, как дота на айкапе)
Ну вот это дело и делает IseFog. Свой лаунчер, изначально для ускорение функционала мемхака, но не взлетело, оказалось как у айкапа для защиты публике важнее... Кто бы мог подумать?
Naadir #555 - 1 неделю назад (отредактировано ) 0
quq_CCCP:
функции для работы с сайленсом, позволяют задать разные типы сайленса (от обычного безмолвия, то паузы, когда способности скрываются с карты комманд)
» код
(( код jass
set pAddSilenceOnAbility=GameDLL+0x052B60 оффсет для 1.26
set pRemoveSilenceFromAbility=GameDLL+0x052BC0 оффсет для 1.26
set pAddSilenceOnAbility = GameDLL + 0x3E9FA0 оффсет для 1.27
set pRemoveSilenceFromAbility = GameDLL + 0x3EE3C0 оффсет для 1.27
function AddSilenceToAbility takes integer a returns nothing
if a > 0 then
call CallThisCallWith3Args( pAddSilenceOnAbility, a, 0, 1 )
0 for hide, 1 for silence
endif
endfunction

function RemoveSilenceFromAbility takes integer a returns nothing
if a > 0 then
call CallThisCallWith3Args( pRemoveSilenceFromAbility, a, 0, 1 )
endif
endfunction

function AddSilenceHideToAbility takes integer a returns nothing
if a > 0 then
call CallThisCallWith3Args( pAddSilenceOnAbility, a, 1, 1 )
endif
endfunction

function RemoveSilenceHideFromAbility takes integer a returns nothing
if a > 0 then
call CallThisCallWith3Args( pRemoveSilenceFromAbility, a, 1, 1 )
endif
endfunction
))
Что именно передаётся в функции? Что такое integer a?

UPD. разобрался по чистой случайности. Е-е-е!:)

UPD2. Вот такой код вызывает не "переключение" абилок между собой, а нечто другое: первый раз юзаем первую абилку => она сайленсится, затем юзаем вторую вбилку => первая выходит из сайленса, но вторая в него не входит, втф?
<...>
function Trig_ToMelee_Actions takes nothing returns nothing
    call AddSilenceToAbility(GetUnitAbility(GetSpellAbilityUnit(),'A048'))
    call RemoveSilenceFromAbility(GetUnitAbility(GetSpellAbilityUnit(),'A049'))
endfunction
<...>
function Trig_ToRange_Actions takes nothing returns nothing
    call AddSilenceToAbility(GetUnitAbility(GetSpellAbilityUnit(),'A049'))
    call RemoveSilenceFromAbility(GetUnitAbility(GetSpellAbilityUnit(),'A048'))
endfunction
<...>
А вот такой код с тем же алгоритмом вызывает последовательный сайленс обеих абилок.
<...>
function Trig_ToMelee_Actions takes nothing returns nothing
    call AddSilenceToAbility(GetUnitAbility(GetSpellAbilityUnit(),'A048'))
    call RemoveSilenceFromAbility(GetUnitAbility(GetSpellAbilityUnit(),'A049'))
    call AddSilenceToAbility(GetUnitAbility(GetSpellAbilityUnit(),'A048'))
endfunction
<...>
function Trig_ToRange_Actions takes nothing returns nothing
    call AddSilenceToAbility(GetUnitAbility(GetSpellAbilityUnit(),'A049'))
    call RemoveSilenceFromAbility(GetUnitAbility(GetSpellAbilityUnit(),'A048'))
    call AddSilenceToAbility(GetUnitAbility(GetSpellAbilityUnit(),'A049'))
endfunction
<...>
0_о
quq_CCCP #556 - 1 неделю назад 0
Naadir, нужен таймер на 0.00 сек, после каста абилки, чтобы корректно накладывать на неё сайленс, снимать сайленс, то же самое с кулдауном, ибо триггер срабатывает немного раньше чем ты реально применил способность, и получается что сайленс прилетел до того как ты нажал кнопку абилки.
Naadir #557 - 1 неделю назад 0
quq_CCCP, окей.
quq_CCCP, а сколько тиков занимает таймер на 0.00 сек.? В ассемблере, когда прогаешь микроконтроллеры, 1 операция = 1 тик. Возможно, тут тоже есть альтернативные способы? Например, вывод пустых строк в чат.
PT153 #558 - 1 неделю назад (отредактировано ) 0
Naadir, все таймеры запускаются после вызова функции, в котором их запустили. Я думаю, что при старте таймера делается такая проверка: если указанное время не больше 0 и коллбек не нулл, то запустить коллбек.
Naadir #559 - 1 неделю назад 0
PT153, т.е. 3 тика? Запуск, проверка, колбэк.
Погодь, или... Если после функции, то там дохера разное время может быть.
PT153 #560 - 1 неделю назад (отредактировано ) 0
Всё происходит вот так.
выполнение функции-действия триггера
какие-то операции
call TimerStart(timer, 0, false, callback)
какие-то операции без пауз
конец выполнения функции-действия триггера
запуск таймера timer
Или так.
выполнение функции-действия триггера
какие-то операции
call TimerStart(timer, 0, false, callback)
какие-то операции без пауз
пауза на любое время
запуск таймера timer
Между всеми указанными действиями нет никаких пауз, только стандартное время выполнения, что очень мало.
В момент запуска таймера и делается проверка, что я предположил.
при старте таймера делается такая проверка: если указанное время не больше 0 и коллбек не нулл, то запустить коллбек
Naadir #561 - 1 неделю назад (отредактировано ) 0
PT153, окей.
quq_CCCP, ничего не работает, если нужно посайленсить одну абилку и снять сайленс с другой одновременно. Хз, почему.
Даже если занести эти действия в 2 разных таймера, получается херня.

Ребят, посмотрите, пожалуйста, мб я недопонимаю что-то. Клепаю новую версию своей карты. Код находится в подкомментарии "Технические" в папке "SkeletonBerserker". Для того, чтобы понять, что ничего не работает, достаточно запустить карту и попробовать применить способности последовательно. Они должны переключаться. Но они этого не делают. При этом с кулдаунами творится что-то совсем эпическое.
прикреплены файлы
quq_CCCP #562 - 1 неделю назад 0
Naadir, ну для начала немного учимся работать с jass, то как бы ты не убил карту с такой манерой написания кода...
globals
    hashtable gamedata = InitHashtable( )
endglobals

function Trig_ToMelee_Conditions takes nothing returns boolean
    return ( GetSpellAbilityId() == 'A048' )
endfunction

function Timer_AddSilence_Expires takes nothing returns nothing
    local timer t  = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local unit enemy = LoadUnitHandle( gamedata, id, 0 )
    local integer spellid = LoadInteger( gamedata, id, 1 )
    
    call StartAbilityCooldown( enemy,'A049', -1 )
    set spellid = GetUnitAbility(enemy,spellid) // для начала нам нужно убедится что у юнита есть такая абилка и её адресс коректный.
    if spellid > 1 then //всегда проверяй корректность адрессов, мы нашли адресс способности в памяьти игры, адресс обьекта а не просто РО кода.
       call AddSilenceToAbility(spellid) // функция сайленса, берет адресс способности и записывает по оффсету в структуру способности сведенья о сайленсе, подумай что будет если адресс не верен?
    endif
    set enemy = null 
    set t = null
endfunction

function Trig_ToMelee_Actions takes nothing returns nothing
    local unit enemy = GetSpellAbilityUnit() // создадим переменную чтобы не мучится гуи пережитками...
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)
    call SetUnitArmor(enemy,GetUnitArmor(enemy)*2)
    // 2 = ranger, 1 = instante, 0 = melee, 5 = splash, 6 = mbounce,
    call SetUnitWeaponType(enemy,0)
    call SetUnitAttackRange1(enemy,128)
    call SaveUnitHandle( gamedata, id, 0, enemy )
    call SaveInteger( gamedata, id, 1, GetSpellAbilityId())
    call TimerStart( t, 0.00, false, function Timer_AddSilence_Expires)
    set t = null
    set enemy = null
endfunction

//===========================================================================
function InitTrig_ToMelee takes nothing returns nothing
    set gg_trg_ToMelee = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_ToMelee, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_ToMelee, Condition( function Trig_ToMelee_Conditions ) )
    call TriggerAddAction( gg_trg_ToMelee, function Trig_ToMelee_Actions )
endfunction
Зачем столько триггеров для такого простого спелла переключателя? Достаточно одного.
Ну вот выбор одного из двух состояний, правда хз нах так было заморачиватся, просто морфы и все.
Ну и для переключателей и механик каста лучше использовать не сайленс а мут абилок, от сайленса он отличается тем что не прирывает каста абилки но не дает применять её в ручную. Подробнее можно глянуть в моей карте.
прикреплены файлы
Naadir #563 - 1 неделю назад 0
quq_CCCP, попробую разобраться. Заморачиваюсь, потому что хочу протестировать способности мемхака.
Naadir #564 - 4 дня назад 0
Функции с уроном и хп вызывают фатал, с чем это может быть связано?
А, по-моему, это я алёшенька.
Ага.