Декомпиляция UnrealScript в Killing Floor: чистка вывода UE Explorer
Уважайте авторов модов и указывайте их. Это не руководство по воровству кода.
Некоторые авторы вырезают из пакетов исходный текст, и сообщество не может ни доработать мод, ни поучиться на нём. У каждого автора свои причины; многолетний спор об этом пересказан в статье Защита кода: почему вырезание исходников ничего не защищает. Здесь мы не спорим ни в какую сторону, а показываем, как вернуть читаемый код с помощью UE Explorer от Eliot (Unreal-Library) и привести в порядок то, что он выдаёт.
Дерево классов и свойства актора в KF Editor.
Байт-код против UnrealScript
Компиляция мутатора превращает UnrealScript в байт-код движка. Процесс необратим: многие конструкции, например цепочки if/else и циклы, не имеют прямого представления в байт-коде. Декомпилятор не может надёжно их восстановить и печатает более запутанный, хотя функционально тот же код. Ниже типичные превращения и как их откатить.
Циклы for
UE Explorer не восстанавливает циклы for. Такой исходник:
// modify zeds in special squads
function ModifySquadArray(out array<SpecialSquad> SquadArray)
{
local int i, j;
for (i = 0; i < SquadArray.Length; i++)
{
for (j = 0; j < SquadArray[i].ZedClass.Length; j++)
{
ReplaceMonsterClass(SquadArray[i].ZedClass[j]);
}
}
}
возвращается метками и goto:
function ModifySquadArray(out array<SpecialSquad> SquadArray)
{
local int i, j;
i = 0;
J0x07:
// End:0x69 [Loop If]
if(i < SquadArray.Length)
{
j = 0;
J0x1E:
// End:0x5F [Loop If]
if(j < SquadArray[i].ZedClass.Length)
{
ReplaceMonsterClass(SquadArray[i].ZedClass[j]);
++ j;
// [Loop Continue]
goto J0x1E;
}
++ i;
// [Loop Continue]
goto J0x07;
}
//return;
}
Это компилируется, но большие функции становятся нечитаемыми. Уберите метки и превратите каждую пару [Loop If] + goto обратно в for: оператор перед меткой — инициализация, if — условие, ++ перед goto — шаг.
// [Explicit Break] замените на break;, а // [Explicit Continue] на continue;.
Блоки replication
Экспортируется всё правильно, кроме того, что у условий репликации пропадают точки с запятой:
replication
{
// Pos:0x000
reliable if(bNetInitial && Role == ROLE_Authority)
CsHDRI
}
Верните их вручную:
replication
{
reliable if (bNetInitial && Role == ROLE_Authority)
CsHDRI;
}
defaultproperties
UE Explorer их показывает, но правильность не гарантирована: у экспортёра есть известные ошибки, а подобъекты в defaultproperties восстанавливаются плохо. Экспортируйте пакет штатным ucc и перенесите его defaultproperties поверх вывода UE Explorer:
ucc.exe batchexport PACKAGENAME.u class uc ../DIRECTORY/
pause
Запускать из папки System. batchexport пишет по .uc на каждый класс с правильными значениями по умолчанию, даже если тела функций вырезаны.
Цепочки else if
UE Explorer печатает только обычные if и вкладывает каждый else if:
static function AddDefaultInventory(KFPlayerReplicationInfo KFPRI, Pawn P)
{
// End:0x44
if(KFPRI.ClientVeteranSkillLevel == 5)
{
KFHumanPawn(P).CreateInventoryVeterancy("CsHDMut.W_Bullpup", default.StartingWeaponSellPriceLevel5);
}
// End:0x8E
else
{
// End:0x8E
if(KFPRI.ClientVeteranSkillLevel == 6)
{
KFHumanPawn(P).CreateInventoryVeterancy("CsHDMut.W_AK47AssaultRifle", default.StartingWeaponSellPriceLevel6);
}
}
//return;
}
Разверните:
static function AddDefaultInventory(KFPlayerReplicationInfo KFPRI, Pawn P)
{
if (KFPRI.ClientVeteranSkillLevel == 5)
{
KFHumanPawn(P).CreateInventoryVeterancy("CsHDMut.W_Bullpup", default.StartingWeaponSellPriceLevel5);
}
else if (KFPRI.ClientVeteranSkillLevel == 6)
{
KFHumanPawn(P).CreateInventoryVeterancy("CsHDMut.W_AK47AssaultRifle", default.StartingWeaponSellPriceLevel6);
}
}
Значения enum в виде чисел
UE Explorer может печатать значения перечислений как числа. Найдите определение enum и верните имена. Элементы нумеруются с 0:
enum ENetMode
{
NM_Standalone, // 0
NM_DedicatedServer, // 1
NM_ListenServer, // 2
NM_Client // 3
};
| Декомпилировано | Читаемо | Где определено |
|---|---|---|
Level.NetMode == 3 | Level.NetMode == NM_Client | Engine/Classes/LevelInfo.uc |
RemoteRole = 2 | RemoteRole = ROLE_SimulatedProxy | Engine/Classes/Actor.uc |
В исходниках скриптов KF на GitHub (InsultingPros/KillingFloor) есть все стандартные классы. Если открыть их в VS Code, «перейти к определению» найдёт любой enum за секунды. В гайде по UT Package Tool есть готовые таблицы самых частых enum.
Чек-лист чистки
- Экспортировать
defaultpropertiesчерезucc batchexportи перенести в декомпилированные классы. - Собрать циклы
forиз меток иgoto, превратить комментарии explicit break/continue в операторы. - Добавить недостающие точки с запятой в
replication. - Развернуть вложенные
else { if }вelse if. - Заменить числа enum на имена.
- Скомпилировать через ucc make и проверить, прежде чем что-то публиковать.
- Указать автора оригинала.