re: refute the OB entity-flag on the FULL enumeration -- the stationary-entity hole is closed
Every earlier refutation in this file carried the caveat that entities2.typed types entities by their position CHANGING, so a stationary objective is invisible to it. This session's definition-pointer enumeration does not have that limit, so the sweep was re-run against it (ob_flag_all.py, guarded route, stage asserted, HUD cropped beside each sample): A: HUD 004, 147 entities -> 152 candidates B: HUD 012, 133 entities -> 15 candidates intersection: 1 The lone survivor pos+0x0250 = 239d6732 is the same offset AND identical value this file already characterised as a per-group word. Membership test: all 12 holders are UN_e010_ADAN_Attacker_S, 12 of 16 live attackers. It is a squad parameter, and it survived only because that population equalled the counter at both samples. Also reconfirms "not a class head-count" on 147 entities including capital ships. Trap recorded: the first sweep reported 298 entities and a class with head-count exactly 4 -- a perfect-looking hit that was pure artifact. Deduping by ADDRESS leaves the measured exact 2x duplication (pairs 0x1000 apart, byte-identical positions) intact and doubles every population. Dedup on the position VALUE.
This commit is contained in:
56
tools/re-capture/ob_flag_all.py
Normal file
56
tools/re-capture/ob_flag_all.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""Flag sweep over the DEFINITION-POINTER enumeration (sees stationary entities)."""
|
||||
import sys, os, struct, collections, json
|
||||
sys.path.insert(0, '/tmp/rc')
|
||||
import gmem, gworld, entities2 as E
|
||||
|
||||
LO, HI = -0x400, 0xC00
|
||||
|
||||
def entities(w):
|
||||
"""Every entity via its definition pointer: position = hit - 0x130."""
|
||||
defs = E.definitions(w)
|
||||
lo, hi = gmem.va_to_off(E.ENT_VA_LO), gmem.va_to_off(E.ENT_VA_HI)
|
||||
out = []
|
||||
for pat, nm in defs.items():
|
||||
for a, b in gmem.extents(w.fd, w.size):
|
||||
a, b = max(a, lo), min(b, hi)
|
||||
if b <= a: continue
|
||||
blob = os.pread(w.fd, b - a, a); i = 0
|
||||
while True:
|
||||
j = blob.find(pat, i)
|
||||
if j < 0: break
|
||||
off = a + j
|
||||
if off % 4 == 0: out.append((off - 0x130, nm))
|
||||
i = j + 4
|
||||
return out
|
||||
|
||||
def sweep(w, ents, n):
|
||||
"""(offset, value) pairs shared by exactly n entities."""
|
||||
tally = collections.defaultdict(collections.Counter)
|
||||
for pos, nm in ents:
|
||||
buf = os.pread(w.fd, HI - LO, pos + LO)
|
||||
if len(buf) < HI - LO: continue
|
||||
for k in range(0, HI - LO, 4):
|
||||
tally[LO + k][struct.unpack('>I', buf[k:k+4])[0]] += 1
|
||||
return {(o, v) for o, c in tally.items() for v, k in c.items() if k == n}
|
||||
|
||||
if __name__ == '__main__':
|
||||
n = int(sys.argv[1]); tag = sys.argv[2]
|
||||
w = gworld.World()
|
||||
ents = entities(w)
|
||||
# Dedup by POSITION VALUE, not by address: this session measured an exact
|
||||
# 2x duplication (pairs 0x1000 apart holding byte-identical positions), so
|
||||
# deduping on the address leaves every entity counted twice and the
|
||||
# "exactly N agree" test can never match.
|
||||
ded = {}
|
||||
for pos, nm in ents:
|
||||
b = os.pread(w.fd, 12, pos)
|
||||
if len(b) < 12: continue
|
||||
key = (nm, struct.unpack('>fff', b))
|
||||
ded.setdefault(key, pos)
|
||||
ents = [(pos, nm) for (nm, _), pos in ded.items()]
|
||||
print('entities (definition-pointer enumeration):', len(ents))
|
||||
c = collections.Counter(nm for _, nm in ents)
|
||||
print('classes whose head-count equals %d: %s' % (n, [k for k, v in c.items() if v == n] or 'NONE'))
|
||||
cand = sweep(w, ents, n)
|
||||
print('offsets where exactly %d entities agree: %d' % (n, len(cand)))
|
||||
json.dump([[o, v] for o, v in sorted(cand)], open('/tmp/flag_%s.json' % tag, 'w'))
|
||||
Reference in New Issue
Block a user