Skip to content

Commit

Permalink
Merge branch 'nightly' of https://github.com/tetrjs/tetr.js into nightly
Browse files Browse the repository at this point in the history
  • Loading branch information
Sup3rFire committed Apr 24, 2024
2 parents ef1f2b4 + e2e637f commit 1783f9e
Show file tree
Hide file tree
Showing 41 changed files with 1,178 additions and 275 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/release-beta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Release beta

on:
push:
branches:
- nightly

jobs:
release:
permissions:
contents: write
issues: write
pull-requests: write
id-token: write
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
ref: nightly

- name: Set up Node.js
uses: actions/setup-node@v3

- name: Install dependencies
run: npm ci

- name: Build package
run: npm run build

- name: Release
run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Generate Documentation
run: npm run docs

- name: Commit and Push Documentation
run: |
git config --global user.email "actions@github.com"
git config --global user.name "GitHub Actions"
git add docs
git commit -m "docs: update documentation [skip ci]"
git push
8 changes: 4 additions & 4 deletions docs/assets/highlight.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
--dark-hl-5: #C586C0;
--light-hl-6: #001080;
--dark-hl-6: #9CDCFE;
--light-hl-7: #008000;
--dark-hl-7: #6A9955;
--light-hl-8: #098658;
--dark-hl-8: #B5CEA8;
--light-hl-7: #098658;
--dark-hl-7: #B5CEA8;
--light-hl-8: #008000;
--dark-hl-8: #6A9955;
--light-hl-9: #267F99;
--dark-hl-9: #4EC9B0;
--light-code-background: #FFFFFF;
Expand Down
2 changes: 1 addition & 1 deletion docs/assets/navigation.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/assets/search.js

Large diffs are not rendered by default.

252 changes: 242 additions & 10 deletions docs/classes/Client.html

Large diffs are not rendered by default.

58 changes: 29 additions & 29 deletions docs/classes/ClientPlayer.html

Large diffs are not rendered by default.

74 changes: 37 additions & 37 deletions docs/classes/ClientUser.html

Large diffs are not rendered by default.

48 changes: 24 additions & 24 deletions docs/classes/Game.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/classes/Player.html

Large diffs are not rendered by default.

125 changes: 63 additions & 62 deletions docs/classes/Room.html

Large diffs are not rendered by default.

56 changes: 28 additions & 28 deletions docs/classes/User.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/index.html

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion docs/modules.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/types/GameOptions.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/types/Member.html

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions docs/variables/TetraChannel.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ This project is licensed under the MIT License. See [LICENSE](https://github.com

## Disclaimer

TETR.JS is not associated with TETR.IO or osk. The token provided must match an account that has been approved as a bot account. Contact osk on Discord to receive such bot accounts.
TETR.JS is not associated with TETR.IO or osk. The token provided must match an account that has been approved as a bot account. Contact [TETR.IO Support](https://tetr.io/about/support/) to request a bot account.

## Credits

Expand Down
2 changes: 1 addition & 1 deletion release.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const config = {
branches: ["stable", { name: "nightly", channel: "beta" }],
branches: ["stable", { name: "nightly", channel: "beta", prerelease: true }],
plugins: [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
Expand Down
31 changes: 23 additions & 8 deletions src/client/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import api from "../util/api";
import Room from "../room/Room";
import User from "../user/User";
import channelApi from "../util/channelApi";
import { EventEmitter } from "ws";

/**
* Represents the client.
*/
export default class Client {
export default class Client extends EventEmitter {
private readonly ws = new WebSocketManager(this);

/**
Expand Down Expand Up @@ -43,6 +44,11 @@ export default class Client {
key: "users_me_" + token,
});

if (me.user.role !== "bot")
throw new Error(
`Client "${me.user.username}" is not a bot account. Contact TETR.IO Support (https://tetr.io/about/support/) to apply for a bot account.`
);

this.me = new ClientUser(this.ws, me, await this.fetchUser(me.user._id));

await this.ws.connect();
Expand All @@ -63,18 +69,16 @@ export default class Client {
* A "user" account must not be used and a "bot" account is required. To obtain one, contact [osk](https://osk.sh/).
*/
public async login_password(username: string, password: string): Promise<void> {
let auth = await api(
"/users/authenticate",
undefined,
{ "Content-Type": "application/json" },
"POST",
{ username, password }
);
let auth = await api("/users/authenticate", undefined, undefined, "POST", {
username,
password,
});

await this.login(auth.token);
}

public logout(): void {
this.ws.mayReconnect = false;
this.ws.send({ command: "die" }, false);
clearInterval(this.ws.heartbeat);
this.ws.socket?.close();
Expand All @@ -97,3 +101,14 @@ export default class Client {
return new User(this.ws, user_);
}
}

export default interface Client extends EventEmitter {
/** Emitted when the client violates Ribbon's protocol. */
on(eventName: "nope", listener: (reason: string) => void): this;

/** Emitted when the client gets kicked by the server. */
on(eventName: "kick", listener: (reason: string) => void): this;

/** Emitted when a non fatal error occurs. */
on(eventName: "err", listener: (reason: string) => void): this;
}
15 changes: 2 additions & 13 deletions src/client/ClientUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ export default class ClientUser extends EventEmitter {

this.ws = ws;

if (me.role !== "bot")
throw new Error(
`Client "${me.username}" is not a bot account. Contact osk (https://osk.sh/) to apply for a bot account.`
);

this.user = user;
this.email = me.email;
this.privacy = {
Expand Down Expand Up @@ -172,16 +167,10 @@ export default class ClientUser extends EventEmitter {

export default interface Client extends EventEmitter {
/** Emitted when a user sends a direct message to the client. */
on(
eventName: "dm",
listener: (message: { content: string; author: User }) => void
): this;
on(eventName: "dm", listener: (message: { content: string; author: User }) => void): this;

/** Emitted when a user sends an invite to the client.*/
on(
eventName: "invite",
listener: (invite: { room: string; author: User }) => void
): this;
on(eventName: "invite", listener: (invite: { room: string; author: User }) => void): this;

/** Emitted when the server sends an update on how many users online. */
on(eventName: "online", listener: (online: number) => void): this;
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import User from "./user/User";
import Game from "./game/Game";
import Player from "./game/Player";
import ClientPlayer from "./client/ClientPlayer";
import { TetraChannel } from "./util/channelApi";

export {
Client,
Expand All @@ -16,4 +17,5 @@ export {
Player,
GameOptions,
ClientPlayer,
TetraChannel,
};
17 changes: 6 additions & 11 deletions src/room/Room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,7 @@ export default class Room extends EventEmitter {
this.ws.send({ command: "room.start" });
}

public setConfig(
config: { index: string; value: any }[] | Record<string, any>
) {
public setConfig(config: { index: string; value: any }[] | Record<string, any>) {
if (!Array.isArray(config)) {
this.ws.send({
command: "room.setconfig",
Expand All @@ -254,11 +252,11 @@ export default interface Room extends EventEmitter {
/** Emitted when a player joins the room. */
on(eventName: "join", listener: (player: Member) => void): this;

/** Emitted when the the client gets kicked or banned from the room. */
on(eventName: "kick", listener: (type: string) => void): this;

/** Emitted when a player sends a message. */
on(
eventName: "chat",
listener: (message: { content: string; author: Member }) => void
): this;
on(eventName: "chat", listener: (message: { content: string; author: Member }) => void): this;

/** Emitted when a player leaves the room. */
on(eventName: "leave", listener: (player: User) => void): this;
Expand All @@ -270,10 +268,7 @@ export default interface Room extends EventEmitter {
on(eventName: "start", listener: (game: Game) => void): this;

/** Emitted when the game ends. */
on(
eventName: "end",
listener: (leaderboard: Leaderboard[], victor: Player) => void
): this;
on(eventName: "end", listener: (leaderboard: Leaderboard[], victor: Player) => void): this;
}

export type Member = {
Expand Down
19 changes: 5 additions & 14 deletions src/user/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@ export default class User {
this.role = user.role;
if (user.ts) this.ts = new Date(user.ts);
this.botMaster = user.botmaster;
this.badges = user.badges.map(
(badge: { id: string; label: string; ts?: string }) => {
if (badge.ts) return { ...badge, ts: new Date(badge.ts) };
return badge;
}
);
this.badges = user.badges.map((badge: { id: string; label: string; ts?: string }) => {
if (badge.ts) return { ...badge, ts: new Date(badge.ts) };
return badge;
});
this.xp = user.xp;
this.gamesPlayed = user.gamesplayed;
this.gamesWon = user.gameswon;
Expand Down Expand Up @@ -74,14 +72,7 @@ export default class User {
*
* @readonly
*/
public readonly role:
| "anon"
| "user"
| "bot"
| "halfmod"
| "mod"
| "admin"
| "sysop";
public readonly role: "anon" | "user" | "bot" | "halfmod" | "mod" | "admin" | "sysop";
/**
* When the user account was created. If not set, this account was created before join dates were recorded.
*
Expand Down
57 changes: 53 additions & 4 deletions src/util/api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,52 @@
import { Packr, Unpackr, addExtension } from "msgpackr";
import { APIResponse } from "./types";

const cacheSessionID = `SESS-${Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)}`;

const cache: Map<string, { expire: number; data: any }> = new Map();

addExtension({
type: 1,
read: (e) =>
null === e
? {
success: true,
}
: {
success: true,
...e,
},
});
addExtension({
type: 2,
read: (e) =>
null === e
? {
success: false,
}
: {
success: false,
error: e,
},
});

const unpackr = new Unpackr({
bundleStrings: true,
});

const packr = new Packr({
bundleStrings: true,
});

export class APIError extends Error {
public response: APIResponse;
constructor(res: APIResponse) {
super(res.error.msg);
this.response = res;
Error.captureStackTrace(this, APIError);
}
}

export default async function (
endpoint: string,
token?: string,
Expand All @@ -24,20 +69,24 @@ export default async function (
}

let headers: any = {
Accept: "application/json",
Accept: "application/vnd.osk.theorypack",
"X-Session-ID": cacheSessionID,
...headers_,
};

if (token) headers.Authorization = `Bearer ${token}`;
if (method == "POST") headers["content-type"] = "application/vnd.osk.theorypack";
let response: Promise<APIResponse> = fetch(`https://tetr.io/api${endpoint}`, {
method,
body: body_ ? Buffer.from(JSON.stringify(body_)) : undefined,
body: body_ ? packr.pack(body_) : undefined,
headers,
}).then((res) => res.json());
})
.then((res) => res.arrayBuffer())
.then((res) => unpackr.unpack(Buffer.from(res)));

if (cache_) cache.set(cache_.key, { expire: cache_.expire, data: response });

if (!(await response).success) throw Error((await response).error.msg);
if (!(await response).success) throw new APIError(await response);

return await response;
}
Loading

0 comments on commit 1783f9e

Please sign in to comment.