Skip to content

DBNO Addition, Better Defuser Detection, Also has FortressY10.#126

Open
ImAAhmad wants to merge 26 commits intoredraskal:mainfrom
ImAAhmad:main
Open

DBNO Addition, Better Defuser Detection, Also has FortressY10.#126
ImAAhmad wants to merge 26 commits intoredraskal:mainfrom
ImAAhmad:main

Conversation

@ImAAhmad
Copy link
Copy Markdown

No description provided.

- Add DBNO event type to track knockdowns separately from kills
- Detect finish-off kills using byte indicator at offset 20 post-headshot
- Credit kills to the player who knocked the target, not the finisher
- Add dbnoBy field to track original knocker on finish-off kills
@ImAAhmad ImAAhmad changed the title DBNO Addition, Better Defuser Detection. DBNO Addition, Better Defuser Detection, Also has FortressY10. Dec 16, 2025
ImAAhmad and others added 23 commits February 24, 2026 19:34
- Add DBNO (Down But Not Out) event detection with multi-layer approach: offset-based for Y8-Y9, marker-based for Y10+, fallback from duplicate kills

- Track knocker via dbnoBy field for kill steal detection

- Add DBNO type to MatchUpdate and dbnos stat to PlayerRoundStats/PlayerMatchStats

- Fix Y10S4 defuser timer parsing (DissectID no longer in packet)

- Infer defuser player from team role and alive players
The 3-event revert heuristic (targetKillCount >= 3) was unreliable and
incorrectly removed valid kills for players on the losing team who were
DBNO'd at round end. This caused undercounting of kills by up to 11
across a match.

Removed the revert logic entirely along with the now-unused
targetKillCount and targetFirstKnock tracking maps. The simple
duplicate finish-off filter (skip if target already has a Kill with
DBNOBy set) is sufficient.

Tested against a 10-round Y10S4 match: kills and deaths now match the
in-game scoreboard exactly at totals (68/68), with only 1 kill
attribution difference between two same-team players.
When a DBNO'd player is finished off by someone other than the knocker,
the Kill event now includes a finishedBy field with the finisher's
username. The field is omitted when the knocker and finisher are the
same person. This enables detecting kill steals in post-processing.
…ead code

- Detect camera destructions (+15 score delta) and utility destructions (+25 score delta) inline during scoreboard parsing
- Track defuser plant/disable via +100 score bonus (Y10S4+)
- Remove broken position tracking (magic bytes produce packet counters, not coordinates)
- Remove unused findClosestPlayerToDefuser and Float32 reader
- Add UtilityEvents and CameraDestructions to match/round output
- Ignore .md files except README.md
- Decode position packets using magic bytes 0x60 0x73 0x85 0xFE
- Packet structure: magic(4) + entityID(1) + skip(1) + X,Y,Z float32
- Filter noise: NaN/Inf, coordinate bounds, minimum movement range
- Z height correlates to floor level (Z~3.8 = 2nd floor, Z~0.4 = 1st)
- Add PlayerPosition and EntityPositions structs to movement.go
- Add Float32() reader method and readPosition/finalizePositions
- Include movements in JSON output for both single-round and match mode
- Tested: 6-10 entities tracked per round across all 3 test matches
- Add Team field to EntityPositions struct (Defense/Attack)
- Filter out near-origin game objects from position data
- Classify entities by position sample count: top 5 = Defense, rest = Attack
  (replay records more samples for defenders near the recording camera/site)
- Tested across 14 rounds from 3 matches with consistent 5D/xA results
…e/gadget/reinforcement tracking

- Add Y11S1 version constant (9578674)
- Fix Solid Snake gadget to Soliton Radar Mk. III
- Add ClutchDetail struct with opponents alive, start time, kills
- Add bleedOut field to MatchUpdate for DBNO bleedout detection
- Track drone destructions via +10 defender score deltas
- Track gadget deployments via +20 score deltas
- Add reinforcement/barricade structs and output fields
- Update JSON output for rounds and match with new fields
- Map entity IDs to players by sorting ascending (lowest 10 IDs = players)
- Remove heuristic filters that dropped players with few position samples
- Add Username field to EntityPositions for player identification
- Widen coordinate bounds to avoid clipping edge-of-map positions
- Use header team roles instead of guessing from position count
- Extract yaw and pitch from quaternion data after position XYZ coordinates
- Multi-offset calibration: tries offsets 0-84, sorted by pitch variance priority
- Per-position fallback: tries all calibrated offsets until valid quaternion found
- Coverage: 87-100% for high-activity entities, varies by entity type
- Rotation data omitted (omitempty) where quaternion unavailable
…ecated ioutil

- Add camelToSlug() to convert CamelCase operator names to hyphenated slugs
  (e.g. SolidSnake -> solid-snake) for proper Ubisoft API matching
- Replace deprecated ioutil.WriteFile with os.WriteFile
- Replace io/ioutil import with unicode (needed for camelToSlug)
- Fix malformed build tag in tools.go (was always compiled into binary)
- Remove dead code in exports/exports.go (unreachable error check)
- Remove stale Go 1.20.2 generics comment in header.go
- Clean up stale TODOs in feedback.go and defuse.go
- Rewrite README with current features, Y11S1 examples, movement/rotation
  docs, and go generate instructions
Parse room location packets from the readSpawn magic pattern to track
which room/area each player is in throughout the round. Room names
include floor indicators (1F, 2F, EXT, B) matching the in-game
spectator scoreboard display.

- Add LocationEvent struct with username, room, and timestamp
- Detect room packets via empty-string readSpawn pattern + 3 zero bytes
- Map entity bytes to players using initial spawn order (first 10 events)
- Export locationEvents in both round and match JSON output
- Tested on 3 replays: 151, 202, 208 events respectively
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant