Skip to content

Commit 31ff03a

Browse files
committed
Add anti-spam for /ohno command and refactor handlers
Introduces anti-spam tracking for the /ohno command, kicking players who excessively use it and warning at lower thresholds. Refactors command handler argument destructuring for consistency, improves area tile history limit logic, and updates test/build scripts in package.json. Also includes minor code style and logic improvements throughout playerCommands.
1 parent 0b394ab commit 31ff03a

File tree

5 files changed

+101
-11
lines changed

5 files changed

+101
-11
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ spec/build
1010
spec/plugin
1111
scripts/client.js
1212
scripts/client.ts
13-
dev-server
13+
dev-server
14+
/.kiro

build/scripts/main.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/scripts/playerCommands.js

Lines changed: 53 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"watch": "tsc --watch",
1010
"build": "tsc -p tsconfig.json",
1111
"dev": "node scripts/dev.js",
12-
"test": "tsc -b src && node scripts/remap-imports.js && tsc -p spec jasmine"
12+
"test": "tsc -b && node scripts/remap-imports.js && tsc -p spec && jasmine"
1313
},
1414
"keywords": [],
1515
"author": "",
@@ -21,4 +21,4 @@
2121
"jasmine": "^5.5.0",
2222
"typescript": "^5.7.3"
2323
}
24-
}
24+
}

src/playerCommands.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,8 @@ Available types:[yellow]
558558
const Ohnos = {
559559
enabled: true,
560560
ohnos: new Array<Unit>(),
561+
/** Anti-spam tracking: playerUUID -> {count, lastUsed, warnings} */
562+
spamTracker: new Map<string, {count: number, lastUsed: number, warnings: number}>(),
561563
makeOhno(team:Team, x:number, y:number){
562564
const ohno = UnitTypes.atrax.create(team);
563565
ohno.set(x, y);
@@ -578,10 +580,43 @@ Available types:[yellow]
578580
amount(){
579581
return this.ohnos.length;
580582
},
583+
checkSpam(player: FishPlayer): void {
584+
const now = Date.now();
585+
const playerData = this.spamTracker.get(player.uuid) || {count: 0, lastUsed: 0, warnings: 0};
586+
587+
if (now - playerData.lastUsed > 30000) {
588+
playerData.count = 0;
589+
playerData.warnings = 0;
590+
}
591+
592+
playerData.count++;
593+
playerData.lastUsed = now;
594+
this.spamTracker.set(player.uuid, playerData);
595+
596+
if (playerData.count >= 15) {
597+
player.sendMessage("[red]You have been kicked for /ohno spam. You can rejoin in 5 minutes.");
598+
Call.sendMessage(`[yellow]${player.name}[red] has been kicked for /ohno spam.`);
599+
FishPlayer.messageStaff(`[yellow]Alert: Player [cyan]${player.cleanedName}[] was kicked for /ohno spam (${playerData.count} attempts in 30 seconds).`);
600+
player.kick(`Kicked for spamming /ohno command (${playerData.count} attempts in 30 seconds). You can rejoin in 5 minutes.`, 5 * 60 * 1000);
601+
fail("Player kicked for spam");
602+
} else if (playerData.count >= 10) {
603+
player.sendMessage("[orange]WARNING: Stop spamming /ohno or you will be kicked!");
604+
} else if (playerData.count >= 5) {
605+
player.sendMessage("[yellow]Warning: Please don't spam /ohno. Continued spam will result in punishment.");
606+
}
607+
},
581608
};
582609
Events.on(EventType.GameOverEvent, (e) => {
583610
Ohnos.killAll();
584611
});
612+
Timer.schedule(() => {
613+
const now = Date.now();
614+
for (const [uuid, data] of Ohnos.spamTracker.entries()) {
615+
if (now - data.lastUsed > 300000) {
616+
Ohnos.spamTracker.delete(uuid);
617+
}
618+
}
619+
}, 60, 60);
585620
return Ohnos;
586621
},
587622
requirements: [
@@ -590,11 +625,17 @@ Available types:[yellow]
590625
],
591626
handler({sender, data:Ohnos}){
592627
if(!Ohnos.enabled) fail(`Ohnos have been temporarily disabled.`);
628+
593629
Ohnos.updateLength();
594-
if(
630+
const maxReached = (
595631
Ohnos.ohnos.length >= (Groups.player.size() + 1) ||
596632
sender.team().data().countType(UnitTypes.alpha) >= Units.getCap(sender.team())
597-
) fail(`Sorry, the max number of ohno units has been reached.`);
633+
);
634+
635+
if (maxReached) {
636+
Ohnos.checkSpam(sender);
637+
fail(`Sorry, the max number of ohno units has been reached.`);
638+
}
598639
if(nearbyEnemyTile((sender.unit()!), 6) != null) fail(`Too close to an enemy building!`);
599640
if(!UnitTypes.alpha.supportsEnv(Vars.state.rules.env)) fail(`Ohnos cannot survive in this map.`);
600641

0 commit comments

Comments
 (0)