From 8e378c6129c09ab34f7c85a5e8889e60e5af3533 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Wed, 9 Apr 2025 19:36:58 -0500 Subject: [PATCH] Add static website for viewing server-side teams --- .gitignore | 5 + build-tools/update | 22 +- config/routes.json | 3 +- eslint.config.mjs | 2 + teams.pokemonshowdown.com/.htaccess | 7 + teams.pokemonshowdown.com/404.html | 72 ++++ teams.pokemonshowdown.com/README.md | 5 + .../apple-touch-icon.png | Bin 0 -> 39664 bytes teams.pokemonshowdown.com/favicon.ico | Bin 0 -> 42304 bytes teams.pokemonshowdown.com/index.template.html | 219 +++++++++++ teams.pokemonshowdown.com/src/teams-index.tsx | 75 ++++ .../src/teams-search.tsx | 115 ++++++ teams.pokemonshowdown.com/src/teams-view.tsx | 158 ++++++++ teams.pokemonshowdown.com/src/teams.tsx | 64 +++ teams.pokemonshowdown.com/src/utils.tsx | 370 ++++++++++++++++++ tsconfig.json | 3 +- 16 files changed, 1112 insertions(+), 8 deletions(-) create mode 100644 teams.pokemonshowdown.com/.htaccess create mode 100644 teams.pokemonshowdown.com/404.html create mode 100644 teams.pokemonshowdown.com/README.md create mode 100644 teams.pokemonshowdown.com/apple-touch-icon.png create mode 100644 teams.pokemonshowdown.com/favicon.ico create mode 100644 teams.pokemonshowdown.com/index.template.html create mode 100644 teams.pokemonshowdown.com/src/teams-index.tsx create mode 100644 teams.pokemonshowdown.com/src/teams-search.tsx create mode 100644 teams.pokemonshowdown.com/src/teams-view.tsx create mode 100644 teams.pokemonshowdown.com/src/teams.tsx create mode 100644 teams.pokemonshowdown.com/src/utils.tsx diff --git a/.gitignore b/.gitignore index b9f279805..5c343146e 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,8 @@ npm-debug.log /replay.pokemonshowdown.com/caches/ /replay.pokemonshowdown.com/theme/wrapper.inc.php /replay.pokemonshowdown.com/ads.txt + +/teams.pokemonshowdown.com/js/ +/teams.pokemonshowdown.com/caches/ +/teams.pokemonshowdown.com/index.html +/teams.pokemonshowdown.com/ads.txt diff --git a/build-tools/update b/build-tools/update index 96616c77c..2e9326834 100755 --- a/build-tools/update +++ b/build-tools/update @@ -88,7 +88,7 @@ const compileOpts = Object.assign(eval('(' + fs.readFileSync('.babelrc') + ')'), if (process.argv[2] === 'full') { delete compileOpts.ignore; compiler.compileToDir( - ['caches/pokemon-showdown/server/chat-formatter.ts'], + ['caches/pokemon-showdown/server/chat-formatter.ts', 'caches/pokemon-showdown/sim/teams.ts'], 'play.pokemonshowdown.com/js/server/', compileOpts ); @@ -104,6 +104,8 @@ compiledFiles += compiler.compileToDir(`play.pokemonshowdown.com/src`, `play.pok compiledFiles += compiler.compileToDir(`replay.pokemonshowdown.com/src`, `replay.pokemonshowdown.com/js`, compileOpts); +compiledFiles += compiler.compileToDir(`teams.pokemonshowdown.com/src`, `teams.pokemonshowdown.com/js`, compileOpts); + compiledFiles += compiler.compileToFile( [ 'play.pokemonshowdown.com/src/battle-dex.ts', @@ -145,6 +147,7 @@ function addCachebuster(_, attr, url, urlQuery) { url = url.replace('/dex.pokemonshowdown.com/', '/' + routes.dex + '/'); url = url.replace('/play.pokemonshowdown.com/', '/' + routes.client + '/'); url = url.replace('/pokemonshowdown.com/', '/' + routes.root + '/'); + url = url.replace('/teams.pokemonshowdown.com/', '/' + routes.teams + '/'); if (urlQuery) { if (url.startsWith('/')) { @@ -157,12 +160,15 @@ function addCachebuster(_, attr, url, urlQuery) { return attr + '="' + url + '?' + hash + '"'; } else { - // hardcoded to Replays rn; TODO: generalize + // TODO: generalize better let hash; - try { - const fstr = fs.readFileSync('replay.pokemonshowdown.com/' + url, UTF8); - hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8); - } catch {} + for (const subdir of ['teams', 'replays']) { + if (hash) break; + try { + const fstr = fs.readFileSync(subdir + '.pokemonshowdown.com/' + url, UTF8); + hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8); + } catch {} + } return attr + '="' + url + '?' + (hash || 'v1') + '"'; } @@ -226,4 +232,8 @@ let replaysContents = fs.readFileSync('replay.pokemonshowdown.com/index.template replaysContents = replaysContents.replace(URL_REGEX, addCachebuster); fs.writeFileSync('replay.pokemonshowdown.com/index.php', replaysContents); +let teamsContents = fs.readFileSync('teams.pokemonshowdown.com/index.template.html', UTF8); +teamsContents = teamsContents.replace(URL_REGEX, addCachebuster); +fs.writeFileSync('teams.pokemonshowdown.com/index.html', teamsContents); + console.log("DONE"); diff --git a/config/routes.json b/config/routes.json index 69553f29a..0b1959564 100644 --- a/config/routes.json +++ b/config/routes.json @@ -3,5 +3,6 @@ "client": "play.pokemonshowdown.com", "dex": "dex.pokemonshowdown.com", "replays": "replay.pokemonshowdown.com", - "users": "pokemonshowdown.com/users" + "users": "pokemonshowdown.com/users", + "teams": "teams.pokemonshowdown.com" } diff --git a/eslint.config.mjs b/eslint.config.mjs index 71f81aa74..72f202f1d 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -105,6 +105,8 @@ export default configure([ 'play.pokemonshowdown.com/src/*.tsx', 'replay.pokemonshowdown.com/src/*.ts', 'replay.pokemonshowdown.com/src/*.tsx', + 'teams.pokemonshowdown.com/src/*.ts', + 'teams.pokemonshowdown.com/src/*.tsx', ], extends: [configs.es3ts], languageOptions: { diff --git a/teams.pokemonshowdown.com/.htaccess b/teams.pokemonshowdown.com/.htaccess new file mode 100644 index 000000000..b7e254e16 --- /dev/null +++ b/teams.pokemonshowdown.com/.htaccess @@ -0,0 +1,7 @@ +RewriteEngine on +RewriteRule ^api(/.*)?$ http://localhost:9000/api$1 [P,L] + +RewriteRule ^([A-Za-z0-9-/]+)$ index.html [L,QSA] + +DirectoryIndex index.php index.html /dirindex/dirindex.php +ErrorDocument 404 /dirindex/404.html diff --git a/teams.pokemonshowdown.com/404.html b/teams.pokemonshowdown.com/404.html new file mode 100644 index 000000000..691d118fd --- /dev/null +++ b/teams.pokemonshowdown.com/404.html @@ -0,0 +1,72 @@ + + + + +Team Not Found - Pokémon Showdown! + + + + + + + + + + + + +
+ +
+ +
+ +
+ +
+
+ +
+
+ +
+
+

Not Found

+

+ The team you're looking for is unavailable - either nonexistent or hidden. Check the URL and password? +

+
+ +
+ +
+ + diff --git a/teams.pokemonshowdown.com/README.md b/teams.pokemonshowdown.com/README.md new file mode 100644 index 000000000..3af439c61 --- /dev/null +++ b/teams.pokemonshowdown.com/README.md @@ -0,0 +1,5 @@ +PS teams viewer +=================== + +This is the code powering https://teams.pokemonshowdown.com/ + diff --git a/teams.pokemonshowdown.com/apple-touch-icon.png b/teams.pokemonshowdown.com/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..00fe674b8395b4427d17a8ec02efd2c97f237246 GIT binary patch literal 39664 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∋)^En` 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 Se6Rlj;0yjpSFKLPHvE6;*{-<& literal 0 HcmV?d00001 diff --git a/teams.pokemonshowdown.com/favicon.ico b/teams.pokemonshowdown.com/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..cf7439e089cb5fc368e569c457ed0ba32582a6fd GIT binary patch literal 42304 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%0DpR4H5-j=5 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 + + + +Teams - Pokémon Showdown! + + + + + + + + +

+ +
+ +
+ +
+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/teams.pokemonshowdown.com/src/teams-index.tsx b/teams.pokemonshowdown.com/src/teams-index.tsx new file mode 100644 index 000000000..ef89ecb95 --- /dev/null +++ b/teams.pokemonshowdown.com/src/teams-index.tsx @@ -0,0 +1,75 @@ +/** @jsx preact.h */ +/** @jsxFrag preact.Fragment */ +import preact from '../../play.pokemonshowdown.com/js/lib/preact'; +import { Net, MiniTeam, type ServerTeam } from './utils'; +import type { PageProps } from './teams'; + +declare const toID: (val: any) => string; + +export class TeamIndex extends preact.Component { + override state = { + teams: [] as ServerTeam[], + loggedIn: false as string | false, + loading: true, + search: null as string | null, + }; + constructor(props: PageProps) { + super(props); + this.loadTeams(); + } + loadTeams() { + void Net('/api/getteams').get({ query: { full: 1 } }).then(resultText => { + if (resultText.startsWith(']')) resultText = resultText.slice(1); + let result; + try { + result = JSON.parse(resultText); + } catch { + result = { actionerror: "Malformed response received. Try again later." }; + } + this.setState({ ...result, loading: false }); + }); + } + // todo: find proper type. preact docs unhelpful. + onInput({ currentTarget }: any) { + this.setState({ search: currentTarget.value }); + } + searchMatch(team: ServerTeam) { + const s = toID(this.state.search); + if (!s) return true; + if (!toID(this.state.search)) return true; + if (toID(team.name).includes(s)) return true; + if (toID(team.format).includes(s)) return true; + if (team.team.split(',').map(toID).some(x => x.includes(s))) return true; + if (`${team.teamid}`.startsWith(s)) return true; + return false; + } + render() { + if (this.state.loading) { + return
Loading...
; + } + const teamsByFormat: Record = {}; + for (const team of this.state.teams) { + // this way if a category is empty it doesn't just fill space, since it doesn't + // get added unless it exists + if (!this.searchMatch(team)) continue; + if (!teamsByFormat[team.format]) teamsByFormat[team.format] = []; + teamsByFormat[team.format].push(team); + } + return
+

Hi, {this.state.loggedIn || "guest"}!

+ Go

+ + this.onInput(e)} label="Search teams/formats"> +
+ {!this.state.teams.length ? + You have no teams lol : + Object.entries(teamsByFormat).map(([format, teams]) => ( + <>

{format}:

+
    { + teams.map(team =>
  • ) + }
+
+ ))} +
; + } +} diff --git a/teams.pokemonshowdown.com/src/teams-search.tsx b/teams.pokemonshowdown.com/src/teams-search.tsx new file mode 100644 index 000000000..98b0a7139 --- /dev/null +++ b/teams.pokemonshowdown.com/src/teams-search.tsx @@ -0,0 +1,115 @@ +/** @jsx preact.h */ +/** @jsxFrag preact.Fragment */ +import preact from '../../play.pokemonshowdown.com/js/lib/preact'; +import { Net, type ServerTeam, MiniTeam } from './utils'; +import type { PageProps } from './teams'; + +declare const toID: (val: any) => string; + +const SEARCH_KEYS = ['format', 'owner', 'gen']; + +export class TeamSearcher extends preact.Component { + override state = { + result: [] as ServerTeam[], + curCount: 20, + search: {} as Record, + loading: false, + searchUnchanged: null as null | boolean, + }; + constructor(props: PageProps) { + super(props); + + const url = new URL(location.href); + let makeSearch = false; + for (const key of SEARCH_KEYS) { + const val = url.searchParams.get(key); + if (toID(val)) { + this.state.search[key] = toID(val); + makeSearch = true; + } + if (this.props.args.type === key) { // prioritize url where applicable + const propVal = toID(this.props.args.val); + if (propVal) { + this.state.search[key] = propVal; + makeSearch = true; + } + } + } + const count = Number(url.searchParams.get('count')); + if (!isNaN(count) && count > 0) { + this.state.curCount = count; + } + if (makeSearch) { + this.search(0, true); + } + } + // todo: find proper type. preact docs unhelpful. + onInput(key: string, { currentTarget }: any) { + this.state.search[key] = toID(currentTarget.value); + this.setState({ search: this.state.search }); + } + // format, owner, gen, count params. maxes out at 200. start at 20 and paginate + search(incrementCount = 0, noSetUrl = false) { + this.state.curCount += incrementCount; + this.setState({ + loading: true, + stateUnchanged: true, + curCount: this.state.curCount, + }); + + const url = new URL(location.href); + // clear out old ones so they don't dupe + for (const val in url.searchParams) url.searchParams.delete(val); + // then set new ones + for (const k in this.state.search) { + url.searchParams.set(k, this.state.search[k]); + } + url.searchParams.set('count', `${this.state.curCount}`); + if (!noSetUrl) history.pushState({}, '', url); + + void Net('/api/searchteams').get({ + query: { ...this.state.search, count: this.state.curCount }, + }).then(resultText => { + if (resultText.startsWith(']')) resultText = resultText.slice(1); + let result; + try { + result = JSON.parse(resultText); + } catch { + result = { actionerror: "Malformed response received. Try again later." }; + } + this.setState({ ...result, loading: false }); + }); + } + + render() { + if (this.state.loading) { + return
Loading...
; + } + return
+

Search Teams

+
+
+ + this.onInput('format', e)} />
+ + this.onInput('owner', e)} />
+ + this.onInput('gen', e)} />
+ +
+
+ {!this.state.result.length ? <> : +
    { + this.state.result.map(team =>
  • ) + }
} + {(this.state.result as any).actionerror ? +
{(this.state.result as any).actionerror}
: + <>} + { + this.state.result.length ? + : + <> + } +
; + } +} diff --git a/teams.pokemonshowdown.com/src/teams-view.tsx b/teams.pokemonshowdown.com/src/teams-view.tsx new file mode 100644 index 000000000..ad6077743 --- /dev/null +++ b/teams.pokemonshowdown.com/src/teams-view.tsx @@ -0,0 +1,158 @@ +/** @jsx preact.h */ +/** @jsxFrag preact.Fragment */ +import preact from '../../play.pokemonshowdown.com/js/lib/preact'; +import { Net, PSIcon, unpackTeam } from './utils'; +import { BattleLog } from '../../play.pokemonshowdown.com/src/battle-log'; +import type { PageProps } from './teams'; +import { Dex } from '../../play.pokemonshowdown.com/src/battle-dex'; +import { BattleStatNames } from '../../play.pokemonshowdown.com/src/battle-dex-data'; + +interface Team { + team: string; + title: string; + views: number; + ownerid: string; + format: string; + teamid: string; +} + +function PokemonSet({ set }: { set: Dex.PokemonSet }) { + return
+ {set.name && set.name !== set.species ? <>{set.name} ({set.species}) : <>{set.species}} + {set.gender ? <> ({set.gender}) : <>} + {set.item ? <> @ {set.item} : <>} +
+ {set.ability ? <>Ability: {set.ability}
: <>} + {set.level && set.level !== 100 ? <>Level: {set.level}
: <>} + {set.shiny ? <>Shiny: Yes
: <>} + {set.teraType ? <>Tera Type: {set.teraType} : <>} + + {set.evs ? <>{Dex.statNames.filter(stat => set.evs![stat]).map((stat, index, arr) => ( + <> + {index === 0 ? 'EVs: ' : ''} + {set.evs![stat]} {BattleStatNames[stat]} + {index !== (arr.length - 1) ? ' / ' : ''} + + ))}
: <>} + + {set.nature ? <>{set.nature} Nature
: <>} + + {set.ivs ? <>{Dex.statNames + .filter(stat => !(set.ivs![stat] === undefined || isNaN(set.ivs![stat]) || set.ivs![stat] === 31)) + .map((stat, index, arr) => + <> + {index === 0 ? 'IVs: ' : ''} + {set.ivs![stat]} {BattleStatNames[stat]} + {index !== (arr.length - 1) ? ' / ' : ''} + + )}
: <>} + + {set.moves ? set.moves.map(move => { + if (move.substr(0, 13) === 'Hidden Power ') { + const hpType = move.slice(13); + move = move.slice(0, 13); + move = `${move}[${hpType}]`; + } + // hide the alt so it doesn't interfere w/ copy/pasting + return <>- {move}
; + }) : <>} + + {typeof set.happiness === 'number' && set.happiness !== 255 && !isNaN(set.happiness) ? + <>Happiness: {set.happiness}
: + <>} + {typeof set.dynamaxLevel === 'number' && set.dynamaxLevel !== 10 && !isNaN(set.dynamaxLevel) ? + <>Dynamax Level: {set.dynamaxLevel}
: + <>} + {set.gigantamax ? <>Gigantamax: Yes
: <>} +
; +} + +export class TeamViewer extends preact.Component { + id: string; + pw?: string; + override state = { + team: undefined as null | void | Team, error: undefined as string | undefined, + }; + constructor(props: PageProps) { + super(props); + this.id = props.args.id; + + this.checkTeamID(); + } + render() { + if (this.state.error) { + return
{this.state.error}
; + } + if (!this.state.team) { + return
{ + typeof this.state.team === 'undefined' ? + JSON.stringify(this.state) : + <> +

Team not found.


+ Either it doesn't exist or it's password protected. Check the link? + + }
; + } + const { team, title, ownerid, format, views } = this.state.team; + const teamData = unpackTeam(team); + const gen = Number(/\d+/.exec(format)?.[0]) || 6; + + return
+

{title}

+ Owner: {ownerid}
+ Format: {format}
+ Views: {views}
+ https://psim.us/t/{this.id}
+
+
+ {teamData.map( + set => <> +
+ + {set.item ? : <>} +
+
+ +
+ + )} +
+
; + } + checkTeamID() { + if (this.id.includes('-')) { + [this.id, this.pw] = this.id.split('-'); + } + if (!/^\d+$/.test(this.id)) { + this.setState({ error: "Invalid team ID: " + JSON.stringify(this.props.args) }); + return; + } + this.loadTeamData(); + } + + loadTeamData() { + void Net('/api/getteam').get({ query: { teamid: this.id, password: this.pw, full: 1 } }).then(resultText => { + if (resultText.startsWith(']')) resultText = resultText.slice(1); + let result; + try { + result = JSON.parse(resultText); + } catch { + result = { actionerror: "Malformed response received. Try again later." }; + } + if (result.actionerror) { + this.setState({ error: result.actionerror }); + } else { + this.setState({ team: result.team === null ? result.team : result }); + } + }).catch(e => { + this.setState({ error: `HTTP${e.code}: ${e.message}` }); + }); + } +} diff --git a/teams.pokemonshowdown.com/src/teams.tsx b/teams.pokemonshowdown.com/src/teams.tsx new file mode 100644 index 000000000..304aa37c6 --- /dev/null +++ b/teams.pokemonshowdown.com/src/teams.tsx @@ -0,0 +1,64 @@ +/** @jsx preact.h */ +import preact from '../../play.pokemonshowdown.com/js/lib/preact'; +import { TeamViewer } from './teams-view'; +import { TeamIndex } from './teams-index'; +import { TeamSearcher } from './teams-search'; + +export type PageProps = { args: Record }; + +export const PSRouter = new class { + routes: Record preact.Component)> = {}; + + setRoutes(routes: typeof PSRouter['routes']) { + Object.assign(this.routes, routes); + } + + // @ts-expect-error 'no reachable end point' YES THERE IS changing href stops execution after it + redir(path: string): never { + location.href = path; + } + + go() { + const params = location.pathname.split('/'); + let args: PageProps['args'] = {}; + let Element; + for (const k in this.routes) { + let matched = false; + const routeParts = k.split('/'); + for (let i = 0; i < routeParts.length; i++) { + const part = params[i]; + if (routeParts[i].startsWith('?')) { + routeParts[i] = routeParts[i].slice(1); + if (!part.trim()) break; // can end here + } + if (routeParts[i]?.startsWith(':')) { + args[routeParts[i].slice(1)] = part; + continue; + } + if (part !== routeParts[i]) { + matched = false; + args = {}; // don't accidentally dupe over args + break; + } else { + matched = true; + } + } + if (matched) { + Element = this.routes[k]; + break; + } + } + if (!Element) { + this.redir('//' + Config.routes.teams + "/404.html"); + } else { + preact.render(, document.getElementById('main')!); + } + } +}; + +PSRouter.setRoutes({ + '/view/:id': TeamViewer, + '/': TeamIndex, + '/search/?:type/?:val': TeamSearcher, +}); +PSRouter.go(); diff --git a/teams.pokemonshowdown.com/src/utils.tsx b/teams.pokemonshowdown.com/src/utils.tsx new file mode 100644 index 000000000..d85c01536 --- /dev/null +++ b/teams.pokemonshowdown.com/src/utils.tsx @@ -0,0 +1,370 @@ +/********************************************************************** + * Net + *********************************************************************/ +/** @jsx preact.h */ +import preact from "../../play.pokemonshowdown.com/js/lib/preact"; +import { Dex } from "../../play.pokemonshowdown.com/src/battle-dex"; + +declare const toID: (str: any) => string; + +export interface PostData { + [key: string]: string | number | undefined; +} +export interface NetRequestOptions { + method?: 'GET' | 'POST'; + body?: string | PostData; + query?: PostData; +} +export class HttpError extends Error { + statusCode?: number; + body: string; + constructor(message: string, statusCode: number | undefined, body: string) { + super(message); + this.name = 'HttpError'; + this.statusCode = statusCode; + this.body = body; + try { + (Error as any).captureStackTrace(this, HttpError); + } catch {} + } +} +export class NetRequest { + uri: string; + constructor(uri: string) { + this.uri = uri; + } + + /** + * Makes a basic http/https request to the URI. + * Returns the response data. + * + * Will throw if the response code isn't 200 OK. + * + * @param opts request opts + */ + get(opts: NetRequestOptions = {}): Promise { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + let uri = this.uri; + if (opts.query) { + uri += (uri.includes('?') ? '&' : '?') + Net.encodeQuery(opts.query); + } + xhr.open(opts.method || 'GET', uri); + xhr.onreadystatechange = function () { + const DONE = 4; + if (xhr.readyState === DONE) { + if (xhr.status === 200) { + resolve(xhr.responseText || ''); + return; + } + const err = new HttpError(xhr.statusText || "Connection error", xhr.status, xhr.responseText); + reject(err); + } + }; + if (opts.body) { + xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + xhr.send(Net.encodeQuery(opts.body)); + } else { + xhr.send(); + } + }); + } + + /** + * Makes a http/https POST request to the given link. + * @param opts request opts + * @param body POST body + */ + post(opts: Omit, body: PostData | string): Promise; + /** + * Makes a http/https POST request to the given link. + * @param opts request opts + */ + post(opts?: NetRequestOptions): Promise; + post(opts: NetRequestOptions = {}, body?: PostData | string) { + if (!body) body = opts.body; + return this.get({ + ...opts, + method: 'POST', + body, + }); + } +} + +export function Net(uri: string) { + if (uri.startsWith('/') && !uri.startsWith('//') && Net.defaultRoute) uri = Net.defaultRoute + uri; + if (uri.startsWith('//') && document.location.protocol === 'file:') uri = 'https:' + uri; + return new NetRequest(uri); +} + +/** Prepends URLs starting with `/` with this string. Used by testclient. */ +Net.defaultRoute = ''; + +Net.encodeQuery = function (data: string | PostData) { + if (typeof data === 'string') return data; + let urlencodedData = ''; + for (const key in data) { + if ((data as any)[key] === undefined) continue; + if (urlencodedData) urlencodedData += '&'; + urlencodedData += encodeURIComponent(key) + '=' + encodeURIComponent((data as any)[key]); + } + return urlencodedData; +}; +Net.decodeQuery = function (query: string): { [key: string]: string } { + let out: { [key: string]: string } = {}; + const questionIndex = query.indexOf('?'); + if (questionIndex >= 0) query = query.slice(questionIndex + 1); + for (const queryPart of query.split('&')) { + const [key, value] = queryPart.split('='); + out[decodeURIComponent(key)] = decodeURIComponent(value || ''); + } + return out; +}; + +/********************************************************************** + * Models + *********************************************************************/ + +export class PSSubscription { + observable: PSModel | PSStreamModel; + listener: (value?: any) => void; + constructor(observable: PSModel | PSStreamModel, listener: (value?: any) => void) { + this.observable = observable; + this.listener = listener; + } + unsubscribe() { + const index = this.observable.subscriptions.indexOf(this); + if (index >= 0) this.observable.subscriptions.splice(index, 1); + } +} + +/** + * PS Models roughly implement the Observable spec. Not the entire + * spec - just the parts we use. PSModel just notifies subscribers of + * updates - a simple model for React. + */ +export class PSModel { + subscriptions = [] as PSSubscription[]; + subscribe(listener: () => void) { + const subscription = new PSSubscription(this, listener); + this.subscriptions.push(subscription); + return subscription; + } + subscribeAndRun(listener: () => void) { + const subscription = this.subscribe(listener); + subscription.listener(); + return subscription; + } + update() { + for (const subscription of this.subscriptions) { + subscription.listener(); + } + } +} + +/** + * PS Models roughly implement the Observable spec. PSStreamModel + * streams some data out. This is very not-React, which generally + * expects the DOM to be a pure function of state. Instead PSModels + * which hold state, PSStreamModels give state directly to views, + * so that the model doesn't need to hold a redundant copy of state. + */ +export class PSStreamModel { + subscriptions = [] as PSSubscription[]; + updates = [] as T[]; + subscribe(listener: (value: T) => void) { + // TypeScript bug + const subscription: PSSubscription = new PSSubscription(this, listener); + this.subscriptions.push(subscription); + if (this.updates.length) { + for (const update of this.updates) { + subscription.listener(update); + } + this.updates = []; + } + return subscription; + } + subscribeAndRun(listener: (value: T) => void) { + const subscription = this.subscribe(listener); + subscription.listener(null); + return subscription; + } + update(value: T) { + if (!this.subscriptions.length) { + // save updates for later + this.updates.push(value); + } + for (const subscription of this.subscriptions) { + subscription.listener(value); + } + } +} + +export class PSIcon extends preact.Component<{ + pokemon?: string, item?: string, type?: string, category?: string, hideAlt?: boolean, +}> { + render() { + if (this.props.pokemon) { + return ; + } else if (this.props.item) { + return ; + } else if (this.props.type) { + let type = Dex.types.get(this.props.type).name; + if (!type) type = '???'; + let sanitizedType = type.replace(/\?/g, '%3f'); + return {this.props.hideAlt; + } else if (this.props.category) { + const categoryID = toID(this.props.category); + let sanitizedCategory = ''; + switch (categoryID) { + case 'physical': + case 'special': + case 'status': + sanitizedCategory = categoryID.charAt(0).toUpperCase() + categoryID.slice(1); + break; + default: + sanitizedCategory = 'undefined'; + break; + } + return {this.props.hideAlt; + } else { + return ; + } + } +} + +export type ServerTeam = { + teamid: string, + format: string, + private: string, + team: string, + name?: string, + title?: string, +}; + +export function unpackTeam(buf: string) { + if (!buf) return []; + + let team: Dex.PokemonSet[] = []; + + for (const setBuf of buf.split(`]`)) { + const parts = setBuf.split(`|`); + if (parts.length < 11) continue; + let set: Dex.PokemonSet = { species: '', moves: [] }; + team.push(set); + + // name + set.name = parts[0]; + + // species + set.species = Dex.species.get(parts[1]).name || set.name; + + // item + set.item = Dex.items.get(parts[2]).name; + + // ability + const species = Dex.species.get(set.species); + set.ability = + parts[3] === '-' ? '' : + (species.baseSpecies === 'Zygarde' && parts[3] === 'H') ? 'Power Construct' : + ['', '0', '1', 'H', 'S'].includes(parts[3]) ? + species.abilities[parts[3] as '0' || '0'] || (parts[3] === '' ? '' : '!!!ERROR!!!') : + Dex.abilities.get(parts[3]).name; + + // moves + set.moves = parts[4].split(',').map(moveid => + Dex.moves.get(moveid).name + ); + + // nature + set.nature = parts[5] as Dex.NatureName; + if (set.nature as any === 'undefined') set.nature = undefined; + + // evs + if (parts[6]) { + if (parts[6].length > 5) { + const evs = parts[6].split(','); + set.evs = { + hp: Number(evs[0]) || 0, + atk: Number(evs[1]) || 0, + def: Number(evs[2]) || 0, + spa: Number(evs[3]) || 0, + spd: Number(evs[4]) || 0, + spe: Number(evs[5]) || 0, + }; + } else if (parts[6] === '0') { + set.evs = { hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0 }; + } + } + + // gender + if (parts[7]) set.gender = parts[7]; + + // ivs + if (parts[8]) { + const ivs = parts[8].split(','); + set.ivs = { + hp: ivs[0] === '' ? 31 : Number(ivs[0]), + atk: ivs[1] === '' ? 31 : Number(ivs[1]), + def: ivs[2] === '' ? 31 : Number(ivs[2]), + spa: ivs[3] === '' ? 31 : Number(ivs[3]), + spd: ivs[4] === '' ? 31 : Number(ivs[4]), + spe: ivs[5] === '' ? 31 : Number(ivs[5]), + }; + } + + // shiny + if (parts[9]) set.shiny = true; + + // level + if (parts[10]) set.level = parseInt(parts[9], 10); + + // happiness + if (parts[11]) { + let misc = parts[11].split(',', 4); + set.happiness = (misc[0] ? Number(misc[0]) : undefined); + set.hpType = misc[1]; + set.pokeball = misc[2]; + set.gigantamax = !!misc[3]; + set.dynamaxLevel = (misc[4] ? Number(misc[4]) : 10); + } + } + + return team; +} + +export class MiniTeam extends preact.Component<{ team: ServerTeam, fullTeam?: boolean }> { + render() { + const team = this.props.team; + return <> + + {team.name || team.title || "Untitled " + team.teamid} +
+ + {(this.props.fullTeam ? + unpackTeam(team.team).map(x => x.species) : + team.team.split(',') + ).map(x => ) || (Empty team)} + +
+ ; + } +} diff --git a/tsconfig.json b/tsconfig.json index 2b05e3085..f9fcc1888 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,6 +16,7 @@ "include": [ "./play.pokemonshowdown.com/js/lib/preact.d.ts", "./play.pokemonshowdown.com/src/*", - "./replay.pokemonshowdown.com/src/*" + "./replay.pokemonshowdown.com/src/*", + "./teams.pokemonshowdown.com/src/*" ] }