19

» WarCraft 3 / Причины FATAL ERROR?

Такой же краш как и прежде, но теперь проблема со способностью A0OK:Aave у юнита с типом Hmgd.
19

» WarCraft 3 / Причины FATAL ERROR?

Принятый ответ
ESI=0CFB7EAC
В краш репорте засветился указатель на способность. В .dmp файле сохранена память стека потоков и еще некоторые регионы памяти. Среди них оказалась и область со способностью, в которой виден её равкод: 0x41304F4A или A0OJ. Эта способность основана на Aave (CAbilityAvengerForm).
Также видно равкод владельца — Hmgd.
Что на счет события — во время моих тестов оно срабатывало в начале и в конце перевополощения.
Загруженные файлы
19

» WarCraft 3 / Причины FATAL ERROR?

Была вызвана следующая цепочка методов:
CAbilityMorph::OnEvent
CAbilityMorph::FinishMorphing
CAbility::EnableOrders
CAbility::ShowUI
CAgent::GetParent
При попытке получить владельца некой способности превращения был получен краш из-за нулевого указателя.
Странно что, судя по моим наблюдениями, содержащее владельца поле CAbility::m_owner_unit не было nullptr. Краш произошел при попытке обратиться к вышестоящему агенту через другой способ, который требует наличия сетевого ID у объекта. Возможно, способность уже была убита, но кто-то всё равно вызвал её обработчик событий.
19

» WarCraft 3 / Причины FATAL ERROR?

Так что в итоге показала программа? В момент краша исполнялся какой-то скрипт?
Еще, если бы ты выложил файл с краш-репортом, то было бы больше шансов понять причину.
По скриншоту понятно лишь то, что крашнулось в методе CAgent::GetParent.
Загруженные файлы
19

» WarCraft 3 / MemoryPatch (1.26a) - Расширение лимита оперативной памяти

darkowlom, связной список варкрафта является шаблонным типом из C++, так что для каждого варианта этого типа генерируется новый набор кода. Поэтому недостаточно найти одно место в коде и пропатчить его — необходимо найти все сгенерированные реализации, сколько бы их там ни было (кто знает сколько их там тысяч).
Вот тебе для примера краш одного игрока, который, как я полагаю, использовал подобный патч:
This application has encountered a critical error:

FATAL ERROR!

Program:	D:\wc3\Warcraft III 1.26a LTD\War3.exe
Exception:	0xC0000005 (ACCESS_VIOLATION) at 0023:6F7C4BC2

The instruction at '0x6F7C4BC2' referenced memory at '0x7DB1FF4F'.
The memory could not be 'written'.
Вот как выглядит это место в коде игры:
До инверсии число 0x7DB1FF4F было указателем 0x824E00B0, который как раз находится в верхней половине памяти, которая обычно недоступна.
После того как связной список наткнулся на это место, произошел краш из-за попытки записи в недоступную память.
Это еще повезло, что неудалось произвести запись, а иначе можно было перезаписать случайную память и затем недоумевать, почему в карте творится всякая чертовщина.
Загруженные файлы
19

» WarCraft 3 / MemoryPatch (1.26a) - Расширение лимита оперативной памяти

Связные списки варкрафта оптимизированы с учетом доступности лишь первых 2 ГБ памяти. Если после разблокировки второй половины из неё будет выделен фрагмент для такого списка, то стоит ждать непредсказуемых последствий: случайные повреждения памяти, фатальные ошибки из-за обращений к недоступной памяти.
19

» WarCraft 3 / Снятие ограничения на длину пути в списке карт

Спустя почти год перерыва я таки заглянул снова в игровые внутренности, но хороших новостей у меня нет.
Судя по тому что я вижу, во внутренних типах игры, хранящих информацию об игровой комнате, жестко ограничен размер строки с путем к карте — исправлять такое уже намного сложнее.
И даже если бы я это сделал, то еще остается проблема передачи информации по сети между клиентами, ведь придется уже менять протокол BNET/LAN на всех клиентах, чтобы это заработало.
Мод ничего не может сделать с ограничениями по сети, но всё равно от него есть польза, ведь так хотя бы не придется гадать, почему твоя карта не отображается в списке.
19

» Прочее / Деквадратизированные текстуры для OneShot

Если использовать программу апскейлер с фильтрами NNEDI3 или xBRZ, то можно играть в полноэкранном режиме без сильного мыла.
Или, если вы так любите пиксель арт, то идти нужно до конца и не использовать билинейную фильтрацию стандартного fullscreen режима:
Интересно совпало, что решением стартовой загадки случайно оказался PIN код от моего телефона. Случайно ведь, да?
19

» WarCraft 3 / Самоподключающийся архив

Dam3w, не могу утверждать на счет всех функций встроенных в этот файл, но вероятно он загружает все .mix файлы в папке с игрой уже на стадии инициализации DirectX, которая обрабатывается до игрового интерфейса. Не уверен, правда, будет ли он работать в режиме OpenGL.
19

» WarCraft 3 / Работа с нативными функциями

Vampir_kolik, мне пока не удается найти исходники. В крайнем случае, можно было бы переписать с нуля, ведь кода там немного, но не знаю, найдется ли у меня на это время.
Пока я посоветовал бы тебе поискать ошибки у себя в коде, ведь RedirectCalls сам по себе не создает утечек и вообще никак не связан с движением юнитов. Он лишь создает в памяти функцию обертку на ASM для каждой JASS функции, что скрипт передает нативкам в качестве callback'ов. Сколько у тебя JASS callback'ов, столько и будет выделено памяти.
19

» WarCraft 3 / Самоподключающийся архив

FDG89K, думаю, причина в том, что звуковая система инициализируется уже после графического интерфейса, так что файлы FDF уже были прочитаны к моменту загрузки твоего архив, почему и были проигнорированы.
Для таких модификаций нужно использовать какой-нибудь лаунчер, который загрузит твои MPQ архивы до запуска функции GameMain из Game.dll. Или сделать какой-нибудь мод, который перезагрузит GUI подсистему после твоего mix-архива.
19

» WarCraft 3 / Jass MythBusters

makkad, все любопытствующие могут скачать утекшие бинарники с отладочной информацией и открыть в IDA или подобных программах для изучения.
В патче 1.26a содержимое не отличается.
Содержимое нативок
void __fastcall SetWidgetLife(unsigned int widgetHandle, const unreal *newLife)
{
  CWidget *widget; // [rsp+20h] [rbp-18h]

  widget = ConvertHandle<CWidget>(widgetHandle);
  if ( widget )
    widget->SetLife(widget, newLife);
}

void __fastcall KillUnit(unsigned int unitHandle)
{
  CUnit *unit; // [rsp+20h] [rbp-18h]

  unit = ConvertHandle<CUnit>(unitHandle);
  if ( unit )
    unit->SetLife(unit, &u_0);
}
19

» WarCraft 3 / Журналирование вызовов JASS

Вышла новая версия!
Прокрутить к ресурсу
  • Исправлен краш при загрузке сохранений.
  • Исправлен краш при выборе карты с ошибками в сценарии.
  • Добавлена поддержка отрицательного уровня отступа (использует '-' вместо табов).
  • Теперь логируется запуск/остановка потока и его код выхода, а также результат.
  • Теперь все потоки используют один глобальный уровень отступа, так что дочерние потоки будут логировать "глубже" своих родителей. Спящие потоки все также будут запоминать свой уровень отступа и восстанавливать его при пробуждении.
19

» WarCraft 3 / Неограниченое описание

Вышла новая версия!
Прокрутить к ресурсу
  • Добавил проверки на нулевой указатель при копировании текста из UnitUIDef.
19

» WarCraft 3 / Открытая виртуальная машина

EugeAl, не понимаю, чего ты хочешь добиться.
Чтобы оно было "по дефолту", нужно чтобы близарды сами добавили эти нативки.
Если же хочется пользовательских модификаций, то нужно ставить моды, а как иначе?
19

» WarCraft 3 / Насколько быстро выполняется if ? - [Jass]

LastUchiha, учти, что цикл также будет исполнять свои инструкции для проверки условий и прыжков. Можешь посмотреть во что компилируется функция при помощи JassView. Метки для прыжков это тоже инструкции, но которые ничего не делают и интерпретатор игнорирует их.
Если хочешь, чтобы накладные расходы цикла не сильно влияли на результат, то можешь совершать действие в его теле достаточно много раз, чтобы затенить их.
пример
function BenchmarkComparison takes nothing returns nothing
local integer i = 0
local integer start
local integer elapsed
	call SetOperationLimitEnabled(false)
	set start = GetTickCount()

	loop
		exitwhen i > 1000000
		// ТВОЁ ДЕЙСТВИЕ
		// ТВОЁ ДЕЙСТВИЕ
		// ...
		set i = i + 1
	endloop

	set elapsed = GetTickCount() - start
	call BJDebugMsg("Time elapsed: " + R2S(elapsed / 1000.0) + " seconds.")
endfunction
Можно сделать два варианта действия для этой функции:
1
if MUIID == 0 then
	set MUIID = GetHandleId( GetExpiredTimer() )
endif
2
GetHandleId( GetExpiredTimer() )
Затем сравни их время исполнения.
19

» WarCraft 3 / Журналирование вызовов JASS

Meddin, в стеке виднеется адрес unlimited_description.mix, возможно, что дело в нём.
Нужно будет потом глянуть.
19

» WarCraft 3 / Насколько быстро выполняется if ? - [Jass]

Принятый ответ
Вместо того, чтобы гадать, можно провести замеры.
Я делал мод, который добавляет нативки для бенчмарков — просто кинь JassApi.dll и
natives.mix в папку с игрой и объяви в коде нативки:
native GetTickCount takes nothing returns integer
native SetOperationLimitEnabled takes boolean state returns nothing
native IsOperationLimitEnabled takes nothing returns boolean
После чего сделай функцию, которая многократно выполняет интересующее тебя действие и засеки время до и после исполнения, затем вычисли разницу.
Важно сделать так, чтобы функция исполнялась достаточно долго для того, чтобы погрешность была не слишком велика. Измерять одно действие смысла мало, а вот повторить его миллион раз уже может иметь смысл, чтобы на выполнение задачи ушли секунды, а не наносекунды, что может привести к погрешности ±100%.
Не забудь отключить лимит операций с помощью вызова SetOperationLimitEnabled(false), а иначе виртуальная машина убьет поток из-за превышения лимита.
19

» WarCraft 3 / Журналирование вызовов JASS

Meddin, протестировал на карте DotA LoD 6.83i и не смог словить крашей ни после сохранения и последующей загрузки, ни после нажатия на кнопку "Начать заново".
Возможно, у тебя стоят какие-нибудь конфликтующие моды.
Без отчёта об ошибке и дампа виртуальной машины сложно что-то сказать.
19

» WarCraft 3 / Журналирование вызовов JASS

This mod was written without the ability to support multiple versions, so adding support for new ones will be more difficult.
The source code is open, so you can add support for your version yourself, but I have no motivation to do that: on those rare occasions when I log into the game, I use version 1.26a. And I use other tools for debugging, so I haven't had any use for this mod yet.
19

» WarCraft 3 / Журналирование вызовов JASS

Meddin, у тебя не сохраняется лог?
По идее, он должен сохраняться в любых обстоятельствах, ведь каждую строчку я сразу передаю функции FileWrite, а дальше уже дело за операционной системой.
19

» WarCraft 3 / Помогите (ошибка)

Принятый ответ
Когда просишь помочь с крашем, то стоит скидывать отчет об ошибке, создаваемый игрой при сбое (файлы .txt и .dmp с датой краша в имени).
Также есть программа, которая позволяет просматривать состояние скрипта карты. Если повезет, с ней сразу раскроется причина.
Она умеет сохранять слепок состояния виртуальной машины, который ты тоже можешь скинуть сюда.
19

» WarCraft 3 / Группы с несуществующими юнитами и FirstOfGroup

Meddin, не похоже, чтобы память утекала.
код
void __cdecl GroupClear(DWORD whichGroup)
{
    CGroup *g;

    g = ConvertHandle<CGroup>(whichGroup);
    if ( g )
        CGroup::Clear(g);
}

void __thiscall CGroup::Clear(CGroup *this)
{
    this->units.vtable->Clear(&this->units);
}

void __thiscall CUnitSet::Clear(CUnitSet *this)
{
    CUnitListNode *node;

    while (TRUE)
    {
        node = this->items.root.value;
        if ( (int)node <= 0 )
            break;
        CUnitListNode::~CUnitListNode(this->items.root.value);
        SMemFree(node, CUnitListNode::TypeName, -2, 0);
    }
    this->size = 0;
}
19

» WarCraft 3 / Последний приют 2

EasyMoney, в чем ты её пытаешься открыть? Если в редакторе, то она и не должна в нём открываться, ведь написано же, что она защищена.
А в игре она у меня запускается через WarCraft версии 1.26a.