diff --git a/.gitignore b/.gitignore
index 2a507e2b8..6dbcbd266 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,7 @@ Thumbs.db
npm-debug.log
package-lock.json
/vendor/
+node_modules
/js/server/
/js/*.js.map
@@ -23,15 +24,14 @@ package-lock.json
/js/client-core.js
/js/client-connection.js
-/replays/caches/
-/replays/replay-config.inc.php
-/replays/theme/wrapper.inc.php
-
/website/.well-known/
/website/.pages-cached/
/website/files/
/website/images/
/website/ads.txt
-/website/replays/index.html
-/website/replays/js/
-node_modules
+
+/replay.pokemonshowdown.com/index.html
+/replay.pokemonshowdown.com/js/
+/replay.pokemonshowdown.com/caches/
+/replay.pokemonshowdown.com/replay-config.inc.php
+/replay.pokemonshowdown.com/theme/wrapper.inc.php
diff --git a/build-tools/update b/build-tools/update
index a391751c6..d6f70466b 100755
--- a/build-tools/update
+++ b/build-tools/update
@@ -100,7 +100,7 @@ if (process.argv[2] === 'full') {
compiledFiles += compiler.compileToDir(`src`, `js`, compileOpts);
-compiledFiles += compiler.compileToDir(`website/replays/src`, `website/replays/js`, compileOpts);
+compiledFiles += compiler.compileToDir(`replay.pokemonshowdown.com/src`, `replay.pokemonshowdown.com/js`, compileOpts);
compiledFiles += compiler.compileToFile(
['src/battle-dex.ts', 'src/battle-dex-data.ts', 'src/battle-log.ts', 'src/battle-log-misc.js', 'data/pokemon-showdown/server/chat-formatter.ts', 'data/text.js', 'src/battle-text-parser.ts'],
@@ -149,7 +149,7 @@ function updateURL(a, b, c, d) {
// hardcoded to Replays rn; TODO: generalize
let hash;
try {
- const fstr = fs.readFileSync('website/replays/' + c, {encoding: 'utf8'});
+ const fstr = fs.readFileSync('replay.pokemonshowdown.com/' + c, {encoding: 'utf8'});
hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8);
} catch (e) {}
@@ -166,9 +166,9 @@ function writeFiles(indexContents, preactIndexContents, crossprotocolContents, r
fs.writeFileSync('crossprotocol.html', crossprotocolContents);
fs.writeFileSync('js/replay-embed.js', replayEmbedContents);
- let replaysContents = fs.readFileSync('website/replays/index.template.html', {encoding: 'utf8'});
+ let replaysContents = fs.readFileSync('replay.pokemonshowdown.com/index.template.html', {encoding: 'utf8'});
replaysContents = replaysContents.replace(URL_REGEX, updateURL);
- fs.writeFileSync('website/replays/index.html', replaysContents);
+ fs.writeFileSync('replay.pokemonshowdown.com/index.html', replaysContents);
console.log("DONE");
}
diff --git a/replays/.htaccess b/old-replays/.htaccess
similarity index 100%
rename from replays/.htaccess
rename to old-replays/.htaccess
diff --git a/replays/404.php b/old-replays/404.php
similarity index 100%
rename from replays/404.php
rename to old-replays/404.php
diff --git a/replays/503.php b/old-replays/503.php
similarity index 100%
rename from replays/503.php
rename to old-replays/503.php
diff --git a/replays/apple-touch-icon.png b/old-replays/apple-touch-icon.png
similarity index 100%
rename from replays/apple-touch-icon.png
rename to old-replays/apple-touch-icon.png
diff --git a/replays/build b/old-replays/build
similarity index 100%
rename from replays/build
rename to old-replays/build
diff --git a/replays/converter.lib.php b/old-replays/converter.lib.php
similarity index 100%
rename from replays/converter.lib.php
rename to old-replays/converter.lib.php
diff --git a/replays/favicon.ico b/old-replays/favicon.ico
similarity index 100%
rename from replays/favicon.ico
rename to old-replays/favicon.ico
diff --git a/replays/index.php b/old-replays/index.php
similarity index 100%
rename from replays/index.php
rename to old-replays/index.php
diff --git a/replays/js/ou-305002749.log b/old-replays/js/ou-305002749.log
similarity index 100%
rename from replays/js/ou-305002749.log
rename to old-replays/js/ou-305002749.log
diff --git a/replays/js/smogtours-ou-509.log b/old-replays/js/smogtours-ou-509.log
similarity index 100%
rename from replays/js/smogtours-ou-509.log
rename to old-replays/js/smogtours-ou-509.log
diff --git a/replays/ps_prepreplays.sql b/old-replays/ps_prepreplays.sql
similarity index 100%
rename from replays/ps_prepreplays.sql
rename to old-replays/ps_prepreplays.sql
diff --git a/replays/ps_replays.sql b/old-replays/ps_replays.sql
similarity index 100%
rename from replays/ps_replays.sql
rename to old-replays/ps_replays.sql
diff --git a/replays/search.json.php b/old-replays/search.json.php
similarity index 100%
rename from replays/search.json.php
rename to old-replays/search.json.php
diff --git a/website/replays/search.notjson.php b/old-replays/search.notjson.php
similarity index 100%
rename from website/replays/search.notjson.php
rename to old-replays/search.notjson.php
diff --git a/replays/search.php b/old-replays/search.php
similarity index 100%
rename from replays/search.php
rename to old-replays/search.php
diff --git a/website/replays/search.json.php b/old-replays/search.yesjson.php
similarity index 100%
rename from website/replays/search.json.php
rename to old-replays/search.yesjson.php
diff --git a/replays/turn-image.php b/old-replays/turn-image.php
similarity index 100%
rename from replays/turn-image.php
rename to old-replays/turn-image.php
diff --git a/replays/warstory.php b/old-replays/warstory.php
similarity index 100%
rename from replays/warstory.php
rename to old-replays/warstory.php
diff --git a/replay.pokemonshowdown.com/.htaccess b/replay.pokemonshowdown.com/.htaccess
new file mode 100644
index 000000000..92b3bd965
--- /dev/null
+++ b/replay.pokemonshowdown.com/.htaccess
@@ -0,0 +1,7 @@
+RewriteEngine on
+RewriteRule ^api(/.*)?$ http://localhost:9000/api$1 [P,L]
+
+RewriteRule ^([A-Za-z0-9-]+)$ replay.php?name=$1 [L,QSA]
+RewriteRule ^([A-Za-z0-9-]+)/manage$ replay-manage.php?name=$1&manage [L,QSA]
+RewriteRule ^([A-Za-z0-9-]+)\.log$ replay.log.php?name=$1 [L,QSA]
+RewriteRule ^([A-Za-z0-9-]+)\.json$ replay.log.php?json&name=$1 [L,QSA]
diff --git a/replay.pokemonshowdown.com/404.html b/replay.pokemonshowdown.com/404.html
new file mode 100644
index 000000000..53270ae24
--- /dev/null
+++ b/replay.pokemonshowdown.com/404.html
@@ -0,0 +1,75 @@
+
+
+
+
+
Replay Not Found - Pokémon Showdown!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Not Found
+
+ The battle you're looking for has expired. Battles expire after 15 minutes of inactivity unless they're saved.
+
+
+ In the future, remember to click Upload and share replay to save a replay permanently.
+
+
+
+
+
+
+
+
diff --git a/replays/README.md b/replay.pokemonshowdown.com/README.md
similarity index 100%
rename from replays/README.md
rename to replay.pokemonshowdown.com/README.md
diff --git a/replay.pokemonshowdown.com/apple-touch-icon.png b/replay.pokemonshowdown.com/apple-touch-icon.png
new file mode 100644
index 000000000..00fe674b8
Binary files /dev/null and b/replay.pokemonshowdown.com/apple-touch-icon.png differ
diff --git a/replay.pokemonshowdown.com/check-login.php b/replay.pokemonshowdown.com/check-login.php
new file mode 100644
index 000000000..28f50036c
--- /dev/null
+++ b/replay.pokemonshowdown.com/check-login.php
@@ -0,0 +1,17 @@
+
+ * @license MIT
+ */
+
+require '../lib/ntbb-session.lib.php';
+
+echo ']' . ($curuser['loggedin'] ? $curuser['userid'] : '') . ',';
+
+echo $users->isSysop() ? '1' : '';
diff --git a/replay.pokemonshowdown.com/favicon.ico b/replay.pokemonshowdown.com/favicon.ico
new file mode 100644
index 000000000..cf7439e08
Binary files /dev/null and b/replay.pokemonshowdown.com/favicon.ico differ
diff --git a/website/replays/index.template.html b/replay.pokemonshowdown.com/index.template.html
similarity index 80%
rename from website/replays/index.template.html
rename to replay.pokemonshowdown.com/index.template.html
index c09b33718..b1cb01f68 100644
--- a/website/replays/index.template.html
+++ b/replay.pokemonshowdown.com/index.template.html
@@ -4,7 +4,21 @@
Replays - Pokémon Showdown!
-
+
+
+
@@ -122,11 +136,11 @@
diff --git a/replays/replay-config.example.inc.php b/replay.pokemonshowdown.com/replay-config.example.inc.php
similarity index 100%
rename from replays/replay-config.example.inc.php
rename to replay.pokemonshowdown.com/replay-config.example.inc.php
diff --git a/replays/battle.php b/replay.pokemonshowdown.com/replay-manage.php
similarity index 100%
rename from replays/battle.php
rename to replay.pokemonshowdown.com/replay-manage.php
diff --git a/replays/battle.log.php b/replay.pokemonshowdown.com/replay.log.php
similarity index 68%
rename from replays/battle.log.php
rename to replay.pokemonshowdown.com/replay.log.php
index 5b5aeb615..aa5f3dc1c 100644
--- a/replays/battle.log.php
+++ b/replay.pokemonshowdown.com/replay.log.php
@@ -1,22 +1,22 @@
+ * @license MIT
+ */
+
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
$manage = false;
-// if (@$_REQUEST['name'] === 'smogtours-ou-509') {
-// header('Content-type: text/plain');
-// readfile('js/smogtours-ou-509.log');
-// die();
-// }
-// if (@$_REQUEST['name'] === 'ou-305002749') {
-// header('Content-type: text/plain');
-// readfile('js/ou-305002749.log');
-// die();
-// }
-
require_once 'replays.lib.php';
$replay = null;
@@ -31,8 +31,21 @@ if (substr($id, -2) === 'pw') {
// die($id . ' ' . $password);
}
+// $forcecache = isset($_REQUEST['forcecache8723']);
+$forcecache = false;
if ($id) {
- $replay = $Replays->get($id);
+ if (file_exists('caches/' . $id . '.inc.php')) {
+ include 'caches/' . $id . '.inc.php';
+ $replay['formatid'] = '';
+ $cached = true;
+ } else {
+ require_once 'replays.lib.php';
+ if (!$Replays->db && !$forcecache) {
+ header('HTTP/1.1 503 Service Unavailable');
+ die();
+ }
+ $replay = $Replays->get($id, $forcecache);
+ }
}
if (!$replay) {
header('HTTP/1.1 404 Not Found');
diff --git a/replay.pokemonshowdown.com/replay.php b/replay.pokemonshowdown.com/replay.php
new file mode 100644
index 000000000..fb3546506
--- /dev/null
+++ b/replay.pokemonshowdown.com/replay.php
@@ -0,0 +1,64 @@
+
+ * @license MIT
+ */
+
+error_reporting(E_ALL);
+ini_set('display_errors', TRUE);
+ini_set('display_startup_errors', TRUE);
+
+$manage = false;
+
+require_once 'replays.lib.php';
+
+$replay = null;
+$id = $_REQUEST['name'] ?? '';
+$password = '';
+
+$fullid = $id;
+if (substr($id, -2) === 'pw') {
+ $dashpos = strrpos($id, '-');
+ $password = substr($id, $dashpos + 1, -2);
+ $id = substr($id, 0, $dashpos);
+ // die($id . ' ' . $password);
+}
+
+// $forcecache = isset($_REQUEST['forcecache8723']);
+$forcecache = false;
+if ($id) {
+ if (file_exists('caches/' . $id . '.inc.php')) {
+ include 'caches/' . $id . '.inc.php';
+ $replay['formatid'] = '';
+ $cached = true;
+ } else {
+ require_once 'replays.lib.php';
+ if (!$Replays->db && !$forcecache) {
+ header('HTTP/1.1 503 Service Unavailable');
+ die();
+ }
+ $replay = $Replays->exists($id, $forcecache);
+ }
+}
+if (!$replay) {
+ header('HTTP/1.1 404 Not Found');
+ include '404.html';
+ die();
+}
+if ($replay['password'] ?? null) {
+ if ($password !== $replay['password']) {
+ header('HTTP/1.1 404 Not Found');
+ include '404.html';
+ die();
+ }
+}
+
+include 'index.html';
diff --git a/replays/replays.lib.php b/replay.pokemonshowdown.com/replays.lib.php
similarity index 97%
rename from replays/replays.lib.php
rename to replay.pokemonshowdown.com/replays.lib.php
index a7329159a..3c1087365 100644
--- a/replays/replays.lib.php
+++ b/replay.pokemonshowdown.com/replays.lib.php
@@ -65,6 +65,21 @@ class Replays {
return $replay;
}
+ function exists($id, $forcecache = false) {
+ if ($forcecache) return null;
+
+ if (!$this->db) {
+ $this->init();
+ }
+
+ $res = $this->db->prepare("SELECT id, password FROM ps_replays WHERE id = ? LIMIT 1");
+ $res->execute([$id]);
+ if (!$res) return null;
+ $replay = $res->fetch();
+ if (!$replay) return null;
+
+ return $replay;
+ }
function edit(&$replay) {
if ($replay['private'] === 3) {
$replay['private'] = 3;
diff --git a/replays/js/replay.js b/replay.pokemonshowdown.com/src/replay.js
similarity index 99%
rename from replays/js/replay.js
rename to replay.pokemonshowdown.com/src/replay.js
index 6c9da9a3b..ac7c4ac12 100644
--- a/replays/js/replay.js
+++ b/replay.pokemonshowdown.com/src/replay.js
@@ -1,3 +1,5 @@
+// preserved for replay management
+
/* function updateProgress(done, a, b)
{
if (!battle.paused) return;
diff --git a/website/replays/src/replays-battle.tsx b/replay.pokemonshowdown.com/src/replays-battle.tsx
similarity index 98%
rename from website/replays/src/replays-battle.tsx
rename to replay.pokemonshowdown.com/src/replays-battle.tsx
index fb1e3dcdb..f7d1a42ed 100644
--- a/website/replays/src/replays-battle.tsx
+++ b/replay.pokemonshowdown.com/src/replays-battle.tsx
@@ -3,9 +3,9 @@ import preact from 'preact';
import $ from 'jquery';
import {Net} from './utils';
import {PSRouter} from './replays';
-import {Battle} from '../../../src/battle';
-import {BattleLog} from '../../../src/battle-log';
-import {BattleSound} from '../../../src/battle-sound';
+import {Battle} from '../../src/battle';
+import {BattleLog} from '../../src/battle-log';
+import {BattleSound} from '../../src/battle-sound';
declare function toID(input: string): string;
function showAd(id: string) {
@@ -94,7 +94,7 @@ export class BattlePanel extends preact.Component<{id: string}> {
this.battle = null;
this.result = undefined;
- Net(`https://replay.pokemonshowdown.com/${this.stripQuery(id)}.json`).get().then(result => {
+ Net(`/${this.stripQuery(id)}.json`).get().then(result => {
const replay: NonNullable = JSON.parse(result);
this.result = replay;
const $base = $(this.base!);
diff --git a/website/replays/src/replays.tsx b/replay.pokemonshowdown.com/src/replays.tsx
similarity index 99%
rename from website/replays/src/replays.tsx
rename to replay.pokemonshowdown.com/src/replays.tsx
index 0af6a9a07..3ee3b0441 100644
--- a/website/replays/src/replays.tsx
+++ b/replay.pokemonshowdown.com/src/replays.tsx
@@ -26,7 +26,7 @@ class SearchPanel extends preact.Component<{id: string}> {
loggedInUserIsSysop = false;
sort = 'date';
override componentDidMount() {
- Net('check-login.php').get().then(result => {
+ Net('/check-login.php').get().then(result => {
if (result.charAt(0) !== ']') return;
const [userid, sysop] = result.slice(1).split(',');
this.loggedInUser = userid;
@@ -262,7 +262,7 @@ class FeaturedReplays extends preact.Component {
kdarewolf vs. Onox
Protean + prediction
-
+
[gen6-anythinggoes]
Anta2 vs. dscottnew
Cheek Pouch
diff --git a/website/replays/src/utils.ts b/replay.pokemonshowdown.com/src/utils.ts
similarity index 100%
rename from website/replays/src/utils.ts
rename to replay.pokemonshowdown.com/src/utils.ts
diff --git a/replays/theme/panels.lib.php b/replay.pokemonshowdown.com/theme/panels.lib.php
similarity index 100%
rename from replays/theme/panels.lib.php
rename to replay.pokemonshowdown.com/theme/panels.lib.php
diff --git a/replays/theme/wrapper.inc.template.php b/replay.pokemonshowdown.com/theme/wrapper.inc.template.php
similarity index 100%
rename from replays/theme/wrapper.inc.template.php
rename to replay.pokemonshowdown.com/theme/wrapper.inc.template.php
diff --git a/website/replays/check-login.php b/website/replays/check-login.php
deleted file mode 100644
index 1a8693c8e..000000000
--- a/website/replays/check-login.php
+++ /dev/null
@@ -1,7 +0,0 @@
-isSysop() ? '1' : '';
diff --git a/website/style/global.css b/website/style/global.css
index b9c8c6dcd..9ecce7a9d 100644
--- a/website/style/global.css
+++ b/website/style/global.css
@@ -79,7 +79,8 @@ header {
background: linear-gradient(to bottom, #273661, #4c63a3);
box-shadow: 0.5px 1px 2px rgba(255, 255, 255, 0.45), inset 0.5px 1px -1px rgba(255, 255, 255, 0.5);
}
-.nav a.cur, .nav a.cur:hover, .nav a.cur:active {
+.nav a.cur, .nav a.cur:hover, .nav a.cur:active,
+.dark .nav a.cur, .dark .nav a.cur:hover, .dark .nav a.cur:active {
color: #CCCCCC;
background: rgba(79, 109, 148, 0.7);
box-shadow: 0.5px 1px 2px rgba(255, 255, 255, 0.45);