mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-03-22 01:35:31 -05:00
Convert index.js and team-validator-async.js to typescript (#5987)
This commit is contained in:
parent
cadc3fa05d
commit
ae28a960be
|
|
@ -62,7 +62,7 @@
|
|||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/cloud-env": "^0.2.0",
|
||||
"@types/node": "^12.7.11",
|
||||
"@types/node": "^12.12.6",
|
||||
"@types/node-static": "^0.7.3",
|
||||
"@types/nodemailer": "^6.2.1",
|
||||
"@types/sockjs": "^0.3.31",
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ if (!process.argv[2] || /^[0-9]+$/.test(process.argv[2])) {
|
|||
// $ ./pokemon-showdown 9000
|
||||
|
||||
if (!built) build();
|
||||
require('module')._load('./server', module, true);
|
||||
require('module')._load('./.server-dist', module, true);
|
||||
} else switch (process.argv[2]) {
|
||||
case 'help':
|
||||
case 'h':
|
||||
|
|
@ -87,7 +87,7 @@ if (!process.argv[2] || /^[0-9]+$/.test(process.argv[2])) {
|
|||
{
|
||||
process.argv[2] = process.argv[3];
|
||||
if (!built) build();
|
||||
require('module')._load('./server', module, true);
|
||||
require('module')._load('./.server-dist', module, true);
|
||||
break;
|
||||
}
|
||||
case 'generate-team':
|
||||
|
|
|
|||
|
|
@ -40,8 +40,6 @@
|
|||
* @license MIT
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
// NOTE: This file intentionally doesn't use too many modern JavaScript
|
||||
// features, so that it doesn't crash old versions of Node.js, so we
|
||||
// can successfully print the "We require Node.js 8+" message.
|
||||
|
|
@ -54,24 +52,29 @@ try {
|
|||
} catch (e) {
|
||||
throw new Error("We require Node.js version 10 or later; you're using " + process.version);
|
||||
}
|
||||
|
||||
try {
|
||||
require.resolve('../.sim-dist/index');
|
||||
} catch (e) {
|
||||
throw new Error("Dependencies are unmet; run `node build` before launching Pokemon Showdown again.");
|
||||
}
|
||||
|
||||
const FS = require('../.lib-dist/fs').FS;
|
||||
import {FS} from '../lib/fs';
|
||||
|
||||
/*********************************************************
|
||||
* Load configuration
|
||||
*********************************************************/
|
||||
|
||||
const ConfigLoader = require('../.server-dist/config-loader');
|
||||
// global becomes much easier to use if declared as an object
|
||||
declare const global: any;
|
||||
|
||||
import * as ConfigLoader from './config-loader';
|
||||
global.Config = ConfigLoader.Config;
|
||||
|
||||
global.Monitor = require('../.server-dist/monitor').Monitor;
|
||||
import {Monitor} from './monitor';
|
||||
global.Monitor = Monitor;
|
||||
global.__version = {head: ''};
|
||||
Monitor.version().then(function (hash) {
|
||||
void Monitor.version().then((hash: any) => {
|
||||
global.__version.tree = hash;
|
||||
});
|
||||
|
||||
|
|
@ -91,35 +94,48 @@ if (Config.watchconfig) {
|
|||
* Set up most of our globals
|
||||
*********************************************************/
|
||||
|
||||
global.Dex = require('../.sim-dist/dex').Dex;
|
||||
global.toID = Dex.getId;
|
||||
import {Dex} from '../sim/dex';
|
||||
global.Dex = Dex;
|
||||
global.toId = Dex.getId;
|
||||
|
||||
global.LoginServer = require('../.server-dist/loginserver').LoginServer;
|
||||
import {LoginServer} from './loginserver';
|
||||
global.LoginServer = LoginServer;
|
||||
|
||||
global.Ladders = require('../.server-dist/ladders').Ladders;
|
||||
import {Ladders} from './ladders';
|
||||
global.Ladders = Ladders;
|
||||
|
||||
global.Chat = require('../.server-dist/chat').Chat;
|
||||
import {Chat} from './chat';
|
||||
global.Chat = Chat;
|
||||
|
||||
global.Users = require('../.server-dist/users').Users;
|
||||
import {Users} from './users';
|
||||
global.Users = Users;
|
||||
|
||||
global.Punishments = require('../.server-dist/punishments').Punishments;
|
||||
import {Punishments} from './punishments';
|
||||
global.Punishments = Punishments;
|
||||
|
||||
global.Rooms = require('../.server-dist/rooms').Rooms;
|
||||
import {Rooms} from './rooms';
|
||||
global.Rooms = Rooms;
|
||||
|
||||
global.Verifier = require('../.server-dist/verifier');
|
||||
import * as Verifier from './verifier';
|
||||
global.Verifier = Verifier;
|
||||
Verifier.PM.spawn();
|
||||
|
||||
global.Tournaments = require('../.server-dist/tournaments').Tournaments;
|
||||
import {Tournaments} from './tournaments';
|
||||
global.Tournaments = Tournaments;
|
||||
|
||||
global.IPTools = require('../.server-dist/ip-tools').IPTools;
|
||||
IPTools.loadDatacenters();
|
||||
import {IPTools} from './ip-tools';
|
||||
global.IPTools = IPTools;
|
||||
void IPTools.loadDatacenters();
|
||||
|
||||
if (Config.crashguard) {
|
||||
// graceful crash - allow current battles to finish before restarting
|
||||
process.on('uncaughtException', err => {
|
||||
process.on('uncaughtException', (err: Error) => {
|
||||
Monitor.crashlog(err, 'The main process');
|
||||
});
|
||||
process.on('unhandledRejection', err => {
|
||||
|
||||
// Typescript doesn't like this call
|
||||
// @ts-ignore
|
||||
process.on('unhandledRejection', (err: Error, promise: Promise<any>) => {
|
||||
Monitor.crashlog(err, 'A main process Promise');
|
||||
});
|
||||
}
|
||||
|
|
@ -128,11 +144,12 @@ if (Config.crashguard) {
|
|||
* Start networking processes to be connected to
|
||||
*********************************************************/
|
||||
|
||||
global.Sockets = require('./sockets');
|
||||
import * as Sockets from '../server/sockets';
|
||||
global.Sockets = Sockets;
|
||||
|
||||
exports.listen = function (port, bindAddress, workerCount) {
|
||||
export function listen(port: number, bindAddress: string, workerCount: number) {
|
||||
Sockets.listen(port, bindAddress, workerCount);
|
||||
};
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
// Launch the server directly when app.js is the main module. Otherwise,
|
||||
|
|
@ -147,11 +164,14 @@ if (require.main === module) {
|
|||
* Set up our last global
|
||||
*********************************************************/
|
||||
|
||||
global.TeamValidatorAsync = require('./team-validator-async');
|
||||
import * as TeamValidatorAsync from './team-validator-async';
|
||||
global.TeamValidatorAsync = TeamValidatorAsync;
|
||||
TeamValidatorAsync.PM.spawn();
|
||||
|
||||
/*********************************************************
|
||||
* Start up the REPL server
|
||||
*********************************************************/
|
||||
|
||||
require('../.lib-dist/repl').Repl.start('app', cmd => eval(cmd));
|
||||
import {Repl} from '../lib/repl';
|
||||
// tslint:disable-next-line: no-eval
|
||||
Repl.start('app', cmd => eval(cmd));
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
/**
|
||||
* Team Validator
|
||||
* Pokemon Showdown - http://pokemonshowdown.com/
|
||||
*
|
||||
* Spawns a child process to validate teams.
|
||||
*
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/** @type {typeof import('../lib/crashlogger').crashlogger} */
|
||||
let crashlogger = require(/** @type {any} */('../.lib-dist/crashlogger')).crashlogger;
|
||||
|
||||
class TeamValidatorAsync {
|
||||
/**
|
||||
* @param {string} format
|
||||
*/
|
||||
constructor(format) {
|
||||
this.format = Dex.getFormat(format);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} team
|
||||
* @param {boolean} [removeNicknames]
|
||||
*/
|
||||
validateTeam(team, removeNicknames = false) {
|
||||
let formatid = this.format.id;
|
||||
if (this.format.customRules) formatid += '@@@' + this.format.customRules.join(',');
|
||||
return PM.query({formatid, removeNicknames, team});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} format
|
||||
*/
|
||||
static get(format) {
|
||||
return new TeamValidatorAsync(format);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
* Process manager
|
||||
*********************************************************/
|
||||
|
||||
/** @type {typeof import('../lib/process-manager').QueryProcessManager} */
|
||||
const QueryProcessManager = require(/** @type {any} */('../.lib-dist/process-manager')).QueryProcessManager;
|
||||
|
||||
/** @type {import('../lib/process-manager').QueryProcessManager} */
|
||||
// @ts-ignore
|
||||
const PM = new QueryProcessManager(module, async message => {
|
||||
let {formatid, removeNicknames, team} = message;
|
||||
let parsedTeam = Dex.fastUnpackTeam(team);
|
||||
|
||||
let problems;
|
||||
try {
|
||||
problems = TeamValidator.get(formatid).validateTeam(parsedTeam, removeNicknames);
|
||||
} catch (err) {
|
||||
crashlogger(err, 'A team validation', {
|
||||
formatid: formatid,
|
||||
team: team,
|
||||
});
|
||||
problems = [`Your team crashed the team validator. We've been automatically notified and will fix this crash, but you should use a different team for now.`];
|
||||
}
|
||||
|
||||
if (problems && problems.length) {
|
||||
return '0' + problems.join('\n');
|
||||
}
|
||||
let packedTeam = Dex.packTeam(parsedTeam);
|
||||
// console.log('FROM: ' + message.substr(pipeIndex2 + 1));
|
||||
// console.log('TO: ' + packedTeam);
|
||||
return '1' + packedTeam;
|
||||
});
|
||||
|
||||
if (!PM.isParentProcess) {
|
||||
// This is a child process!
|
||||
global.Config = require(/** @type {any} */('../.server-dist/config-loader')).Config;
|
||||
|
||||
global.TeamValidator = require(/** @type {any} */ ('../.sim-dist/team-validator')).TeamValidator;
|
||||
// @ts-ignore ???
|
||||
global.Monitor = {
|
||||
/**
|
||||
* @param {Error} error
|
||||
* @param {string} source
|
||||
* @param {{}?} details
|
||||
*/
|
||||
crashlog(error, source = 'A team validator process', details = null) {
|
||||
const repr = JSON.stringify([error.name, error.message, source, details]);
|
||||
// @ts-ignore
|
||||
process.send(`THROW\n@!!@${repr}\n${error.stack}`);
|
||||
},
|
||||
};
|
||||
|
||||
if (Config.crashguard) {
|
||||
process.on('uncaughtException', err => {
|
||||
Monitor.crashlog(err, `A team validator process`);
|
||||
});
|
||||
process.on('unhandledRejection', err => {
|
||||
if (err instanceof Error) {
|
||||
Monitor.crashlog(err, 'A team validator process Promise');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
global.Dex = require(/** @type {any} */ ('../.sim-dist/dex')).Dex.includeData();
|
||||
global.toID = Dex.getId;
|
||||
global.Chat = require(/** @type {any} */('../.server-dist/chat')).Chat;
|
||||
|
||||
/** @type {typeof import('../lib/repl').Repl} */
|
||||
const Repl = require(/** @type {any} */('../.lib-dist/repl')).Repl;
|
||||
Repl.start(`team-validator-${process.pid}`, cmd => eval(cmd));
|
||||
} else {
|
||||
PM.spawn(global.Config ? Config.validatorprocesses : 1);
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
* Exports
|
||||
*********************************************************/
|
||||
|
||||
module.exports = {get: TeamValidatorAsync.get, TeamValidatorAsync, PM};
|
||||
105
server/team-validator-async.ts
Normal file
105
server/team-validator-async.ts
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
* Team Validator
|
||||
* Pokemon Showdown - http://pokemonshowdown.com/
|
||||
*
|
||||
* Spawns a child process to validate teams.
|
||||
*
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import {crashlogger} from '../lib/crashlogger';
|
||||
|
||||
declare var global: any;
|
||||
|
||||
export class TeamValidatorAsync {
|
||||
format: Format;
|
||||
|
||||
constructor(format: string) {
|
||||
this.format = Dex.getFormat(format);
|
||||
}
|
||||
|
||||
validateTeam(team: string, removeNicknames: boolean = false) {
|
||||
let formatid = this.format.id;
|
||||
if (this.format.customRules) formatid += '@@@' + this.format.customRules.join(',');
|
||||
return PM.query({formatid, removeNicknames, team});
|
||||
}
|
||||
|
||||
static get(format: string) {
|
||||
return new TeamValidatorAsync(format);
|
||||
}
|
||||
}
|
||||
|
||||
export const get = TeamValidatorAsync.get;
|
||||
|
||||
/*********************************************************
|
||||
* Process manager
|
||||
*********************************************************/
|
||||
|
||||
import {QueryProcessManager} from '../lib/process-manager';
|
||||
|
||||
export const PM = new QueryProcessManager(module, async message => {
|
||||
const {formatid, removeNicknames, team} = message;
|
||||
const parsedTeam = Dex.fastUnpackTeam(team);
|
||||
|
||||
let problems;
|
||||
try {
|
||||
problems = TeamValidator.get(formatid).validateTeam(parsedTeam, removeNicknames);
|
||||
} catch (err) {
|
||||
crashlogger(err, 'A team validation', {
|
||||
formatid,
|
||||
team,
|
||||
});
|
||||
problems = [`Your team crashed the team validator. We've been automatically notified and will fix this crash, but you should use a different team for now.`];
|
||||
}
|
||||
|
||||
if (problems && problems.length) {
|
||||
return '0' + problems.join('\n');
|
||||
}
|
||||
const packedTeam = Dex.packTeam(parsedTeam);
|
||||
// console.log('FROM: ' + message.substr(pipeIndex2 + 1));
|
||||
// console.log('TO: ' + packedTeam);
|
||||
return '1' + packedTeam;
|
||||
});
|
||||
|
||||
import {Repl} from '../lib/repl';
|
||||
import {Dex as importedDex} from '../sim/dex';
|
||||
import {TeamValidator} from '../sim/team-validator';
|
||||
import {Chat} from './chat';
|
||||
import {Config} from './config-loader';
|
||||
|
||||
if (!PM.isParentProcess) {
|
||||
// This is a child process!
|
||||
global.Config = Config;
|
||||
|
||||
global.TeamValidator = TeamValidator;
|
||||
|
||||
// @ts-ignore ???
|
||||
global.Monitor = {
|
||||
crashlog(error: Error, source: string = 'A team validator process', details: any = null) {
|
||||
const repr = JSON.stringify([error.name, error.message, source, details]);
|
||||
// @ts-ignore
|
||||
process.send(`THROW\n@!!@${repr}\n${error.stack}`);
|
||||
},
|
||||
};
|
||||
|
||||
if (Config.crashguard) {
|
||||
process.on('uncaughtException', (err: Error) => {
|
||||
Monitor.crashlog(err, `A team validator process`);
|
||||
});
|
||||
// Typescript doesn't like this call
|
||||
// @ts-ignore
|
||||
process.on('unhandledRejection', (err: Error, promise: Promise) => {
|
||||
if (err instanceof Error) {
|
||||
Monitor.crashlog(err, 'A team validator process Promise');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
global.Dex = importedDex.includeData();
|
||||
global.toId = Dex.getId;
|
||||
|
||||
// tslint:disable-next-line: no-eval
|
||||
Repl.start(`team-validator-${process.pid}`, cmd => eval(cmd));
|
||||
} else {
|
||||
PM.spawn(global.Config ? Config.validatorprocesses : 1);
|
||||
}
|
||||
|
|
@ -43,7 +43,8 @@ before('initialization', function () {
|
|||
require('../.lib-dist/repl').Repl.start = noop;
|
||||
|
||||
// Start the server.
|
||||
require('../server');
|
||||
// NOTE: This used "server" before when we needed ".server-dist"
|
||||
require('../.server-dist');
|
||||
|
||||
LoginServer.disabled = true;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user