Strongly type Config
Some checks failed
Node.js CI / build (22.x) (push) Has been cancelled

(Also remove a bunch of global types)
This commit is contained in:
Guangcong Luo 2025-05-19 13:27:19 -07:00
parent de13c8c5d4
commit fc6d963912
18 changed files with 75 additions and 53 deletions

View File

@ -1,3 +1,4 @@
/** @type {import('../play.pokemonshowdown.com/src/client-main').PSConfig} */
var Config = Config || {};
/* version */ Config.version = "0";

View File

@ -10,6 +10,7 @@
*/
import { type AnimTable, BattleOtherAnims } from './battle-animations';
import { Config } from './client-main';
export const BattleMoveAnims: AnimTable = {
taunt: {

View File

@ -25,6 +25,7 @@ import {
} from "./battle-dex-data";
import type * as DexData from "./battle-dex-data";
import type { Teams } from "./battle-teams";
import { Config } from "./client-main";
export declare namespace Dex {
/* eslint-disable @typescript-eslint/no-shadow */
@ -290,9 +291,9 @@ export const Dex = new class implements ModdedDex {
}
if (avatar.includes('.') && window.Config?.server?.registered) {
// custom avatar served by the server
let protocol = (Config.server.port === 443) ? 'https' : 'http';
return protocol + '://' + Config.server.host + ':' + Config.server.port +
'/avatars/' + encodeURIComponent(avatar).replace(/%3F/g, '?');
const protocol = (Config.server.port === 443) ? 'https' : 'http';
const server = `${protocol}://${Config.server.host}:${Config.server.port}`;
return `${server}/avatars/${encodeURIComponent(avatar).replace(/%3F/g, '?')}`;
}
return Dex.resourcePrefix + 'sprites/trainers/' + Dex.sanitizeName(avatar || 'unknown') + '.png';
}
@ -888,7 +889,7 @@ export const Dex = new class implements ModdedDex {
getItemIcon(item: any) {
let num = 0;
if (typeof item === 'string' && exports.BattleItems) item = exports.BattleItems[toID(item)];
if (typeof item === 'string' && window.BattleItems) item = window.BattleItems[toID(item)];
if (item?.spritenum) num = item.spritenum;
let top = Math.floor(num / 16) * 24;
@ -922,8 +923,8 @@ export const Dex = new class implements ModdedDex {
getPokeballs() {
if (this.pokeballs) return this.pokeballs;
this.pokeballs = [];
if (!window.BattleItems) window.BattleItems = {};
for (const data of Object.values<AnyObject>(window.BattleItems)) {
window.BattleItems ||= {};
for (const data of Object.values(BattleItems)) {
if (!data.isPokeball) continue;
this.pokeballs.push(data.name);
}
@ -944,7 +945,7 @@ export class ModdedDex {
pokeballs: string[] | null = null;
constructor(modid: ID) {
this.modid = modid;
const gen = parseInt(modid.substr(3, 1), 10);
const gen = parseInt(modid.charAt(3), 10);
if (!modid.startsWith('gen') || !gen) throw new Error("Unsupported modid");
this.gen = gen;
}
@ -1132,8 +1133,8 @@ export class ModdedDex {
getPokeballs() {
if (this.pokeballs) return this.pokeballs;
this.pokeballs = [];
if (!window.BattleItems) window.BattleItems = {};
for (const data of Object.values<AnyObject>(window.BattleItems)) {
window.BattleItems ||= {};
for (const data of Object.values(BattleItems)) {
if (data.gen && data.gen > this.gen) continue;
if (!data.isPokeball) continue;
this.pokeballs.push(data.name);

View File

@ -19,6 +19,7 @@ import { Dex, toID, toRoomid, toUserid, type ID } from './battle-dex';
import { Teams } from './battle-teams';
import { BattleTextParser, type Args, type KWArgs } from './battle-text-parser';
import { Net } from './client-connection'; // optional
import { Config } from './client-main';
// Caja
declare const html4: any;
@ -298,7 +299,7 @@ export class BattleLog {
const body = args[2];
const roomid = this.scene?.battle.roomid;
if (!roomid) break;
app.rooms[roomid].notifyOnce(title, body, 'highlight');
window.app?.rooms[roomid].notifyOnce(title, body, 'highlight');
break;
case 'showteam': {
@ -1344,7 +1345,7 @@ export class BattleLog {
}
static interstice = (() => {
const whitelist: string[] = Config.whitelist;
const whitelist = Config.whitelist || [];
const patterns = whitelist.map(entry => new RegExp(
`^(https?:)?//([A-Za-z0-9-]*\\.)?${entry.replace(/\./g, '\\.')}(/.*)?`, 'i'
));

View File

@ -10,6 +10,7 @@
import preact from "../js/lib/preact";
import { Dex, toID, type ID } from "./battle-dex";
import type { DexSearch, SearchRow, SearchType } from "./battle-dex-search";
import { Config } from "./client-main";
export class PSSearchResults extends preact.Component<{
search: DexSearch, windowing?: number | null, hideFilters?: boolean, firstRow?: SearchRow,

View File

@ -1,4 +1,4 @@
import { PS } from "./client-main";
import { Config, PS } from "./client-main";
export class BattleBGM {
/**
@ -116,7 +116,7 @@ export const BattleSound = new class {
if (this.soundCache[url]) return this.soundCache[url];
try {
const sound = document.createElement('audio');
sound.src = 'https://' + Config.routes.client + '/' + url;
sound.src = `https://${Config.routes.client}/${url}`;
sound.volume = this.effectVolume / 100;
this.soundCache[url] = sound;
return sound;

View File

@ -5,7 +5,7 @@
* @license MIT
*/
import { PS } from "./client-main";
import { Config, PS } from "./client-main";
declare const SockJS: any;
declare const POKEMON_SHOWDOWN_TESTCLIENT_KEY: string | undefined;
@ -26,8 +26,8 @@ export class PSConnection {
}
connect() {
const server = PS.server;
const port = server.protocol === 'https' ? ':' + server.port : ':' + server.httpport;
const url = server.protocol + '://' + server.host + port + server.prefix;
const port = server.protocol === 'https' ? `:${server.port}` : `:${server.httpport || server.port}`;
const url = `${server.protocol}://${server.host}${port}${server.prefix}`;
try {
this.socket = new SockJS(url, [], { timeout: 5 * 60 * 1000 });
} catch {

View File

@ -13,7 +13,7 @@
* @license AGPLv3
*/
import { PS } from "./client-main";
import { Config, PS } from "./client-main";
declare const ColorThief: any;
/**********************************************************************

View File

@ -22,6 +22,38 @@ import { Teams } from './battle-teams';
declare const BattleTextAFD: any;
declare const BattleTextNotAFD: any;
/**********************************************************************
* Config
*********************************************************************/
export interface ServerInfo {
id: ID;
protocol: string;
host: string;
port: number;
httpport?: number;
altport?: number;
prefix: string;
afd?: boolean;
registered?: boolean;
}
export interface PSConfig {
server: ServerInfo;
defaultserver: ServerInfo;
routes: {
root: string,
client: string,
dex: string,
replays: string,
users: string,
teams: string,
};
customcolors: Record<string, string>;
whitelist?: string[];
testclient?: boolean;
}
export declare const Config: PSConfig;
/**********************************************************************
* Prefs
*********************************************************************/

View File

@ -3,42 +3,22 @@
// dex data
///////////
type AnyObject = { [k: string]: any };
declare const BattleText: { [id: string]: { [templateName: string]: string } };
declare const BattleFormats: { [id: string]: import('./panel-teamdropdown').FormatData };
declare const BattlePokedex: any;
declare const BattleMovedex: any;
declare const BattleAbilities: any;
declare const BattleItems: any;
declare const BattleAliases: any;
declare const BattleStatuses: any;
declare const BattlePokemonSprites: any;
declare const BattlePokemonSpritesBW: any;
declare const BattlePokedex: { [id: string]: AnyObject };
declare const BattleMovedex: { [id: string]: AnyObject };
declare const BattleAbilities: { [id: string]: AnyObject };
declare const BattleItems: { [id: string]: AnyObject };
declare const BattleAliases: { [id: string]: string };
declare const BattleStatuses: { [id: string]: AnyObject };
declare const BattlePokemonSprites: { [id: string]: AnyObject };
declare const BattlePokemonSpritesBW: { [id: string]: AnyObject };
declare const NonBattleGames: { [id: string]: string };
// PS globals
/////////////
declare const Config: any;
declare const Replays: any;
declare const exports: any;
type AnyObject = { [k: string]: any };
declare const app: { user: AnyObject, rooms: AnyObject, ignore?: AnyObject };
// Window
/////////
interface Window {
[k: string]: any;
}
// Temporary globals (exported from modules, used by non-module files)
// When creating new module files, these should all be commented out
// to make sure they're not being used globally in modules.
// declare var Battle: typeof import('./battle').Battle;
// type Battle = import('./battle').Battle;
// declare var BattleScene: typeof import('./battle-animations').BattleScene;
// type BattleScene = import('./battle-animations').BattleScene;
// declare var Pokemon: typeof import('./battle').Pokemon;
// type Pokemon = import('./battle').Pokemon;
// type ServerPokemon = import('./battle').ServerPokemon;
// declare var BattleLog: typeof import('./battle-log').BattleLog;
// type BattleLog = import('./battle-log').BattleLog;

View File

@ -6,7 +6,7 @@
*/
import preact from "../js/lib/preact";
import { PS, PSRoom, type RoomOptions, type RoomID } from "./client-main";
import { PS, PSRoom, type RoomOptions, type RoomID, Config } from "./client-main";
import { PSIcon, PSPanelWrapper, PSRoomPanel } from "./panels";
import { ChatLog, ChatRoom, ChatTextEntry, ChatUserList } from "./panel-chat";
import { FormatDropdown } from "./panel-mainmenu";

View File

@ -7,7 +7,7 @@
* @license MIT
*/
import { PS, PSRoom } from "./client-main";
import { Config, PS, PSRoom } from "./client-main";
import { Net } from "./client-connection";
import { PSPanelWrapper, PSRoomPanel } from "./panels";
import { BattleLog } from "./battle-log";

View File

@ -7,7 +7,7 @@
import preact from "../js/lib/preact";
import { PSLoginServer } from "./client-connection";
import { PS, PSRoom, type RoomID, type RoomOptions, type Team } from "./client-main";
import { Config, PS, PSRoom, type RoomID, type RoomOptions, type Team } from "./client-main";
import { PSIcon, PSPanelWrapper, PSRoomPanel } from "./panels";
import type { BattlesRoom } from "./panel-battle";
import type { ChatRoom } from "./panel-chat";

View File

@ -4,7 +4,9 @@ import type { ID } from "./battle-dex-data";
import { BattleLog } from "./battle-log";
import { PSLoginServer } from "./client-connection";
import { PSBackground } from "./client-core";
import { PSRoom, type RoomOptions, PS, type PSLoginState, type RoomID, type TimestampOptions } from "./client-main";
import {
PS, PSRoom, Config, type RoomOptions, type PSLoginState, type RoomID, type TimestampOptions,
} from "./client-main";
import { type BattleRoom } from "./panel-battle";
import { ChatUserList, type ChatRoom } from "./panel-chat";
import { PSRoomPanel, PSPanelWrapper, PSView } from "./panels";

View File

@ -10,7 +10,7 @@
*/
import preact from "../js/lib/preact";
import { PS, type PSRoom, type RoomID } from "./client-main";
import { Config, PS, type PSRoom, type RoomID } from "./client-main";
import { PSView } from "./panels";
import type { Battle } from "./battle";
import { BattleLog } from "./battle-log"; // optional

View File

@ -3,6 +3,7 @@
import preact from '../../play.pokemonshowdown.com/js/lib/preact';
import { Net, MiniTeam, type ServerTeam } from './utils';
import type { PageProps } from './teams';
import { Config } from '../../play.pokemonshowdown.com/src/client-main';
declare const toID: (val: any) => string;

View File

@ -3,6 +3,7 @@
import preact from '../../play.pokemonshowdown.com/js/lib/preact';
import { Net, type ServerTeam, MiniTeam } from './utils';
import type { PageProps } from './teams';
import { Config } from '../../play.pokemonshowdown.com/src/client-main';
declare const toID: (val: any) => string;
declare const BattleAliases: Record<string, string>;

View File

@ -6,6 +6,7 @@ import { BattleLog } from '../../play.pokemonshowdown.com/src/battle-log';
import type { PageProps } from './teams';
import { Dex } from '../../play.pokemonshowdown.com/src/battle-dex';
import { BattleStatNames } from '../../play.pokemonshowdown.com/src/battle-dex-data';
import { Config } from '../../play.pokemonshowdown.com/src/client-main';
declare const toID: (str: any) => string;
declare const BattleAliases: Record<string, string>;