UNPKG

slp-enforcer

Version:

Finds violations of the Melee Controller Ruleset by inspecting SLP files

189 lines (188 loc) 12.2 kB
"use strict"; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const globals_1 = require("@jest/globals"); const index_1 = require("../index"); const sdi_1 = require("../sdi"); const fs = __importStar(require("fs")); const path = __importStar(require("path")); globals_1.test('Test Region Sanity Check', () => { // DZ - Dead Zone Test globals_1.expect(sdi_1.getSDIRegion(0, 0)).toBe(sdi_1.SDIRegion.DZ); globals_1.expect(sdi_1.getSDIRegion(0.2, 0.2)).toBe(sdi_1.SDIRegion.DZ); globals_1.expect(sdi_1.getSDIRegion(-0.2, -0.2)).toBe(sdi_1.SDIRegion.DZ); // NE - Northeast globals_1.expect(sdi_1.getSDIRegion(0.8, 0.8)).toBe(sdi_1.SDIRegion.NE); globals_1.expect(sdi_1.getSDIRegion(0.9, 0.7)).toBe(sdi_1.SDIRegion.NE); // SE - Southeast globals_1.expect(sdi_1.getSDIRegion(0.8, -0.8)).toBe(sdi_1.SDIRegion.SE); globals_1.expect(sdi_1.getSDIRegion(0.9, -0.7)).toBe(sdi_1.SDIRegion.SE); // SW - Southwest globals_1.expect(sdi_1.getSDIRegion(-0.8, -0.8)).toBe(sdi_1.SDIRegion.SW); globals_1.expect(sdi_1.getSDIRegion(-0.9, -0.7)).toBe(sdi_1.SDIRegion.SW); // NW - Northwest globals_1.expect(sdi_1.getSDIRegion(-0.8, 0.8)).toBe(sdi_1.SDIRegion.NW); globals_1.expect(sdi_1.getSDIRegion(-0.9, 0.7)).toBe(sdi_1.SDIRegion.NW); // N - North globals_1.expect(sdi_1.getSDIRegion(0, 0.8)).toBe(sdi_1.SDIRegion.N); globals_1.expect(sdi_1.getSDIRegion(0.2, 0.9)).toBe(sdi_1.SDIRegion.N); // E - East globals_1.expect(sdi_1.getSDIRegion(0.8, 0)).toBe(sdi_1.SDIRegion.E); globals_1.expect(sdi_1.getSDIRegion(0.9, 0.2)).toBe(sdi_1.SDIRegion.E); // S - South globals_1.expect(sdi_1.getSDIRegion(0, -0.8)).toBe(sdi_1.SDIRegion.S); globals_1.expect(sdi_1.getSDIRegion(0.2, -0.9)).toBe(sdi_1.SDIRegion.S); // W - West globals_1.expect(sdi_1.getSDIRegion(-0.8, 0)).toBe(sdi_1.SDIRegion.W); globals_1.expect(sdi_1.getSDIRegion(-0.9, 0.2)).toBe(sdi_1.SDIRegion.W); // TILT - Middle-ish area globals_1.expect(sdi_1.getSDIRegion(0.4, 0.4)).toBe(sdi_1.SDIRegion.TILT); globals_1.expect(sdi_1.getSDIRegion(-0.4, -0.4)).toBe(sdi_1.SDIRegion.TILT); globals_1.expect(sdi_1.getSDIRegion(0.2, -0.3)).toBe(sdi_1.SDIRegion.TILT); // Edge cases // Testing near the edges of the DZ boundary (0.2875) globals_1.expect(sdi_1.getSDIRegion(0.2876, 0)).toBe(sdi_1.SDIRegion.TILT); globals_1.expect(sdi_1.getSDIRegion(0, 0.2876)).toBe(sdi_1.SDIRegion.TILT); globals_1.expect(sdi_1.getSDIRegion(-0.2876, 0)).toBe(sdi_1.SDIRegion.TILT); globals_1.expect(sdi_1.getSDIRegion(0, -0.2876)).toBe(sdi_1.SDIRegion.TILT); // Test values on the boundary of magnitude 0.7 (diagonal) globals_1.expect(sdi_1.getSDIRegion(0.7, 0.7)).toBe(sdi_1.SDIRegion.NE); globals_1.expect(sdi_1.getSDIRegion(-0.7, 0.7)).toBe(sdi_1.SDIRegion.NW); globals_1.expect(sdi_1.getSDIRegion(0.7, -0.7)).toBe(sdi_1.SDIRegion.SE); globals_1.expect(sdi_1.getSDIRegion(-0.7, -0.7)).toBe(sdi_1.SDIRegion.SW); // Boundary checks for cardinal directions (0.7) globals_1.expect(sdi_1.getSDIRegion(0.7, 0)).toBe(sdi_1.SDIRegion.E); globals_1.expect(sdi_1.getSDIRegion(0, 0.7)).toBe(sdi_1.SDIRegion.N); globals_1.expect(sdi_1.getSDIRegion(-0.7, 0)).toBe(sdi_1.SDIRegion.W); globals_1.expect(sdi_1.getSDIRegion(0, -0.7)).toBe(sdi_1.SDIRegion.S); }); globals_1.test('Test SDI from legal digital file', () => { let data = fs.readFileSync(path.join(__dirname, '../../test_data/legal/digital/potion_p3/potion_' + 2 + '.slp'), null); let game = new index_1.SlippiGame(index_1.toArrayBuffer(data)); globals_1.expect(game).not.toBeNull(); let gameCoords = index_1.getCoordListFromGame(game, 2, true); globals_1.expect(sdi_1.failsSDIRuleOne(gameCoords)).toEqual([]); globals_1.expect(sdi_1.failsSDIRuleThree(gameCoords)).toEqual([]); }); globals_1.test('Test isDiagonalAdjacent()', async () => { globals_1.expect(sdi_1.isDiagonalAdjacent(sdi_1.SDIRegion.SE, sdi_1.SDIRegion.NW)).toEqual(false); globals_1.expect(sdi_1.isDiagonalAdjacent(sdi_1.SDIRegion.SE, sdi_1.SDIRegion.SE)).toEqual(false); globals_1.expect(sdi_1.isDiagonalAdjacent(sdi_1.SDIRegion.SE, sdi_1.SDIRegion.DZ)).toEqual(false); globals_1.expect(sdi_1.isDiagonalAdjacent(sdi_1.SDIRegion.SE, sdi_1.SDIRegion.SW)).toEqual(true); globals_1.expect(sdi_1.isDiagonalAdjacent(sdi_1.SDIRegion.NW, sdi_1.SDIRegion.NE)).toEqual(true); globals_1.expect(sdi_1.isDiagonalAdjacent(sdi_1.SDIRegion.SW, sdi_1.SDIRegion.SE)).toEqual(true); }); globals_1.test('Test SDI (manual coords)', async () => { // Sanity check. No movement. No violation let coords = [{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }]; globals_1.expect(sdi_1.failsSDIRuleOne(coords)).toEqual([]); // Easy case. Lots of SDI. Violation. coords = [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 0, y: 0 }, { x: 1, y: 0 }, { x: 0, y: 0 }, { x: 1, y: 0 }]; globals_1.expect(sdi_1.failsSDIRuleOne(coords).length).toBeGreaterThanOrEqual(1); // Too many frames in the tilt zone, doesn't count as SDI! coords = [{ x: 0, y: 0 }, { x: 0.3, y: 0 }, { x: 0.32, y: 0 }, { x: 0.35, y: 0 }, { x: 0.4, y: 0 }, { x: 1, y: 0 }, { x: 0, y: 0 }, { x: 1, y: 0 }]; globals_1.expect(sdi_1.failsSDIRuleOne(coords)).toEqual([]); // Slowest possible SDIs. Doesn't count as SDI since it has travel time coords = [{ x: 0, y: 0 }, { x: 0.3, y: 0 }, { x: 0.35, y: 0 }, { x: 0.4, y: 0 }, { x: 1, y: 0 }, { x: 0, y: 0 }, { x: 0.35, y: 0 }, { x: 0.4, y: 0 }, { x: 1, y: 0 }]; globals_1.expect(sdi_1.failsSDIRuleOne(coords).length).toEqual(0); // Doesn't count as SDI since it has travel time coords = [{ x: 0, y: 0 }, { x: 0.3, y: 0 }, { x: 1, y: 0 }, { x: 0, y: 0 }, { x: 0.3, y: 0 }, { x: 1, y: 0 }]; globals_1.expect(sdi_1.failsSDIRuleOne(coords).length).toEqual(0); // Violation. SDI, then put in a bunch of travel time after. // IE: You don't get off the hook just because you have travel time after the SDI coords = [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 0, y: 0 }, { x: 1, y: 0 }, { x: 0.3, y: 0 }, { x: 0.35, y: 0 }, { x: 0.4, y: 0 }]; globals_1.expect(sdi_1.failsSDIRuleOne(coords).length).toBeGreaterThanOrEqual(1); }); globals_1.test('Test SDI (legal A)', async () => { let data = fs.readFileSync(path.join(__dirname, '../../test_data/legal/digital/sdi/sdi_r18_v2.slp'), null); let game = new index_1.SlippiGame(index_1.toArrayBuffer(data)); globals_1.expect(game).not.toBeNull(); let coords = index_1.getCoordListFromGame(game, 0, true); // TODO: Re-enable these tests once we get an SLP that works // expect(hasIllegalSDI(game, 0, coords)).toEqual([]) globals_1.expect(sdi_1.failsSDIRuleOne(coords)).toEqual([]); // expect(failsSDIRuleTwo(coords)).toEqual([]) globals_1.expect(sdi_1.failsSDIRuleThree(coords)).toEqual([]); }); globals_1.test('Test SDI (legal B)', async () => { let data = fs.readFileSync(path.join(__dirname, '../../test_data/legal/digital/sdi/sdi_t20_cardinal_diagonal.slp'), null); let game = new index_1.SlippiGame(index_1.toArrayBuffer(data)); globals_1.expect(game).not.toBeNull(); let coords = index_1.getCoordListFromGame(game, 0, true); globals_1.expect(index_1.hasIllegalSDI(game, 0, coords).result).toEqual(false); globals_1.expect(sdi_1.failsSDIRuleOne(coords)).toEqual([]); globals_1.expect(sdi_1.failsSDIRuleTwo(coords)).toEqual([]); globals_1.expect(sdi_1.failsSDIRuleThree(coords)).toEqual([]); }); globals_1.test('Test SDI (legal C)', async () => { let data = fs.readFileSync(path.join(__dirname, '../../test_data/legal/digital/sdi/sdi_mash.slp'), null); let game = new index_1.SlippiGame(index_1.toArrayBuffer(data)); globals_1.expect(game).not.toBeNull(); let coords = index_1.getCoordListFromGame(game, 0, true); globals_1.expect(index_1.hasIllegalSDI(game, 0, coords).result).toEqual(false); globals_1.expect(sdi_1.failsSDIRuleOne(coords)).toEqual([]); globals_1.expect(sdi_1.failsSDIRuleTwo(coords)).toEqual([]); globals_1.expect(sdi_1.failsSDIRuleThree(coords)).toEqual([]); }); globals_1.test('Test SDI (legal D)', async () => { let data = fs.readFileSync(path.join(__dirname, '../../test_data/legal/digital/sdi/Game_20250201T233229.slp'), null); let game = new index_1.SlippiGame(index_1.toArrayBuffer(data)); globals_1.expect(game).not.toBeNull(); let coords = index_1.getCoordListFromGame(game, 0, true); globals_1.expect(sdi_1.failsSDIRuleOne(coords)).toEqual([]); globals_1.expect(sdi_1.failsSDIRuleTwo(coords)).toEqual([]); globals_1.expect(sdi_1.failsSDIRuleThree(coords)).toEqual([]); }); globals_1.test('Test SDI (legal E)', async () => { let data = fs.readFileSync(path.join(__dirname, '../../test_data/legal/digital/sdi/Game_20250201T232732.slp'), null); let game = new index_1.SlippiGame(index_1.toArrayBuffer(data)); globals_1.expect(game).not.toBeNull(); let coords = index_1.getCoordListFromGame(game, 1, true); globals_1.expect(sdi_1.failsSDIRuleOne(coords)).toEqual([]); globals_1.expect(sdi_1.failsSDIRuleTwo(coords)).toEqual([]); globals_1.expect(sdi_1.failsSDIRuleThree(coords)).toEqual([]); }); globals_1.test('Test SDI (non legal A)', async () => { let data = fs.readFileSync(path.join(__dirname, '../../test_data/nonlegal/digital/sdi/sdi_tas_neutral_cardinal.slp'), null); let game = new index_1.SlippiGame(index_1.toArrayBuffer(data)); globals_1.expect(game).not.toBeNull(); let coords = index_1.getCoordListFromGame(game, 3, true); // Fails rule #1 globals_1.expect(index_1.hasIllegalSDI(game, 3, coords).result).toEqual(true); let violations = sdi_1.failsSDIRuleOne(coords); globals_1.expect(violations.length).toEqual(195); globals_1.expect(violations[10].reason).toEqual("Failed SDI rule #1"); globals_1.expect(violations[10].metric).toEqual(139); globals_1.expect(violations[10].evidence).toEqual([{ "x": 0, "y": 0 }, { "x": 0, "y": 0 }, { "x": -1, "y": 0 }, { "x": 0, "y": 0 }, { "x": -1, "y": 0 }, { "x": 0, "y": 0 }, { "x": -1, "y": 0 }, { "x": 0, "y": 0 }, { "x": -1, "y": 0 }, { "x": 0, "y": 0 }]); }); globals_1.test('Test SDI (non legal B)', async () => { let data = fs.readFileSync(path.join(__dirname, '../../test_data/nonlegal/digital/sdi/sdi_tas_cardinal_diagonal.slp'), null); let game = new index_1.SlippiGame(index_1.toArrayBuffer(data)); globals_1.expect(game).not.toBeNull(); let coords = index_1.getCoordListFromGame(game, 3, true); let violations = sdi_1.failsSDIRuleTwo(coords); globals_1.expect(violations.length).toEqual(36); globals_1.expect(violations[10].reason).toEqual("Failed SDI rule #2"); globals_1.expect(violations[10].metric).toEqual(226); globals_1.expect(violations[10].evidence).toEqual([{ "x": 1, "y": 0 }, { "x": 0.7, "y": 0.7 }, { "x": 1, "y": 0 }, { "x": 0.7, "y": 0.7 }, { "x": 1, "y": 0 }]); }); globals_1.test('Test SDI (non legal C)', async () => { let data = fs.readFileSync(path.join(__dirname, '../../test_data/nonlegal/digital/sdi/sdi_unnerfed.slp'), null); let game = new index_1.SlippiGame(index_1.toArrayBuffer(data)); globals_1.expect(game).not.toBeNull(); let coords = index_1.getCoordListFromGame(game, 3, true); // Fails rule #3 but not rule #1 globals_1.expect(index_1.hasIllegalSDI(game, 3, coords).result).toEqual(true); globals_1.expect(sdi_1.failsSDIRuleOne(coords)).toEqual([]); let violations = sdi_1.failsSDIRuleThree(coords); globals_1.expect(violations.length).toEqual(8); globals_1.expect(violations[4].reason).toEqual("Failed SDI rule #3"); globals_1.expect(violations[4].metric).toEqual(2535); globals_1.expect(violations[4].evidence).toEqual([{ "x": 0.7, "y": 0.7 }, { "x": 0.7, "y": 0.7 }, { "x": 0, "y": 1 }, { "x": -0.7, "y": 0.7 }, { "x": 0.7, "y": 0.7 }]); });