mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-05-18 19:28:35 -05:00
simulator.js doesn't actually contain the simulator, but is really just an implementation of battles in the RoomGame interface. Renames: `Simulator.Battle` -> `Rooms.RoomBattle` `Simulator.BattlePlayer` -> `Rooms.RoomBattlePlayer` `Simulator.SimulatorManager` -> `Rooms.SimulatorManager` `Simulator.SimulatorProcess` -> `Rooms.SimulatorProcess` `Simulator.create` -> no longer exists, use `new Rooms.RoomBattle(...)`
178 lines
5.1 KiB
JavaScript
178 lines
5.1 KiB
JavaScript
/**
|
|
* Main file
|
|
* Pokemon Showdown - http://pokemonshowdown.com/
|
|
*
|
|
* This is the main Pokemon Showdown app, and the file you should be
|
|
* running to start Pokemon Showdown if you're using it normally.
|
|
*
|
|
* This file sets up our SockJS server, which handles communication
|
|
* between users and your server, and also sets up globals. You can
|
|
* see details in their corresponding files, but here's an overview:
|
|
*
|
|
* Users - from users.js
|
|
*
|
|
* Most of the communication with users happens in users.js, we just
|
|
* forward messages between the sockets.js and users.js.
|
|
*
|
|
* Rooms - from rooms.js
|
|
*
|
|
* Every chat room and battle is a room, and what they do is done in
|
|
* rooms.js. There's also a global room which every user is in, and
|
|
* handles miscellaneous things like welcoming the user.
|
|
*
|
|
* Tools - from tools.js
|
|
*
|
|
* Handles getting data about Pokemon, items, etc.
|
|
*
|
|
* Ladders - from ladders.js and ladders-remote.js
|
|
*
|
|
* Handles Elo rating tracking for players.
|
|
*
|
|
* Chat - from chat.js
|
|
*
|
|
* Handles chat and parses chat commands like /me and /ban
|
|
*
|
|
* Sockets - from sockets.js
|
|
*
|
|
* Used to abstract out network connections. sockets.js handles
|
|
* the actual server and connection set-up.
|
|
*
|
|
* @license MIT license
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
/*********************************************************
|
|
* Make sure we have everything set up correctly
|
|
*********************************************************/
|
|
|
|
// Make sure our dependencies are available, and install them if they
|
|
// aren't
|
|
|
|
try {
|
|
require.resolve('sockjs');
|
|
} catch (e) {
|
|
if (require.main !== module) throw new Error("Dependencies unmet");
|
|
|
|
let command = 'npm install --production';
|
|
console.log('Installing dependencies: `' + command + '`...');
|
|
require('child_process').spawnSync('sh', ['-c', command], {stdio: 'inherit'});
|
|
}
|
|
|
|
/*********************************************************
|
|
* Load configuration
|
|
*********************************************************/
|
|
|
|
try {
|
|
require.resolve('./config/config');
|
|
} catch (err) {
|
|
if (err.code !== 'MODULE_NOT_FOUND') throw err; // should never happen
|
|
|
|
// Copy it over synchronously from config-example.js since it's needed before we can start the server
|
|
console.log("config.js doesn't exist - creating one with default settings...");
|
|
fs.writeFileSync(path.resolve(__dirname, 'config/config.js'),
|
|
fs.readFileSync(path.resolve(__dirname, 'config/config-example.js'))
|
|
);
|
|
} finally {
|
|
global.Config = require('./config/config');
|
|
}
|
|
|
|
if (Config.watchconfig) {
|
|
let configPath = require.resolve('./config/config');
|
|
fs.watchFile(configPath, (curr, prev) => {
|
|
if (curr.mtime <= prev.mtime) return;
|
|
try {
|
|
delete require.cache[configPath];
|
|
global.Config = require('./config/config');
|
|
if (global.Users) Users.cacheGroupData();
|
|
console.log('Reloaded config/config.js');
|
|
} catch (e) {
|
|
console.log('Error reloading config/config.js: ' + e.stack);
|
|
}
|
|
});
|
|
}
|
|
|
|
/*********************************************************
|
|
* Set up most of our globals
|
|
*********************************************************/
|
|
|
|
global.Monitor = require('./monitor');
|
|
|
|
global.Tools = require('./tools');
|
|
global.toId = Tools.getId;
|
|
|
|
global.LoginServer = require('./loginserver');
|
|
|
|
global.Ladders = require(Config.remoteladder ? './ladders-remote' : './ladders');
|
|
|
|
global.Users = require('./users');
|
|
|
|
global.Punishments = require('./punishments');
|
|
|
|
global.Chat = require('./chat');
|
|
|
|
global.Rooms = require('./rooms');
|
|
|
|
delete process.send; // in case we're a child process
|
|
global.Verifier = require('./verifier');
|
|
Verifier.PM.spawn();
|
|
|
|
global.Tournaments = require('./tournaments');
|
|
|
|
global.Dnsbl = require('./dnsbl');
|
|
Dnsbl.loadDatacenters();
|
|
|
|
if (Config.crashguard) {
|
|
// graceful crash - allow current battles to finish before restarting
|
|
process.on('uncaughtException', err => {
|
|
let crashType = require('./crashlogger')(err, 'The main process');
|
|
if (crashType === 'lockdown') {
|
|
Rooms.global.startLockdown(err);
|
|
} else {
|
|
Rooms.global.reportCrash(err);
|
|
}
|
|
});
|
|
process.on('unhandledRejection', err => {
|
|
throw err;
|
|
});
|
|
}
|
|
|
|
/*********************************************************
|
|
* Start networking processes to be connected to
|
|
*********************************************************/
|
|
|
|
global.Sockets = require('./sockets');
|
|
|
|
exports.listen = function (port, bindAddress, workerCount) {
|
|
Sockets.listen(port, bindAddress, workerCount);
|
|
};
|
|
|
|
if (require.main === module) {
|
|
// if running with node app.js, set up the server directly
|
|
// (otherwise, wait for app.listen())
|
|
let port;
|
|
if (process.argv[2]) {
|
|
port = parseInt(process.argv[2]); // eslint-disable-line radix
|
|
}
|
|
Sockets.listen(port);
|
|
}
|
|
|
|
/*********************************************************
|
|
* Set up our last global
|
|
*********************************************************/
|
|
|
|
// Generate and cache the format list.
|
|
Tools.includeFormats();
|
|
|
|
global.TeamValidator = require('./team-validator');
|
|
TeamValidator.PM.spawn();
|
|
|
|
/*********************************************************
|
|
* Start up the REPL server
|
|
*********************************************************/
|
|
|
|
require('./repl').start('app', cmd => eval(cmd));
|