pokemon-showdown-client/crossdomain.php
Guangcong Luo cf8bb24e71 Refactor data storage
Data (teams and prefs) are now always stored in localStorage in the
`https://play.pokemonshowdown.com` origin. Data storage at a low
level has been mostly rewritten for this, and moved to storage.js.

Tools.prefs has been renamed Storage.prefs, although the API
Tools.prefs(prefName) is still available, and recommended for
battle.js (because storage.js isn't available in replays). All
other pref functionality, such as setting prefs and saving prefs,
should only be used in Storage.prefs.

If the browser blocks third-party cookies in a detectable way,
data is instead stored in the local origin.

As a final safety measure, prefs/teams are mirrored in the local origin
in case third-party cookies are blocked in an undetectable way.

This refactor also replaces the 'init:loadprefs' and 'init:loadteams'
events with a new load tracking system that's basically a simplified
implementation of Promises, documented in the comments for
Tools.makeLoadTracker().
2015-11-28 04:36:41 -05:00

155 lines
4.2 KiB
PHP

<?php
$config = array();
$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') {
$config['host'] = 'showdown';
} else {
die; // not authorised
}
include_once '../pokemonshowdown.com/config/servers.inc.php';
$hyphenpos = strrpos($config['host'], '-');
if ($hyphenpos) {
$postfix = substr($config['host'], $hyphenpos + 1);
if ($postfix === 'afd') {
$config['afd'] = true;
$config['host'] = substr($config['host'], 0, $hyphenpos);
} else if (ctype_digit($postfix)) {
$config['port'] = intval(substr($config['host'], $hyphenpos + 1));
$config['host'] = substr($config['host'], 0, $hyphenpos);
}
}
$config['id'] = $config['host'];
if (isset($PokemonServers[$config['host']])) {
$server =& $PokemonServers[$config['host']];
if (@$server['banned']) {
$config['banned'] = true;
} else {
$config['host'] = $server['server'];
if (!isset($config['port'])) {
$config['port'] = $server['port'];
} else if ($config['port'] !== $server['port']) {
$config['id'] .= ':' . $config['port'];
}
if (isset($server['altport'])) $config['altport'] = $server['altport'];
$config['registered'] = true;
// $yourip = $_SERVER['REMOTE_ADDR'];
$yourip = @$_SERVER['HTTP_X_FORWARDED_FOR'];
if (substr($config['host'].':', 0, strlen($yourip)+1) === $yourip.':') {
$config['host'] = 'localhost'.substr($config['host'],strlen($yourip));
}
}
} else {
if (isset($config['port'])) {
$config['id'] .= ':' . $config['port'];
} else {
$config['port'] = 8000; // default port
}
// see if this is actually a registered server
if ($config['host'] !== 'localhost') {
foreach ($PokemonServers as &$server) {
if ($config['host'] === $server['server'] && (
$config['port'] === $server['port'] ||
(isset($server['altport']) && $config['port'] === $server['altport'])
)) {
$path = isset($_REQUEST['path']) ? $_REQUEST['path'] : '';
$config['redirect'] = 'http://' . $server['id'] . '.psim.us/' . rawurlencode($path);
break;
}
}
}
}
if (@$config['redirect']) {
?>
<!DOCTYPE html>
<meta charset="utf-8" />
<script>
parent.location.replace(<?= json_encode($config['redirect']) ?>);
</script>
<?php
die();
}
// For Internet Explorer.
// See http://www.p3pwriter.com/LRN_111.asp
// See also http://stackoverflow.com/questions/389456/cookie-blocked-not-saved-in-iframe-in-internet-explorer
//
// The privacy fields specified here should be accurate.
header('P3P: CP="NOI CUR ADM DEV COM NAV STA OUR IND"');
?>
<!DOCTYPE html>
<meta charset="utf-8" />
<script src="/js/lib/jquery-2.1.4.min.js"></script>
<body>
<script>
var config = <?php echo json_encode(json_encode($config)) ?>;
var yourOrigin = <?php echo json_encode('http://' . $host) ?>;
var myOrigin = 'https://play.pokemonshowdown.com';
function postMessage (message) {
return window.parent.postMessage(message, yourOrigin);
}
function messageHandler(e) {
if (e.origin !== yourOrigin) return;
var data = e.data;
// data's first char:
// T: store teams
// P: store prefs
// R: GET request
// S: POST request
switch (data.charAt(0)) {
case 'T':
localStorage.setItem('showdown_teams', data.substr(1));
break;
case 'P':
localStorage.setItem('showdown_prefs', data.substr(1));
break;
case 'R':
case 'S':
var rq = JSON.parse(data.substr(1));
$.ajax({
type: (data.charAt(0) === 'R' ? 'GET' : 'POST'),
url: rq[0],
data: rq[1],
success: function(ajaxdata) {
postMessage('r' + JSON.stringify([rq[2], ajaxdata]));
},
dataType: rq[3]
});
break;
}
}
window.addEventListener('message', messageHandler);
postMessage('c' + config);
var testVal = '' + Date.now();
try {
localStorage.setItem('showdown_allow3p', testVal);
} catch (err) {}
if (localStorage.getItem('showdown_allow3p') === testVal) {
postMessage('a1');
postMessage('p' + localStorage.getItem('showdown_prefs'));
postMessage('t' + localStorage.getItem('showdown_teams'));
} else {
postMessage('a0');
}
if (location.origin !== myOrigin) {
// This happens sometimes, but we'll pretend it doesn't
}
</script>