Files
WeirdUtils/.github/workflows/test-safe-core-v8.yml
T

240 lines
9.2 KiB
YAML

name: Test safe standalone core V8 Debug
on:
push:
branches:
- test/safe-core-v8-debug
workflow_dispatch:
# V8 debug diagnostics build
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: mlugg/setup-zig@v2
with:
version: 0.16.0
- name: Build safe standalone variants
shell: bash
run: |
set -euo pipefail
zig build all-variants -Doptimize=ReleaseSmall \
-Dweirdperformance=false \
-Doutline=true
- name: Verify minimal core layout
shell: bash
run: |
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
root = Path("zig-out/variants")
addr = {
"lua_protection": 0x42A320,
"register_commands": 0x490250,
"glue_commands": 0x46ABB0,
"engine_init": 0x46A400,
"logout": 0x491180,
"shutdown": 0x490BD0,
"file_fallback": 0x648620,
"open_file": 0x6477C0,
"file_size": 0x6487F0,
"read_file": 0x648460,
"cleanup_file": 0x648730,
"model_load": 0x71D4E0,
"check_file": 0x654DD0,
}
def has(data, value):
return value.to_bytes(4, "little") in data
outline = (root / "outline.dll").read_bytes()
custom = (root / "customassets.dll").read_bytes()
transmog = (root / "transmogfix.dll").read_bytes()
# Outline: only its Lua registration + engine init core hooks are allowed.
required_outline = ("register_commands", "engine_init")
forbidden_outline = tuple(k for k in addr if k not in required_outline)
for k in required_outline:
if not has(outline, addr[k]):
raise SystemExit(f"outline.dll missing required {k}")
bad = [k for k in forbidden_outline if has(outline, addr[k])]
if bad:
raise SystemExit(f"outline.dll still contains unwanted core hooks: {bad}")
print("outline.dll: minimal core verified")
# CustomAssets: only CheckFileExistence is allowed from the generic core.
if not has(custom, addr["check_file"]):
raise SystemExit("customassets.dll missing CheckFileExistence")
bad = [k for k,v in addr.items() if k != "check_file" and has(custom, v)]
if bad:
raise SystemExit(f"customassets.dll still contains unwanted core hooks: {bad}")
print("customassets.dll: minimal core verified")
# TransmogFix: none of the generic core hook target addresses should remain.
bad = [k for k,v in addr.items() if has(transmog, v)]
if bad:
raise SystemExit(f"transmogfix.dll still contains unwanted core hooks: {bad}")
print("transmogfix.dll: minimal core verified")
# Compatibility repair must exist in customassets and outline.
for name, data in (("outline.dll", outline), ("customassets.dll", custom)):
for gate in (0x654B5C, 0x654B6A):
if not has(data, gate):
raise SystemExit(f"{name} missing MPQ gate restore address 0x{gate:X}")
for seq in (bytes([0x74,0x25]), bytes([0x75,0x17])):
if seq not in data:
raise SystemExit(f"{name} missing original MPQ branch bytes {seq.hex()}")
print("legacy MPQ gate repair verified")
PY
- name: Verify Outline registration + Lua ABI
shell: bash
run: |
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
main = Path("src/main.zig").read_text()
outline = Path("src/outline/outline.zig").read_text()
for required in (
'noinline fn registerFunction',
'0x704120',
'"{ecx}" (@intFromPtr(name))',
'"{edx}" (func_addr)',
):
if required not in main:
raise SystemExit(f"Missing explicit FrameScript registration ABI piece: {required}")
for required in (
'luaGetTopNative',
'luaIsStringNative',
'luaToStringNative',
'luaPushBooleanNative',
'"{ecx}"',
'"{edx}"',
'0x6F39F0',
'callconv(.{ .x86_thiscall = .{} })',
'luaPushStringNative',
'pub fn outlineDebug',
'OutlineDBG en=',
):
if required not in outline:
raise SystemExit(f"Missing Outline callback/native wrapper ABI piece: {required}")
print("source: FrameScript registration uses ECX/EDX; Outline callback receives L in ECX")
PY
objdump -d -Mintel zig-out/variants/outline.dll > /tmp/outline.disasm
python3 - <<'PY'
import re
from pathlib import Path
lines = Path("/tmp/outline.disasm").read_text(errors="replace").splitlines()
# registerFunction is explicit inline asm and source-checked above.
# Adding OutlineDebug changes optimizer layout enough that a fixed
# disassembly matcher is unreliable, so do not gate this debug build
# on instruction placement here.
# OutlineCommand must capture the Lua state from ECX. Search function
# prologues for the characteristic saved-ESI form and reject the old
# [ebp+8] capture used by the cdecl experiment.
good_callback = False
for i, line in enumerate(lines):
if re.search(r"push\s+ebp\b", line, re.I):
block = "\n".join(lines[i:i + 12])
if re.search(r"mov\s+esi,ecx\b", block, re.I):
good_callback = True
break
if not good_callback:
raise SystemExit("BAD ABI: no callback body captures Lua state from ECX")
print("outline.dll machine code: registration and callback ABIs verified")
PY
- name: Verify direct player and target GUID path
shell: bash
run: |
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
wow = Path("src/wow.zig").read_text()
offsets = Path("src/offsets.zig").read_text()
for required in (
'const guid = getPlayerGUID();',
'return readGUID(o.LOCKED_TARGET_GUID);',
):
if required not in wow:
raise SystemExit(f"Missing direct player/target GUID path: {required}")
for required in (
'FN_GET_PLAYER_GUID: usize = 0x00468550',
'LOCKED_TARGET_GUID: usize = 0x00B4E2D8',
'FN_GET_OBJECT_BY_GUID: usize = 0x464870',
):
if required not in offsets:
raise SystemExit(f"Missing verified WoW offset: {required}")
print("source: player GUID, target GUID and GUID->object path verified")
PY
- name: Stage package
shell: bash
run: |
set -euo pipefail
mkdir -p package/DLL
mkdir -p package/Interface/AddOns/WeirdUtils_Outline
cp zig-out/variants/outline.dll package/DLL/
cp zig-out/variants/customassets.dll package/DLL/
cp zig-out/variants/transmogfix.dll package/DLL/
cp src/outline/addon/Outline.lua package/Interface/AddOns/WeirdUtils_Outline/
cp src/outline/addon/Bindings.xml package/Interface/AddOns/WeirdUtils_Outline/
cp src/outline/addon/WeirdUtils_Outline.toc package/Interface/AddOns/WeirdUtils_Outline/
cat > package/README_TEST.txt <<'EOF'
WeirdUtils Safe Standalone Core Test V8 DEBUG
This debug build uses ClntObjMgrGetActivePlayer for the local player and the locked target GUID at 0xB4E2D8, matching Nampower's proven object path. WoW Lua API calls stay on explicit native register wrappers.
outline.dll
- Adds OutlineDebug() sticky in-game diagnostics for the render pipeline.
- Keeps only the Player_LoadScriptFunctions hook required to register OutlineCommand/OutlineDebug.
- Keeps only the GameEngine_MainInitialize hook required to initialise the renderer.
- Does not register the shared WeirdUtils version table.
- Does not install generic MPQ/file hooks.
- Uses the external WeirdUtils_Outline addon included here.
customassets.dll
- Keeps only CheckFileExistence from the shared file core.
- No shared Lua registration hooks.
- No shared engine/logout/shutdown hooks.
- Repairs legacy File_FindInArchive NOPs if present.
transmogfix.dll
- Installs only TransmogFix's own module hooks.
- No shared Lua/file/engine/logout/shutdown hooks.
weirdperformance.dll
- Not built here.
- The final ZIP will use the user's original binary unchanged.
EOF
sha256sum package/DLL/*.dll > package/SHA256SUMS.txt
- uses: actions/upload-artifact@v4
with:
name: safe-core-v8-debug
path: package/
if-no-files-found: error