Добавлен , опубликован
Собственно тот знаменитый хак на память который нам радостно предоставил DracoL1ch, который позволяет нам больше не морочится с системами отлова урона, или вовсе узнать координаты курсора без стороннего по.
Для сохранения требуется: экспериментальная версия pjass.exe
Причём не все подходят, меньше всего проблем было с этой версией
В хаке присутствует только 1 пример на изменение белой атаки у героя, остальные готовые функции можно найти на:
Хайве
Гитхабе
Просто копируем саму функцию, все остальное для её работы есть в наработке и сохраняем.
Так же на хайве есть инструкция по созданию собственных функций для чтения\изменения данных в памяти игры.
`
ОЖИДАНИЕ РЕКЛАМЫ...
21
DracoL1ch, Clamp просто выше сказал, что может, как захочет.
quq_CCCP, можно.
30
ClotPh, после моего коммента был ещё один, где сказали об огромной задержке.
21
Clamp, а десинк из-за нее будет? Если нет, то еще приемлемо...
32
ClotPh, разумеется будет если данные с кем то не синхронизируются, придется долго морщить лоб и писать 1005500 проверок, все ли игроки получили данные о координатах или нет?
Тем более никто не развивал набор функций для работы с мышью и прочим, пока авторы хака копают в другую сторону, вам остается либо ждать либо самостоятельно пилить функции с быстрой синхронизацией.
32
Новая функция для мемхака старой версии
код
    function HideCooldownUIById takes unit whichUnit, integer id, boolean hide returns nothing
        local integer pAbility = GetUnitAbilityForAddresss( ConvertHandle( whichUnit ), id )
   
        if pAbility < 1 then
            return
        endif
    
        set pAbility = pAbility + 0x20
    
         if hide and not IsFlagBitSet( ReadRealMemory( pAbility ), 0x400 ) then
            call WriteRealMemory( pAbility, ReadRealMemory( pAbility ) + 0x400 )
        elseif not hide and IsFlagBitSet( ReadRealMemory( pAbility ), 0x400 ) then
            call WriteRealMemory( pAbility, ReadRealMemory( pAbility ) - 0x400 )
        endif

    endfunction
Собственно функция скрывает кулдаун указанной способности, скрывает только визуальный эффект кулдауна, сам кулдаун она не сбивает.
Так же есть проверка скрыт ли кулдаун индикатор у конкретной абилки:
    function IsCooldownUIHided takes integer pAbility returns boolean

        if pAbility < 1 then
            return false
        endif

        return IsFlagBitSet( ReadRealMemory( pAbility + 0x20 ), 0x400 )
    endfunction
Еще 1 функция, на этот раз можем узнать Id абилки которую может выучить герой
    function GetHeroAbilityFromList takes unit uHero, integer list returns integer
        set LastConvertedHandle = ConvertHandle( uHero )
    
        if IsUnitType( uHero, UNIT_TYPE_HERO ) and LastConvertedHandle > 1 and list > 0 then
            return RMem( RMem( LastConvertedHandle + 496 ) + 240 + 4 * list )
        endif

        return 0
    endfunction
Берет героя и номер абилки (см-рисунок)
Возвращает id абилки из списка доступных для изучения способностей, номер абилки это её порядковый номер в списке.
Загруженные файлы
21
О, насчет узнавания абилки шикарно. А для "старого" мемхака её можно?
Вот бы узнать абилку у юнита в неком слоте и переписать ее в некий слот другому юниту.
Просто шик был бы.
Omg дота же та же реализуется в 100 раз проще, чем все то, что там сейчас, что никак до конца не доходят раскурить мозги, втч потому, что чувствуется, что это дико нерационально.
Вообще раз адрес есть и оттуда можно читать, не вижу, почему бы туда нельзя было и записать =)
32
ClotPh, можно, нужно заменить RMem на ReadMemory.
Не помню я выкладывал функции кое каких эффектов от способностей?
21
quq_CCCP, и убрать умножение на 4?
UPD - а, нет, скорее все загнать в скобки и поделить на 4.
32
Исходники библиотеки DotaHelper
Мб кому то понадобится, лично меня интересуют дабл клики способностей
7
Вопрос по DotaHelper
Какие аргументы передавать в функцию?
int __stdcall RawImage_AddCallback(int RawImage, const char * MouseActionCallback, RawImageCallbackData * callbackdata, unsigned int events)
По остальным функциям есть какая-никакая документация, а тут я не возьму в толк, что передавать:(
32
Ige, увы сам Dracolich разработкой не занимается, вопросы только к автору на гитхабе...
Так и не понял где список id абилок для двойного клика
7
quq_CCCP, судя по всему, вот эта функция добавляет способность в список
int __stdcall AddDoubleClickSkillID( int skillID )

quq_CCCP, не знаешь, автор (Karaulov) появляется здесь?
32
Хз, даже...
Надо будет попробовать вырезать дабл клик да импортнуть себе в карту...
7
quq_CCCP, работает
DotaHelper
library DotaHelper initializer onInit uses InjectDLL
{
    #define DOTA_HELPER_DLL = "DotAAllstarsHelper688j.dll"

    bool DOTA_HELPER_DLL_LOADED = false

    int InitDotaHelper(int hexGameVersion)
    {
        int nhandle1 = GetModuleProcAddress(DOTA_HELPER_DLL, "InitDotaHelper")

        if nhandle1 == 0 {
            BJDebugMsg("[" + `FUNCNAME` + "]: неверный адрес!")
            return -1
        }
        
        DOTA_HELPER_DLL_LOADED = true
        return std_call1(nhandle1, hexGameVersion)
    }

    private void onInit()
    {
        if (not ExportDllFromMpqAndInjectToWarcraft(DOTA_HELPER_DLL, DOTA_HELPER_DLL)) {
            BJDebugMsg("Failed to inject " + DOTA_HELPER_DLL)
            return
        }

        InitDotaHelper(GameVersion)
    }
}
DoubleClickSkill
library DoubleClickSkill initializer onInit uses DotaHelper
{
    int pToggleClickHelper = 0
    int pAddDoubleClickSkillID = 0

    int ToggleClickHelper(bool enable)
    {
        if pToggleClickHelper == 0 {
            BJDebugMsg("[" + `FUNCNAME` + "]: неверный адрес!")
            return -1
        }

        return std_call1(pToggleClickHelper, B2I(enable))
    }

    int AddDoubleClickSkillID(int id)
    {
        if pAddDoubleClickSkillID == 0 {
            BJDebugMsg("[" + `FUNCNAME` + "]: неверный адрес!")
            return -1
        }

        return std_call1(pAddDoubleClickSkillID, id)
    }

    private void onInit()
    {
        pToggleClickHelper = GetModuleProcAddress(DOTA_HELPER_DLL, "ToggleClickHelper")
        pAddDoubleClickSkillID = GetModuleProcAddress(DOTA_HELPER_DLL,"AddDoubleClickSkillID")
    }
}

Пример
//добавляем способности в "список"
AddDoubleClickSkillID('A000')
AddDoubleClickSkillID('A001')

ToggleClickHelper(GetLocalPlayer() == Player(0)) // активируем двойной клик для игрока(0)
21
Так, срочно копошусь, пытаюсь переписать функции чтения и записи полей абил героев на "старый" мемхак
Есть где ошибки?


    function GetHeroAbilityFromList takes unit uHero, integer list returns integer
        set LastConvertedHandle = ConvertHandle( uHero )
    
        if IsUnitType( uHero, UNIT_TYPE_HERO ) and LastConvertedHandle > 1 and list > 0 then
            return ReadMemory[(LastConvertedHandle + 496 ) + 240 + 4 * list )/4]
        endif

        return 0
    endfunction

Это пока в блокноте пишу
/////////
Или там разные части отдельно на 4 делить? Ну ща проверю
Хотя какая разница-то по идее, лол
ТАК, вот, короче, что пока скомпилировалось, но что оно и откуда куда читать и писать будет и будет ли, один Господь знает:

//ПЕРЕЗАПИСЬ И ЧТЕНИЕ ПОЛЕЙ СПОСОБНОСТЕЙ
    function GetHeroAbilityFromList takes unit uHero, integer list returns integer
        local integer LastConvertedHandle = ConvertHandle( uHero )
    
        if IsUnitType( uHero, UNIT_TYPE_HERO ) and LastConvertedHandle > 1 and list > 0 then
            return Memory[((LastConvertedHandle + 496 ) + 240 + 4 * list )/4]
        endif

        return 0
    endfunction


    function SetHeroAbilityFromListToAbilityOtherHero takes unit uHero, integer list, integer abireadedfromlist returns nothing
        local integer LastConvertedHandle = ConvertHandle( uHero )
    
        if IsUnitType( uHero, UNIT_TYPE_HERO ) and IsUnitType( uHero, UNIT_TYPE_HERO ) and LastConvertedHandle > 1 and list > 0 then
            set Memory[((LastConvertedHandle + 496 ) + 240 + 4 * list )/4] = abireadedfromlist
        endif

    endfunction
//ПЕРЕЗАПИСЬ И ЧТЕНИЕ ПОЛЕЙ СПОСОБНОСТЕЙ - ЗАКРЫТО.
Ну и че это за ерь?... Ничего оно никуда не пишет, а если пишет, то хз что хз куда.
*************!!!!
А так благополучно фаталит...
ПЕРЕЗАПИСЬ И ЧТЕНИЕ ПОЛЕЙ СПОСОБНОСТЕЙ
function GetHeroAbilityFromList takes unit uHero, integer list returns integer
local integer LastConvertedHandle = ConvertHandle( uHero )

if IsUnitType( uHero, UNIT_TYPE_HERO ) and LastConvertedHandle > 1 and list > 0 then
return Memory[((LastConvertedHandle + 496 )/4 + (240 + 4 * list ))/4]
endif
return 0
endfunction
function SetHeroAbilityFromListToAbilityOtherHero takes unit uHero, integer list, integer abireadedfromlist returns nothing
local integer LastConvertedHandle = ConvertHandle( uHero )

if IsUnitType( uHero, UNIT_TYPE_HERO ) and IsUnitType( uHero, UNIT_TYPE_HERO ) and LastConvertedHandle > 1 and list > 0 then
set Memory[((LastConvertedHandle + 496 )/4 + (240 + 4 * list ))/4] = abireadedfromlist
endif
endfunction
ПЕРЕЗАПИСЬ И ЧТЕНИЕ ПОЛЕЙ СПОСОБНОСТЕЙ - ЗАКРЫТО.
//////////
ладно, ну ее к... матери, ща по-другому сделаю
ладно, действительно гребаное издевательство, чтоб еще когда-нибудь так морочиться
//////////
так, а если вот так
это еще если удастся этот гребаный новый мемхак затащить
ПЕРЕЗАПИСЬ И ЧТЕНИЕ ПОЛЕЙ СПОСОБНОСТЕЙ
function GetHeroAbilityFromList takes unit uHero, integer list returns integer
set LastConvertedHandle = ConvertHandle( uHero )

if IsUnitType( uHero, UNIT_TYPE_HERO ) and LastConvertedHandle > 1 and list > 0 then
return RMem( RMem( LastConvertedHandle + 496 ) + 240 + 4 * list )
endif
return 0
endfunction
function SetHeroAbilityFromList takes unit uHero, integer list, integer ability
set LastConvertedHandle = ConvertHandle( uHero )

if IsUnitType( uHero, UNIT_TYPE_HERO ) and LastConvertedHandle > 1 and list > 0 then
WMem( RMem( LastConvertedHandle + 496 ) + 240 + 4 * list ), ability)
endif

endfunction
ПЕРЕЗАПИСЬ И ЧТЕНИЕ ПОЛЕЙ СПОСОБНОСТЕЙ - ЗАКРЫТО.
32
Насколько помню, записть листа абилок была нестабильна, норм работает только чтение...
 function GetHeroAbilityFromList takes unit uHero, integer list returns integer
        set LastConvertedHandle = ConvertHandle( uHero )
    
        if IsUnitType( uHero, UNIT_TYPE_HERO ) and LastConvertedHandle > 1 and list > 0 then
            return ReadMemory( ReadMemory( LastConvertedHandle + 496 ) + 240 + 4 * list )
        endif

        return 0
    endfunction
LastConvertedHandle - адресс героя, 496 адрес абилки 'Aher' -герой, в её полях лежат способности для изучения, ну а 240 + каждые 4 байта это адреса абилок. т.е 244 это первая абилка в списке, 248 вторая и так далее....
21
quq_CCCP, так, жопа. Почему-то при попытке воспользоваться возникает фатал.
Задаю рандомной переменной, например
set i = GetHeroAbilityFromList(u6,1)
и сразу фатал еррор.
Пробовалось и через функцию под "старый" мемхак, и через новый (RMem и WMem вроде уже импортированы).
Кстати, когда u6 - НЕ герой, всё равно фатал, хотя по идее должен был бы быть ноль...
32
ClotPh, Еще можно проверить ReadRealMemory вместо ReadMemory
Ну а фатал при выборе негероя - навреное ConvertHandle Кривая... там больше и фаталить нечему...
21
quq_CCCP, так-так, а, конверты хэндла в мемхаках же разные, один для функций другого не подходит? Мб именно сейчас дело в этом...
Я пока для начала просто уже прочесть абилку пытаюсь и вывести результат на экран...
32
Еще одно но, адреса абилок в оригинале записываются как F8/FC/100/104
21
quq_CCCP, это мне не понятно
У меня там в какой-то момент вроде выводилось целочисленной в текст на экране что-то, но вместо равкода абилки какая-то хня из многих цифр, я хочу равкод выкопать
32
ClotPh, ро код и есть много цифр на экране
Чтобы был ро код как в редакторе - Id2String()
21
quq_CCCP, так, минутку, то есть равкод я не откопаю?
Ок, сейчас хоть цифры попробую снова... жопа =/
А, во, понятно, ок
16
Ни в коем случае не используйте записывание строки через мемхак
Речь о том, чтобы заменить ссылку на строку где-либо своей ссылкой
Хотя смысл и не теряется, но у сборщика мусора явно едет крыша, и без рестарта вк будут рандомно выпадать краши. Так что пока без обновлений строк где-либо вообще
Чтобы оставить комментарий, пожалуйста, войдите на сайт.