-
Notifications
You must be signed in to change notification settings - Fork 0
/
pokemon-showdown
197 lines (181 loc) · 6.24 KB
/
pokemon-showdown
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#!/bin/sh
true /*
# Shell script will interpret above as a command and execute everything after
# it, while JavaScript will interpret this as beginning of a comment and skip
# shell script contents.
#
# As shell script parses lines only when they are needed, nothing after exit 1
# can possibly cause a syntax error.
if nodepath="$(command -v node || command -v nodejs)"; then
exec "$nodepath" "--trace-warnings" "$0" "$@"
fi
echo "We require Node.js version 8 or later; Node.js not found"
exit 1
*/;
const child_process = require('child_process');
const fs = require('fs');
const path = require('path');
// # Make sure we're Node 8+
try {
eval('{ let a = async () => {}; }');
} catch (e) {
console.log("We require Node.js version 8 or later; you're using " + process.version);
process.exit(1);
}
// # Make sure our dependencies are available, and install them if they
// # aren't
try {
require.resolve('sockjs');
} catch (e) {
console.log('Installing dependencies...');
child_process.execSync('npm install --production', {stdio: 'inherit'});
}
// # Make sure config.js exists. If not, copy it over synchronously from
// # config-example.js, since it's needed before we can start the server
try {
require.resolve('./config/config');
} catch (err) {
if (err.code !== 'MODULE_NOT_FOUND') throw err; // should never happen
console.log('config.js does not exist. Creating one with default settings...');
fs.writeFileSync(
path.resolve(__dirname, 'config/config.js'),
fs.readFileSync(path.resolve(__dirname, 'config/config-example.js'))
);
}
if (!process.argv[2] || /^[0-9]+$/.test(process.argv[2])) {
// Start the server. We manually load app.js so it can be configured to run as
// the main module, rather than this file being considered the main module.
// This ensures any dependencies that were just installed can be found when
// running on Windows and avoids any other potential side effects of the main
// module not being app.js like it is assumed to be.
//
// The port the server should host on can be passed using the second argument
// when launching with this file the same way app.js normally allows, e.g. to
// host on port 9000:
// $ ./pokemon-showdown 9000
require('module')._load('./app', module, true);
} else switch (process.argv[2]) {
case 'help':
case 'h':
case '?':
case '-h':
case '--help':
case '-?':
console.log('pokemon-showdown [PORT]');
console.log('');
console.log(' Starts a PS server on the specified port');
console.log(' (Defaults to the port setting in config/config.js)');
console.log(' (The port setting in config/config.js defaults to 8000)');
console.log('');
console.log('pokemon-showdown generate-team [FORMAT-ID [RANDOM-SEED]]');
console.log('');
console.log(' Generates a random team, and writes it to stdout in packed team format');
console.log(' (Format defaults to "gen7randombattle")');
console.log('');
console.log('pokemon-showdown validate-team [FORMAT-ID]');
console.log('');
console.log(' Reads a team from stdin, and validates it');
console.log(' If valid: exits with code 0');
console.log(' If invalid: writes errors to stderr, exits with code 1');
console.log('');
console.log('pokemon-showdown simulate-battle');
console.log('');
console.log(' Simulates a battle, taking input to stdin and writing output to stdout');
console.log(' Protocol is documented in ./sim/README.md');
console.log('');
console.log('pokemon-showdown unpack-team');
console.log('');
console.log(' Reads a team from stdin, writes the unpacked JSON to stdout');
console.log('');
console.log('pokemon-showdown pack-team');
console.log('');
console.log(' Reads a JSON team from stdin, writes the packed team to stdout');
console.log(' NOTE for all team-processing functions: We can only handle JSON teams');
console.log(' and packed teams; the PS server is incapable of processing exported');
console.log(' teams.');
console.log('');
console.log('pokemon-showdown help');
console.log('');
console.log(' Displays this reference');
break;
case 'generate-team':
{
const Dex = require('./sim/dex');
global.toId = Dex.getId;
const seed = process.argv[4] ? process.argv[4].split(',').map(Number) : undefined;
console.log(Dex.packTeam(Dex.generateTeam(process.argv[3], seed)));
}
break;
case 'validate-team':
{
const Dex = require('./sim/dex');
const TeamValidator = require('./sim/team-validator');
const validator = TeamValidator(process.argv[3]);
const Streams = require('./lib/streams');
const stdin = new Streams.ReadStream(process.stdin);
stdin.readLine().then(function (textTeam) {
try {
const team = Dex.fastUnpackTeam(textTeam);
const result = validator.validateTeam(team);
if (result) {
console.error(result.join('\n'));
process.exit(1);
}
process.exit(0);
} catch (e) {
console.error(e);
process.exit(1);
}
});
}
break;
case 'simulate-battle':
{
const BattleTextStream = require('./sim/battle-stream').BattleTextStream;
const Streams = require('./lib/streams');
const stdin = new Streams.ReadStream(process.stdin);
const stdout = new Streams.WriteStream(process.stdout);
const battleStream = new BattleTextStream();
stdin.pipeTo(battleStream);
battleStream.pipeTo(stdout);
}
break;
case 'unpack-team':
{
const Dex = require('./sim/dex');
const Streams = require('./lib/streams');
const stdin = new Streams.ReadStream(process.stdin);
stdin.readLine().then(function (packedTeam) {
try {
const unpackedTeam = Dex.fastUnpackTeam(packedTeam);
console.log(JSON.stringify(unpackedTeam));
process.exit(0);
} catch (e) {
console.error(e);
process.exit(1);
}
});
}
break;
case 'pack-team':
{
const Dex = require('./sim/dex');
const Streams = require('./lib/streams');
const stdin = new Streams.ReadStream(process.stdin);
stdin.readLine().then(function (unpackedTeam) {
try {
const packedTeam = Dex.packTeam(JSON.parse(unpackedTeam));
console.log(packedTeam);
process.exit(0);
} catch (e) {
console.error(e);
process.exit(1);
}
});
}
break;
default:
console.error('Unrecognized command: ' + process.argv[2]);
console.error('Use `pokemon-showdown help` for help');
process.exit(1);
}