Skip to content

Commit 34e7b15

Browse files
committed
chore: update to handle offsets
1 parent f00df92 commit 34e7b15

4 files changed

Lines changed: 29 additions & 30 deletions

File tree

.github/workflows/build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,5 @@ jobs:
4343
with:
4444
package-name: gamedata-validator
4545
package-type: container
46-
min-versions-to-keep: 8
46+
min-versions-to-keep: 4
4747
ignore-versions: '^buildcache-*'

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ format:
1919
at image build time.
2020

2121
Each entry is one of:
22-
- `signatures` — a `linux` byte pattern, scanned against the binary; healthy = exactly one match.
23-
- `vtable` — a `binary` + `class` + `linux` vfunc index; healthy = the index still fits inside that
24-
class's vtable (catches CS2 updates that shrink/shift a vtable). Class names are resolved by RTTI.
25-
26-
`offsets`-only entries (e.g. in upstream CCS gamedata) are skipped — there's nothing to scan.
22+
- `signatures` — a `linux` byte pattern, scanned against the binary; healthy = found (at least one
23+
match, matching the official checker). A missing signature (0 matches) is broken.
24+
- `offsets` — standard CCS `offsets` (`windows`/`linux` vfunc index). When the entry also carries our
25+
`library` + `class` extension, the `linux` index is bound-checked against that RTTI class's vtable
26+
size (catches CS2 updates that shrink/shift a vtable). Bare `offsets` with no `class` (e.g. in
27+
upstream CCS gamedata) can't be validated and are skipped.
2728

2829
## Result
2930

gamedata/fivestack.gamedata.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@
77
}
88
},
99
"FiveStack_NetworkServerService_GetIGameServer": {
10-
"vtable": {
11-
"binary": "engine2",
12-
"class": "CNetworkServerService",
10+
"library": "engine2",
11+
"class": "CNetworkServerService",
12+
"offsets": {
1313
"windows": 23,
1414
"linux": 24
1515
}
1616
},
1717
"FiveStack_NetworkGameServer_GetAddonName": {
18-
"vtable": {
19-
"binary": "engine2",
20-
"class": "CNetworkGameServerBase",
18+
"library": "engine2",
19+
"class": "CNetworkGameServerBase",
20+
"offsets": {
2121
"windows": 26,
2222
"linux": 26
2323
}

main.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
def load_entries(file_path):
1616
signatures = {}
17-
vtables = {}
17+
offsets = {}
1818
with open(file_path) as f:
1919
for name, entry in commentjson.load(f).items():
2020
if not isinstance(entry, dict):
@@ -27,32 +27,30 @@ def load_entries(file_path):
2727
signatures[name] = {"lib": lib, "linux": sig["linux"]}
2828
continue
2929

30-
vt = entry.get("vtable")
31-
if vt and vt.get("binary") and vt.get("class") and vt.get("linux") is not None:
32-
vtables[name] = {
33-
"binary": vt["binary"],
34-
"class": vt["class"],
35-
"offset": vt["linux"],
36-
}
37-
return signatures, vtables
30+
off = entry.get("offsets")
31+
lib = entry.get("library") or entry.get("lib")
32+
cls = entry.get("class")
33+
if off and lib and cls and off.get("linux") is not None:
34+
offsets[name] = {"lib": lib, "class": cls, "offset": off["linux"]}
35+
return signatures, offsets
3836

3937

40-
def check_vtable(set_name, name, vt):
38+
def check_offset(set_name, name, off):
4139
result = {
4240
"set": set_name,
4341
"signature": name,
4442
"kind": "vtable",
45-
"class": vt["class"],
46-
"offset": vt["offset"],
43+
"class": off["class"],
44+
"offset": off["offset"],
4745
"count": None,
4846
"ok": False,
4947
}
5048
try:
51-
result["count"] = s2binlib.get_vfunc_count(vt["binary"], vt["class"])
49+
result["count"] = s2binlib.get_vfunc_count(off["lib"], off["class"])
5250
except Exception as error:
5351
result["error"] = str(error)
5452
return result
55-
result["ok"] = 0 <= vt["offset"] < result["count"]
53+
result["ok"] = 0 <= off["offset"] < result["count"]
5654
return result
5755

5856

@@ -71,7 +69,7 @@ def main():
7169
if not path.exists(file_path):
7270
print(f"[skip] missing {file_path}", flush=True)
7371
continue
74-
signatures, vtables = load_entries(file_path)
72+
signatures, offsets = load_entries(file_path)
7573
for name, sig in signatures.items():
7674
_, count = s2binlib.pattern_scan(sig["lib"], sig["linux"])
7775
results.append(
@@ -80,11 +78,11 @@ def main():
8078
"signature": name,
8179
"kind": "signature",
8280
"count": count,
83-
"ok": count == 1,
81+
"ok": count >= 1,
8482
}
8583
)
86-
for name, vt in vtables.items():
87-
results.append(check_vtable(set_name, name, vt))
84+
for name, off in offsets.items():
85+
results.append(check_offset(set_name, name, off))
8886

8987
broken = [r for r in results if not r["ok"]]
9088
result = {

0 commit comments

Comments
 (0)