diff --git a/server/chat-plugins/suspect-tests.ts b/server/chat-plugins/suspect-tests.ts
index ca768d96b1d2b..b6d346c98e0ab 100644
--- a/server/chat-plugins/suspect-tests.ts
+++ b/server/chat-plugins/suspect-tests.ts
@@ -1,5 +1,6 @@
import { Utils } from '../../lib';
import { FS } from '../../lib/fs';
+import { type BestOfGame } from '../room-battle-bestof';
const SUSPECTS_FILE = 'config/suspects.json';
@@ -56,6 +57,45 @@ export const commands: Chat.ChatCommands = {
return this.sendReplyBox(buffer);
},
+ async join(target, room, user) {
+ const format = Dex.formats.get(target);
+ if (format.effectType !== 'Format') throw new Chat.ErrorMessage(`"${target}" is not a valid tier.`);
+
+ const suspect = suspectTests.suspects[format.id];
+ if (!suspect) throw new Chat.ErrorMessage(`There is not currently a suspect test in ${format.name}`);
+
+ // don't allow a user to reset RD while in a rated game of the same format
+ for (const gameid of user.games) {
+ const game = Rooms.get(gameid)?.game;
+ if (!game || game.ended) continue;
+ if (!game.playerTable[user.id]) continue;
+ if (game.gameid === 'battle') {
+ const battle = game as RoomBattle;
+ if (battle.rated && battle.format === format.id) {
+ throw new Chat.ErrorMessage(`You are currently in a rated ${format.name} battle.`);
+ }
+ } else if (game.gameid === 'bestof') {
+ const bestof = game as BestOfGame;
+ if (bestof.options.rated && bestof.format.id === format.id) {
+ throw new Chat.ErrorMessage(`You are currently in a rated ${format.name} game.`);
+ }
+ }
+ }
+
+ const [out, error] = await LoginServer.request('suspects/join', {
+ format: format.id,
+ user: user.id,
+ });
+ if (out?.actionerror || error) {
+ throw new Chat.ErrorMessage("Error joining suspect test: " + (out?.actionerror || error?.message));
+ }
+
+ this.sendReplyBox(`You are now participating in the ${suspect.suspect} suspect test in ${format.name}!
` +
+ `Your wins and losses in ${format.name} during the test will be counted separately and used to calculate your COIL.
` +
+ `If you achieve the required COIL value on this account, you will be eligible to vote.
` +
+ `(Remember to use the /linksmogon command!)`);
+ },
+
edit: 'add',
async add(target, room, user) {
checkPermissions(this);
@@ -117,7 +157,7 @@ export const commands: Chat.ChatCommands = {
tier: format.name,
suspect: suspectString,
date: dateActual,
- url: out.url || prevSuspect.url,
+ url: out.url || prevSuspect?.url,
};
saveSuspectTests();
this.sendReply(`Added a suspect test notice for ${suspectString} in ${format.name}.`);
@@ -230,7 +270,7 @@ export const commands: Chat.ChatCommands = {
async setbvalue(target, room, user, connection, cmd) {
checkPermissions(this);
if (!toID(target)) {
- return this.parse(`/help ${cmd}`);
+ return this.parse(`/help suspects ${cmd}`);
}
const [formatStr, source] = this.splitOne(target);
const format = Dex.formats.get(formatStr);
@@ -280,7 +320,7 @@ export const commands: Chat.ChatCommands = {
`/suspects remove [tier]: deletes a suspect test. Requires: ~
` +
`/suspects whitelist [username]: allows [username] to add suspect tests. Requires: ~
` +
`/suspects unwhitelist [username]: disallows [username] from adding suspect tests. Requires: ~
` +
- `/suspects setbvalue OR /suspects sbv [formatid], [B value]: Activate COIL ranking for the given [formatid] with the given [B value].` +
+ `/suspects setbvalue OR /suspects sbv [formatid], [B value]: Activate COIL ranking for the given [formatid] with the given [B value]. ` +
`Requires: suspect whitelist ~`
);
},
diff --git a/server/ladders-remote.ts b/server/ladders-remote.ts
index aacb5df2b3385..f65aab16bcd68 100644
--- a/server/ladders-remote.ts
+++ b/server/ladders-remote.ts
@@ -118,8 +118,8 @@ export class LadderStore {
room.add(`|error|Unexpected response ${data} from ladder server.`);
room.update();
problem = true;
- } else if (data.errorip) {
- room.add(`|error|This server's request IP ${data.errorip} is not a registered server.`);
+ } else if (data.errorip !== undefined) {
+ room.add(`|error|This server's request IP "${data.errorip}" is not a registered server.`);
room.add(`|error|You should be using ladders.js and not ladders-remote.js for ladder tracking.`);
room.update();
problem = true;