Support configurable URLs (#1543)

This commit is contained in:
Annika 2020-07-21 15:27:21 -07:00 committed by GitHub
parent 3f169151d3
commit 367ed82e56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 285 additions and 214 deletions

2
.gitignore vendored
View File

@ -4,6 +4,7 @@
/index.php
/index.html
/preactalpha.html
/crossprotocol.html
/data/*
node_modules/
eslint-cache/
@ -39,6 +40,7 @@ package-lock.json
/js/panel-teambuilder-team.js
/js/panel-teamdropdown.js
/js/panel-battle.js
/js/replay-embed.js
/replays/caches/
/replays/replay-config.inc.php

View File

@ -9,9 +9,11 @@ License: GPLv2 or later
error_reporting(E_ALL);
include_once __DIR__ . '/config/config.inc.php';
if (@$_GET['act'] === 'dlteam') {
header("Content-Type: text/plain; charset=utf-8");
if (substr(@$_SERVER['HTTP_REFERER'], 0, 32) !== 'https://play.pokemonshowdown.com') {
if (substr(@$_SERVER['HTTP_REFERER'], 0, 32) !== 'https://' . $psconfig['routes']['client']) {
// since this is only to support Chrome on HTTPS, we can get away with a very specific referer check
die("access denied");
}
@ -26,9 +28,9 @@ if (preg_match('/^http\\:\\/\\/[a-z0-9]+\\.psim\\.us\\//', $_SERVER['HTTP_REFERE
}
// header("X-Debug: " . @$_SERVER['HTTP_REFERER']);
include_once 'lib/ntbb-session.lib.php';
include_once '../pokemonshowdown.com/config/servers.inc.php';
include_once 'lib/dispatcher.lib.php';
require_once __DIR__ . '/lib/ntbb-session.lib.php';
include_once __DIR__ . '/../pokemonshowdown.com/config/servers.inc.php';
include_once __DIR__ . '/lib/dispatcher.lib.php';
$dispatcher = new ActionDispatcher(array(
new DefaultActionHandler(),

View File

@ -8,18 +8,18 @@ const child_process = require("child_process");
const rootDir = path.resolve(__dirname, '..');
process.chdir(rootDir);
if (!fs.existsSync('data/Pokemon-Showdown')) {
if (!fs.existsSync('data/pokemon-showdown')) {
child_process.execSync('git clone https://github.com/smogon/pokemon-showdown.git', {
cwd: 'data',
});
}
process.stdout.write("Syncing data from Git repository... ");
child_process.execSync('git pull', {cwd: 'data/Pokemon-Showdown'});
child_process.execSync('npm run build', {cwd: 'data/Pokemon-Showdown'});
child_process.execSync('git pull', {cwd: 'data/pokemon-showdown'});
child_process.execSync('npm run build', {cwd: 'data/pokemon-showdown'});
console.log("DONE");
const Dex = require('../data/Pokemon-Showdown/.sim-dist/dex').Dex;
const Dex = require('../data/pokemon-showdown/.sim-dist/dex').Dex;
const toID = Dex.getId;
process.stdout.write("Loading gen 6 data... ");
Dex.includeData();
@ -985,7 +985,7 @@ console.log("DONE");
process.stdout.write("Building `data/pokedex.js`... ");
{
const Pokedex = requireNoCache('../data/Pokemon-Showdown/.data-dist/pokedex.js').BattlePokedex;
const Pokedex = requireNoCache('../data/pokemon-showdown/.data-dist/pokedex.js').BattlePokedex;
for (const id in Pokedex) {
const entry = Pokedex[id];
if (Dex.data.FormatsData[id]) {
@ -1011,7 +1011,7 @@ console.log("DONE");
process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.js`...");
{
const Movedex = requireNoCache('../data/Pokemon-Showdown/.data-dist/moves.js').BattleMovedex;
const Movedex = requireNoCache('../data/pokemon-showdown/.data-dist/moves.js').BattleMovedex;
const buf = 'exports.BattleMovedex = ' + es3stringify(Movedex) + ';';
fs.writeFileSync('data/moves.js', buf);
}
@ -1021,7 +1021,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j
*********************************************************/
{
const Items = requireNoCache('../data/Pokemon-Showdown/.data-dist/items.js').BattleItems;
const Items = requireNoCache('../data/pokemon-showdown/.data-dist/items.js').BattleItems;
const buf = 'exports.BattleItems = ' + es3stringify(Items) + ';';
fs.writeFileSync('data/items.js', buf);
}
@ -1031,7 +1031,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j
*********************************************************/
{
const Abilities = requireNoCache('../data/Pokemon-Showdown/.data-dist/abilities.js').BattleAbilities;
const Abilities = requireNoCache('../data/pokemon-showdown/.data-dist/abilities.js').BattleAbilities;
const buf = 'exports.BattleAbilities = ' + es3stringify(Abilities) + ';';
fs.writeFileSync('data/abilities.js', buf);
}
@ -1041,7 +1041,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j
*********************************************************/
{
const TypeChart = requireNoCache('../data/Pokemon-Showdown/.data-dist/typechart.js').BattleTypeChart;
const TypeChart = requireNoCache('../data/pokemon-showdown/.data-dist/typechart.js').BattleTypeChart;
const buf = 'exports.BattleTypeChart = ' + es3stringify(TypeChart) + ';';
fs.writeFileSync('data/typechart.js', buf);
}
@ -1051,7 +1051,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j
*********************************************************/
{
const Aliases = requireNoCache('../data/Pokemon-Showdown/.data-dist/aliases.js').BattleAliases;
const Aliases = requireNoCache('../data/pokemon-showdown/.data-dist/aliases.js').BattleAliases;
const buf = 'exports.BattleAliases = ' + es3stringify(Aliases) + ';';
fs.writeFileSync('data/aliases.js', buf);
}
@ -1061,7 +1061,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j
*********************************************************/
{
const FormatsData = requireNoCache('../data/Pokemon-Showdown/.data-dist/formats-data.js').BattleFormatsData;
const FormatsData = requireNoCache('../data/pokemon-showdown/.data-dist/formats-data.js').BattleFormatsData;
const buf = 'exports.BattleFormatsData = ' + es3stringify(FormatsData) + ';';
fs.writeFileSync('data/formats-data.js', buf);
}
@ -1071,7 +1071,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j
*********************************************************/
{
const Formats = requireNoCache('../data/Pokemon-Showdown/.config-dist/formats.js').Formats;
const Formats = requireNoCache('../data/pokemon-showdown/.config-dist/formats.js').Formats;
const buf = 'exports.Formats = ' + es3stringify(Formats) + ';';
fs.writeFileSync('data/formats.js', buf);
}
@ -1081,7 +1081,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j
*********************************************************/
{
const Learnsets = requireNoCache('../data/Pokemon-Showdown/.data-dist/learnsets.js').BattleLearnsets;
const Learnsets = requireNoCache('../data/pokemon-showdown/.data-dist/learnsets.js').BattleLearnsets;
const buf = 'exports.BattleLearnsets = ' + es3stringify(Learnsets) + ';';
fs.writeFileSync('data/learnsets.js', buf);
}

View File

@ -18,7 +18,7 @@ const thisFile = __filename;
const thisDir = __dirname;
const rootDir = path.resolve(thisDir, '..');
const Dex = require('../data/Pokemon-Showdown/.sim-dist/dex').Dex;
const Dex = require('../data/pokemon-showdown/.sim-dist/dex').Dex;
const toID = Dex.getId;
function updateLearnsets(callback) {

View File

@ -6,7 +6,7 @@ const path = require("path");
process.chdir(path.resolve(__dirname, '..'));
const imageSize = require('image-size');
const Dex = require('./../data/Pokemon-Showdown/.sim-dist/dex').Dex;
const Dex = require('./../data/pokemon-showdown/.sim-dist/dex').Dex;
const toID = Dex.getId;
process.stdout.write("Updating animated sprite dimensions... ");

View File

@ -17,6 +17,13 @@ const thisDir = __dirname;
const rootDir = path.resolve(thisDir, '..');
process.chdir(rootDir);
const AUTOCONFIG_START = '/*** Begin automatically generated configuration ***/';
const AUTOCONFIG_END = '/*** End automatically generated configuration ***/';
function escapeRegex(string) {
return string.replace(/[\/\*\.]/g, '\\$&');
}
/*********************************************************
* Update version number
*********************************************************/
@ -36,9 +43,27 @@ try {
version += ` (${head.slice(0, 8)}${head !== origin ? `/${origin.slice(0, 8)}` : ''})`;
} catch (e) {}
let configBuf = fs.readFileSync('config/config.js', {encoding: 'utf8'});
configBuf = configBuf.replace(/\/\* version \*\/[^;\n]*;/, `/* version */ Config.version = ${JSON.stringify(version)};`);
const routes = JSON.parse(fs.readFileSync('config/routes.json'));
const autoconfigRegex = new RegExp(`${escapeRegex(AUTOCONFIG_START)}[^]+${escapeRegex(AUTOCONFIG_END)}`);
const autoconfig = `${AUTOCONFIG_START}
Config.version = ${JSON.stringify(version)};
Config.routes = {
root: '${routes.root}',
client: '${routes.client}',
dex: '${routes.dex}',
replays: '${routes.replays}',
users: '${routes.users}',
};
${AUTOCONFIG_END}`;
// remove old automatically generated configuration and add the new one
let configBuf = fs.readFileSync('config/config.js', {encoding: 'utf8'});
if (autoconfigRegex.test(configBuf)) {
configBuf = configBuf.replace(autoconfigRegex, autoconfig);
} else {
configBuf += autoconfig;
}
fs.writeFileSync('config/config.js', configBuf);
console.log("DONE");
@ -82,31 +107,50 @@ if (!ignoreGraphics) {
* Update cachebuster and News
*********************************************************/
function updateIndex() {
// add hashes to js and css files
process.stdout.write("Updating hashes... ");
const URL_REGEX = /(src|href)="\/(.*?)(\?[a-z0-9]*?)?"/g;
function updateURL(a, b, c, d) {
c = c.replace('/replay.pokemonshowdown.com/', '/' + routes.replays + '/');
c = c.replace('/dex.pokemonshowdown.com/', '/' + routes.dex + '/');
c = c.replace('/play.pokemonshowdown.com/', '/' + routes.client + '/');
c = c.replace('/pokemonshowdown.com/', '/' + routes.root + '/');
if (d) {
let hash = Math.random(); // just in case creating the hash fails
try {
const filename = c.replace('/' + routes.client + '/', '');
const fstr = fs.readFileSync(filename, {encoding: 'utf8'});
hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8);
} catch (e) {}
return b + '="/' + c + '?' + hash + '"';
} else {
return b + '="/' + c + '"';
}
}
function writeFiles(indexContents, preactIndexContents, crossprotocolContents, replayEmbedContents) {
process.stdout.write("Writing new HTML files... ");
fs.writeFileSync('index.html', indexContents);
fs.writeFileSync('preactalpha.html', preactIndexContents);
fs.writeFileSync('crossprotocol.html', crossprotocolContents);
console.log("DONE");
process.stdout.write("Writing replay-embed.js... ");
fs.writeFileSync('js/replay-embed.js', replayEmbedContents);
console.log("DONE");
}
function updateFiles() {
// add hashes to js and css files and rewrite URLs
process.stdout.write("Updating hashes and URLs... ");
let indexContents = fs.readFileSync('index.template.html', {encoding: 'utf8'});
indexContents = indexContents.replace(/(src|href)="\/(.*?)\?[a-z0-9]*?"/g, function (a, b, c) {
let hash = Math.random(); // just in case creating the hash fails
try {
const filename = c.replace('/play.pokemonshowdown.com/', '');
const fstr = fs.readFileSync(filename, {encoding: 'utf8'});
hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8);
} catch (e) {}
return b + '="/' + c + '?' + hash + '"';
});
let indexContents2 = fs.readFileSync('preactalpha.template.html', {encoding: 'utf8'});
indexContents2 = indexContents2.replace(/(src|href)="\/(.*?)\?[a-z0-9]*?"/g, function (a, b, c) {
let hash = Math.random(); // just in case creating the hash fails
try {
const filename = c.replace('/play.pokemonshowdown.com/', '');
const fstr = fs.readFileSync(filename, {encoding: 'utf8'});
hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8);
} catch (e) {}
return b + '="/' + c + '?' + hash + '"';
});
indexContents = indexContents.replace(URL_REGEX, updateURL);
let preactIndexContents = fs.readFileSync('preactalpha.template.html', {encoding: 'utf8'});
preactIndexContents = preactIndexContents.replace(URL_REGEX, updateURL);
let crossprotocolContents = fs.readFileSync('crossprotocol.template.html', {encoding: 'utf8'});
crossprotocolContents = crossprotocolContents.replace(URL_REGEX, updateURL);
let replayEmbedContents = fs.readFileSync('js/replay-embed.template.js', {encoding: 'utf8'});
replayEmbedContents = replayEmbedContents.replace(/play\.pokemonshowdown\.com/g, routes.client);
console.log("DONE");
// add news, only if it's actually likely to exist
@ -128,12 +172,11 @@ function updateIndex() {
indexContents = indexContents.replace(/<!-- news -->/g, newsData[1]);
console.log("DONE");
process.stdout.write("Writing new `index.html` file... ");
fs.writeFileSync('index.html', indexContents);
fs.writeFileSync('preactalpha.html', indexContents2);
console.log("DONE");
writeFiles(indexContents, preactIndexContents, crossprotocolContents, replayEmbedContents);
});
} else {
writeFiles(indexContents, preactIndexContents, crossprotocolContents, replayEmbedContents);
}
}
updateIndex();
updateFiles();

View File

@ -2,6 +2,8 @@
mb_internal_encoding('UTF-8');
$routes = json_decode(file_get_contents(__DIR__ . '/routes.json'), true);
$psconfig = [
'sysops' => ['zarel'],
@ -22,6 +24,9 @@ $psconfig = [
'prefix' => 'ps_',
'charset' => 'utf8',
// routes
'routes' => $routes,
// CORS requests
'cors' => [

View File

@ -117,6 +117,17 @@ Config.whitelist = [
'4cdn\\.org'
];
// `defaultserver` specifies the server to use when the domain name in the
// address bar is `Config.routes.client`.
Config.defaultserver = {
id: 'showdown',
host: 'sim3.psim.us',
port: 443,
httpport: 8000,
altport: 80,
registered: true
};
Config.roomsFirstOpenScript = function () {
};

7
config/routes.json Normal file
View File

@ -0,0 +1,7 @@
{
"root": "pokemonshowdown.com",
"client": "play.pokemonshowdown.com",
"dex": "dex.pokemonshowdown.com",
"replays": "replay.pokemonshowdown.com",
"users": "pokemonshowdown.com/users"
}

View File

@ -1,12 +1,14 @@
<?php
$config = array();
require_once __DIR__ . '/config/config.inc.php';
$host = strtolower(strval(@$_REQUEST['host']));
if (preg_match('/^([a-z0-9-_\.]*?)\.psim\.us$/', $host, $m)) {
$config['host'] = $m[1];
if ($config['host'] === 'logs') die; // not authorised
if ($config['host'] === 'sim') die; // not authorised
} else if ($host === 'play.pokemonshowdown.com') {
} else if ($host === $psconfig['routes']['client']) {
$config['host'] = 'showdown';
} else {
die; // not authorised
@ -102,7 +104,7 @@ header('P3P: CP="NOI CUR ADM DEV COM NAV STA OUR IND"');
var configHost = <?php echo json_encode($config['host']) ?>;
var config = <?php echo json_encode(json_encode($config)) ?>;
var yourOrigin = <?php echo json_encode($protocol . '//' . $host) ?>;
var myOrigin = 'https://play.pokemonshowdown.com';
var myOrigin = 'https://<?php echo $psconfig['routes']['client'] ?>';
function postReply (message) {
if (window.parent.postMessage === postReply) return;

View File

@ -2,7 +2,8 @@
ini_set('max_execution_time', 60); // 1 minute
include '../pokemonshowdown.com/config/servers.inc.php';
require_once __DIR__ . '/../pokemonshowdown.com/config/servers.inc.php';
require_once __DIR__ . '/config/config.inc.php';
spl_autoload_register(function ($class) {
require_once('lib/css-sanitizer/'.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php');
@ -70,11 +71,11 @@ if ($curlret) {
// Parse a stylesheet from a string
$parser = Parser::newFromString($curlret);
$stylesheet = $parser->parseStylesheet();
// Apply sanitization to the stylehseet
$sanitizer = StylesheetSanitizer::newDefault();
$newStylesheet = $sanitizer->sanitize( $stylesheet );
// Convert the sanitized stylesheet back to text
$outputcss = Wikimedia\CSS\Util::stringify( $newStylesheet, [ 'minify' => true ] );
@ -98,7 +99,7 @@ if ($invalidate) {
Done: <?= htmlspecialchars($customcssuri) ?> was reloaded.
</p>
<p>
<a href="http://pokemonshowdown.com/servers/<?= $server ?>">Back to server management</a>
<a href="http://<?= $psconfig['routes']['root'] ?>/servers/<?= $server ?>">Back to server management</a>
</p>
<?php
}

View File

@ -39,7 +39,6 @@ https://psim.us/dev
<meta name="apple-mobile-web-app-capable" content="yes" />
<link rel="manifest" href="/manifest.json" />
<meta name="google-signin-client_id" content="912270888098-jjnre816lsuhc5clj3vbcn4o2q7p4qvk.apps.googleusercontent.com">
<script>var Config = {};</script>
<!--[if lte IE 8]><script>document.location.replace('http://pokemonshowdown.com/autodownload/win');</script><![endif]-->
<!-- Google Analytics -->
<script>
@ -99,6 +98,7 @@ ga('send', 'pageview');
var LM = document.getElementById('loading-message');
LM.innerHTML += ' DONE<br />Loading libraries...';
</script>
<script src="//play.pokemonshowdown.com/config/config.js?"></script>
<script src="//play.pokemonshowdown.com/js/lib/jquery-2.1.4.min.js"></script>
<script src="//play.pokemonshowdown.com/js/lib/jquery-cookie.js"></script>
<script src="//play.pokemonshowdown.com/js/lib/autoresize.jquery.min.js?"></script>
@ -115,7 +115,6 @@ ga('send', 'pageview');
LM.innerHTML += ' DONE<br />Loading data...';
</script>
<script src="//play.pokemonshowdown.com/config/config.js?"></script>
<script src="//play.pokemonshowdown.com/js/battledata.js?"></script>
<script src="//play.pokemonshowdown.com/js/storage.js?"></script>
<script src="//play.pokemonshowdown.com/data/pokedex-mini.js?"></script>

View File

@ -280,7 +280,7 @@
if (this.battle.ended) {
var replayDownloadButton = '<span style="float:right;"><a href="//replay.pokemonshowdown.com/" class="button replayDownloadButton" style="padding:2px 6px"><i class="fa fa-download"></i> Download replay</a><br /><br /><button name="saveReplay"><i class="fa fa-upload"></i> Upload and share replay</button></span>';
var replayDownloadButton = '<span style="float:right;"><a href="//' + Config.routes.replays + '/" class="button replayDownloadButton" style="padding:2px 6px"><i class="fa fa-download"></i> Download replay</a><br /><br /><button name="saveReplay"><i class="fa fa-upload"></i> Upload and share replay</button></span>';
// battle has ended
if (this.side) {

View File

@ -912,7 +912,7 @@
var userid = toID(targets[0]);
var registered = app.user.get('registered');
if (registered && registered.userid === userid) {
buffer += '<tr><td colspan="8" style="text-align:right"><a href="//pokemonshowdown.com/users/' + userid + '">Reset W/L</a></tr></td>';
buffer += '<tr><td colspan="8" style="text-align:right"><a href="//' + Config.routes.users + '/' + userid + '">Reset W/L</a></tr></td>';
}
buffer += '</table></div>';
self.add('|raw|' + buffer);

View File

@ -112,7 +112,7 @@
leave: function () {},
update: function () {
if (!this.curFormat) {
var buf = '<div class="ladder pad"><p>See a user\'s ranking with <a class="button" href="//pokemonshowdown.com/users/" target="_blank">User lookup</a></p>' +
var buf = '<div class="ladder pad"><p>See a user\'s ranking with <a class="button" href="//' + Config.routes.users + '/" target="_blank">User lookup</a></p>' +
//'<p><strong style="color:red">I\'m really really sorry, but as a warning: we\'re going to reset the ladder again soon to fix some more ladder bugs.</strong></p>' +
'<p>(btw if you couldn\'t tell the ladder screens aren\'t done yet; they\'ll look nicer than this once I\'m done.)</p>' +
'<p><button name="selectFormat" value="help" class="button"><i class="fa fa-info-circle"></i> How the ladder works</button></p><ul>';

View File

@ -56,7 +56,7 @@
this.$('.mainmenu').html(buf);
// right menu
if (document.location.hostname === 'play.pokemonshowdown.com') {
if (document.location.hostname === Config.routes.client) {
this.$('.rightmenu').html('<div class="menugroup"><p><button class="button mainmenu1 onlineonly disabled" name="joinRoom" value="rooms">Join chat</button></p></div>');
} else {
this.$('.rightmenu').html('<div class="menugroup"><p><button class="button mainmenu1 onlineonly disabled" name="joinRoom" value="lobby">Join lobby chat</button></p></div>');
@ -127,7 +127,7 @@
addNews: function () {
var self = this;
$.ajax({
url: "https://pokemonshowdown.com/news.json",
url: "https://" + Config.routes.root + "/news.json",
dataType: "json",
success: function (data) {
var html = '';

View File

@ -33,9 +33,10 @@
},
joinRoomPopup: function () {
app.addPopupPrompt("Room name:", "Join room", function (room) {
var routeLength = (Config.routes.client + '/').length;
if (room.substr(0, 7) === 'http://') room = room.slice(7);
if (room.substr(0, 8) === 'https://') room = room.slice(8);
if (room.substr(0, 25) === 'play.pokemonshowdown.com/') room = room.slice(25);
if (room.substr(0, routeLength) === Config.routes.client + '/') room = room.slice(routeLength);
if (room.substr(0, 8) === 'psim.us/') room = room.slice(8);
if (room.substr(0, document.location.hostname.length + 1) === document.location.hostname + '/') room = room.slice(document.location.hostname.length + 1);
room = toRoomid(room);

View File

@ -829,7 +829,7 @@
var urlprefix = "data:text/plain;base64,";
if (document.location.protocol === 'https:') {
// Chrome is dumb and doesn't support data URLs in HTTPS
urlprefix = "https://play.pokemonshowdown.com/action.php?act=dlteam&team=";
urlprefix = "https://" + Config.routes.client + "/action.php?act=dlteam&team=";
}
var contents = Storage.exportTeam(team.team).replace(/\n/g, '\r\n');
var downloadurl = "text/plain:" + filename + ":" + urlprefix + encodeURIComponent(window.btoa(unescape(encodeURIComponent(contents))));
@ -1538,7 +1538,7 @@
// We fetch this as 'text' and JSON.parse it ourserves in order to have consistent behavior
// between the localdev CORS helper and the real jQuery.get function, which would already parse
// this into an object based on the content-type header.
$.get('https://play.pokemonshowdown.com/data/sets/' + format + '.json', {}, function (data) {
$.get('https://' + Config.routes.client + '/data/sets/' + format + '.json', {}, function (data) {
try {
self.smogonSets[format] = JSON.parse(data);
} catch (e) {

View File

@ -737,7 +737,7 @@
buf += '<p><strong>Default</strong></p>';
buf += '<div class="bglist">';
buf += '<button name="setBg" value=""' + (!cur ? ' class="cur"' : '') + '><strong style="background:#888888;color:white;padding:16px 18px;display:block;font-size:12pt">' + (location.host === 'play.pokemonshowdown.com' ? 'Random' : 'Default') + '</strong></button>';
buf += '<button name="setBg" value=""' + (!cur ? ' class="cur"' : '') + '><strong style="background:#888888;color:white;padding:16px 18px;display:block;font-size:12pt">' + (location.host === Config.routes.client ? 'Random' : 'Default') + '</strong></button>';
buf += '</div><div style="clear:left"></div>';
buf += '<p><strong>Official</strong></p>';

View File

@ -373,7 +373,7 @@ function toId() {
app.socket.close();
},
setPersistentName: function (name) {
if (location.host !== 'play.pokemonshowdown.com') return;
if (location.host !== Config.routes.client) return;
$.cookie('showdown_username', (name !== undefined) ? name : this.get('name'), {
expires: 14
});
@ -409,7 +409,7 @@ function toId() {
// type: 'modal'
// });
} else {
if (document.location.hostname === 'play.pokemonshowdown.com' || Config.testclient) {
if (document.location.hostname === Config.routes.client || Config.testclient) {
this.addRoom('rooms', null, true);
} else {
this.addRoom('lobby', null, true);
@ -887,7 +887,7 @@ function toId() {
} else if (data === 'nonexistent' && Config.server.id && roomid.slice(0, 7) === 'battle-' && errormessage) {
var replayid = roomid.slice(7);
if (Config.server.id !== 'showdown') replayid = Config.server.id + '-' + replayid;
var replayLink = 'https://replay.pokemonshowdown.com/' + replayid;
var replayLink = 'https://' + Config.routes.replays + '/' + replayid;
$.ajax(replayLink + '.json', {dataType: 'json'}).done(function (replay) {
if (replay) {
var title = BattleLog.escapeHTML(replay.p1) + ' vs. ' + BattleLog.escapeHTML(replay.p2);
@ -1304,9 +1304,9 @@ function toId() {
if (this.className === 'closebutton') return; // handled elsewhere
if (this.className.indexOf('minilogo') >= 0) return; // handled elsewhere
if (!this.href) return; // should never happen
var isReplayLink = this.host === 'replay.pokemonshowdown.com' && Config.server.id === 'showdown';
var isReplayLink = this.host === Config.routes.replays && Config.server.id === 'showdown';
if ((
isReplayLink || ['play.pokemonshowdown.com', 'psim.us', location.host].includes(this.host)
isReplayLink || [Config.routes.client, 'psim.us', location.host].includes(this.host)
) && this.className !== 'no-panel-intercept') {
if (!e.cmdKey && !e.metaKey && !e.ctrlKey) {
var target = this.pathname.substr(1);
@ -1383,7 +1383,7 @@ function toId() {
this.fixedWidth = true;
}
}
if (!app.roomsFirstOpen && !this.down && $(window).width() >= 916 && document.location.hostname === 'play.pokemonshowdown.com') {
if (!app.roomsFirstOpen && !this.down && $(window).width() >= 916 && document.location.hostname === Config.routes.client) {
this.addRoom('rooms');
}
this.updateLayout();
@ -2516,7 +2516,7 @@ function toId() {
var buf = '<div class="userdetails">';
if (avatar) buf += '<img class="trainersprite' + (userid === ownUserid ? ' yours' : '') + '" src="' + Dex.resolveAvatar(avatar) + '" />';
buf += '<strong><a href="//pokemonshowdown.com/users/' + userid + '" target="_blank">' + BattleLog.escapeHTML(name) + '</a></strong><br />';
buf += '<strong><a href="//' + Config.routes.users + '/' + userid + '" target="_blank">' + BattleLog.escapeHTML(name) + '</a></strong><br />';
var offline = data.rooms === false;
if (data.status || offline) {
var status = offline ? '(Offline)' : data.status.startsWith('!') ? data.status.slice(1) : data.status;
@ -2723,7 +2723,7 @@ function toId() {
initialize: function (data) {
var buf = '';
buf = '<p>Your replay has been uploaded! It\'s available at:</p>';
buf += '<p><a href="https://replay.pokemonshowdown.com/' + data.id + '" target="_blank" class="no-panel-intercept">https://replay.pokemonshowdown.com/' + data.id + '</a></p>';
buf += '<p><a href="https://' + Config.routes.replays + '/' + data.id + '" target="_blank" class="no-panel-intercept">https://' + Config.routes.replays + '/' + data.id + '</a></p>';
buf += '<p><button class="autofocus" name="close">Close</button></p>';
this.$el.html(buf).css('max-width', 620);
},

View File

@ -17,11 +17,11 @@ linkStyle('https://play.pokemonshowdown.com/style/battle.css?a7');
linkStyle('https://play.pokemonshowdown.com/style/replay.css?a7');
linkStyle('https://play.pokemonshowdown.com/style/utilichart.css?a7');
requireScript('https://play.pokemonshowdown.com/js/config.js?a7');
requireScript('https://play.pokemonshowdown.com/js/lib/jquery-1.11.0.min.js');
requireScript('https://play.pokemonshowdown.com/js/lib/lodash.compat.js');
requireScript('https://play.pokemonshowdown.com/js/lib/html-sanitizer-minified.js');
requireScript('https://play.pokemonshowdown.com/js/lib/soundmanager2-nodebug-jsmin.js');
requireScript('https://play.pokemonshowdown.com/js/config.js?a7');
requireScript('https://play.pokemonshowdown.com/js/battledata.js?a7');
requireScript('https://play.pokemonshowdown.com/data/pokedex-mini.js?a7');
requireScript('https://play.pokemonshowdown.com/data/pokedex-mini-bw.js?a7');

View File

@ -1,15 +1,3 @@
Config.origindomain = 'play.pokemonshowdown.com';
// `defaultserver` specifies the server to use when the domain name in the
// address bar is `Config.origindomain`.
Config.defaultserver = {
id: 'showdown',
host: 'sim3.psim.us',
port: 443,
httpport: 8000,
altport: 80,
registered: true
};
function Storage() {}
Storage.initialize = function () {
@ -64,7 +52,7 @@ Storage.bg = {
if (!bgid) {
if (location.host === 'smogtours.psim.us') {
bgid = 'shaymin';
} else if (location.host === 'play.pokemonshowdown.com') {
} else if (location.host === Config.routes.client) {
bgid = ['horizon', 'ocean', 'waterfall', 'shaymin', 'charizards', 'psday'][Math.floor(Math.random() * 6)];
} else {
$(document.body).css({
@ -226,7 +214,7 @@ if (!Storage.bg.id) {
// localStorage is banned, and since prefs are cached in other
// places in certain cases.
Storage.origin = 'https://play.pokemonshowdown.com';
Storage.origin = 'https://' + Config.routes.client;
Storage.prefs = function (prop, value, save) {
if (value === undefined) {
@ -357,9 +345,9 @@ Storage.initPrefs = function () {
$(window).on('message', Storage.onMessage);
if (document.location.hostname !== Config.origindomain) {
if (document.location.hostname !== Config.routes.client) {
$(
'<iframe src="https://play.pokemonshowdown.com/crossdomain.php?host=' +
'<iframe src="https://' + Config.routes.client + '/crossdomain.php?host=' +
encodeURIComponent(document.location.hostname) +
'&path=' + encodeURIComponent(document.location.pathname.substr(1)) +
'&protocol=' + encodeURIComponent(document.location.protocol) +
@ -368,7 +356,7 @@ Storage.initPrefs = function () {
} else {
Config.server = Config.server || Config.defaultserver;
$(
'<iframe src="https://play.pokemonshowdown.com/crossprotocol.html?v1.2" style="display: none;"></iframe>'
'<iframe src="https://' + Config.routes.client + '/crossprotocol.html?v1.2" style="display: none;"></iframe>'
).appendTo('body');
setTimeout(function () {
// HTTPS may be blocked
@ -397,7 +385,7 @@ Storage.onMessage = function ($e) {
Config.server = JSON.parse(data.substr(1));
if (Config.server.registered && Config.server.id !== 'showdown' && Config.server.id !== 'smogtours') {
var $link = $('<link rel="stylesheet" ' +
'href="//play.pokemonshowdown.com/customcss.php?server=' +
'href="//' + Config.routes.client + '/customcss.php?server=' +
encodeURIComponent(Config.server.id) + '" />');
$('head').append($link);
}
@ -432,7 +420,7 @@ Storage.onMessage = function ($e) {
// in Safari, cross-origin local storage is apparently treated as session
// storage, so mirror the storage in the current origin just in case
if (document.location.hostname === Config.origindomain) {
if (document.location.hostname === Config.routes.client) {
try {
localStorage.setItem('showdown_teams_local', packedTeams);
} catch (e) {}

View File

@ -243,7 +243,7 @@ class DefaultActionHandler {
}
public function logout($dispatcher, &$reqData, &$out) {
global $users, $curuser;
global $users, $curuser, $psconfig;
if (!$_POST ||
!isset($reqData['userid']) ||
@ -252,7 +252,7 @@ class DefaultActionHandler {
die;
}
$users->logout(); // this kills the `sid` cookie
setcookie('showdown_username', '', time()-60*60*24*2, '/', 'play.pokemonshowdown.com');
setcookie('showdown_username', '', time()-60*60*24*2, '/', $psconfig['routes']['client']);
$out['actionsuccess'] = true;
}
@ -492,7 +492,7 @@ class DefaultActionHandler {
// The ] denotes that it was successful
die(']A friend request has been sent to ' . $player['username'] . '!');
}
/**
* This function simply removes the friend given in the query string.
*/

View File

@ -158,7 +158,7 @@ class NTBBLadder {
}
$rp = $this->getrp();
$ladderdb->query(
"INSERT INTO `{$ladderdb->prefix}ladder` (`formatid`,`userid`,`username`,`rptime`) VALUES (?,?,?,?)",
"INSERT INTO `{$ladderdb->prefix}ladder` (`formatid`,`userid`,`username`,`rptime`,`rpdata`,`col1`) VALUES (?,?,?,?,'',0)",
[$this->formatid, $user['userid'], $user['username'], $rp]
);
$user['rating'] = array(

View File

@ -1,12 +1,12 @@
<?php
require_once dirname(__FILE__) . '/ntbb-database.lib.php';
require_once __DIR__ . '/ntbb-database.lib.php';
require_once __DIR__ . '/../config/config.inc.php';
// require_once dirname(__FILE__) . '/password_compat/lib/password.php';
$curuser = false;
class NTBBSession {
var $cookiedomain = 'pokemonshowdown.com';
var $trustedproxies = array(
'103.21.244.0/22',
'103.22.200.0/22',
@ -253,7 +253,7 @@ class NTBBSession {
}
function login($name, $pass, $timeout = false, $debug = false) {
global $psdb, $curuser;
global $psdb, $curuser, $psconfig;
$ctime = time();
$this->logout();
@ -296,31 +296,33 @@ class NTBBSession {
unset($curuser['nonce']);
unset($curuser['passwordhash']);
// setcookie('sid', $this->scookie, ['expires' => time() + (363)*24*60*60, 'path' => '/', 'domain' => $this->cookiedomain, 'secure' => true, 'httponly' => true, 'samesite' => 'None']);
// setcookie('sid', $this->scookie, ['expires' => time() + (363)*24*60*60, 'path' => '/', 'domain' => $psconfig['routes']['root'], 'secure' => true, 'httponly' => true, 'samesite' => 'None']);
$encodedcookie = rawurlencode($this->scookie);
header("Set-Cookie: sid=$encodedcookie; Max-Age=31363200; Domain={$this->cookiedomain}; Path=/; Secure; SameSite=None");
header("Set-Cookie: sid=$encodedcookie; Max-Age=31363200; Domain={$psconfig['routes']['root']}; Path=/; Secure; SameSite=None");
return $curuser;
}
function updateCookie() {
global $psconfig;
if (!$this->sid) {
$this->sid = $this->mksid($this->sid);
$this->scookie = ',,' . $this->sid;
// setcookie('sid', $this->scookie, ['expires' => time() + (363)*24*60*60, 'path' => '/', 'domain' => $this->cookiedomain, 'secure' => true, 'httponly' => true, 'samesite' => 'None']);
// setcookie('sid', $this->scookie, ['expires' => time() + (363)*24*60*60, 'path' => '/', 'domain' => $psconfig['routes']['root'], 'secure' => true, 'httponly' => true, 'samesite' => 'None']);
$encodedcookie = rawurlencode($this->scookie);
header("Set-Cookie: sid=$encodedcookie; Max-Age=31363200; Domain={$this->cookiedomain}; Path=/; Secure; SameSite=None");
header("Set-Cookie: sid=$encodedcookie; Max-Age=31363200; Domain={$psconfig['routes']['root']}; Path=/; Secure; SameSite=None");
}
}
function killCookie() {
global $psconfig;
if ($this->sid) {
$this->scookie = ',,' . $this->sid;
// setcookie('sid', $this->scookie, ['expires' => time() + (363)*24*60*60, 'path' => '/', 'domain' => $this->cookiedomain, 'secure' => true, 'httponly' => true, 'samesite' => 'None']);
// setcookie('sid', $this->scookie, ['expires' => time() + (363)*24*60*60, 'path' => '/', 'domain' => $psconfig['routes']['root'], 'secure' => true, 'httponly' => true, 'samesite' => 'None']);
$encodedcookie = rawurlencode($this->scookie);
header("Set-Cookie: sid=$encodedcookie; Max-Age=31363200; Domain={$this->cookiedomain}; Path=/; Secure; SameSite=None");
header("Set-Cookie: sid=$encodedcookie; Max-Age=31363200; Domain={$psconfig['routes']['root']}; Path=/; Secure; SameSite=None");
} else {
// setcookie('sid', '', ['expires' => time() - 60*60*24*2, 'path' => '/', 'domain' => $this->cookiedomain, 'secure' => true, 'httponly' => true, 'samesite' => 'None']);
header("Set-Cookie: sid=; Max-Age=0; Domain={$this->cookiedomain}; Path=/; Secure; SameSite=None");
// setcookie('sid', '', ['expires' => time() - 60*60*24*2, 'path' => '/', 'domain' => $psconfig['routes']['root'], 'secure' => true, 'httponly' => true, 'samesite' => 'None']);
header("Set-Cookie: sid=; Max-Age=0; Domain={$psconfig['routes']['root']}; Path=/; Secure; SameSite=None");
}
}

View File

@ -51,6 +51,7 @@
linkStyle("style/battle-search.css");
linkStyle("/style/font-awesome.css");
</script>
<script defer src="/config/config.js?"></script>
<script defer src="/js/client-core.js?"></script>
<script defer src="/js/battle-dex.js?"></script>

View File

@ -4,7 +4,8 @@ error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
include_once 'theme/panels.lib.php';
require_once __DIR__ . '/theme/panels.lib.php';
require_once __DIR__ . '/../config/config.inc.php';
$id = $_REQUEST['name'] ?? '';
$password = '';
@ -70,7 +71,7 @@ if (@$replay['password']) {
}
$url = '/' . $id . '-' . $replay['password'] . 'pw';
echo '<p>This private replay now has a new harder-to-guess URL:</p>';
echo '<p><a href="' . $url . '" data-target="replace">https://replay.pokemonshowdown.com' . $url . '</a></p>';
echo '<p><a href="' . $url . '" data-target="replace">https://' . $psconfig['routes']['replays'] . $url . '</a></p>';
die();
}
if ($password !== $replay['password'] && !$manage) {
@ -131,9 +132,9 @@ $panels->start();
<?php if (@$replay['private']) echo '<strong>THIS REPLAY IS PRIVATE</strong> - make sure you have the owner\'s permission to share<br />'; ?>
<pre class="urlbox" style="word-wrap: break-word;"><?php echo htmlspecialchars('https://replay.pokemonshowdown.com/'.$fullid); ?></pre>
<pre class="urlbox" style="word-wrap: break-word;"><?php echo htmlspecialchars('https://'.$psconfig['routes']['replays'].'/'.$fullid); ?></pre>
<h1 style="font-weight:normal;text-align:left"><strong><?= htmlspecialchars($format) ?></strong>: <a href="//pokemonshowdown.com/users/<?= userid($replay['p1']) ?>" class="subtle"><?= htmlspecialchars($replay['p1']) ?></a> vs. <a href="//pokemonshowdown.com/users/<?= userid($replay['p2']) ?>" class="subtle"><?= htmlspecialchars($replay['p2']) ?></a></h1>
<h1 style="font-weight:normal;text-align:left"><strong><?= htmlspecialchars($format) ?></strong>: <a href="//<?= $psconfig['routes']['replays'] ?>/<?= userid($replay['p1']) ?>" class="subtle"><?= htmlspecialchars($replay['p1']) ?></a> vs. <a href="//<?= $psconfig['routes']['replays'] ?>/<?= userid($replay['p2']) ?>" class="subtle"><?= htmlspecialchars($replay['p2']) ?></a></h1>
<p style="padding:0 1em;margin-top:0">
<small class="uploaddate" data-timestamp="<?= @$replay['uploadtime'] ?? @$replay['date'] ?>"><em>Uploaded:</em> <?php echo date("M j, Y", @$replay['uploadtime'] ?? @$replay['date']); ?><?= @$replay['rating'] ? ' | <em>Rating:</em> ' . $replay['rating'] : '' ?></small>
</p>
@ -175,9 +176,9 @@ if ($manage) {
<input type="hidden" name="replayid" value="<?php echo htmlspecialchars($replay['id']); ?>" />
<!--
You can get this log directly at https://replay.pokemonshowdown.com/<?php echo $replay['id']; ?>.log
You can get this log directly at https://<?php echo $psconfig['routes']['replays']; ?>/<?php echo $replay['id']; ?>.log
Or with metadata at https://replay.pokemonshowdown.com/<?php echo $replay['id']; ?>.json
Or with metadata at https://<?php echo $psconfig['routes']['replays']; ?>/<?php echo $replay['id']; ?>.json
Most PS pages you'd want to scrape will have a .json version!

View File

@ -15,20 +15,7 @@ function updateIndex() {
// add hashes to js and css files
process.stdout.write("Updating hashes... ");
indexContents = indexContents.replace(/(src|href)="\/(.*?)\?[a-z0-9]*?"/g, function (a, b, c) {
let hash = Math.random(); // just in case creating the hash fails
try {
var filepath = c;
if (c.includes('/play.pokemonshowdown.com/')) {
const filename = c.replace('/play.pokemonshowdown.com/', '');
filepath = '../' + filename;
}
const fstr = fs.readFileSync(filepath, {encoding: 'utf8'});
hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8);
} catch (e) {}
return b + '="/' + c + '?' + hash + '"';
});
indexContents = indexContents.replace(/(src|href)="\/(.*?)(\?[a-z0-9]*?)?"/g, runReplace);
console.log("DONE");
process.stdout.write("Writing new `wrapper.inc.php` file... ");
@ -36,4 +23,25 @@ function updateIndex() {
console.log("DONE");
}
function runReplace(a, b, c) {
let hash = Math.random(); // just in case creating the hash fails
const routes = JSON.parse(fs.readFileSync('../config/routes.json'));
try {
var filepath = c;
if (c.includes('/' + routes.client + '/')) {
const filename = c.replace('/' + routes.client + '/', '');
filepath = '../' + filename;
}
const fstr = fs.readFileSync(filepath, {encoding: 'utf8'});
hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8);
} catch (e) {}
c = c.replace('/replay.pokemonshowdown.com/', '/' + routes.replays + '/');
c = c.replace('/dex.pokemonshowdown.com/', '/' + routes.dex + '/');
c = c.replace('/play.pokemonshowdown.com/', '/' + routes.client + '/');
c = c.replace('/pokemonshowdown.com/users/', '/' + routes.users + '/');
c = c.replace('/pokemonshowdown.com/', '/' + routes.root + '/');
return b + '="/' + c + '?' + hash + '"';
}
updateIndex();

View File

@ -20,7 +20,7 @@ if (!$name)
<div class="wrapper">
<noscript>turn on javascript</noscript>
<form id="form" onsubmit="return doSubmit()">
1. if you haven't done so, upload a replay <a href="https://replay.pokemonshowdown.com/">https://replay.pokemonshowdown.com/</a>, get its URL, and come back here.
1. if you haven't done so, upload a replay <a href="https://<?= $psconfig['routes']['replays'] ?>/">https://<?= $psconfig['routes']['replays'] ?>/</a>, get its URL, and come back here.
<br />
2. Paste the URL: <input type="text" size="90" id="text" onkeyup="update()" onchange="update()" />
<br />
@ -35,16 +35,16 @@ function doSubmit()
if (val.substr(0,7) === 'http://') val = val.substr(7);
if (val.substr(0,8) === 'http://') val = val.substr(8);
if (val.substr(0,4) === 'www.') val = val.substr(4);
if (val.substr(0,'replay.pokemonshowdown.com/'.length) === 'replay.pokemonshowdown.com/')
if (val.substr(0,'<?= $psconfig['routes']['replays'] ?>/'.length) === '<?= $psconfig['routes']['replays'] ?>/')
{
val = val.substr('replay.pokemonshowdown.com/'.length);
val = val.substr('<?= $psconfig['routes']['replays'] ?>/'.length);
ok = true;
}
if (!ok) return false;
else
{
document.location.href = 'http://replay.pokemonshowdown.com/warstory-'+val;
document.location.href = 'http://<?= $psconfig['routes']['replays'] ?>/warstory-'+val;
return false;
}
}
@ -56,9 +56,9 @@ function update()
if (val.substr(0,7) === 'http://') val = val.substr(7);
if (val.substr(0,8) === 'http://') val = val.substr(8);
if (val.substr(0,4) === 'www.') val = val.substr(4);
if (val.substr(0,'replay.pokemonshowdown.com/'.length) === 'replay.pokemonshowdown.com/')
if (val.substr(0,'<?= $psconfig['routes']['replays'] ?>/'.length) === '<?= $psconfig['routes']['replays'] ?>/')
{
val = val.substr('replay.pokemonshowdown.com/'.length);
val = val.substr('<?= $psconfig['routes']['replays'] ?>/'.length);
ok = true;
}
@ -200,7 +200,7 @@ function turnCallback(battle)
Bswitch = null;
}
imagestring = '<div><img src="http://play.pokemonshowdown.com/replay/turn_'+imagestring+'.png" /></div>';
imagestring = '<div><img src="http://<?= $psconfig['routes']['client'] ?>/replay/turn_'+imagestring+'.png" /></div>';
$('#warstory').append($('#battle-log .inner').html());
$('#battle-log .inner').html('');
var lastchild = $('#warstory').children().last();
@ -265,20 +265,20 @@ function endCallback(battle)
var teamcode = '[hide="'+battle.mySide.name+'\'s team"]';
for (var i=0; i<battle.mySide.pokemon.length && i<6; i++)
{
teamcode += '[img]http://play.pokemonshowdown.com/sprites/gen5/'+battle.mySide.pokemon[i].spriteid+'.png[/img]';
teamcode += '[img]http://<?= $psconfig['routes']['client'] ?>/sprites/gen5/'+battle.mySide.pokemon[i].spriteid+'.png[/img]';
}
teamcode += '[/hide]'+"\n";
teamcode += '[hide="'+battle.yourSide.name+'\'s team"]';
for (var i=0; i<battle.yourSide.pokemon.length && i<6; i++)
{
teamcode += '[img]http://play.pokemonshowdown.com/sprites/gen5/'+battle.yourSide.pokemon[i].spriteid+'.png[/img]';
teamcode += '[img]http://<?= $psconfig['routes']['client'] ?>/sprites/gen5/'+battle.yourSide.pokemon[i].spriteid+'.png[/img]';
}
teamcode += '[/hide]'+"\n\n";
bbcode = teamcode + bbcode;
bbcode = "[indent]>>>[url=\"http://play.pokemonshowdown.com/replay/battle-<?php echo $name ?>\"][size=\"3\"]Click to [b]watch this replay[/b]![/size][/url]<<<[/indent]\n\n"+bbcode;
bbcode += "\n\n[indent]>>>[url=\"http://play.pokemonshowdown.com/replay/battle-<?php echo $name ?>\"][size=\"3\"]Click to [b]watch this replay[/b]![/size][/url]<<<[/indent]";
bbcode = "[indent]>>>[url=\"http://<?= $psconfig['routes']['client'] ?>/replay/battle-<?php echo $name ?>\"][size=\"3\"]Click to [b]watch this replay[/b]![/size][/url]<<<[/indent]\n\n"+bbcode;
bbcode += "\n\n[indent]>>>[url=\"http://<?= $psconfig['routes']['client'] ?>/replay/battle-<?php echo $name ?>\"][size=\"3\"]Click to [b]watch this replay[/b]![/size][/url]<<<[/indent]";
$('#warstory').prepend('<textarea rows="20" cols="90"></textarea>');
$('#warstory textarea').text(bbcode);
}

View File

@ -3190,7 +3190,7 @@ const BattleMoveAnims: AnimTable = {
},
morningsun: {
anim(scene, [attacker, defender]) {
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/weather-sunnyday.jpg')", 700, 0.5);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/weather-sunnyday.jpg')`, 700, 0.5);
scene.showEffect('wisp', {
x: attacker.x + 40,
y: attacker.y - 40,
@ -3243,7 +3243,7 @@ const BattleMoveAnims: AnimTable = {
},
moonlight: {
anim(scene, [attacker]) {
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/bg-space.jpg')", 800, 0.6);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/bg-space.jpg')`, 800, 0.6);
scene.showEffect('shine', {
x: attacker.x + 40,
y: attacker.y - 40,
@ -3315,7 +3315,7 @@ const BattleMoveAnims: AnimTable = {
},
cosmicpower: {
anim(scene, [attacker]) {
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/bg-space.jpg')", 600, 0.6);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/bg-space.jpg')`, 600, 0.6);
scene.showEffect('wisp', {
x: attacker.x + 40,
y: attacker.y - 40,
@ -4796,7 +4796,7 @@ const BattleMoveAnims: AnimTable = {
},
seismictoss: {
anim(scene, [attacker, defender]) {
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/bg-space.jpg')", 500, 0.6, 300);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/bg-space.jpg')`, 500, 0.6, 300);
scene.showEffect('wisp', {
x: defender.x,
y: defender.y + 10,
@ -7233,7 +7233,7 @@ const BattleMoveAnims: AnimTable = {
},
meteormash: {
anim(scene, [attacker, defender]) {
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/bg-space.jpg')", 1000, 0.4);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/bg-space.jpg')`, 1000, 0.4);
scene.showEffect(attacker.sp, {
x: attacker.leftof(20),
y: attacker.y,
@ -15715,7 +15715,7 @@ const BattleMoveAnims: AnimTable = {
},
psystrike: {
anim(scene, [attacker, defender]) {
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/weather-psychicterrain.png')", 950, 0.6);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/weather-psychicterrain.png')`, 950, 0.6);
scene.showEffect('poisonwisp', {
x: defender.x - 100,
y: defender.y,
@ -16379,7 +16379,7 @@ const BattleMoveAnims: AnimTable = {
},
moonblast: {
anim(scene, [attacker, defender]) {
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/bg-space.jpg')", 800, 0.6);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/bg-space.jpg')`, 800, 0.6);
scene.showEffect('mistball', {
x: attacker.x,
y: attacker.y,
@ -16643,7 +16643,7 @@ const BattleMoveAnims: AnimTable = {
},
wish: {
anim(scene, [attacker]) {
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/bg-space.jpg')", 600, 0.4);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/bg-space.jpg')`, 600, 0.4);
scene.showEffect('wisp', {
x: attacker.x,
@ -16657,7 +16657,7 @@ const BattleMoveAnims: AnimTable = {
}, 'accel');
},
residualAnim(scene, [attacker]) {
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/bg-space.jpg')", 600, 0.4);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/bg-space.jpg')`, 600, 0.4);
scene.showEffect('wisp', {
x: attacker.x,
@ -17734,7 +17734,7 @@ const BattleMoveAnims: AnimTable = {
},
dracometeor: {
anim(scene, [attacker, defender]) {
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/bg-space.jpg')", 1100, 0.8);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/bg-space.jpg')`, 1100, 0.8);
scene.showEffect('flareball', {
x: defender.leftof(-200),
y: defender.y + 175,
@ -19053,7 +19053,7 @@ const BattleMoveAnims: AnimTable = {
let ystep = (defender.x - 200 - attacker.x) / 5;
let zstep = (defender.z - attacker.z) / 5;
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/weather-sunnyday.jpg')", 900, 0.5);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/weather-sunnyday.jpg')`, 900, 0.5);
for (let i = 0; i < 5; i++) {
scene.showEffect('energyball', {
@ -19197,7 +19197,7 @@ const BattleMoveAnims: AnimTable = {
let ystep = 20;
let zstep = 0;
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/weather-sunnyday.jpg')", 900, 0.5);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/weather-sunnyday.jpg')`, 900, 0.5);
scene.showEffect('sword', {
x: attacker.leftof(10),
@ -19482,7 +19482,7 @@ const BattleMoveAnims: AnimTable = {
let ystep = (defender.x - 200 - attacker.x) / 5;
let zstep = (defender.z - attacker.z) / 5;
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/weather-sandstorm.png')", 900, 0.5);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/weather-sandstorm.png')`, 900, 0.5);
for (let i = 0; i < 5; i++) {
scene.showEffect('mudwisp', {
@ -19682,7 +19682,7 @@ const BattleMoveAnims: AnimTable = {
},
sheercold: { // Reminder: Improve this later
anim(scene, [attacker, defender]) {
scene.backgroundEffect("url('https://play.pokemonshowdown.com/sprites/gen6bgs/bg-icecave.jpg')", 1000, 0.6);
scene.backgroundEffect(`url('https://${Config.routes.client}/sprites/gen6bgs/bg-icecave.jpg')`, 1000, 0.6);
scene.showEffect('icicle', {
x: defender.x,
y: defender.y,
@ -21911,7 +21911,7 @@ const BattleMoveAnims: AnimTable = {
},
dragonascent: {
anim(scene, [attacker, defender]) {
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/bg-space.jpg')", 1000, 0.7);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/bg-space.jpg')`, 1000, 0.7);
scene.showEffect('iceball', {
x: attacker.leftof(-25),
y: attacker.y + 250,
@ -25402,7 +25402,7 @@ const BattleMoveAnims: AnimTable = {
},
plasmafists: {
anim(scene, [attacker, defender]) {
scene.backgroundEffect("url('https://play.pokemonshowdown.com/sprites/gen6bgs/bg-earthycave.jpg')", 2000, 1);
scene.backgroundEffect(`url('https://${Config.routes.client}/sprites/gen6bgs/bg-earthycave.jpg')`, 2000, 1);
scene.backgroundEffect('#000000', 1000, 0.6);
scene.backgroundEffect('#FFFFFF', 300, 0.6, 1000);
scene.showEffect('electroball', {
@ -29252,7 +29252,7 @@ const BattleMoveAnims: AnimTable = {
oceanicoperetta: {
anim(scene, [attacker, defender]) {
scene.backgroundEffect('linear-gradient(#000000 20%, #0000DD)', 2700, 0.4);
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/weather-raindance.jpg')", 700, 0.2, 2000);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/weather-raindance.jpg')`, 700, 0.2, 2000);
scene.showEffect('iceball', {
x: attacker.x,
y: attacker.y + 120,
@ -29575,7 +29575,7 @@ const BattleMoveAnims: AnimTable = {
},
splinteredstormshards: {
anim(scene, [attacker, defender]) {
scene.backgroundEffect("url('https://play.pokemonshowdown.com/sprites/gen6bgs/bg-earthycave.jpg')", 2700, 0.8, 300);
scene.backgroundEffect(`url('https://${Config.routes.client}/sprites/gen6bgs/bg-earthycave.jpg')`, 2700, 0.8, 300);
scene.backgroundEffect('linear-gradient(#FFC720 15%, #421800)', 2700, 0.7);
scene.backgroundEffect('#ffffff', 400, 0.6, 2500);
scene.showEffect('rock3', {
@ -30298,7 +30298,7 @@ const BattleMoveAnims: AnimTable = {
}
const defender = defenders[1] || defenders[0];
scene.backgroundEffect('#000000', 300, 0.9);
scene.backgroundEffect("url('https://play.pokemonshowdown.com/sprites/gen6bgs/bg-earthycave.jpg')", 2000, 0.7, 300);
scene.backgroundEffect(`url('https://${Config.routes.client}/sprites/gen6bgs/bg-earthycave.jpg')`, 2000, 0.7, 300);
scene.backgroundEffect('linear-gradient(#FB5C1E 20%, #3F1D0F', 2000, 0.6, 300);
scene.backgroundEffect('#FFFFFF', 1000, 0.9, 2200);
scene.showEffect('shine', {
@ -30970,8 +30970,8 @@ const BattleMoveAnims: AnimTable = {
let ystep = (defender.x - 200 - attacker.x) / 5;
let zstep = (defender.z - attacker.z) / 5;
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/weather-trickroom.png')", 700, 1);
scene.backgroundEffect("url('https://play.pokemonshowdown.com/fx/bg-space.jpg')", 2500, 1, 700);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/weather-trickroom.png')`, 700, 1);
scene.backgroundEffect(`url('https://${Config.routes.client}/fx/bg-space.jpg')`, 2500, 1, 700);
scene.backgroundEffect('#FFFFFF', 1500, 1, 2500);
scene.showEffect('flareball', {

View File

@ -89,6 +89,17 @@ class BattleScene {
constructor(battle: Battle, $frame: JQuery, $logFrame: JQuery) {
this.battle = battle;
if (window.soundManager) {
soundManager.setup({url: `https://${Config.routes.client}/swf/`});
if (window.Replays) soundManager.onready(window.Replays.soundReady);
soundManager.onready(() => {
soundManager.createSound({
id: 'notif',
url: `https://${Config.routes.client}/audio/notification.wav`,
});
});
}
$frame.addClass('battle');
this.$frame = $frame;
this.log = new BattleLog($logFrame[0] as HTMLDivElement, this);

View File

@ -113,17 +113,6 @@ if (typeof window === 'undefined') {
window.exports = window;
}
if (window.soundManager) {
soundManager.setup({url: 'https://play.pokemonshowdown.com/swf/'});
if (window.Replays) soundManager.onready(window.Replays.soundReady);
soundManager.onready(() => {
soundManager.createSound({
id: 'notif',
url: 'https://play.pokemonshowdown.com/audio/notification.wav',
});
});
}
// @ts-ignore
window.nodewebkit = !!(typeof process !== 'undefined' && process.versions && process.versions['node-webkit']);
@ -277,15 +266,15 @@ const Dex = new class implements ModdedDex {
resourcePrefix = (() => {
let prefix = '';
if (window.document?.location?.protocol !== 'http:') prefix = 'https:';
return `${prefix}//play.pokemonshowdown.com/`;
return `${prefix}//${window.Config ? Config.routes.client : 'play.pokemonshowdown.com'}/`;
})();
fxPrefix = (() => {
if (window.document?.location?.protocol === 'file:') {
if (window.Replays) return `https://play.pokemonshowdown.com/fx/`;
if (window.Replays) return `https://${window.Config ? Config.routes.client : 'play.pokemonshowdown.com'}/fx/`;
return `fx/`;
}
return `//play.pokemonshowdown.com/fx/`;
return `//${window.Config ? Config.routes.client : 'play.pokemonshowdown.com'}/fx/`;
})();
loadedSpriteData = {xy: 1, bw: 0};

View File

@ -454,7 +454,7 @@ class BattleLog {
static usernameColor(name: ID) {
if (this.colorCache[name]) return this.colorCache[name];
let hash;
if (window.Config?.customcolors?.[name]) {
if (Config.customcolors[name]) {
hash = MD5(Config.customcolors[name]);
} else {
hash = MD5(name);
@ -639,7 +639,7 @@ class BattleLog {
}
static interstice = (() => {
const whitelist: string[] = window.Config?.whitelist || [];
const whitelist: string[] = Config.whitelist;
const patterns = whitelist.map(entry => new RegExp(
`^(https?:)?//([A-Za-z0-9-]*\\.)?${entry}(/.*)?`,
'i'));
@ -655,7 +655,7 @@ class BattleLog {
return false;
},
getURI(uri: string) {
return 'http://pokemonshowdown.com/interstice?uri=' + encodeURIComponent(uri);
return `http://${Config.routes.root}/interstice?uri=${encodeURIComponent(uri)}`;
},
};
})();
@ -892,20 +892,20 @@ class BattleLog {
let buf = '<!DOCTYPE html>\n';
buf += '<meta charset="utf-8" />\n';
buf += '<!-- version 1 -->\n';
buf += '<title>' + BattleLog.escapeHTML(battle.tier) + ' replay: ' + BattleLog.escapeHTML(battle.p1.name) + ' vs. ' + BattleLog.escapeHTML(battle.p2.name) + '</title>\n';
buf += `<title>${BattleLog.escapeHTML(battle.tier)} replay: ${BattleLog.escapeHTML(battle.p1.name)} vs. ${BattleLog.escapeHTML(battle.p2.name)}</title>\n`;
buf += '<style>\n';
buf += 'html,body {font-family:Verdana, sans-serif;font-size:10pt;margin:0;padding:0;}body{padding:12px 0;} .battle-log {font-family:Verdana, sans-serif;font-size:10pt;} .battle-log-inline {border:1px solid #AAAAAA;background:#EEF2F5;color:black;max-width:640px;margin:0 auto 80px;padding-bottom:5px;} .battle-log .inner {padding:4px 8px 0px 8px;} .battle-log .inner-preempt {padding:0 8px 4px 8px;} .battle-log .inner-after {margin-top:0.5em;} .battle-log h2 {margin:0.5em -8px;padding:4px 8px;border:1px solid #AAAAAA;background:#E0E7EA;border-left:0;border-right:0;font-family:Verdana, sans-serif;font-size:13pt;} .battle-log .chat {vertical-align:middle;padding:3px 0 3px 0;font-size:8pt;} .battle-log .chat strong {color:#40576A;} .battle-log .chat em {padding:1px 4px 1px 3px;color:#000000;font-style:normal;} .chat.mine {background:rgba(0,0,0,0.05);margin-left:-8px;margin-right:-8px;padding-left:8px;padding-right:8px;} .spoiler {color:#BBBBBB;background:#BBBBBB;padding:0px 3px;} .spoiler:hover, .spoiler:active, .spoiler-shown {color:#000000;background:#E2E2E2;padding:0px 3px;} .spoiler a {color:#BBBBBB;} .spoiler:hover a, .spoiler:active a, .spoiler-shown a {color:#2288CC;} .chat code, .chat .spoiler:hover code, .chat .spoiler:active code, .chat .spoiler-shown code {border:1px solid #C0C0C0;background:#EEEEEE;color:black;padding:0 2px;} .chat .spoiler code {border:1px solid #CCCCCC;background:#CCCCCC;color:#CCCCCC;} .battle-log .rated {padding:3px 4px;} .battle-log .rated strong {color:white;background:#89A;padding:1px 4px;border-radius:4px;} .spacer {margin-top:0.5em;} .message-announce {background:#6688AA;color:white;padding:1px 4px 2px;} .message-announce a, .broadcast-green a, .broadcast-blue a, .broadcast-red a {color:#DDEEFF;} .broadcast-green {background-color:#559955;color:white;padding:2px 4px;} .broadcast-blue {background-color:#6688AA;color:white;padding:2px 4px;} .infobox {border:1px solid #6688AA;padding:2px 4px;} .infobox-limited {max-height:200px;overflow:auto;overflow-x:hidden;} .broadcast-red {background-color:#AA5544;color:white;padding:2px 4px;} .message-learn-canlearn {font-weight:bold;color:#228822;text-decoration:underline;} .message-learn-cannotlearn {font-weight:bold;color:#CC2222;text-decoration:underline;} .message-effect-weak {font-weight:bold;color:#CC2222;} .message-effect-resist {font-weight:bold;color:#6688AA;} .message-effect-immune {font-weight:bold;color:#666666;} .message-learn-list {margin-top:0;margin-bottom:0;} .message-throttle-notice, .message-error {color:#992222;} .message-overflow, .chat small.message-overflow {font-size:0pt;} .message-overflow::before {font-size:9pt;content:\'...\';} .subtle {color:#3A4A66;}\n';
buf += '</style>\n';
buf += '<div class="wrapper replay-wrapper" style="max-width:1180px;margin:0 auto">\n';
buf += '<input type="hidden" name="replayid" value="' + replayid + '" />\n';
buf += '<div class="battle"></div><div class="battle-log"></div><div class="replay-controls"></div><div class="replay-controls-2"></div>\n';
buf += '<h1 style="font-weight:normal;text-align:center"><strong>' + BattleLog.escapeHTML(battle.tier) + '</strong><br /><a href="http://pokemonshowdown.com/users/' + toID(battle.p1.name) + '" class="subtle" target="_blank">' + BattleLog.escapeHTML(battle.p1.name) + '</a> vs. <a href="http://pokemonshowdown.com/users/' + toID(battle.p2.name) + '" class="subtle" target="_blank">' + BattleLog.escapeHTML(battle.p2.name) + '</a></h1>\n';
buf += `<h1 style="font-weight:normal;text-align:center"><strong>${BattleLog.escapeHTML(battle.tier)}</strong><br /><a href="http://${Config.routes.users}/${toID(battle.p1.name)}" class="subtle" target="_blank">${BattleLog.escapeHTML(battle.p1.name)}</a> vs. <a href="http://${Config.routes.users}/${toID(battle.p2.name)}" class="subtle" target="_blank">${BattleLog.escapeHTML(battle.p2.name)}</a></h1>\n`;
buf += '<script type="text/plain" class="battle-log-data">' + battle.activityQueue.join('\n').replace(/\//g, '\\/') + '</script>\n'; // lgtm [js/incomplete-sanitization]
buf += '</div>\n';
buf += '<div class="battle-log battle-log-inline"><div class="inner">' + battle.scene.log.elem.innerHTML + '</div></div>\n';
buf += '</div>\n';
buf += '<script>\n';
buf += 'let daily = Math.floor(Date.now()/1000/60/60/24);document.write(\'<script src="https://play.pokemonshowdown.com/js/replay-embed.js?version\'+daily+\'"></\'+\'script>\');\n';
buf += `let daily = Math.floor(Date.now()/1000/60/60/24);document.write('<script src="https://${Config.routes.client}/js/replay-embed.js?version'+daily+'"></'+'script>');\n`;
buf += '</script>\n';
return buf;
}

View File

@ -8,7 +8,7 @@
*/
class PSSearchResults extends preact.Component<{search: DexSearch}> {
readonly URL_ROOT = '//dex.pokemonshowdown.com/';
readonly URL_ROOT = `//${Config.routes.dex}/`;
renderPokemonSortRow() {
const search = this.props.search;

View File

@ -57,7 +57,7 @@ const PSLoginServer = new class {
query(data: {}, callback: (res: {[k: string]: any} | null) => void) {
let url = '/~~' + PS.server.id + '/action.php';
if (location.pathname.endsWith('.html')) {
url = 'https://play.pokemonshowdown.com' + url;
url = 'https://' + Config.routes.client + url;
// @ts-ignore
if (typeof POKEMON_SHOWDOWN_TESTCLIENT_KEY === 'string') {
// @ts-ignore

View File

@ -82,10 +82,7 @@ if (!window.console) {
*********************************************************************/
// PS's model classes are defined here
const PSURL = (
(document.location!.protocol !== 'http:' ? 'https:' : '') +
'//play.pokemonshowdown.com/'
);
const PSURL = `${document.location!.protocol !== 'http:' ? 'https:' : ''}//${Config.routes.client}/`;
class PSSubscription {
observable: PSModel | PSStreamModel<any>;
@ -215,7 +212,7 @@ const PSBackground = new class extends PSStreamModel {
if (!bgid) {
if (location.host === 'smogtours.psim.us') {
bgid = 'shaymin';
} else if (location.host === 'play.pokemonshowdown.com') {
} else if (location.host === Config.routes.client) {
const bgs = ['horizon', 'ocean', 'waterfall', 'shaymin', 'charizards'];
bgid = bgs[Math.floor(Math.random() * 5)];
if (bgid === this.curId) bgid = bgs[Math.floor(Math.random() * 5)];

View File

@ -59,7 +59,7 @@ class PSPrefs extends PSStreamModel<string | null> {
storageEngine: 'localStorage' | 'iframeLocalStorage' | '' = '';
storage: {[k: string]: any} = {};
readonly origin = 'https://play.pokemonshowdown.com';
readonly origin = `https://${Config.routes.client}`;
constructor() {
super();
@ -222,7 +222,7 @@ class PSTeams extends PSStreamModel<'team' | 'format'> {
this.byKey[team.key] = team;
}
unpackOldBuffer(buffer: string) {
alert("Your team storage format is too old for PS. You'll need to upgrade it at https://play.pokemonshowdown.com/recoverteams.html");
alert(`Your team storage format is too old for PS. You'll need to upgrade it at https://${Config.routes.client}/recoverteams.html`);
this.list = [];
return;
}
@ -298,13 +298,13 @@ interface PSGroup {
}
class PSServer {
id = 'showdown';
host = 'sim3.psim.us';
port = 8000;
altport = 80;
registered = true;
id = Config.defaultserver.id;
host = Config.defaultserver.host;
port = Config.defaultserver.port;
altport = Config.defaultserver.altport;
registered = Config.defaultserver.registered;
prefix = '/showdown';
protocol: 'http' | 'https' = 'https';
protocol: 'http' | 'https' = Config.defaultserver.https ? 'https' : 'http';
groups: {[symbol: string]: PSGroup} = {
'~': {
name: "Administrator (~)",

View File

@ -306,7 +306,7 @@ class MainMenuPanel extends PSRoomPanel<MainMenuRoom> {
}
<p>
<div style={{textAlign: 'center'}}>
<img width="96" height="96" src="//play.pokemonshowdown.com/sprites/gen5/teddiursa.png" alt="" />
<img width="96" height="96" src={`//${Config.routes.client}/sprites/gen5/teddiursa.png`} alt="" />
</div>
Bear with us as we freak out.
</p>
@ -349,10 +349,10 @@ class MainMenuPanel extends PSRoomPanel<MainMenuRoom> {
<div class="mainmenufooter">
<div class="bgcredit"></div>
<small>
<a href="//dex.pokemonshowdown.com/" target="_blank">Pok&eacute;dex</a> | {}
<a href="//replay.pokemonshowdown.com/" target="_blank">Replays</a> | {}
<a href="//pokemonshowdown.com/rules" target="_blank">Rules</a> | {}
<a href="//pokemonshowdown.com/credits" target="_blank">Credits</a> | {}
<a href={`//${Config.routes.dex}/`} target="_blank">Pok&eacute;dex</a> | {}
<a href={`//${Config.routes.replays}/`} target="_blank">Replays</a> | {}
<a href={`//${Config.routes.root}/rules`} target="_blank">Rules</a> | {}
<a href={`//${Config.routes.dex}/credits`} target="_blank">Credits</a> | {}
<a href="//smogon.com/forums/" target="_blank">Forum</a>
</small>
</div>
@ -414,12 +414,12 @@ class TeamDropdown extends preact.Component<{format: string}> {
<div class="team">
<strong>Random team</strong>
<small>
<span class="picon" style="float:left;background:transparent url(https://play.pokemonshowdown.com/sprites/pokemonicons-sheet.png?a6) no-repeat scroll -0px -0px"></span>
<span class="picon" style="float:left;background:transparent url(https://play.pokemonshowdown.com/sprites/pokemonicons-sheet.png?a6) no-repeat scroll -0px -0px"></span>
<span class="picon" style="float:left;background:transparent url(https://play.pokemonshowdown.com/sprites/pokemonicons-sheet.png?a6) no-repeat scroll -0px -0px"></span>
<span class="picon" style="float:left;background:transparent url(https://play.pokemonshowdown.com/sprites/pokemonicons-sheet.png?a6) no-repeat scroll -0px -0px"></span>
<span class="picon" style="float:left;background:transparent url(https://play.pokemonshowdown.com/sprites/pokemonicons-sheet.png?a6) no-repeat scroll -0px -0px"></span>
<span class="picon" style="float:left;background:transparent url(https://play.pokemonshowdown.com/sprites/pokemonicons-sheet.png?a6) no-repeat scroll -0px -0px"></span>
<span class="picon" style={`float:left;background:transparent url(https://${Config.routes.client}/sprites/pokemonicons-sheet.png?a6) no-repeat scroll -0px -0px`}></span>
<span class="picon" style={`float:left;background:transparent url(https://${Config.routes.client}/sprites/pokemonicons-sheet.png?a6) no-repeat scroll -0px -0px`}></span>
<span class="picon" style={`float:left;background:transparent url(https://${Config.routes.client}/sprites/pokemonicons-sheet.png?a6) no-repeat scroll -0px -0px`}></span>
<span class="picon" style={`float:left;background:transparent url(https://${Config.routes.client}/sprites/pokemonicons-sheet.png?a6) no-repeat scroll -0px -0px`}></span>
<span class="picon" style={`float:left;background:transparent url(https://${Config.routes.client}/sprites/pokemonicons-sheet.png?a6) no-repeat scroll -0px -0px`}></span>
<span class="picon" style={`float:left;background:transparent url(https://${Config.routes.client}/sprites/pokemonicons-sheet.png?a6) no-repeat scroll -0px -0px`}></span>
</small>
</div>
</button>;

View File

@ -88,8 +88,8 @@ class PSHeader extends preact.Component<{style: {}}> {
return <div id="header" class="header" style={this.props.style}>
<img
class="logo"
src="https://play.pokemonshowdown.com/pokemonshowdownbeta.png"
srcset="https://play.pokemonshowdown.com/pokemonshowdownbeta@2x.png 2x"
src={`https://${Config.routes.client}/pokemonshowdownbeta.png`}
srcset={`https://${Config.routes.client}/pokemonshowdownbeta@2x.png 2x`}
alt="Pokémon Showdown! (beta)"
width="146" height="44"
/>
@ -227,7 +227,7 @@ class UserPanel extends PSRoomPanel<UserRoom> {
src={Dex.resolveAvatar('' + (user.avatar || 'unknown'))}
/>
}
<strong><a href={`//pokemonshowdown.com/users/${user.userid}`} target="_blank" style={away ? {color: '#888888'} : null}>{name}</a></strong><br />
<strong><a href={`//${Config.routes.users}/${user.userid}`} target="_blank" style={away ? {color: '#888888'} : null}>{name}</a></strong><br />
{status && <div class="userstatus">{status}</div>}
{groupName && <div class="usergroup roomgroup">{groupName}</div>}
{globalGroupName && <div class="usergroup globalgroup">{globalGroupName}</div>}

View File

@ -299,7 +299,7 @@ class PSMain extends preact.Component {
if (href) {
// yes that's what we needed
} else if (PS.server.id === 'showdown') {
if (elem.host && elem.host !== 'play.pokemonshowdown.com' && elem.host !== 'psim.us') {
if (elem.host && elem.host !== Config.routes.client && elem.host !== 'psim.us') {
return null;
}
href = elem.pathname;

View File

@ -51,6 +51,7 @@
linkStyle("style/battle-search.css");
linkStyle("style/font-awesome.css");
</script>
<script src="https://play.pokemonshowdown.com/config/config.js"></script>
<script src="config/testclient-key.js"></script>
<script src="js/client-core.js"></script>

View File

@ -12,13 +12,14 @@
<link rel="stylesheet" href="style/font-awesome.css" />
<meta name="robots" content="noindex" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<script src="https://play.pokemonshowdown.com/config/config.js"></script>
<script>
function loadRemoteData(src) {
var scriptEl = document.createElement('script');
scriptEl.src = src.replace(/.*\/?data\//g, 'https://play.pokemonshowdown.com/data/');
document.head.appendChild(scriptEl);
}
var Config = {testclient: true};
Config.testclient = true;
(function() {
if (location.search !== '') {
var m = /\?~~(([^:\/]*)(:[0-9]*)?)/.exec(location.search);
@ -85,7 +86,6 @@
window.exports = window;
</script>
<script src="https://play.pokemonshowdown.com/config/config.js"></script>
<script src="js/battledata.js" onerror="alert('You must build the client with `node build` before using testclient.html')"></script>
<script src="data/pokedex-mini.js" onerror="loadRemoteData(this.src)"></script>
<script src="data/pokedex-mini-bw.js" onerror="loadRemoteData(this.src)"></script>