// ── What a weapon is called on a page ────────────────────────────────────── // // The plugin names the weapon in a kill by the held entity's SHORT PREFAB NAME // (`ak47u.entity`) — the same name the title lists beside this file count by, // and the right key for counting. It is the wrong thing to print: the feed said // "with ak47u entity". So every event read gives the frame a `weaponName` from // here, and the site and the app print that, falling back to the prefab name // themselves only for a module too old to send one. // // The table is the ranged weapons — every gun, bow, crossbow, launcher and // flamethrower — named as the game names them. Read off the Oxide rig's own item // list on 2026-10-23 (Rust 26139947) by the same read-only walk the title lists // came from: each item whose held entity is an `AttackEntity`, its short prefab // name and its English display name. Melee, throwables and anything a later Rust // update adds fall back to `stripped()`, which drops the `.entity` / `.weapon` // ending and turns the rest into words ("salvaged sword"), so a new weapon reads // acceptably before anyone edits this list. To refresh, walk the list again. const NAMES = new Map([ ['50cal.left.entity', 'Dual 50 Cal Turret'], ['50cal.right.entity', 'Dual 50 Cal Turret'], ['50cal.single.entity', '50 Cal Turret'], ['ak47u.entity', 'Assault Rifle'], ['ak47u.glass.blue.entity', 'Crystal Assault Rifle Sapphire'], ['ak47u.glass.entity', 'Crystal Assault Rifle Diamond'], ['ak47u.glass.green.entity', 'Crystal Assault Rifle Emerald'], ['ak47u.glass.pink.entity', 'Crystal Assault Rifle Pink Diamond'], ['ak47u.glass.red.entity', 'Crystal Assault Rifle Ruby'], ['ak47u_diver.entity', 'Abyss Assault Rifle'], ['ak47u_ice.entity', 'Ice Assault Rifle'], ['ak47u_jungle.entity', 'Jungle Relic Assault Rifle'], ['ak47u_med.entity', 'Medieval Assault Rifle'], ['blunderbuss.entity', 'Blunderbuss'], ['bolt_rifle.entity', 'Bolt Action Rifle'], ['bow_hunting.entity', 'Hunting Bow'], ['compound_bow.entity', 'Compound Bow'], ['crossbow.entity', 'Crossbow'], ['crossbow_bowless.entity', 'Bowless Crossbow'], ['double_shotgun.entity', 'Double Barrel Shotgun'], ['flamethrower.entity', 'Flame Thrower'], ['glock.entity', 'Prototype 17'], ['hc_revolver.entity', 'High Caliber Revolver'], ['hmlmg.entity', 'HMLMG'], ['krieg_shotgun.entity', 'Krieg Shotgun'], ['l96.entity', 'L96 Rifle'], ['legacybow.entity', 'Legacy Bow'], ['lr300.entity', 'LR-300 Assault Rifle'], ['lr300_space.entity', 'Space LR-300 Assault Rifle'], ['m16a2.entity', 'M16A2'], ['m249.entity', 'M249'], ['m39.entity', 'M39 Rifle'], ['m4_shotgun.entity', 'M4 Shotgun'], ['m92.entity', 'M92 Pistol'], ['mgl.entity', 'Multiple Grenade Launcher'], ['militaryflamethrower.entity', 'Military Flame Thrower'], ['mini_crossbow.entity', 'Mini Crossbow'], ['mp5.entity', 'MP5A4'], ['nailgun.entity', 'Nailgun'], ['pistol_revolver.entity', 'Revolver'], ['pistol_semiauto.a.m15.entity', 'M15 Semi-Automatic Pistol'], ['pistol_semiauto.entity', 'Semi-Automatic Pistol'], ['python.entity', 'Python Revolver'], ['rocket_launcher.entity', 'Rocket Launcher'], ['rocket_launcher_dragon.entity', 'Dragon Rocket Launcher'], ['semi_auto_rifle.entity', 'Semi-Automatic Rifle'], ['shotgun_pump.entity', 'Pump Shotgun'], ['shotgun_waterpipe.entity', 'Waterpipe Shotgun'], ['sks.entity', 'SKS'], ['smg.entity', 'Custom SMG'], ['spas12.entity', 'Spas-12 Shotgun'], ['t1_smg.entity', 'Handmade SMG'], ['thompson.entity', 'Thompson'], ]) /** The endings a held entity's prefab name carries that no player says. */ const ENDING = /[._](entity|weapon|deployed)$/ /** A prefab name as words: its ending dropped, its dots and underscores spaces. */ function stripped(prefab) { return String(prefab).trim().replace(ENDING, '').replace(/[_.]+/g, ' ').trim() } /** What to print for a weapon's prefab name: the game's own name, or the stripped one. */ function nameOf(prefab) { if (typeof prefab !== 'string' || !prefab.trim()) return null return NAMES.get(prefab.trim()) || stripped(prefab) } module.exports = { nameOf, stripped, NAMES }