From 0d252ff6abe87f3587d8a5881e5397553335e5a5 Mon Sep 17 00:00:00 2001 From: "Dr. Dvorak" <171316552+DocDvorak@users.noreply.github.com> Date: Sun, 7 Jun 2026 05:36:30 -0700 Subject: [PATCH 01/32] Reorganize modules/exports and auto-generate docs Pulled the socket API event types and some class organization concepts from the `typescript` branch. Added auto-generated API documentation and a CI workflow to deploy it to Github Pages. Also wrote several guides. Breaking Changes: * Flattened the endpoint method structure on `ScreepsAPI` * Almost every endpoint method has been renamed * Changed type of `ScreepsAPI.rateLimits` to `RateLimitTracker` * Renamed `ScreepsAPI` to `ScreepsHttpClient` Features: * Exported `ScreepsSocketClient` (formerly `Socket`) and many other types * `ConfigManager` is now exported as `ScreepsConfigManager` * `ScreepsConfigManager` now checks for config files in the default value of `$XDG_CONFIG_HOME` if it is not defined (Linux/*BSD only) * `ScreepsConfigManager` now checks `$HOME/Library/Application Support` for config files on macOS. * Added `screepsapi:config` debug namespace for `ScreepsConfigManager` Docs: * Added `typedoc` dev dependency to generate documentation from docblocks * Added more docblocks * Moved guides from `docs/` to `guides/` * Wrote several new guides * Migrated code from README and examples/ to v2 * TypeScript example scripts can still be run from the command line: ```sh yarn exec tsx examples/file-name.ts ``` Chores: * Added a Github Actions workflow to generate and deploy docs to Github Pages --- .github/workflows/docs.yml | 41 + .github/workflows/lint.yml | 18 +- .github/workflows/publish.yml | 22 +- .github/workflows/test.yml | 18 +- .gitignore | 1 + README.md | 173 +- bin/screeps-api.ts | 64 +- docs/Endpoints.md | 236 -- eslint.config.mjs | 61 +- examples/README.md | 3 - examples/console.js | 128 - examples/console.md | 12 + examples/console.ts | 82 + examples/dev_test.js | 41 - examples/download-code.md | 10 + examples/download-code.ts | 33 + examples/download-memory.md | 10 + examples/download-memory.ts | 13 + examples/download_code.js | 28 - examples/download_memory.js | 14 - examples/index.md | 15 + examples/socket-demo.md | 8 + examples/socket-demo.ts | 33 + guides/configuration.md | 190 ++ guides/debugging.md | 42 + guides/migration-2.md | 74 + {docs => guides}/rate-limits.md | 8 +- guides/servers.md | 42 + .../websocket.md | 36 +- package.json | 11 +- rollup.config.mjs | 6 +- src/Api.ts | 1801 -------------- src/ConfigManager.ts | 339 --- src/RateLimitTracker.ts | 104 + src/RawAPI.ts | 1776 -------------- src/ScreepsAPI.ts | 257 -- src/ScreepsConfigManager.ts | 382 +++ src/ScreepsHttpClient.ts | 2088 +++++++++++++++++ src/{Socket.ts => ScreepsSocketClient.ts} | 201 +- src/common/decorations.ts | 153 ++ src/common/index.ts | 11 + src/common/market.ts | 47 + src/common/resources.ts | 136 ++ src/common/rooms.ts | 740 ++++++ src/common/users.ts | 81 + src/http/auth.ts | 108 + src/http/base.ts | 187 ++ src/http/experimental.ts | 37 + src/http/game.ts | 215 ++ src/http/gameMarket.ts | 57 + src/http/gameShards.ts | 25 + src/http/index.ts | 22 + src/http/leaderboard.ts | 59 + src/http/scoreboard.ts | 37 + src/http/seasons.ts | 27 + src/http/servers.ts | 28 + src/http/user.ts | 259 ++ src/http/userCode.ts | 27 + src/http/userDecorations.ts | 34 + src/http/userMemory.ts | 48 + src/http/userMessages.ts | 81 + src/http/warpath.ts | 42 + src/index.ts | 9 +- src/socket/base.ts | 144 ++ src/socket/index.ts | 9 + src/socket/server.ts | 25 + src/socket/user.ts | 117 + src/ws-browser.ts | 7 + typedoc.json | 28 + yarn.lock | 311 ++- 70 files changed, 6569 insertions(+), 4963 deletions(-) create mode 100644 .github/workflows/docs.yml delete mode 100644 docs/Endpoints.md delete mode 100644 examples/README.md delete mode 100644 examples/console.js create mode 100644 examples/console.md create mode 100644 examples/console.ts delete mode 100644 examples/dev_test.js create mode 100644 examples/download-code.md create mode 100644 examples/download-code.ts create mode 100644 examples/download-memory.md create mode 100644 examples/download-memory.ts delete mode 100644 examples/download_code.js delete mode 100644 examples/download_memory.js create mode 100644 examples/index.md create mode 100644 examples/socket-demo.md create mode 100644 examples/socket-demo.ts create mode 100644 guides/configuration.md create mode 100644 guides/debugging.md create mode 100644 guides/migration-2.md rename {docs => guides}/rate-limits.md (73%) create mode 100644 guides/servers.md rename docs/Websocket_endpoints.md => guides/websocket.md (86%) delete mode 100644 src/Api.ts delete mode 100644 src/ConfigManager.ts create mode 100644 src/RateLimitTracker.ts delete mode 100644 src/RawAPI.ts delete mode 100644 src/ScreepsAPI.ts create mode 100644 src/ScreepsConfigManager.ts create mode 100644 src/ScreepsHttpClient.ts rename src/{Socket.ts => ScreepsSocketClient.ts} (67%) create mode 100644 src/common/decorations.ts create mode 100644 src/common/index.ts create mode 100644 src/common/market.ts create mode 100644 src/common/resources.ts create mode 100644 src/common/rooms.ts create mode 100644 src/common/users.ts create mode 100644 src/http/auth.ts create mode 100644 src/http/base.ts create mode 100644 src/http/experimental.ts create mode 100644 src/http/game.ts create mode 100644 src/http/gameMarket.ts create mode 100644 src/http/gameShards.ts create mode 100644 src/http/index.ts create mode 100644 src/http/leaderboard.ts create mode 100644 src/http/scoreboard.ts create mode 100644 src/http/seasons.ts create mode 100644 src/http/servers.ts create mode 100644 src/http/user.ts create mode 100644 src/http/userCode.ts create mode 100644 src/http/userDecorations.ts create mode 100644 src/http/userMemory.ts create mode 100644 src/http/userMessages.ts create mode 100644 src/http/warpath.ts create mode 100644 src/socket/base.ts create mode 100644 src/socket/index.ts create mode 100644 src/socket/server.ts create mode 100644 src/socket/user.ts create mode 100644 typedoc.json diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..e483032 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,41 @@ +name: Deploy Docs Site +on: + push: + branches: + - master + +# Prohibit concurrent workflows +concurrency: + group: pages + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + pages: write + steps: + - uses: actions/checkout@v6 + - run: corepack enable + - uses: actions/setup-node@v6 + with: + node-version-file: .node-version + cache: yarn + - run: yarn install --immutable + - run: yarn build:docs + - id: deployment + uses: actions/upload-pages-artifact@v3 + with: + path: ./docs + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 07e8b5b..9b686a2 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,17 +8,17 @@ on: - master jobs: - build: + lint: runs-on: ubuntu-latest permissions: contents: read id-token: write steps: - - uses: actions/checkout@v6 - - run: corepack enable - - uses: actions/setup-node@v6 - with: - node-version-file: .node-version - cache: yarn - - run: yarn install --immutable - - run: yarn lint + - uses: actions/checkout@v6 + - run: corepack enable + - uses: actions/setup-node@v6 + with: + node-version-file: .node-version + cache: yarn + - run: yarn install --immutable + - run: yarn lint diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f341fc7..7df86e7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,19 +4,19 @@ on: types: [published] jobs: - build: + publish: runs-on: ubuntu-latest permissions: contents: read id-token: write steps: - - uses: actions/checkout@v6 - - run: corepack enable - - uses: actions/setup-node@v6 - with: - node-version-file: .node-version - registry-url: https://registry.npmjs.org/ - cache: yarn - - run: yarn install --immutable - - run: yarn test - - run: yarn npm publish --access public + - uses: actions/checkout@v6 + - run: corepack enable + - uses: actions/setup-node@v6 + with: + node-version-file: .node-version + registry-url: https://registry.npmjs.org/ + cache: yarn + - run: yarn install --immutable + - run: yarn test + - run: yarn npm publish --access public diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a48cb6a..200d1e8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,17 +8,17 @@ on: - master jobs: - build: + test: runs-on: ubuntu-latest permissions: contents: read id-token: write steps: - - uses: actions/checkout@v6 - - run: corepack enable - - uses: actions/setup-node@v6 - with: - node-version-file: .node-version - cache: yarn - - run: yarn install --immutable - - run: yarn test + - uses: actions/checkout@v6 + - run: corepack enable + - uses: actions/setup-node@v6 + with: + node-version-file: .node-version + cache: yarn + - run: yarn install --immutable + - run: yarn test diff --git a/.gitignore b/.gitignore index 6caccf6..aa34a2d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ node_modules auth.js dist +docs npm-debug.log screeps.json diff --git a/README.md b/README.md index 20efa52..39d3257 100644 --- a/README.md +++ b/README.md @@ -5,99 +5,56 @@ [![License](https://img.shields.io/npm/l/screeps-api.svg)](https://npmjs.com/package/screeps-api) [![Version](https://img.shields.io/npm/v/screeps-api.svg)](https://npmjs.com/package/screeps-api) [![Downloads](https://img.shields.io/npm/dw/screeps-api.svg)](https://npmjs.com/package/screeps-api) +[![Docs](https://img.shields.io/badge/API-Docs-green)](https://screepers.github.io/node-screeps-api/) [![Test Status](https://github.com/screepers/node-screeps-api/actions/workflows/test.yml/badge.svg)](https://github.com/screepers/node-screeps-api/actions/workflows/test.yml) [![Lint Status](https://github.com/screepers/node-screeps-api/actions/workflows/lint.yml/badge.svg)](https://github.com/screepers/node-screeps-api/actions/workflows/lint.yml) ![npm](https://nodei.co/npm/screeps-api.png "NPM") -## Notice on authentication +## Application Usage -As of 12/29/2017 Screeps now uses auth tokens obtained via your screeps account settings. -User/pass auth will stop working February 1, 2018! -[Screeps Announcement](http://blog.screeps.com/2017/12/auth-tokens/) +As of v1.0, all endpoint methods are asynchronous. -## CLI Usage - -As of 1.7.0, a small CLI program (`screeps-api`) is included. - -Server config is specified via a `.screeps.yml` file conforming to the [Unified Credentials File format](https://github.com/screepers/screepers-standards/blob/master/SS3-Unified_Credentials_File.md) - -``` -screeps-api - - Usage: [options] [command] - - Options: - - -V, --version output the version number - --server Server config to use (default: main) - -h, --help output usage information - - Commands: - - raw [args...] Execute raw API call - memory [options] [path] Get Memory contents - segment [options] Get segment contents. Use 'all' to get all) - download [options] Download code - upload [options] Upload code - -``` - - -## API Usage - -As of 1.0, all functions return Promises - -```javascript -const { ScreepsAPI } = require('screeps-api'); -const fs = require('fs'); +```typescript +import { ScreepsHttpClient } from 'screeps-api' +import fs from 'node:fs' // Supports @tedivm's [Unified Credentials File format](https://github.com/screepers/screepers-standards/blob/34bd4e6e5c8250fa0794d915d9f78d3c45326076/SS3-Unified_Credentials_File.md) (Pending [screepers-standard PR #8](https://github.com/screepers/screepers-standards/pull/8)) -const api = await ScreepsAPI.fromConfig('main', 'appName') +const api = await ScreepsHttpClient.fromConfig('main', { client: 'appName' }) // This loads the server config 'main' and the configs section 'appName' if it exists // config section can be accessed like this: -// If making a CLI app, its suggested to have a `--server` argument for selection console.log(api.appConfig.myConfigVar) +// If making a CLI app, its suggested to have a `--server` argument for selection -// All options are optional -const api = new ScreepsAPI({ - token: 'Your Token from Account/Auth Tokens' - protocol: 'https', - hostname: 'screeps.com', - port: 443, - path: '/' // Do no include '/api', it will be added automatically -}); - -// You can overwrite parameters if needed -api.auth('screeps@email.com','notMyPass',{ - protocol: 'https', - hostname: 'screeps.com', - port: 443, - path: '/' // Do no include '/api', it will be added automatically -}) - -// If you want to point to the screeps PTR (Public Test Realm), -// you can set the 'path' option to '/ptr' and it will work fine. +// HTTP API -// Dump Memory -api.memory.get() +// Dump entire Memory object to a file +api.userMemoryGet() .then(memory => { fs.writeFileSync('memory.json', JSON.stringify(memory)) }) - .catch(err => console.error(err)); - + .catch(console.error) -// Dump Memory Path -api.memory.get('rooms.W0N0') - .then(memory => { +// Dump a subset of Memory to a file +api.userMemoryGet('rooms.W0N0') + .then((memory) => { fs.writeFileSync('memory.rooms.W0N0.json', JSON.stringify(memory)) }) - .catch(err => console.error(err)); + .catch(console.error) // Get user info -api.me().then((user)=>console.log(user)) +api.authMe().then((user) => console.log(user)) + +// Download and upload code +api.userCodeGet('default').then((data) => console.log('code', data)) +api.userCodeSet({ + branch: 'default', + modules: { + main: 'module.exports.loop = function(){ ... }' + } +}) -// Socket API +// WebSocket API api.socket.connect() // Events have the structure of: @@ -106,11 +63,11 @@ api.socket.connect() // id: 'E3N3', // Only on certain events // data: { ... } // } -api.socket.on('connected',()=>{ +api.socket.on('connected', () => { // Do stuff after connected }) -api.socket.on('auth',(event)=>{ - event.data.status contains either 'ok' or 'failed' +api.socket.on('auth', (event) => { + event.data.status // contains either 'ok' or 'failed' // Do stuff after auth }) @@ -118,10 +75,11 @@ api.socket.on('auth',(event)=>{ // connected disconnected message auth time protocol package subscribe unsubscribe console // Subscribtions can be queued even before the socket connects or auths, -// although you may want to subscribe from the connected or auth callback to better handle reconnects +// although you may want to subscribe from the connected or auth callback +// to better handle reconnects api.socket.subscribe('console') -api.socket.on('console',(event)=>{ +api.socket.on('console', (event) => { event.data.messages.log // List of console.log output for tick }) @@ -132,51 +90,42 @@ api.socket.subscribe('console', (event)=>{ }) // More common examples -api.socket.subscribe('cpu',(event)=>console.log('cpu',event.data)) -api.code.get('default').then(data=>console.log('code',data)) -api.code.set('default',{ - main: 'module.exports.loop = function(){ ... }' +api.socket.subscribe('cpu', (event) => console.log('cpu', event.data)) +api.socket.subscribe('memory/stats', (event) => { + console.log('stats', event.data) }) -api.socket.subscribe('memory/stats',(event)=>{ - console.log('stats',event.data) -}) -api.socket.subscribe('memory/rooms.E0N0',(event)=>{ - console.log('E0N0 Memory',event.data) +api.socket.subscribe('memory/rooms.E0N0', (event) => { + console.log('E0N0 Memory', event.data) }) ``` -## Endpoint documentation - -Server endpoints are listed in the `docs` folder: - * [Endpoints.md](/docs/Endpoints.md) for direct access - * [Websocket_endpoints.md](/docs/Websocket_endpoints.md) for web socket endpoints -Those lists are currently not exhaustive. - -## Debugging +## CLI Usage -`node-screeps-api` uses the [Debug](https://www.npmjs.com/package/debug) package to expose diagnostic information. Debug output is divided into several namespaces: -* `screepsApi:http`: HTTP requests -* `screepsApi.ratelimit`: HTTP API rate limit state -* `screepsApi.ratelimitexceeded`: HTTP API endpoint rate limit exceeded events -* `screepsApi.socket`: Socket API events/messages +As of v1.7, a small CLI program (`screeps-api`) is included. -Multiple namespaces can be specified by providing a comma-delimited list (ex: `screepsApi:http,screepsApi:ratelimit`). All namespaces can be specified by providing `screepsApi:*`. +Server/auth credentials are located using `ScreepsConfigManager.loadConfig()`. -To enable debug output in Node, set the `DEBUG` environment variable to the -namespace(s) you want to enable. Here is an example that uses the CLI in bash: -```sh -DEBUG=screepsApi.http,screepsApi.ratelimit screeps-api raw --server main auth.me +``` +$ screeps-api +Usage: screeps-api [options] [command] + +Options: + -V, --version output the version number + -h, --help display help for command + +Commands: + call [options] [args...] Call an API endpoint method on ScreepsHttpClient + memory [options] [path] Read from or write to Memory + segment [options] Read or write RawMemory segments + download [options] <> Download code and WASM binaries + upload [options] Upload code and WASM binaries + help [command] display help for command ``` -These environment variables work when invoking your own apps as well. - -You can also enable/disable debug logs dynamically using `ScreepsApi.debug()`: -```ts -const api = ScreepsApi.fromConfig('main', 'appName') +## Endpoint Documentation -// Enable debug logging for HTTP requests and rate limits: -api.debug({ http: true, rateLimit: true }) +Check the [docs](https://screepers.github.io/node-screeps-api/) for a detailed list of supported endpoints: +* HTTP API: [`ScreepsHttpClient`](https://screepers.github.io/node-screeps-api/docs/classes/index.ScreepsHttpClient.html) +* WebSocket API: [`ScreepsSocketClient`](https://screepers.github.io/node-screeps-api/docs/classes/index.ScreepsSocketClient.html) for web socket endpoints -// Diable all debug logging -api.debug() -``` +Please note that the listed endpoints and WebSocket events are not exhaustive. diff --git a/bin/screeps-api.ts b/bin/screeps-api.ts index e01c074..61e7c52 100755 --- a/bin/screeps-api.ts +++ b/bin/screeps-api.ts @@ -3,7 +3,8 @@ import { Command } from 'commander' import { readFile, writeFile } from 'node:fs/promises' import path from 'node:path' import process from 'node:process' -import { ScreepsAPI } from '../src/ScreepsAPI' +import { ScreepsHttpClient } from '../src' +import { UserCodeSetRequest } from './http' interface CommandOptions { server?: string @@ -11,8 +12,8 @@ interface CommandOptions { type RawApiFn = (...args: unknown[]) => Promise -function init(opts?: CommandOptions): Promise { - return ScreepsAPI.fromConfig(opts?.server ?? 'main') +function init(opts?: CommandOptions): Promise { + return ScreepsHttpClient.fromConfig(opts?.server ?? 'main') } function json(data: unknown) { @@ -46,36 +47,26 @@ const pkg = JSON.parse(await readFile(pkgUrl, 'utf8')) as { version: string } program .version(pkg.version) -commandBase('raw', ' [args...]') - .summary('Call an API endpoint via ScreepsAPI.raw.') - .description(`Call an API endpoint defined on ScreepsAPI.raw. +commandBase('call', ' [args...]') + .summary('Call an API endpoint method on ScreepsHttpClient') + .description(`Call an API endpoint defined on ScreepsHttpClient. - is formatted as it would be if you were calling the endpoint via ScreepsAPI.raw. -[args...] are passed directly to the relevant ScreepsAPI.raw function. + is formatted as it would be if you were calling the endpoint via ScreepsHttpClient. +[args...] are passed directly to the relevant ScreepsHttpClient method. `) .addHelpText('after', `Examples: -# Run 'GET /api/auth/me' on the 'ptr' server from your credentials file -screeps-api --server ptr raw auth.me -# Run 'GET /api/scoreboards/list?limit=20&offset=50' on default server -screeps-api raw scoreboard 20 50 -# Run 'GET /api/scoreboards/list?limit=20&offset=50' on default server -screeps-api raw scoreboard 20 50 -# Fetch entire Memory object from shard0 on 'mmo' server from your credentials file -screeps-api raw user.memory.get "" "shard0" +# Run 'GET /api/auth/me' on the "ptr" server from your credentials file +screeps-api --server ptr call authMe +# Run 'GET /api/scoreboards/list?limit=20&offset=50' on "main" server from your credentials file +screeps-api call scoreboardList 20 50 +# Fetch entire Memory object from shard0 on "mmo" server from your credentials file +screeps-api call userMemoryGet "" "shard0" `) - .action(async function (cmd: string, args: unknown[], opts?: CommandOptions) { + .action(async function (endpoint: string, args: unknown[], opts?: CommandOptions) { const api = await init(opts) - const path = cmd.split('.') - let fn: { [key: string]: unknown } | RawApiFn = api.raw - for (const part of path) { - if (typeof fn === 'function') { - console.error(`Command '${cmd}' not found on ScreepsAPI.raw`) - this.help({ error: true }) // prints to stderr and exits with error code - } - fn = fn[part] as typeof fn - } + const fn = api[endpoint as unknown as keyof typeof api] if (!fn || typeof fn !== 'function') { - console.error(`Command '${cmd}' not found on ScreepsAPI.raw`) + console.error(`Endpoint method '${endpoint}' not found on ScreepsHttpClient`) this.help({ error: true }) // prints to stderr and exits with error code } await out(await (fn as RawApiFn).apply(api, args)) @@ -111,12 +102,12 @@ If --set is used, this command will instead set the value of [path] to th this.help({ error: true }) // prints to stderr and exits with error code } const data = await readFile(opts.set, 'utf8') - await api.memory.set(memPath, data, opts.shard) + await api.userMemorySet(memPath, data, opts.shard) await out('Memory written') return } - const res = await api.memory.get(memPath, opts.shard) + const res = await api.userMemoryGet(memPath, opts.shard) if (!res.data) { return } @@ -137,9 +128,8 @@ interface SegmentOptions extends CommandOptions { } commandBase('segment', '') - .description(`Read or write RawMemory segments. - -Reads/downloads segment data by default. should be a comma-delimited + .summary('Read or write RawMemory segments') + .description(`Reads/downloads segment data by default. should be a comma-delimited list of all segment IDs that should be fetched (or 'all' to get all segments). If --set is used, must be the ID of a single segment. @@ -155,13 +145,13 @@ If --set is used, must be the ID of a single segment. this.help({ error: true }) // prints to stderr and exits with error code } const data = await readFile(opts.set, 'utf8') - await api.memory.segment.set(segment, JSON.parse(data), opts.shard) + await api.userMemorySegmentSet(segment, JSON.parse(data), opts.shard) await out('Segment uploaded') } else { if (segment === 'all') { segment = Array.from({ length: 100 }, (_v, k) => k).join(',') } - const { data } = await api.memory.segment.get(segment, opts.shard) + const { data } = await api.userMemorySegmentGet(segment, opts.shard) const dir = opts.dir const segments = data if (dir) { @@ -194,7 +184,7 @@ commandBase('download') .action(async function (opts: DownloadOptions) { const api = await init(opts) const dir = opts.dir - const { modules } = await api.code.get(opts.branch) + const { modules } = await api.userCodeGet(opts.branch) if (dir) { await Promise.all(Object.keys(modules).map(async (fn) => { const data = modules[fn] @@ -219,7 +209,7 @@ commandBase('upload', '') .option('-b --branch ', 'Code branch', 'default') .action(async function (files: string[], opts: UploadOptions) { const api = await init(opts) - const modules: Api.UserCodeSetRequest['modules'] = {} + const modules: UserCodeSetRequest['modules'] = {} const ps = [] for (const file of files) { ps.push((async (file) => { @@ -234,7 +224,7 @@ commandBase('upload', '') })(file)) } await Promise.all(ps) - await out(api.code.set({ branch: opts.branch, modules })) + await out(api.userCodeSet({ branch: opts.branch, modules })) }) function run() { diff --git a/docs/Endpoints.md b/docs/Endpoints.md deleted file mode 100644 index d278e51..0000000 --- a/docs/Endpoints.md +++ /dev/null @@ -1,236 +0,0 @@ -Copied from [python-screeps](https://github.com/screepers/python-screeps/blob/master/docs/Endpoints.md) - -Start by sending a request to `auth/signin` with your e-mail address and -password in a JSON object in the POST data. The response JSON object contains a -token (a hex string); remember that value. Each time you make a request that -requires authentication (the leaderboard and terrain ones, at least, don't), -send the most recent token value as both the `X-Token` and `X-Username` -headers. The response will contain a new token value in the `X-Token` header -with which you should replace your saved token. (You can send the token on every -request and just check for a new one in the response, so you don't have to know -exactly which calls require authentication.) - -Example request parameters are given below, along with schemata for the server's -responses. - -Memory and console endpoints are from -[bzy-xyz](https://gist.github.com/bzy-xyz/9c4d8c9f9498a2d7983d). - -You can access the PTR by changing `screeps.com` to `screeps.com/ptr` in all URLs. - -# Enumeration values -When an endpoint takes `interval` or `statName` as an argument, the valid values -are the ones listed below. - -- interval: 8, 180, 1440 (8 for 1h, 180 for 24h and 1440 for 7 days) -- statName: creepsLost, creepsProduced, energyConstruction, energyControl, energyCreeps, energyHarvested - -# Authentication -- [POST] `https://screeps.com/api/auth/signin` - - post data: `{ email, password }` - - response: `{ ok, token }` - -# Room information -- `https://screeps.com/api/game/room-overview?interval=8&room=E1N8` - - `{ ok, owner: { username, badge: { type, color1, color2, color3, param, flip } }, stats: { energyHarvested: [ { value, endTime } ], energyConstruction: [ { value, endTime } ], energyCreeps: [ { value, endTime } ], energyControl: [ { value, endTime } ], creepsProduced: [ { value, endTime } ], creepsLost: [ { value, endTime } ] }, statsMax: { energy1440, energyCreeps1440, energy8, energyControl8, creepsLost180, energyHarvested8, energy180, energyConstruction180, creepsProduced8, energyControl1440, energyCreeps8, energyHarvested1440, creepsLost1440, energyConstruction1440, energyHarvested180, creepsProduced180, creepsProduced1440, energyCreeps180, energyControl180, energyConstruction8, creepsLost8 } }` - -- `https://screeps.com/api/game/room-terrain?room=E1N8` - - `{ ok, terrain: [ { room, x, y, type } ] }` - - `type` in each element of `terrain` can be "wall" or "swamp" - -- `https://screeps.com/api/game/room-terrain?room=E1N8&encoded=1` - - `{ ok, terrain: [ { _id, room, terrain, type } ] }` - - `terrain` is a string of digits, giving the terrain left-to-right and top-to-bottom - - 0: plain, 1: wall, 2: swamp, 3: also wall - - encoded argument can be anything non-empty - -- `https://screeps.com/api/game/room-status?room=E1N8` - - `{ _id, status, novice }` - - `status` can at least be "normal" or "out of borders" - - if the room is in a novice area, `novice` will contain the Unix timestamp of the end of the protection (otherwise it is absent) - -- `https://screeps.com/api/experimental/pvp?interval=50` - - `{ ok, time, rooms: [ { _id, lastPvpTime } ] }` - - `time` is the current server tick - - `_id` contains the room name for each room, and `lastPvpTime` contains the last tick pvp occurred - - if neither a valid `interval` nor a valid `start` argument is provided, the result of the call is still `ok`, but with an empty rooms array. - -- `https://screeps.com/api/experimental/pvp?start=14787157` - - `{ ok, time, rooms: [ { _id, lastPvpTime } ] }` - -# Market information - -- `https://screeps.com/api/game/market/orders-index` - - `{"ok":1,"list":[{"_id":"XUHO2","count":2}]}` - - `_id` is the resource type, and there will only be one of each type. - - `count` is the number of orders. - - - `https://screeps.com/api/game/market/my-orders` - - `{ ok, list: [ { _id, created, user, active, type, amount, remainingAmount, resourceType, price, totalAmount, roomName } ] }` - - - `https://screeps.com/api/game/market/orders?resourceType=Z` - - `{ ok, list: [ { _id, created, user, active, type, amount, remainingAmount, resourceType, price, totalAmount, roomName } ] }` - - `resourceType` is one of the RESOURCE_* constants. - - - `https://screeps.com/api/user/money-history` - - `{"ok":1,"page":0,"list":[ { _id, date, tick, user, type, balance, change, market: {} } ] }` - - `page` used for pagination. - - `hasMore` is true if there are more pages to view. - - `market` - - New Order- `{ order: { type, resourceType, price, totalAmount, roomName } }` - - Extended Order- `{ extendOrder: { orderId, addAmount } }` - - Fulfilled Order- `{ resourceType, roomName, targetRoomName, price, npc, amount }` - - Price Change - `{ changeOrderPrice: { orderId, oldPrice, newPrice } }` - -# Leaderboard -- `https://screeps.com/api/leaderboard/seasons` - - `{ ok, seasons: [ { _id, name, date } ] }` - - the `_id` returned here is used for the season name in the other leaderboard calls - -- `https://screeps.com/api/leaderboard/find?mode=world&season=2015-09&username=danny` - - `{ ok, _id, season, user, score, rank }` - - `user` (not `_id`) is the user's _id, as returned by `me` and `user/find` - - `rank` is 0-based - -- `https://screeps.com/api/leaderboard/find?mode=world&username=danny` - - `{ ok, list: [ _id, season, user, score, rank ] }` - - lists ranks in all seasons - -- `https://screeps.com/api/leaderboard/list?limit=10&mode=world&offset=10&season=2015-09` - - `{ ok, list: [ { _id, season, user, score, rank } ], count, users: { : { _id, username, badge: { type, color1, color2, color3, param, flip }, gcl } } }` - -# Messages -- `https://screeps.com/api/user/messages/index` - - `{ ok, messages: [ { _id, message: { _id, user, respondent, date, type, text, unread } } ], users: { : { _id, username, badge: { type, color1, color2, color3, param, flip } } } }` - -- `https://screeps.com/api/user/messages/list?respondent=55605a6654db1fa952de8d90` - - `{ ok, messages: [ { _id, date, type, text, unread } ] }` - -- [POST] `https://screeps.com/api/user/messages/send` - - post data: `{ respondent, text }` - - `respondent` is the long _id of the user, not the username - - response: `{ ok }` - -- `https://screeps.com/api/user/messages/unread-count` - - `{ ok, count }` - -# User information -- `https://screeps.com/api/auth/me` - - `{ ok, _id, email, username, cpu, badge: { type, color1, color2, color3, param, flip }, password, notifyPrefs: { sendOnline, errorsInterval, disabledOnMessages, disabled, interval }, gcl, credits, lastChargeTime, lastTweetTime, github: { id, username }, twitter: { username, followers_count } }` - -- `https://screeps.com/api/user/find?username=danny` - - `{ ok, user: { _id, username, badge: { type, color1, color2, color3, param, flip }, gcl } }` - -- `https://screeps.com/api/user/find?id=55c91dc66e36d62a6167e1b5` - - `{ ok, user: { _id, username, badge: { type, color1, color2, color3, param, flip }, gcl } }` - -- `https://screeps.com/api/user/overview?interval=1440&statName=energyControl` - - `{ ok, rooms: [ ], stats: { : [ { value, endTime } ] }, statsMax }` - -- `https://screeps.com/api/user/respawn-prohibited-rooms` - - `{ ok, rooms: [ ] }` - -- `https://screeps.com/api/user/world-status` - - `{ ok, status }` - - `status` can be `"lost"`, `"empty"` or `"normal"`, lost is when you loose all your spawns, empty is when you have respawned and not placed your spawn yet.; - -- `https://screeps.com/api/user/world-start-room` - - `{ ok, room: [ ] }` - - `room` is an array, but seems to always contain only one element - -- `https://screeps.com/api/xsolla/user` - - `{ ok, active }` - - `active` is the Unix timestamp of the end of your current subscribed time - -- [POST] `https://screeps.com/api/user/console` - - post data: `{ expression }` - - response: `{ ok, result: { ok, n }, ops: [ { user, expression, _id } ], insertedCount, insertedIds: [ ] }` - -- `https://screeps.com/api/user/memory?path=flags.Flag1` - - `{ ok, data }` - - `data` is the string `gz:` followed by base64-encoded gzipped JSON encoding of the requested memory path - - the path may be empty or absent to retrieve all of Memory - -- [POST] `https://screeps.com/api/user/memory` - - post data: `{ path, value }` - - response: `{ ok, result: { ok, n }, ops: [ { user, expression, hidden } ], data, insertedCount, insertedIds }` - -- `https://screeps.com/api/user/memory-segment?segment=[0-99]` - - `{ okay, data }` - - response: `{ ok, data: '' }` - -- [POST ]`https://screeps.com/api/user/memory-segment` - - post data: `{ segment, data }` - - -# Manipulating the game world -- [POST] `https://screeps.com/api/game/gen-unique-object-name` - - post data: `{ type }` - - response: `{ ok, name }` - - `type` can be at least "flag" or "spawn" - -- [POST] `https://screeps.com/api/game/create-flag` - - post data: `{ room, x, y, name, color, secondaryColor }` - - response: `{ ok, result: { nModified, ok, upserted: [ { index, _id } ], n }, connection: { host, id, port } }` - - if the name is new, `result.upserted[0]._id` is the game id of the created flag - - if not, this moves the flag and the response does not contain the id (but the id doesn't change) - - `connection` looks like some internal MongoDB thing that is irrelevant to us - -- [POST] `https://screeps.com/api/game/change-flag` - - post data: `{ _id, room, x, y }` - - response: `{ ok, result: { nModified, ok, n }, connection: { host, id, port } }` - -- [POST] `https://screeps.com/api/game/change-flag-color` - - post data: `{ _id, color, secondaryColor }` - - response: `{ ok, result: { nModified, ok, n }, connection: { host, id, port } }` - -- [POST] `https://screeps.com/api/game/add-object-intent` - - post data: `{ _id, room, name, intent }` - - response: `{ ok, result: { nModified, ok, upserted: [ { index, _id } ], n }, connection: { host, id, port } }` - - `_id` is the game id of the object to affect (except for destroying structures), `room` is the name of the room it's in - - this method is used for a variety of actions, depending on the `name` and `intent` parameters - - remove flag: `name = "remove"`, `intent = {}` - - destroy structure: `_id = "room"`, `name = "destroyStructure"`, `intent = [ {id: , roomName, , user: } ]` - - can destroy multiple structures at once - - suicide creep: `name = "suicide"`, `intent = {id: }` - - unclaim controller: `name = "unclaim"`, `intent = {id: }` - - intent can be an empty object for suicide and unclaim, but the web interface sends the id in it, as described - - remove construction site: `name = "remove"`, `intent = {}` - -- [POST] `https://screeps.com/api/game/set-notify-when-attacked` - - post data: `{ _id, enabled }` - - `enabled` is either `true` or `false` (literal values, not strings) - - response: `{ ok, result: { ok, nModified, n }, connection: { id, host, port } }` - -- [POST] `https://screeps.com/api/game/create-construction` - - post data: `{ room, structureType, x, y}` - - `structureType` is the same value as one of the in-game STRUCTURE_* constants ('road', 'spawn', etc.) - - `{ ok, result: { ok, n }, ops: [ { type, room, x, y, structureType, user, progress, progressTotal, _id } ], insertedCount, insertedIds }` - -# Other -- `https://screeps.com/api/game/time` - - `{ ok, time }` - -- [GET/POST] `https://screeps.com/api/user/code` - - for pushing or pulling code, as documented at http://support.screeps.com/hc/en-us/articles/203022612 - -- [POST] `https://screeps.com/api/game/map-stats` - - post data: `{ rooms: [ ], statName: "..."}` - - statName can be "owner0", "claim0", or a stat (see the enumeration above) followed by an interval - - if it is owner0 or claim0, there's no separate stat block in the response - - response: `{ ok, stats: { : { status, novice, own: { user, level }, : [ { user, value } ] } }, users: { : { _id, username, badge: { type, color1, color2, color3, param, flip } } } }` - - `status` and `novice` are as per the `room-status` call - - `level` can be 0 to indicate a reserved room - -- `https://screeps.com/room-history/E1N8/12340.json` - - `{ timestamp, room, base, ticks: {