mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
110 lines
4.1 KiB
JavaScript
110 lines
4.1 KiB
JavaScript
'use strict';
|
|
|
|
const crypto = require('crypto');
|
|
const fs = require('fs');
|
|
const http = require('http');
|
|
const net = require('net');
|
|
const os = require('os');
|
|
const path = require('path');
|
|
const { spawn } = require('child_process');
|
|
|
|
const SERVER_DIR = path.resolve(process.env.POKESERVER_DIR || path.join(__dirname, '..', '..', '..', 'pokeserver'));
|
|
const gifts = require(path.join(SERVER_DIR, 'gifts.js'));
|
|
|
|
function freePort() {
|
|
return new Promise((resolve, reject) => {
|
|
const s = net.createServer();
|
|
s.unref();
|
|
s.on('error', reject);
|
|
s.listen(0, '127.0.0.1', () => {
|
|
const port = s.address().port;
|
|
s.close(() => resolve(port));
|
|
});
|
|
});
|
|
}
|
|
|
|
function request(port, method, urlPath, body, password) {
|
|
return new Promise((resolve, reject) => {
|
|
const data = body === undefined ? null : Buffer.from(JSON.stringify(body), 'utf8');
|
|
const headers = {};
|
|
if (data) {
|
|
headers['Content-Type'] = 'application/json';
|
|
headers['Content-Length'] = data.length;
|
|
}
|
|
if (password) headers.Authorization = 'Basic ' + Buffer.from('admin:' + password).toString('base64');
|
|
const req = http.request({ host: '127.0.0.1', port, method, path: urlPath, headers }, (res) => {
|
|
const chunks = [];
|
|
res.on('data', (c) => chunks.push(c));
|
|
res.on('end', () => resolve({ code: res.statusCode, body: Buffer.concat(chunks).toString('utf8') }));
|
|
});
|
|
req.on('error', reject);
|
|
if (data) req.write(data);
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
async function waitUp(port) {
|
|
for (let i = 0; i < 100; i++) {
|
|
try {
|
|
const r = await request(port, 'GET', gifts.FEED_PATH);
|
|
if (r.code === 200) return r;
|
|
} catch (e) {
|
|
await new Promise((r) => setTimeout(r, 100));
|
|
}
|
|
}
|
|
throw new Error('server did not come up');
|
|
}
|
|
|
|
async function main() {
|
|
const dir = fs.mkdtempSync(path.join(process.env.G3GIFT_TMP || os.tmpdir(), 'g3gift-'));
|
|
const keyPath = path.join(dir, 'gift-test.pem');
|
|
const { privateKey } = crypto.generateKeyPairSync('ed25519');
|
|
fs.writeFileSync(keyPath, privateKey.export({ format: 'pem', type: 'pkcs8' }), { mode: 0o600 });
|
|
const pub = gifts.publicKeyHex(privateKey);
|
|
const password = crypto.randomBytes(8).toString('hex');
|
|
const httpPort = await freePort();
|
|
const relayPort = await freePort();
|
|
const child = spawn(process.execPath, [path.join(SERVER_DIR, 'server.js')], {
|
|
cwd: SERVER_DIR,
|
|
env: Object.assign({}, process.env, {
|
|
PORT: String(relayPort),
|
|
HTTP_PORT: String(httpPort),
|
|
DASHBOARD_PASSWORD: password,
|
|
GIFT_KEY_PATH: keyPath,
|
|
DATA_DIR: path.join(dir, 'data'),
|
|
CART_MIRROR_ENABLED: '0',
|
|
STATS_ENABLED: '0',
|
|
}),
|
|
stdio: ['ignore', 'ignore', 'inherit'],
|
|
});
|
|
const stop = () => {
|
|
try { child.kill('SIGTERM'); } catch (e) {}
|
|
process.exit(0);
|
|
};
|
|
process.on('SIGTERM', stop);
|
|
process.on('SIGINT', stop);
|
|
child.on('exit', (code) => {
|
|
process.stderr.write('g3gift_server: pokeserver exited ' + code + '\n');
|
|
process.exit(1);
|
|
});
|
|
|
|
await waitUp(httpPort);
|
|
const body = [];
|
|
for (let i = 0; i < 10; i++) body.push(['Welcome to the POKéMON', 'WIRELESS CLUB news.', 'New WONDER CARDS arrive', 'over WIRELESS COMMUNICATION.'][i] || '');
|
|
const set = {
|
|
cards: ['mystic_ticket', 'mew', 'stamp_card'].map((key) => ({ key, enabled: true, card: gifts.presetByKey(key).card })),
|
|
news: [{ key: 'club_news', enabled: true, news: { key: 'club_news', id: 1, sendType: 0, bgType: 1, titleText: 'WIRELESS CLUB NEWS', bodyText: body } }],
|
|
};
|
|
const saved = await request(httpPort, 'POST', '/visible/gifts', set, password);
|
|
if (saved.code !== 200) throw new Error('publish failed ' + saved.code + ' ' + saved.body);
|
|
const feed = JSON.parse((await request(httpPort, 'GET', gifts.FEED_PATH)).body);
|
|
if (!gifts.verifyFeed(feed, pub)) throw new Error('feed does not verify under the test key');
|
|
fs.writeFileSync(path.join(dir, 'ready'), httpPort + ' ' + pub + '\n');
|
|
process.stdout.write('READY ' + httpPort + ' ' + pub + ' ' + dir + '\n');
|
|
}
|
|
|
|
main().catch((err) => {
|
|
process.stderr.write('g3gift_server: ' + (err && err.stack || err) + '\n');
|
|
process.exit(1);
|
|
});
|