,

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

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


Просмотров: 53 811



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


Bornikkeny #1 - 3 года назад 0
Надо попробовать. Вещ однако!
Borodach #2 - 3 года назад 0
А реально создать такую функцию изменения данных, которая меняет описание чисел способностей и предметов на переменные в игре?
quq_CCCP #3 - 3 года назад 0
Borodach:
А реально создать такую функцию изменения данных, которая меняет описание чисел способностей и предметов на переменные в игре?
Она уже есть!
function SetAbilityUbertip takes integer id, integer lvl, string s returns boolean
function GetAbilityUbertip takes integer id, integer lvl returns string
В доте лича меняются описания скиилов у инвокера (конкретное кол-во урона, прочие эффекты которые зависят от уровня сфер).
Копируем код с гитхаба (на хайве неудобно) и вставляем в тхт файл, открываем жасскрафтом и Citr+F (название интересующей функции) и копируем себе в карту все что требуется.
l_Avenger_l #4 - 3 года назад 0
Побочные эффекты возможны?)) карта потом не нагнется от такого ?)
quq_CCCP #5 - 3 года назад 0
l_Avenger_l, Не тестировалось в широких массах, ошибки в некоторых функциях приводят к фатальным ошибкам.
А примеру функция которая запускает способность в кулдаун фаталит если:
юнита нет, способности нет, способность является пассивкой (тестировалось только с змеиной ловкостью и демонической силой, у перерождения кулдаун работает исправно)
Так что нужно правильно организовать код чтобы не пускать кулдауны у дохлых или несуществующих юнитов. А так же всегда проверять их на наличие способности.
l_Avenger_l #6 - 3 года назад 0
Там сказано, что можно не морочиться с отловом урона, это типа можно напрямую вычислить от руки ли бы нанесен удар?
А так текущую атаку самого героя буз лишних бд)
есть функция SetUnitArmorType я так понял позволяет меня тип защиты, интересно если юниту в зависимости от предметов менять тип его защиты к чему это приведет ?))
GetLocalPlayer #7 - 3 года назад 0
Не тестировалось в широких массах
А бетовскую версию нового дотана разве еще нигде не хостботят?
quq_CCCP #8 - 3 года назад 0
GetLocalPlayer, Хостботят, и исправляют все ошибки.
Очень понравилась функция которая накладывает сайленс на указанную способность юнита.
Bornikkeny #9 - 3 года назад 0
quq_CCCP:
l_Avenger_l, Не тестировалось в широких массах, ошибки в некоторых функциях приводят к фатальным ошибкам.
А примеру функция которая запускает способность в кулдаун фаталит если:
юнита нет, способности нет, способность является пассивкой (тестировалось только с змеиной ловкостью и демонической силой, у перерождения кулдаун работает исправно)
Так что нужно правильно организовать код чтобы не пускать кулдауны у дохлых или несуществующих юнитов. А так же всегда проверять их на наличие способности.
Мне вот страшно стало. Ведь это глобальные изменения? То есть, если Рубик сворует, скажем, торнадо то получится что описание будет точ-в-точ как у Инвокера? Или все эти изменения будут локальны для каждого юнита. Но в это трудом верится, как-то.
quq_CCCP #10 - 3 года назад 0
Bornikkeny, Описание меняется у всех абилок с таким ро кодом на карте
Bornikkeny #11 - 3 года назад 0
quq_CCCP:
Bornikkeny, Описание меняется у всех абилок с таким ро кодом на карте
Вот вот. Но с другой стороны, от этого становится легче :)
quq_CCCP #12 - 3 года назад 0
Рубик помойму ворует отдельные версии скиллов для кражи у инвокера...
Кет #13 - 3 года назад 0
ссылка на гитхаб ведёт на хайв
Bornikkeny #14 - 3 года назад (отредактировано ) 0
quq_CCCP:
Рубик помойму ворует отдельные версии скиллов для кражи у инвокера...
Я рак, конечно этого не знал :D
Кет:
ссылка на гитхаб ведёт на хайв
О, повелитель пришел поклон
quq_CCCP #15 - 3 года назад 0
Кет:
ссылка на гитхаб ведёт на хайв
Уже исправил.
Кет #16 - 3 года назад 1
Она уже есть!
Для предметов вроде нет. Эх =(
quq_CCCP #17 - 3 года назад 0
Иконки у способностей на основе "Сфера замедления" можно разблокировать, сделав кликабельным, а так же возможность кастовать спелл в ручную, но эффект автокаста при ударе останется.
Пригодится для автокаста способностей у которых его нету а ИИ писать не охото.
Кстати наконец то решен извечный вопрос - кулдаун на пассивке!
Можно ставить кд перерождению, а чтобы оно ни сработало когда это ненужно вешаем на юнита событие TriggerRegisterDeathEvent ( EVENT_WINDGET_DEARH) и запускать способность в кд той же функцией. Увы но только это событие срабатывает при смерти юнита с крестом перерождения.
l_Avenger_l #18 - 3 года назад 0
А как выяснить тип нанесенного урона(с руки или спелл)?
quq_CCCP #19 - 3 года назад 0
l_Avenger_l:
А как выяснить тип нанесенного урона(с руки или спелл)?
Нужно триггер на событие получения урона и смотреть тип атаки и урона, и гадать.
вот код
// WARNING!! IT CAN BE USED ONLY IN FIRST CONDITION AT FIRST POSITION
function GJ_GetRealDmg126a takes nothing returns real
	return cleanReal(indexToReal(ReadEBP_offset(0x380)))
endfunction

// WARNING!! IT CAN BE USED ONLY IN FIRST CONDITION AT FIRST POSITION
function GJ_GetRealDmg127a takes nothing returns real
	return cleanReal(indexToReal(ReadEBP_offset(0x400)))
endfunction

function GJ_SaveLastDmg126a takes nothing returns boolean
	if GetTriggerEventId()!=EVENT_UNIT_DAMAGED then
		return true
	endif
	
	set GJ_LastDmg = GJ_GetRealDmg126a( )
	
	set GJ_LastAttackType=ReadEBP_offset(0x37C)
	if ReadEBP_offset(0x368)!=0 or ReadEBP_offset(0x378)==0x3F800000 then
		set GJ_LastDamageType=0
	else
		set GJ_LastDamageType=ReadEBP_offset(0x378)
	endif
//	call BJDebugMsg("rewrote with "+R2S(GJ_LastDmg))
	return true
endfunction

function GJ_SaveLastDmg127a takes nothing returns boolean
	if GetTriggerEventId()!=EVENT_UNIT_DAMAGED then
		return true
	endif
	set GJ_LastDmg = GJ_GetRealDmg127a( )
	set GJ_LastAttackType=ReadEBP_offset(0x3B0)
	if ReadEBP_offset(0x3CC)!=0 then
		set GJ_LastDamageType=0
	else
		set GJ_LastDamageType=ReadEBP_offset(0x3F0)
	endif
	return true
endfunction
нужно еще 3 глобалки, эту функцию в условие триггера и все.
Далее смотрим на тип урона.
BaHeK #20 - 3 года назад 0
Есть функциия GJ_SaveLastDmg127a. С помощью можно узнать урон, тип атаки, тип урона.
quq_CCCP #21 - 3 года назад 0
В условие триггера пихаешь, она пишет в GJ_LastDmg , GJ_LastAttackType тип атаки и урона а потом уже их и смотришь.
l_Avenger_l #22 - 3 года назад 0
Pjass заменил, но при сохранении один фиг высвечивает 11 ошибок)
Кет #23 - 3 года назад 0
l_Avenger_l, так и должно быть. Главное — не больше 11.
l_Avenger_l #24 - 3 года назад 0
и как обойти, в наглую в архив запихать?))
ENAleksey #25 - 3 года назад 0
l_Avenger_l, Кет, ошибок быть не должно, ни одной. Просто выключи cJass.
l_Avenger_l #26 - 3 года назад (отредактировано ) 0
Разговора нет,спасибо))
Многие функции из писка пишет что неизвестные, как быть?)
quq_CCCP #27 - 3 года назад (отредактировано ) 0
l_Avenger_l, копировать - это сам хак и пару функций для теста, остальные копируем с гитхаба и вносим в свою карту, функций очень много я не вносил их все + дебаги лича, копируй самостоятельно или пиши функции сам лич уже выложил гайд про устройство структуры юнитов.
l_Avenger_l #28 - 3 года назад 0
Все спасибо, пошел копипастить))
quq_CCCP #29 - 3 года назад 0
Кастом стун увы кривой, нужно переписывать функцию.
Нужно обязательно следить за смертью юнита, даже если у него есть крест перерождения - стоит затунить мертвого и на него не будет действовать ни 1 стун.
Кет:
Она уже есть!
Для предметов вроде нет. Эх =(
Зато есть:
function ChangeItemId takes item it, integer targetID returns nothing
	local integer cid=ConvertHandle(it)/4
	local integer curID
	if cid == 0 then
		return
	endif
	set curID=Memory[cid+0x30/4]
	set Memory[cid+0x30/4]=targetID
endfunction
Назначает одному предмету описание и иконку другого, кликабельность и все бонусы нет, просто добавляет в бонусы первого бонусы от второго, если они влезут (4 способности лимит так и остался), тоже неплохо для реализации блокировки предметов.
Кет #30 - 3 года назад (отредактировано ) 0
quq_CCCP, дык я имел в виду динамическое описание у предметов, а не блокировку.
quq_CCCP #31 - 3 года назад 0
Кет:
quq_CCCP, дык я имел в виду динамическое описание у предметов, а не блокировку.
А он не блокиурет а меняет один предмет другим, правда перетаскивая способности от другого. Сделай N одинаковых предметов с разными описаниями и меняй их этой функцией.
Я проверял на талисмане жизни и предмету с активкой добавляющим броню, в результате описание и иконка сменились а нажимать низя, бонус хп остялся и добавилась защита.
Кет #32 - 3 года назад 2
Сделай N одинаковых предметов с разными описаниями и меняй их этой функцией.
С таким же успехом это можно сделать и без мемхака =(
quq_CCCP #33 - 3 года назад 0
Кет:
Сделай N одинаковых предметов с разными описаниями и меняй их этой функцией.
С таким же успехом это можно сделать и без мемхака =(
Ну да, просто с этой функцией проще и удобнее, не вызывается никаких событий, не сбивается кулдаун на иконке и так далее.
16GB #34 - 3 года назад 0
function SetAbilityUbertip takes integer id, integer lvl, string s returns boolean
function GetAbilityUbertip takes integer id, integer lvl returns string
В доте лича меняются описания скиилов у инвокера (конкретное кол-во урона, прочие эффекты которые зависят от уровня сфер).
Копируем код с гитхаба (на хайве неудобно) и вставляем в тхт файл, открываем жасскрафтом и Citr+F (название интересующей функции) и копируем себе в карту все что требуется.
а локально это дело менять нельзя? просто если героев будет больше одного начнётся ерунда
quq_CCCP #35 - 3 года назад 0
16GB, не проверял но лучше синкать строки ибо может быть десинх если ты будешь брать инфу у абилок.
В теории локальное изменение строк прокатит, ибо это все лишь ссылка на разное содержимое.
Нужно будет протестить.
BaHeK #36 - 3 года назад 0
Вот сделал функцию, но не уверен в работаспособности.
function GetItemUbertip takes integer id returns string
	local integer pD = GameDLL + 0xBB809C
	local integer i = Memory[pD/4]/4 + 2
	
	loop
		exitwhen Memory[i] == 0
		if Memory[i + 5] == id then
			return ConvertNullTerminatedStringToString(Memory[Memory[i+0x9A]/4])
		endif
		set i = i + 0xC0
	endloop
	
	return ""
endfunction
quq_CCCP #37 - 3 года назад (отредактировано ) 0
Думаю все в курсе что GetUnitAbilityForAddresss довольно медленная функция ( по тестам лича в 15 раз медленее чем GetUnitAbilityLevel )
По этому стоит проверять наличие аблики у цели по GetUnitAbilityLevel а так же заносить результаты в хештаблицу или массив для более быстрой работы.
Поэтому вот 1 из вариантов оптимизации:
» код
function GetUnitAbilityForAddresss takes integer pConvertedHandle, integer abilid returns integer
        local integer pAddr1 = pConvertedHandle + 476
        local integer pAddr2 = pConvertedHandle + 480
        local integer pOff1 = LoadInteger( gg_htb_HashData, abilid, pConvertedHandle )
        
        if pOff1 > 1 then
            call BJDebugMsg("Значение уже записано!")
            return pOff1
        endif
        

        set pAddr1 = Memory[pAddr1 / 4]
        set pAddr2 = Memory[pAddr2 / 4]
        
        if pAddr1 == 0 or pAddr2 == 0 or BitwiseAnd( pAddr1, pAddr2 ) == -1 then
            return 0
        endif
        
        set pOff1 = GetSomeAddressForAbility( pAddr1, pAddr2 )
        if pOff1 == 0 then
            return 0
        endif
        
        loop
            exitwhen pOff1 == 0
            if Memory[pOff1 / 4 + 52 / 4] == abilid then
                call SaveInteger( gg_htb_HashData, abilid, pConvertedHandle, pOff1 )
                return pOff1
            endif
            
            set pOff1 = GetSomeAddressForAbility( Memory[pOff1 / 4 + 36 / 4], Memory[pOff1 / 4 + 40 / 4] )
        endloop
        
        return pOff1
    endfunction
BaHeK, Щяс проверил твою функцию, фатал...
BaHeK #38 - 3 года назад 0
У меня 1.27 если что.
quq_CCCP #39 - 3 года назад 0
BaHeK:
У меня 1.27 если что.
У меня 1.26, но не вижу переключателя на другие патчи у тебя в функции.
BaHeK #40 - 3 года назад 0
quq_CCCP, в таком случае мне нужно будет установить 2 варика с разными версиями, но такой возможности у меня нет. Так что только 1.27.
darkowlom #41 - 3 года назад 1
quq_CCCP, хеш таблицы сами по себе медленнее хромого коня, или они все таки перегоняют эту функцию в скорости?
quq_CCCP #42 - 3 года назад 2
darkowlom:
quq_CCCP, хеш таблицы сами по себе медленнее хромого коня, или они все таки перегоняют эту функцию в скорости?
Ну вот как раз хештаблицы то не медленные, а быстрее чем каждый раз искать, да и это грубый пример оптимизации, как будто вы забыли про системы хранения данных на массивах?
darkowlom #43 - 3 года назад 0
quq_CCCP, я просто пробовал через хештаблицу передавать данные в внешнюю длл, так как из внешней получить данные массива сложно, скорость передачи была далеко не лучшей - отсюда и вопрос
ENAleksey #44 - 3 года назад (отредактировано ) 0
darkowlom, передачу данных можно реализовать с помощью экспортируемых функций в dll.
__declspec(dllexport) unsigned int __stdcall SendValueToDll(int key, int value)
{
	// Сохраняем полученные значения
	return true;
}
И в карте:
function SendValueToDll takes integer key, integer value returns integer
    local integer hHandle = GetModuleProcAddress("MyDll.dll", "SendValueToDll")
    if hHandle != 0 then 
        return CallStdcallWith2Args(hHandle, key, value)
    endif 
    return 0
endfunction
alexprey #45 - 3 года назад 0
чет полная жесть уже начинает с этой штуковиной :(
страшно становится после этого запускать. А то еще вирусняки начнет качать. Интересно было бы почитать как эта штука работает
в гите и на хайве не удалось увидеть
ENAleksey #46 - 3 года назад 2
Интересно было бы почитать как эта штука работает
Только в новой версии добавили возможность разблокировать память на запись. И на гитхабе есть описания к функциям.
quq_CCCP #47 - 3 года назад 0
alexprey:
чет полная жесть уже начинает с этой штуковиной :(
страшно становится после этого запускать. А то еще вирусняки начнет качать. Интересно было бы почитать как эта штука работает
в гите и на хайве не удалось увидеть
Кстати там есть функции создания файла на машине юзера и открывания ссылки в браузере, а так же сколачивание с указанного сайта указанного файла на пк юзера (юзается для обновление версии карты у лича)
Очень даже можно загнать читерам, ломающим карты вирус позлее вроде Neshta чтобы потом мучились.
Кет #48 - 3 года назад 0
quq_CCCP, хм, значит близзы должны скоро всё это зарубить -_- Интересно, дадут ли что взамен, как с предыдущим ретурнбагом?
darkowlom #49 - 3 года назад (отредактировано ) 1
quq_CCCP, надо писать антихак для варика - для подозрительных действий просящий разрешение у юзера
А вообще всех надо научить писать свои собственные читы - это полезно для мозга и интересно - раскладывать партию с разрабами
Кет, близы должны дать нормальный инстурментарий пользователю, аля как в юнити/анриле от графики до данных. Иначе толку мало
quq_CCCP #50 - 3 года назад 0
Кет:
quq_CCCP, хм, значит близзы должны скоро всё это зарубить -_- Интересно, дадут ли что взамен, как с предыдущим ретурнбагом?
Думаю они не знают об этом, вирусописателей то поубавилось как и юзеров которым это интересно, открыть страничку в браузере вроде у нас на XGM выкладывали на ретурн баге еще во времена патча 1.21...
Они кое как сделали 27 патч и все, пропали... видимо до вк 4.