20

» WarCraft 3 / Jass MythBusters

Unryze, есть миф, что if then {без кода} else {код} endif быстрее, чем if not then {код} endif. Я так и не получил утвердительного ответа на вопрос — так ли это?
Извиняюсь, если спрашиваю уже баянистую тему.
Этот миф имеет место существованию! Давайте же рассмотрим вновь байткод:
Сравнение байткода
Байткод func1
0C1A0800 -> literal register (type) bool
261A0000 -> not register
2A1A0000 -> jmpf register
000012AD -> label для прыжка
16000000 -> calljass (вызов джасс функции, операция схожа с callnative)
00000A93 -> id функции
2B000000 -> jmp
000012AE -> label id прыжка
28000000 -> label
000012AD -> id label'а
28000000 -> label
000012AE -> id label'а
0C000000 -> literal R0
27000000 -> ret
Байткод func2
0C1B0800 -> literal register (type) bool
2A1B0000 -> jmpf register
000012AF -> label для прыжка
2B000000 -> jmp
000012B0 -> label id прыжка
28000000 -> label
000012AF -> id label'а
16000000 -> calljass (вызов джасс функции, операция схожа с callnative)
00000A93 -> id функции
28000000 -> label
000012B0 -> id label'а
0C000000 -> literal R0
27000000 -> ret
Фактически, если "лень" читать и разбирать опять байткод и все операции, то можете исходить из логики, что любой код, где меньше "действий", создаст меньше байткода (если конечно же их базовая структура схожа), собственно где "действий" меньше, то она будет быстрее, что и получается тут:
Результат скорости
Ярг Восьмой, бред какой-то
Как видишь, оказалось не бредом, хотя и разница слишком минимальная и на уровне погрешности, что не делает этот миф очень важным, но даёт пример того, что меньше лишнего кода - всегда лучше. Это как сравнение not flag и flag == false, not flag будет всегда быстрее, ибо выполняется на 1 операцию меньше.
20

» WarCraft 3 / MemoryHackAPI

раскрыть
Я тут обратил внимание, что функция EnableOPLimit не очень справляется, что вызывает некоторые сложности с тестированием (Ну и может вызвать десинки в мультиплеере). Например при исполнении этой функции поток, почему-то рвется.
function TestEnableOpLimit2()
{
    rect r= Rect(0,0,1,1);
    integer i = 0;
    EnableOPLimit(false);
    BJDebugMsg("TestEnableOpLimit2 started");
    for(0<i<100000)
    {
        DestroyGroup(GetUnitsInRectMatching(r,null));
    }
     BJDebugMsg("TestEnableOpLimit2 ended");//????????????????????
}  
Карту прилагаю.
Потому что ОП лимит нужно устанавливать до начала этого потока. То бишь вызвать единожды патчинг ОП лимита и лишь потом вызвать функцию где будет цикл на 100000 повторов, как сделано в MemHackAPI. Я же не просто так в начале снимаю лимит и лишь затем таймером с мелкой задержкой вызываю код? :)
20

» WarCraft 3 / Jass MythBusters

PT153 local location loc всегда в начале будет 05070000, это банальное объявление для VM, что объявляется локальная переменная с типом. То бишь было бы local integer то стало бы 05060000.
В примере утекает именно локальная loc если её не обнулить, но утечка так же будет если не вызвать RemoveLocation, если же мы это делаем единожды и когда-нибудь этот объект удалим то обнуления локалки - достаточно.
А по поводу почему всё local handle - потому что байткоду плевать на прямой тип переменной, ибо для VM все переменные расширяющие Handle - это Handle.
		OPCODE_VARIABLE_NOTHING = 0,   // "nothing"
		OPCODE_VARIABLE_UNKNOWN,       // "unknown"
		OPCODE_VARIABLE_NULL,          // "null"
		OPCODE_VARIABLE_CODE,          // "code"
		OPCODE_VARIABLE_INTEGER,       // "integer"
		OPCODE_VARIABLE_REAL,          // "real"
		OPCODE_VARIABLE_STRING,        // "string"
		OPCODE_VARIABLE_HANDLE,        // "handle"
		OPCODE_VARIABLE_BOOLEAN,       // "boolean"
		OPCODE_VARIABLE_INTEGER_ARRAY, // "integer array"
		OPCODE_VARIABLE_REAL_ARRAY,    // "real array"
		OPCODE_VARIABLE_STRING_ARRAY,  // "string array"
		OPCODE_VARIABLE_HANDLE_ARRAY,  // "handle array"
		OPCODE_VARIABLE_BOOLEAN_ARRAY, // "boolean array"
"Судя по твоему тесту с юнитов - утечек не будет."
Верно, утечки не будет.
"Я так понял, проблема с локалками возникает в том случае, если в функции создаётся хендл.
То есть, если создаётся хендл, то ЛЮБУЮ локалку этой функции, в которой этот хендл находится или находился в процессе выполнения функции, нужно обнулить."
Абсолютно верно, однако если же мы не удалим объект и "утеряем" его и никогда сами не удалим, то будет утечка не переменной, а непосредственно объекта.
20

» WarCraft 3 / Jass MythBusters

А, я гениален, не стоило в 4 утра делать тесты, я мало того что закомментировал строчку вызова теста, так я ещё и неправильно функцию обозвал. Переделаю все тесты ещё раз, чтобы наверняка.
pGameWar3 = *(pGameDLL+0xab65f4)
pGameState = *(pGameWar3+0x1c)
pGameState+0x194 - сколько мест в таблице выделено
pGameState+0x198 - сколько мест в таблице занято
pGameState+0x19с - Массив структур, хранящих количество ссылок на хэндл, указатель на объект, и, возможно, еще что-то.
pGameState+0x1A0 - Шаг повышения размера таблицы.
Я предполагаю, что при наличии ссылок, хэндл не будет перевыдан другоу объекту, что, я надеюсь, логично, но, вероятно, сам, оригинальный объект, которому соответствует хэндл, может быть удален.
Строго говоря, утечка в 3?! байта - не критично, но за несколько часов, при достаточном усердии, можно набрать достаточно. Но в коротких играх, вероятно, источником проблем такая утечка не будет.
А безопасности, в рамках моего понимания, необнуление не даст, так как по сути, если на сущность нет ссылок на хэндл, а сама сущность удалена - нет никаких способов с ей провзаимодействовать или пострадать от её отсутствия.
Спасибо, я то смотрел на эти оффсеты и забыл о них совсем. Обнуление вызывает поп стека, что скорее всего и отвечает за очищение потенциальной утечки. В любом случае все тесты надо будет переделать, ну и поправить пояснение по ним.
По поводу хендла, я думаю без синтетики банально не дойти до того, когда старый хендл (то бишь его Id будет перевыдан новому юниту), ибо как раз этого и боялись многие, которые полагались на GetHandleId для индексаций, хеширования и т.д. Но суть в том, что в логике игры оно есть, чтобы предотвратить так называемое превышение лимита памяти.
Всем спасибо, в ближайшее время поправлю,
Редактирование:
Все мои тесты подтвердились, всё-таки оригинал карты на которой я проводил тесты не в 4 утра - показала те же результаты, хоть что-то хорошее. То бишь ответ:
Предыдущий ответ в 4 утра
Я решил проверить, насколько серьезны будут утечки, если не обнулять локалки, используя множественный запуск нижеописанной функции.
В результате небольшого наблюдения можно увидеть, что при этом, занимаемое место в таблице хэндлов растет, и она сама раздувается, за счет периодических перевыделений памяти, что, при больших количествах таких утечек вызовет лаги при, собственно, перевыделении, и, при достаточном терпении, окончание доступной памяти. (Однажды сам столкнулся с проблемой вылета на такой карте из-за стандартной и проблемной стандартной функции CountLivingPlayerUnitsOfTypeId, после более чем трех часов игры, после того, как в нее были внесены исправления в области обнуления локалок, криты прикратились)
Конечно, это не быстро, но не менее 3х байт за не до конца обнуленные ссылки на хэндл, что можно пронаблюдать на видео, а, при желании, и повторить самому.
Карту прилагаю.
Растёт последний индекс хендла (он будет расти в любом случае, даже если ты дождёшься удаления юнита - и это правильно). Конечно я не сталкивался ещё с моментами когда достигался лимит хендлов, но судя по коду игры, если хендл "пустой", то он выдаётся уже новому юниту (если нет нового доступного), то бишь есть "переработка" хендлов.
Ниже прикрепил мой пример, как видишь, на чистой карте тупо с оборотом и таймеров, ничего не растёт.
Если не сложно, скинь потом оффсеты по которым ты вышел на число хендлов, думаю будет полезно глянуть.
Ладно, я пожалуй спать, завтра и статью обновлю (внесу правки), заодно и про Хештаблицу дополню пункт по поводу её размера.
Редактирование:
Гляну ещё и предоставленное видео по локации, ещё раз проведу у себя тесты, ибо я тоже помню, что в какой-то момент, где не было обнуления начала уходить память. Конечно посыл не был тем, чтобы все забили на обнуление, стоит наверное перефразировать момент с советом на обнуление и выразить его более строго. Ибо фактическое наличие обнуления - не потребляет уймы операций, так ещё и служит элементом безопасности.
Редактирование 2:
Решил сделать как в примере 1024 таймера, результат у меня почему-то тот же:
Либо у меня какой-то магический компьютер, то ли моя WFE какими-то выкрутасами эту проблему решает (что слишком сомнительно, ибо ничего подобного в моей программе нет).
Вариант без ВФЕ, результат тот же:
Карта:
Стоит игнорировать, ибо код не вызывался вообще. (Примеры для статьи делались в карте где не было этого косяка).
PT153 по поводу твоего примера, хотел бы исправить свой ответ (не стоило мне спешить с ответом с телефона).
Рассмотрим код ещё раз и взглянем на его байткод:
	globals
		location Loc
	endglobals

	function DoSomething takes nothing returns nothing
		local location loc
		set Loc = Location(0., 0.)
		set loc = Loc
	endfunction
Байткод
05070000 -> local handle
00000487 -> её id
0C290500 -> literal register (type) location
13290000 -> push register
0C2A0500 -> literal register (type) location
132A0000 -> push register
15000000 -> callnative
00000314 -> id нативки
11000000 -> setvar
00000F7D -> id переменной
0E2B0700 -> get var register (type) Handle
00000F7D -> id переменной
112B0000 -> setvar register
00000487 -> id переменной
0E2C0700 -> get var register (type) Handle
00000F7D -> id перемнной
132C0000 -> push register
15000000 -> callnative
00000315 -> id нативки
0C000000 -> literal R0
27000000 -> return
Что мы получаем? 3 фактических push, так как локальный реестр не был обнулён, то popstack (который вызывается всегда) решает его не трогать. Рассмотрим теперь что добавиться при RemoveLocation и обнулении обоих переменных и даст ли это что-либо.
call RemoveLocation( Loc )
set Loc = null
set loc = null
Добавит:
Байткод
0C2D0200 -> literal register (type) null
112D0000 -> setvar register
00000F7D -> id переменной
0C2E0200 -> literal register (type) null
112E0000 -> setvar register
00000487 -> id переменной
И мы получаем, что утечка "устранена". Однако обнуление глобальной по факту - бесполезно, потому мой поспешный ответ был частично правильным. То бишь посыл Location в глобалку, а затем её присваивание - равноцельно прямому посылу создания объекта.
Однако если мы возьмём это:
globals
    location Loc = Location( 0., 0. )
endglobals

function TestFunctionEx takes nothing returns nothing
    local location loc = Loc
endfunction

function TestFunction takes nothing returns nothing
    local integer i = 0
    
    loop
        exitwhen i > 1000
        call TimerStart( CreateTimer( ), .01, true, function TestFunctionEx )
        set i = i + 1
    endloop
endfunction
Что даст:
Байткод
05070000 -> local (type) handle
00000487 -> id переменной
0E2A0700 -> getvar register handle
00000F7D -> id переменной
112A0000 -> setvar register
00000487 -> id переменной
0C000000 -> literal R0
27000000 -> return
То утечки нет ввиду того, что более нету push действий и мы не добавляем регистры, в действии можно посмотреть на видео:

PT153 вопрос к тебе, как думаешь, утекает ли это? Заведомо прошу не делать тесты, а просто сделать свои предположения.
globals
    hashtable HashTable = InitHashtable( )
    location Loc = Location( .0, .0 )
endglobals

function TestFunctionEx takes nothing returns nothing
    local unit u = LoadUnitHandle( HashTable, 123, 321 )
endfunction

function TestFunction takes nothing returns nothing
    local integer i = 0
    
    call SaveUnitHandle( HashTable, 123, 321, CreateUnit( Player( 0 ), 'Hpal', 0., 0., 270. ) )
    
    loop
        exitwhen i > 1000
        call TimerStart( CreateTimer( ), .01, true, function TestFunctionEx )
        set i = i + 1
    endloop
endfunction

Добавлен новый пункт в статье про размер Хештаблиц. Спасибо JackFastGame за идею.
Загруженные файлы
20

» WarCraft 3 / MemoryHackAPI

Функция ReduceAbilityCooldown иногда работает только визуально: на UI кулдаун уменьшается, но кулдаун самой абилки при этом не изменился, и даже когда на UI уже нет кулдауна, абилка всё равно будет говорить, что пока нельзя применить. Это как-нибудь фиксится?
Хм, изучу, в карте где я это применял такой проблемы не было. Хотя там я напрямую просто устанавливал значение, а не отнимал. Единственное что может создавать эту проблему - это немного устаревший способ чтения таймстемпов, возможно я его обновлю до того, что я написал во ВФЕ (то бишь путём чтения этих значений непосредственно самой игрой, а не из памяти).
20

» WarCraft 3 / Jass MythBusters

Я решил проверить, насколько серьезны будут утечки, если не обнулять локалки, используя множественный запуск нижеописанной функции.
В результате небольшого наблюдения можно увидеть, что при этом, занимаемое место в таблице хэндлов растет, и она сама раздувается, за счет периодических перевыделений памяти, что, при больших количествах таких утечек вызовет лаги при, собственно, перевыделении, и, при достаточном терпении, окончание доступной памяти. (Однажды сам столкнулся с проблемой вылета на такой карте из-за стандартной и проблемной стандартной функции CountLivingPlayerUnitsOfTypeId, после более чем трех часов игры, после того, как в нее были внесены исправления в области обнуления локалок, криты прикратились)
Конечно, это не быстро, но не менее 3х байт за не до конца обнуленные ссылки на хэндл, что можно пронаблюдать на видео, а, при желании, и повторить самому.
Карту прилагаю.
Растёт последний индекс хендла (он будет расти в любом случае, даже если ты дождёшься удаления юнита - и это правильно). Конечно я не сталкивался ещё с моментами когда достигался лимит хендлов, но судя по коду игры, если хендл "пустой", то он выдаётся уже новому юниту (если нет нового доступного), то бишь есть "переработка" хендлов.
Ниже прикрепил мой пример, как видишь, на чистой карте тупо с оборотом и таймеров, ничего не растёт.
Если не сложно, скинь потом оффсеты по которым ты вышел на число хендлов, думаю будет полезно глянуть.
Ладно, я пожалуй спать, завтра и статью обновлю (внесу правки), заодно и про Хештаблицу дополню пункт по поводу её размера.
Редактирование:
Гляну ещё и предоставленное видео по локации, ещё раз проведу у себя тесты, ибо я тоже помню, что в какой-то момент, где не было обнуления начала уходить память. Конечно посыл не был тем, чтобы все забили на обнуление, стоит наверное перефразировать момент с советом на обнуление и выразить его более строго. Ибо фактическое наличие обнуления - не потребляет уймы операций, так ещё и служит элементом безопасности.
Редактирование 2:
Решил сделать как в примере 1024 таймера, результат у меня почему-то тот же:
Либо у меня какой-то магический компьютер, то ли моя WFE какими-то выкрутасами эту проблему решает (что слишком сомнительно, ибо ничего подобного в моей программе нет).
Вариант без ВФЕ, результат тот же:
Карта:
20

» WarCraft 3 / Jass MythBusters

Unryze, ещё кое-что интересно, работа с темповой группой
что быстрее: делать всё в цикле без булекспра или делать всё в булекспре? бенчмарк вовсе минусовый результат показывает, но вероятно тут проблемы уже моего компа
раскрыть
globals
    private constant group TempG = CreateGroup( )
    private unit bj_lastFilterUnit = null
endglobals

native UnitAlive takes unit id returns boolean

private function cond takes nothing returns boolean
    set bj_lastFilterUnit = GetFilterUnit( )
    if UnitAlive( bj_lastFilterUnit ) then
        call SetWidgetLife( bj_lastFilterUnit, GetWidgetLife( bj_lastFilterUnit ) )
    endif
    return false
endfunction

function TestBenchmarking takes nothing returns nothing
    local integer p     = 0
    local integer i     = 0
    local integer time  = 0
    local unit u
    local boolexpr b = Condition( function cond )
    
    set i    = 0
    set time = GetLocalTime( 0 )
    loop
        exitwhen i == 10000
        call GroupEnumUnitsInRect( TempG, bj_mapInitialPlayableArea, null )
        
        loop
            set u = FirstOfGroup( TempG )
            exitwhen u == null
            call GroupRemoveUnit( TempG, u )
            if UnitAlive( u ) then
                call SetWidgetLife( u, GetWidgetLife( u ) )
            endif
        endloop
        
        // Some stuff here
        set i = i + 1
    endloop
    set time  = GetLocalTime( 0 ) - time
    call DisplayTextToPlayer( GetLocalPlayer( ), 0, 0, "First Delay: " + I2S( time ) + "ms" )
    
    set i    = 0
    set time = GetLocalTime( 0 )
    loop
        exitwhen i == 10000
        call GroupEnumUnitsInRect( TempG, bj_mapInitialPlayableArea, b )
        // Some other stuff here
        set i = i + 1
    endloop
    set time  = GetLocalTime( 0 ) - time
    call DisplayTextToPlayer( GetLocalPlayer( ), 0, 0, "Second Delay: " + I2S( time ) + "ms" )
endfunction

Первый из группы будет всегда быстрее, фильтр фактически равен обычному форгруппу (просто убирает нужду в дополнительном переборе, ибо можно сделать всё в фильтре). По поводу -мс скорости - такое бывает, когда таки слишком много операций и поток насильно обрывается, обычно вызвано слишком долгим тайм-аутом.
> мы СОЗДАЁМ переменную и присваиваем её в локальную переменную
Создаём объект

Простой ответ - сами переменные не утекают ни при каких обстоятельствах и они преобразуются в нечто статичное, и им выделена память единожды. Потому, утечки вызываются фактически банальной проблемой логики в самом коде, то бишь вы создали хендл, а затем его не удалили и так может повторяться уйму раз.
Ладно, тогда почему тут всё удаляется, а потребление ОЗУ растёт? В твоих примерах с группой и локацией переменная обнуляется.

	globals
		location Loc
	endglobals

	function DoSomething takes nothing returns nothing
		local location l
		set Loc = Location(0., 0.)
		set l = Loc
	endfunction
Вот это утекает?
Немного неправильно выразился, исправлю, спасибо. Я имел ввиду, что мы в начале создаём переменную и затем даём ей референс объекта.
"Ладно, тогда почему тут всё удаляется, а потребление ОЗУ растёт? В твоих примерах с группой и локацией переменная обнуляется."
Смотри видео внимательно, оно потом падает, ибо проходят и другие действия. Оно не растёт без конца. Оно ещё и падает
Предоставленный код тобою - утекает лишь в случае если его повторять и не удалять используемый объект.
PT153, ну ссылка локальной же не обнуляется, утекает значит
Дело там не в обнулении, там оно ничего не даст. Я примером пытался пояснить, что у текает не сама "локальная", а объект, который присваивается. То бишь пример с CreateUnit по факту.
20

» WarCraft 3 / Jass MythBusters

Unryze, смешно получается, суть как раз была что IsTerrainPathable медленнее чем сместить тот же предмет, спрятать его, а потом сравнивать координаты предмета и нужной точки
даже откопал старый вопрос с комментариями от сильных людей: xgm.guru/p/wc3/168497

а, стоп, IsTerrainPathable имеет ещё один косяк если не ошибаюсь, оно не проверяет по нормальному проходимость путей от декораций

раскрыть
    local item it = CreateItem( 'spsh', 500.00, 500.00 )
    local real x
    local real y
    
    call CreateDestructable( 'ATtr', 0.00, 0.00, 270.00, 1.00, 0 ) 
    
    call SetItemVisible( it, false )
    
    if not IsTerrainPathable( 0.00, 0.00, PATHING_TYPE_WALKABILITY ) then
        call BJDebugMsg( "IsTerrainPathable: проходимо" )
    else
        call BJDebugMsg( "IsTerrainPathable: непроходимо" )
    endif
    
    call SetItemPosition( it, 0.00, 0.00 )
    call SetItemVisible( it, false )
    set x = GetItemX( it )
    set y = GetItemY( it )
    
    if ( x + 1.00 < 0.00 or x - 1.00 > 0.00 ) or ( y + 1.00 < 0.00 or y - 1.00 > 0.00 ) then
        call BJDebugMsg( "Предмет: непроходимо" )
    else
        call BJDebugMsg( "Предмет: проходимо" )
    endif
Да, вот этот косяк я забыл, хотя по факту это и не косяк, ибо проверяется именно проходимость земли. Ну, тогда тут не миф, а даже есть причина использовать SetPosition, всяко неплохо! JackFastGame:
Unryze, про хэш-таблицу ещё был миф, что это огромный объект, который лучше больше одного раза не создавать, даже в статье на этом сайте было написано об этом.
Когда буду у компьютера добавлю это в статью, спасибо!
20

» WarCraft 3 / Jass MythBusters

Unryze, не раз замечал как люди пытаются обойти функцию IsTerrainPathable путём проверки проходимости предметом (SetItemPosition) или юнитом (SetUnitPosition), по привычке сам начал использовать проверку предметом, можно об этом тоже пару слов добавить
Проверю, почему нет, конечно по скорости IsTerrainPathable (по логике должен всегда быть быстрее), конечно мне сложно понять смысл обхода этой функции (разве что когда-то был косяк в ней, что она возвращала инверсию, то бишь если проходимо, то вернёт false).
В любом случае, спасибо за предложение! :)
Провёл тест, разница в 13мс на 10000 повторов:
rsfghd если тебе не сложно, можешь пояснить в чём была суть отказа от IsTerrainPathable, чтобы я примерно сообразил как это расписать. Ибо по скорости, оно всегда медленнее, по-мимо старого косяка инверсии флага, ничего вспомнить не могу. :(
Загруженные файлы
20

» WarCraft 3 / Jass MythBusters

Резервирую первый комментарий для дополнинй.
Также, хочу сообщить, что данная статья ещё не доделана, просто хотелось загрузить хотя бы один самый главный миф как можно скорее. Со временем я добавлю ещё мифов и предоставлю данные для их опровержения, если у кого-то есть варианты, которые вы бы хотели предложить, то предлагайте, постараюсь их проверить в кратчайшие сроки!
20

» WarCraft 3 / MemoryHackAPI

Тема обновлена, добавлена ссылка на GitHub со всеми версиями, где так же в шаговой доступности pjass.exe, который необходим для компиляции карты в JNPG World Editor.
В данный момент последняя версия 1.6.
В скором времени будет залита 1.7 версия и список функций скорее всего будет вновь обновлён (он станет ещё больше...)
20

» WarCraft 3 / WFE - Warcraft Feature Extender

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

» XGM Team / Хунта снова у власти

ScorpioT1000:
Unryze, ты тогда обижался вместо конструктивного диалога и сейчас продолжаешь истерику

Боже, какие же вы дети, конструктивный диалог - это когда дали мут и без оснований стёрли ресурс и какой-то недоспец по вирусам мне втирал, что гугл вам угрожал и т.д.? У тебя точно с памятью всё окей? Или же как ты тёр мою ссылку на мою же ВК группу под разделом "рекламы"? И нет, это не истерика, но если у тебя такое ЧСВ, что ты не видишь своих косяков - тут не о чем даже говорить дальше. Не хотите публично извиниться за балаболизм и наезды по вирусам не по делу? А?
tysch_tysch:
Угараю с людей которые не умеют контролировать свой темперамент и любая критика переходит в rage с удалением себя отовсюду.
Что касается истории с подозрительным кодом в сборке:
  1. Не мы создаём парсеры вирусни, а их мнение влияет на позицию в выдаче
Я повторяю вопрос, так когда мне ресурсы Яндекс, ВК и Гугл удалят за ЛОЖНЫЕ срабатывания?
  1. Отказ от сотрудничества и истерика — очевидно противоречит любым правилам сайта
Очередное слово "истерика", я задавал и тебе и скорпу прямые вопросы, на что получил хи-хи/ха-ха не нравится - вали. Так что может не будешь дальше гнать?
Я не просто так скрин с твоим жалким вбросом сохранил и скрытые редактирования постов от Скорпа.
  1. На то мы и хунта, чтобы творить порядок железной рукой, хотите по-другому выбирайте своих админов мы поддержим
Хочешь прямой ответ? Ты, Скорп, Берги - должны как минимум слететь с позиций админов. Лишний раз подтверждаете свою некомпетентность + кривую память.
Мне ей богу не западло опять начать тему уже почти 2ух годовалой давности, как Скорп втихаря выдал мут и мне пришлось в Дискорд переться, чтобы узнать, что за дела ибо на сайте даже в ЛС писать не мог.
Так что давайте вы своё ЧСВ засунете себе в одно место и будете признавать свои косяки, а не дальше играть в "ха-ха мы такие, сякие, нам можно всё, а остальным биба".
Мне реально вас жалко, что всё ещё не понимаете, что своими действиями всё дальше распугиваете народ и себя на посмешище выставляете. Может лет так через 20 до вас это дойдёт. Вы не заметили тенденцию, что все те, кто преуспели в Вар 3 обходят ваш форум стороной или же нелестно о нём выражаются? Не думали почему же так? И нет, это не из-за берги, который рвёт свою пятую точку за рефандед, а из-за вашего пофигистического и наглого отношения к тем, кто лично ВАМ не нравится, ибо не прогнулся под ваши наезды.
Минусуйте, удаляйте, это последний пост, пока не соизволите в своём глазу дупло увидеть, а не в чужих соринках рыться.
20

» XGM Team / Хунта снова у власти

mistwood:
Ясно, найс у вас модер комментарии удаляет и трет даже в теме об смене власти, и дальше мне выписывает нарушения и молчанки.
Спасибо за честный хгм.
  1. Предвзятое отношение. 2. Удаляет комменты, где я спрашиваю почему получил бан. (теперь понимаю почему многие талантливые ребята cюда заходят в редких случаях, привет unryze)
Я извиняюсь, но с таким подходом у вас на сайте люди не будут регится и общаться (продолжать развивать комьюнити).
Мне например, до боли обидно, что мне выписали бан за ОФФТОП в тебе где таких сообщений 100500, а потом за вопрос причем здесь оффтоп, потерли мои комменты и выписали молчанку. Почему обидно? Да потому что я люблю ХГМ, люблю читать здесь статьи и общаться. А из-за таких модеров, все желание сюда заходить отпадает...
И тебе привет, ну я уже высмеивал абсурдность текущей администрации в частности Скорпио за тихопринудительные пинки, но не суть. Всё ещё жду удаления ресурсов от Яндекса и Гугла, да и в целом даже ВК... (привет Тсыч)
ну и в целом, всю личку закидали инфой по последнему конкурсу и т.д.
А если затронуть тему администрации, если честно даже комментировать не буду, мне сложно сказать кто из них вообще должен быть у "руля", но явно не Берги (без обид друг, но администратор из тебя такой же, как из меня балерин). Но не суть то важно, Вар 3 доживает свои дни, ровно как и этот форум на котором скоро останутся лишь сами админы ну и их близкие друганы.
Ну, на этом можно опять в спячку уйти. :D
Загруженные файлы
20

» WarCraft 3 / Memory hack API v1.4

Попросили сюда ответить по поводу свежих вопросов.
NETSHOW:
будет новая версия или нет?
Уже есть и 1.6, делались на заказ, но ввиду уже "давних" перепалок с ХГМ, просто желания нет сюда что-то обновлять, а в ВК просто забыл/не хотел.
mikroBER:
quq_CCCP:
NETSHOW, ну уже выложили 1.5, новый ах правда и новые фрейм фишки с либами не выложили.
куда выложили? попытался найти, не нашёл.
Ответ выше, но дополню, кто интересовался в целом получил 1.5 после контакта в лс.
PT153:
Я как-нибудь выложу мемхак 1.5 с исправлениями (если потребуются), а также подсветку констант и функций в JNGP.
Вроде я уже всё поправил, кроме ТАБОВ на пробелы. К слову надо будет как-то один раз тоже самому сделать, а то компилятор парашного Вар 3 всё корявит, лишь war3map.wct в идеальной форме остаётся...
Гуванч:
Подскажите пожалуйста как настроить детект урона в версии 1.4 встроеная функция не работает пришлось самому узнавать id урона от способностей но у всех по разному даже триггерный урон разного номера стоит как быть? Проверка что урон не был с руки не помогает.

А что нового в версии 1.5 и что исправили из 1.4?
Пример Детекта урона есть в карте, прочитать и приглядеться не составляет особого труда. Ну требуется минимальное понимание Джасса и всё.
goodlyhero:
quq_CCCP:
Ну вот 1.5, мемхак.
А есть хотябы краткий список изменений?
Из того что увидел - зачем-то впихнута длл под видом "Extracache.dat", видимо с целью потенциально облегчить мапхакеру обход антихака 😍
Постыдился бы такие глупости писать даже в шутку, я человек, который ненавидит хаки и хакеров такую дичь никогда бы не сделал. Это было сделано тоже на заказ, для детекта Cheat Engine и AutoHotkey программ.
20

» WarCraft 3 / Как двигать хп с мемхаком анрайза v1.4 1.26a

Для редактирования Лейблов хп/мп нужно сделать следующее:
local integer pHPLabel = ReadRealMemory( GetUIPortrait( ) + 0x240 )
local integer pMPLabel = ReadRealMemory( GetUIPortrait( ) + 0x244 )
Далее эти адреса редактировать/двигать и т.д. через LayoutAPI или напрямую через общий FrameAPI, думаю и сам легко разберёшься.
GameUI содержит большую часть, но не весь интерфейс, обратно в оффлайн отчаливаю.
20

» WarCraft 3 / Import Exploit - чудеса импорта (MIX)

Bogdan Shmay:
как открыть mix можно подробно плис(
Точно так же как и любую карту/mpq через MPQ Editor, закинул в программу и всё~
20

» WarCraft 3 / Группа - юниты игрока вызывает утечку

Ну, Варкрафт 3 в целом не любит когда слишком много юнитов одновременно на экране, а если учитывать, что у них ещё возможно есть и модель, то графическая часть начинает сильно резать фпс, с этим особо ты ничего не сделаешь. По поводу твоего кода, слишком напоминает GUI особенно проверками, ниже как бы я написал, но так как это отрывок и нет пояснения что в целом код должен делать, то я не знаю сколь близко он выполнит твои цели/нужды.
Код
globals
    timer gg_timer_Move = null
endglobals

function GetAxisAngle takes real fromX, real fromY, real targX, real targY returns real
	return Rad2Deg( Atan2( targY - fromY, targX - fromX ) )
endfunction

function GetAxisDistance takes real castX, real fcastY, real targX, real targY returns real
	return SquareRoot( Pow( targX - castX, 2 ) + Pow( fcastY - targY, 2 ) )
endfunction

function NewX takes real locX, real dist, real angle returns real
	return locX + dist * Cos( Deg2Rad( angle ) )
endfunction

function NewY takes real locY, real dist, real angle returns real
	return locY + dist * Sin( Deg2Rad( angle ) )
endfunction

function Move_GroupActionsHandler takes unit target returns nothing
    local integer uid   = GetUnitTypeId( target )
    local real speed    = 8   //скорость движения | Локальные переменные советую писать с маленькой буквы.
    local real targX    = GetUnitX( target ) // GetWidgetX не быстрее GetUnitX, не нужно этого делать :)
    local real targY    = GetUnitY( target ) // GetWidgetY не быстрее GetUnitY, не нужно этого делать :)
    local real moveX    = 0.
    local real moveY    = 0.
    local real angle    = 0.

    if udg_Time >= 6000 then
        if uid >= 'h044' and uid <= 'h046' then
            call RemoveUnit( target )
        else
            call UnitDamageTargetBJ( udg_Caster, target, 2000., ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNKNOWN )
        endif
    else
        if GetAxisDistance( udg_CasterX, udg_CasterY, targX, targY ) <= udg_Time / 10 * 8 then // Сделай один раз враппер и будет проще.
            if RAbsBJ( targX ) <= 4000 and RAbsBJ( targY ) <= 4000 then    //чтобы не двигал если юнит на краю карты | не нужно каждый раз читать местоположение по-новой.
                if not IsUnitType( target, UNIT_TYPE_STRUCTURE ) and target != udg_Caster and target != udg_DummyCaster then
                    set angle = GetAxisAngle( udg_CasterX, udg_CasterY, targX, targY ) //угол между координатами кастера и коорд юнита | через враппер.
                    set moveX = NewX( moveX, speed, angle )
                    set moveY = NewY( moveY, speed, angle ) // В твоей же системе было с минусом, ибо угол считался от кастера, собственно, если нужно отталкивание, но нужен +, если что просто замени на -speed

                    if not IsTerrainPathable( moveX, moveY, PATHING_TYPE_FLYABILITY ) or uid == 'h045' or uid == 'h046' then // лучше в начале проверить есть ли смысл двигать или нет.
                        // + RAbsBJ( 50 ) дал бы не совсем правильные результаты, ибо координаты могут быть отрицательными...
                        if GetTerrainType( moveX, moveY ) != 'Jdrt'  then
                            call SetTerrainType( moveX, moveY, 'Jdrt', -1, 1, 0 )       //если тип земли не изменен на этот, изменить его
                        endif
                        call SetUnitX( target, moveX )  //двигаем юнита
                        call SetUnitY( target, moveY )
                    endif
                endif
            endif
        endif
    endif
endfunction

function Move_GroupActions takes nothing returns nothing  //двигаем всех юнитов от точки кастера??
    call Move_GroupActionsHandler( GetEnumUnit( ) )
endfunction

function Move_Actions takes nothing returns nothing
    local integer i = 0
    local integer pid = GetOwningPlayer( udg_Caster )

    if udg_Time == 0 then  //в начале создаются даммики 45 штук...
        loop
            exitwhen i == 45
            set udg_MoveAngle = i * 8.
            set udg_Dummy[ i ] = CreateUnit( Player( pid ), 'h045', udg_CasterX - 200 * Cos( udg_MoveAngle ), udg_CasterY - 200 * Sin( udg_MoveAngle ), udg_MoveAngle )
            set i = i + 1
        endloop

        if udg_Group == null then
            set udg_Group = CreateGroup( )
        endif
    else
        if udg_Time <= 6000 then
            set i = 0
            loop
                exitwhen i > bj_MAX_PLAYERS // цикл всех игроков ничем не хуже...
                if Player( i ) == PLAYER_SLOT_STATE_PLAYING then
                    call GroupEnumUnitsOfPlayer( udg_Group, Player( i ), null )
                    call ForGroup( udg_Group, function Move_GroupActions )
                    call GroupClear( udg_Group )
                endif
                set i = i + 1
            endloop
        else
            call PauseUnit( udg_Caster, false )
            call PauseTimer( gg_timer_Move )
        endif
    endif

    set udg_Time = udg_Time + 10
endfunction

//===========================================================================
function InitTrig_Move takes nothing returns nothing
    set gg_timer_Move = CreateTimer( )
    call TimerStart( gg_timer_Move, .01, true, function Move_Actions )
endfunction
20

» WarCraft 3 / MemoryHackAPI

DracoL1ch:

function GetNthUnitFromGroup takes group g, integer n returns unit//n [1....x]
	local integer a
	set LastConvertedHandle=ConvertHandle(g)
	if LastConvertedHandle>0 then
		set a=CallThisCallWith2Args(GameDLL+0x421A20,LastConvertedHandle+0x24,n-1)
		if a>0 then
			return I2Unit(a)
		endif
	endif
	return null
endfunction
function CountUnitsInGroupNative takes group g returns integer
	set LastConvertedHandle=ConvertHandle(g)
	if LastConvertedHandle>0 then
		return RMem(LastConvertedHandle+0x34)
	endif
	return 0
endfunction
Функции с группами я уже сделал, включая ForEach, но спасибо. Ресурс загрузил, но ещё не обновили.
по поводу кручения у меня такое есть, наверное ты вместо неё косинусы и считаешь
function CalculateObjectOrientationRules takes handle h, real yaw, real pitch, real roll, real facing, integer flag returns nothing
	call WRMem(DataArray3Address+800,yaw)
	call WRMem(DataArray3Address+804,pitch)
	call WRMem(DataArray3Address+808,roll)
	//Convert Object YawPitchRoll Into Matrix
	call CallFastCallWith4Args(GameDLL+0x4B2C50,DataArray3Address+700,DataArray3Address+800,mR2I(facing),flag)
	//update object's data
	call CallThisCallWith10Args(GameDLL+0x4D3170,RMem(ConvertHandle(h)+0x28),RMem(DataArray3Address+700),RMem(DataArray3Address+704),RMem(DataArray3Address+708),RMem(DataArray3Address+712),RMem(DataArray3Address+716),RMem(DataArray3Address+720),RMem(DataArray3Address+724),RMem(DataArray3Address+728),RMem(DataArray3Address+732))
endfunction
где DataArray3Address - просто массив для хранения данных "подряд"
Да, так и есть, но после бенчмарка ThisCall старался обойтись без них, изучу этот код, сравню по скорости позже, если будет быстрее, почищу и заменю мою.
Спасибо :)
20

» WarCraft 3 / MemoryHackAPI

MemHackAPI v1.1 изменения:
  1. Исправлен метод снятия OP лимита.
  2. Исправлено снятие OP лимита на 1.27а (работало не полноценно).
  3. Возвращены тайпкасты I2T/T2I и I2U/U2I (HandleId в триггер/юнита и обратно).
  4. Изменено имя функции ConvertUnitAddressToHandleID на ObjectToHandleId.
  5. Добавлена ObjectToUnit, быстрее чем ObjectToHandleId в 2 раза, предазначено только для юнитов.
  6. Исправлена функция SetObjectScaleEx.
  7. Добавлена функция SetObjectSpaceRotation takes integer pObject, real yaw, real pitch, real roll returns nothing, позволяет крутить объект в 3D пространстве.
  8. Добавлена категория MemHackGroupAPI.
  9. Добавлена функция GetAddressGroupUnitCount takes integer pObj returns integer.
  10. Добавлена функция GetAddressGroupAddressUnitByIndex takes integer pObj, integer index returns integer.
  11. Добавлена функция GetGroupUnitCount takes group g returns integer.
  12. Добавлена функция GetUnitFromGroupByIndex takes group g, integer index returns unit.
  13. Добавлена функция GetRandomUnitFromGroup takes group g returns unit.
  14. Добавлена функция ForEach takes group g returns unit.
  15. Добавлены дополнительные опции в GetLocalTime.
  16. Добавлены примеры проведения бенчмарков в Testing триггер.
  17. Добавлена категория MemHackConstantsAPI.
  18. Добавлена функция EnableOPLimit takes flag returns nothing.
  19. Добавлена функция IsOPLimitEnabled takes nothing returns boolean.
20

» WarCraft 3 / MemoryHackAPI

ScorpioT1000:
ShellExecute - это интересно
вы все в виртуалках чтоль сидите чтоб такое позволять?)
Если кому-то нужно нагадить, это можно сделать и без шелла, допустим через kernel32 или User32, но даже для этого нужны руки...
Хорошие новости по поводу верчения эффекта в 3d, даже на таймере .01, игра не теряет fps (не падает ниже 64).
Ниже таймеры с периодичностью .25/.10/.01
20

» WarCraft 3 / MemoryHackAPI

В будущем будет добавлено 3d кручение, когда обновлю карту, кому не терпится попробовать, вот код:
    function SetObjectSpaceRotation takes integer pObject, real yaw, real pitch, real roll returns nothing
        if pObject > 0 then
            set yaw   = Deg2Rad( yaw )
            set pitch = Deg2Rad( pitch )
            set roll  = Deg2Rad( roll )

            call SetSpriteDataOffsetAddressR( pObject, 0x108,  Cos( yaw ) * Cos( pitch ) )
            call SetSpriteDataOffsetAddressR( pObject, 0x10C,  ( Cos( yaw ) * Sin( pitch ) * Sin( roll ) ) - ( Sin( yaw ) * Cos( roll ) ) )
            call SetSpriteDataOffsetAddressR( pObject, 0x110,  ( Cos( yaw ) * Sin( pitch ) * Cos( roll ) ) + ( Sin( yaw ) * Sin( roll ) ) )
            call SetSpriteDataOffsetAddressR( pObject, 0x114,  Sin( yaw ) * Cos( pitch ) )
            call SetSpriteDataOffsetAddressR( pObject, 0x118,  ( Sin( yaw ) * Sin( pitch ) * Sin( roll ) ) + ( Cos( yaw ) * Cos( roll ) ) )
            call SetSpriteDataOffsetAddressR( pObject, 0x11C,  ( Sin( yaw ) * Sin( pitch ) * Cos( roll ) ) - ( Cos( yaw ) * Sin( roll ) ) )
            call SetSpriteDataOffsetAddressR( pObject, 0x120,  -Sin( pitch ) )
            call SetSpriteDataOffsetAddressR( pObject, 0x124,  Cos( pitch ) * Sin( roll ) )
            call SetSpriteDataOffsetAddressR( pObject, 0x128,  Cos( pitch ) * Cos( roll ) )
        endif
    endfunction
Скриншот примера прикрепил. Код будет прооптимизирован, чтобы убрать схожие операции перемножения и т.д., чтобы ускорить обработку, пускай и незначительно.
Загруженные файлы
20

» WarCraft 3 / MemoryHackAPI

Bergi_Bear:
function SetEffectScaleEx takes effect e, real x, real y, real z returns nothing
Нормально работает? а то в рефордже вообще никак, а я в своё время не добрался до эффектов в мемхаке, так что не проверял
Спасибо, что напомнил, в функции есть косяк, поправлю как раз:
Исправленный код:
	function SetObjectScaleEx takes integer pObject, real x, real y, real z returns nothing
        if pObject > 0 then
            call SetSpriteDataOffsetAddressR( pObject, 0x108, x )
            call SetSpriteDataOffsetAddressR( pObject, 0x118, y )
            call SetSpriteDataOffsetAddressR( pObject, 0x128, z )
        endif
	endfunction
Размеры 2., 5., 2.
П.С. ещё пару правок сделал в коде, когда доправлю и ещё немного очеловечу код - загружу обновление.
Ну и самое вкусное, менять модели эффектам можно, то есть не нужно удалять эффект, и так как модели не синхаются, можно менять модель эффекта в локальном блоке.
Так же я добавил, возможно не заметили: function SetObjectAnimationByIndex takes integer pObject, integer index returns nothing
То есть, да, можно проигрывать анимации эффекта, возможно в будущем сделаю и через string, если жасс не умрёт от перебора и сравнения адрессов string...
Загруженные файлы
20

» WarCraft 3 / MemoryHackAPI

GetLocalPlayer:
Lua интерпретатор заинжектить пробовали?
ЛУА интерпретатор сделать конечно можно, но проку маловато, единственное, чем оно может быть полезно - с работой с памятью "из вне" Джасса, но даже так, сомнительно это всё. А по остальным минусам не хочу говорить, а то задену тех, кто используют LUA, лишние споры/нервотрёпки ни к чему :)
20

» WarCraft 3 / MemoryHackAPI

Тема обновлена, весь близкий к пользователю API был выписан в саму тему, ввиду занятости пока что не могу каждую функцию описать, но конечно немного сомневаюсь в нужде этого, так как я попытался все функции и даже параметры/аргументы и в целом переменные называть максимально близко к тому, что они выполняют.
Сравнение с прошлыми МемХаками думаю вскоре напишу, если это конечно кому-то интересно.