Skip to content

Commit

Permalink
feat: i18n and logger and program
Browse files Browse the repository at this point in the history
  • Loading branch information
BIYUEHU committed Feb 22, 2024
1 parent e791d38 commit 6686a64
Show file tree
Hide file tree
Showing 17 changed files with 776 additions and 420 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: 'ci'
on:
push:
branches:
- '**'
pull_request:
branches:
- '**'

jobs:
build:
runs-on: ubuntu-latest
name: Build the package
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v4
with:
node-version: 18
cache: 'yarn'
- run: yarn install
env:
CYPRESS_INSTALL_BINARY: 0
- run: yarn build
209 changes: 209 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
# Mcwss [![npm package](https://badgen.net/npm/v/mcwss)](https://npmjs.com/package/mcwss) [![wakatime](https://wakatime.com/badge/user/018dc603-712a-4205-a226-d4c9ccd0d02b/project/018dceb3-4749-44d6-93be-b3e581301a74.svg)](https://wakatime.com/badge/user/018dc603-712a-4205-a226-d4c9ccd0d02b/project/018dceb3-4749-44d6-93be-b3e581301a74)

> The project is refactory version for version of three years (2021) ago base on TypeScript.
A simple Minecraft Bedrock Edition websocket server framework, help developer to setup websocket server faster for Minecraft or your self package depend on it.Its core `Mcwss` base a events emiter and provide many of events which can be listened.In addition,it provides `Client` instance object to interact with every clent.

## 🧊 Usage

> What? You donot know how to install Node.js program? Are you kidding me? Please find [Google Search](https://google.com) to help you.
Base on program cli to start:

```sh
mcwss
```

For C(~~Z~~)hinese(English understanding hard population):

```sh
mcwss --lang zh_CN
```

Start your Minecraft Bedrock Edition and input commands:

```sh
/wsserver ws://localhost:1
# or:
/connect ws://localhost:1
```

Test a few:

```sh
*/help
*/helph
```

### Options

- `--port [num]` Set websocket server port
- `--mode [type]` Set logger level, debug or build
- `--lang [locale]` Set view language, en_US, ja_JP, zh_TW, zh_CN
- `-v, --version` Display version number
- `-h, --help` Display this message

Example:

```sh
mcwss --port 2333 --mode debug --lang ja_JP
```

### built-in commands

- `*/help` Show Mcwss command help
- `*/connect` Show WebSocket connection time
- `*/about` Show about information§r
- `*/clears` Clear chat content§r
- `*/func <path>` Execute mcfunction on server§r
- `*/helph` Show hidden command help§r",

Game hidden Command:

- `./closewebsocket` Close websocket connection§r
- `./gettopsolidblock <x> <y> <z>` Get top solid block coordinates§r
- `./querytarget <selector>` Get precise float coordinates of entity§r
- `./agent` Mascot§r
- `./enableencryption` Unknown§r
- `./closechat` Close chat§r
- `./geteduclientinfo` Get version info§r
- `./getlocalplayername` Return player name§r

## 🎯 Events

Lifecycle Events:

- ready
- dispose
- error
- connection
- message
- close

Minecraft Events:

- block_broken
- block_placed
- end_of_day
- entity_spawned
- item_acquired
- item_crafted
- item_destroyed
- item_smelted
- item_used
- jukebox_used
- mob_interacted
- mob_killed
- player_bounced
- player_died
- player_message
- player_teleported
- player_transform
- player_travelled
- unknown_minecraft_event
- command_response

## 🚀 Class

### Mcwss

- `start(): void` Start a websocket server
- `stop(): void` Stop a websocket server

Extends `Events`:

- `emit<T extends keyof EventsList>(type: T, ...data: [...Parameters<EventsList[T]>]): void` Emit a event
- `parallel<T extends keyof EventsList>(type: T, ...data: [...Parameters<EventsList[T]>]): Promise<void>` Emit a event asynchronous
- `on<T extends keyof EventsList>(type: T, callback: EventsList[T]): void` Listen a event
- `once<T extends keyof EventsList>(type: T, callback: EventsList[T]): void` Listen a event once
- `off<T extends keyof EventsList>(type: T, callback: EventsList[T]): void` Cancel to listen a event
- `offAll<T extends keyof EventsList>(type: T): void` Cancel to listen all events

### Client

- `req: IncomingMessage` Client websocket object
- `sessionId: number` Connection identify at `Mcwss`
- `sessionDate: Date` Connection setup time
- `send(data: SendPacket): void` Send a packet to client
- `close(): void` Close connection with client
- `subscribe(event: MinecraftEvents): void` Subscribe a minecraft event
- `unsubscribe(event: MinecraftEvents): void` Unsubscribe a minecraft event
- `run(cmd: string | string[]): void` Run a or many of command to client
- `chat(message: string): void` Send a normal message to client (Base for `/say`)
- `chatf(message: string, color?: TextColor, sender?: string, target: CommandTarget = CommandTarget.SELF): void` Send a advanced message to client (Base for `/tellraw`)
- `func(file: string): void` Run a `.mcfunction` file to client

```typescript
const enum TextColor {
GREEN = '§a',
RED = '§c',
BLUE = '§b',
YELLOW = '§e'
}

const enum CommandTarget {
ALL = '@a',
SELF = '@s',
RANDOM = '@r',
EVERY = '@e',
NEAR = '@p'
}
```

## 🧩 Internationalization

Supports languages:

```typescript

```

## 🌰 Example

Setup your self program or package base on Mcwss, refer to `src/utils/line.ts` for more information.

```typescript
import Mcwss from 'mcwss';
import { log, error } from 'console';

const mcwss = new Mcwss({ port: 2333 });

/* events register */
mcwss.on('ready', () => log(`WebSocketServer started at ws://localehost:${port} `));

mcwss.on('dispose', () => log('WebSocketServer stopped'));

mcwss.on('error', (data) =>
error(data.client ? `[Client:${data.client.sessionId}]` : '[Server]', data.error.name, data.error.message)
);

mcwss.on('connection', (data) =>
log(`[Client:${data.client.sessionId}]`, 'new connection from', data.client.req.socket.remoteAddress)
);

mcwss.on('close', (data) => {
if (data.raw) {
log(`[Client:${data.raw.client.sessionId}]`, 'Closing in progress code:', data.raw.code);
return;
}
log('WebSocketServer is closeing...');
});

mcwss.on('block_broken', (data) => {
const { block, player, tool } = data.body;
/* ... */
});

mcwss.on('end_of_day', (data) => {
const { player } = data.body;
/* ... */
});

/* ... */

mcwss.start();
```

## 📜 License

Comply with The GNU General Public License v3.0 open-source license.
3 changes: 3 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Todo-list

- [ ] Program print i18n
3 changes: 3 additions & 0 deletions bin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node

require('./lib/utils/program.js');
29 changes: 29 additions & 0 deletions locales/en_US.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"none": "none",
"block.broken": "Player {0} broke block {2} {3} at {1}",
"block.placed": "Player {0} placed block {2} using tool {3} at {1}",
"end.of.day": "Player {0} just experienced nightfall at {1}",
"entity.spawned": "Player {0} spawned an entity of type {2} at {1}",
"item.acquired": "Player {0} acquired {2} {3} at {1}",
"item.crafted": "Player {0} crafted {2} {3} at {1}",
"item.destroyed": "Player {0} destroyed {2} {3} at {1}",
"item.smelted": "Player {0} smelted {2} at {1}",
"item.used": "Player {0} used {2} {3} at {1}",
"jukebox.used": "Player {0} played {2} {3} record at {1}",
"mob.interacted": "Player {0} interacted {3} with {2} at {1}",
"mob.killed": "Player {0} killed {3} ({4}) at {2} located at {1}",
"mob.killed.unnamed": "unnamed",
"player.bounced": "Player {0} bounced from {2} at {1}",
"player.died": "Player {0} was killed by {2} at {1}",
"player.message": "{0} sent a {2} message to {1}: {3}",
"player.message.all": "Everyone",
"player.teleported": "Player {0} teleported {2} blocks at {1}",
"player.transform": "Player {0} transformed",
"player.travelled": "Player {0} travelled {2} blocks at {1}",
"command.response": "Response:\n{0}",
"command.help": "§2--- Mcwss Command Help ---§r\n*/help §7- Show Mcwss command help§r\n*/connect §7- Show WebSocket connection time§r\n*/about §7- Show about information§r\n*/clears §7- Clear chat content§r\n*/func <path> §7- Execute mcfunction on server§r\n*/helph §7- Show hidden command help§r",
"command.helpf": "§2---- Hidden Command Help ----§r\n./closewebsocket §7- Close websocket connection§r\n./gettopsolidblock <x> <y> <z> §7- Get top solid block coordinates§r\n./querytarget <selector> §7- Get precise float coordinates of entity§r\n./agent §7- Mascot§r\n./enableencryption §7- Unknown§r\n./closechat §7- Close chat§r\n./geteduclientinfo §7- Get version info§r\n./getlocalplayername §7- Return player name§r",
"command.connect": "Connected normally: {0} seconds\nConnection time: {1}",
"command.about": "Mcwss\nAuthor: {0}\nVersion: {1}\nConnection IP: {2}",
"command.function": "Failed to execute mcfunction: File {0} does not exist"
}
29 changes: 29 additions & 0 deletions locales/ja_JP.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"none": "なし",
"block.broken": "プレイヤー{0}が{1}で{2} {3}ブロックを壊しました",
"block.placed": "プレイヤー{0}が{1}でツール{3}を使って{2}ブロックを設置しました",
"end.of.day": "プレイヤー{0}が{1}で夜を迎えました",
"entity.spawned": "プレイヤー{0}が{1}で{2}タイプのエンティティを生成しました",
"item.acquired": "プレイヤー{0}が{1}で{2}個の{3}を入手しました",
"item.crafted": "プレイヤー{0}が{1}で{2}個の{3}を作成しました",
"item.destroyed": "プレイヤー{0}が{1}で{2}個の{3}を破壊しました",
"item.smelted": "プレイヤー{0}が{1}で{2}を溶かしました",
"item.used": "プレイヤー{0}が{1}で{2}個の{3}を使用しました",
"jukebox.used": "プレイヤー{0}が{1}で{2}個の{3}レコードを再生しました",
"mob.interacted": "プレイヤー{0}が{1}で{2}と{3}の相互作用をしました",
"mob.killed": "プレイヤー{0}が{1}にいる{3}({4})を{2}で殺しました",
"mob.killed.unnamed": "無名",
"player.bounced": "プレイヤー{0}が{1}で{2}から跳ね返りました",
"player.died": "プレイヤー{0}が{1}で{2}に殺されました",
"player.message": "{0}が{1}に{2}メッセージを送信しました: {3}",
"player.message.all": "全員",
"player.teleported": "プレイヤー{0}が{1}で{2}ブロック分テレポートしました",
"player.transform": "プレイヤー{0}が変身しました",
"player.travelled": "プレイヤー{0}が{1}で{2}ブロック移動しました",
"command.response": "応答: \n{0}",
"command.help": "§2--- Mcwssコマンドヘルプ ---§r\n*/help §7- Mcwssコマンドヘルプを表示§r\n*/connect §7- WebSocketの接続時間を表示§r\n*/about §7- 情報を表示§r\n*/clears §7- チャット内容を消去§r\n*/func <path> §7- サーバー上でmcfunctionを実行§r\n*/helph §7- 非表示コマンドヘルプを表示§r",
"command.helpf": "§2---- 非表示コマンドヘルプ ----§r\n./closewebsocket §7- websocket接続を閉じる§r\n./gettopsolidblock <x> <y> <z> §7- 最上部の固体ブロック座標を取得§r\n./querytarget <selector> §7- エンティティの正確な浮動小数点座標を取得§r\n./agent §7- マスコット§r\n./enableencryption §7- 不明§r\n./closechat §7- チャットを閉じる§r\n./geteduclientinfo §7- バージョン情報を取得§r\n./getlocalplayername §7- プレイヤー名を返す§r",
"command.connect": "正常に接続しました: {0}秒\n接続時間: {1}",
"command.about": "Mcwss\n作成者: {0}\nバージョン: {1}\n接続IP: {2}",
"command.function": "mcfunctionの実行に失敗しました: ファイル{0}が存在しません"
}
29 changes: 29 additions & 0 deletions locales/zh_CN.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"none": "",
"block.broken": "玩家 {0} 在 {1} 处破坏了方块 {2} {3}",
"block.placed": "玩家 {0} 在 {1} 处放置了方块 {2} 通过工具 {3}",
"end.of.day": "玩家 {0} 在 {1} 处刚经历了黑夜",
"entity.spawned": "玩家 {0} 在 {1} 处生成了 {2} 类型的生物实体",
"item.acquired": "玩家 {0} 在 {1} 处获得了 {2} 个 {3}",
"item.crafted": "玩家 {0} 在 {1} 处合成了 {2} 个 {3}",
"item.destroyed": "玩家 {0} 在 {1} 处破坏了 {2} 个 {3}",
"item.smelted": "玩家 {0} 在 {1} 处熔炼了 {2}",
"item.used": "玩家 {0} 在 {1} 处使用了 {2} 个 {3}",
"jukebox.used": "玩家 {0} 在 {1} 处播放了 {2} 个 {3} 唱片",
"mob.interacted": "玩家 {0} 在 {1} 处与 {2} 发生了 {3} 交互",
"mob.killed": "玩家 {0} 在 {1} 处杀死了在 {2} 处的 {3}({4})",
"mob.killed.unnamed": "未命名",
"player.bounced": "玩家 {0} 在 {1} 处被 {2} 弹起",
"player.died": "玩家 {0} 在 {1} 处被 {2} 杀死",
"player.message": "{0} 对 {1} 发送了 {2} 消息:{3}",
"player.message.all": "所有人",
"player.teleported": "玩家 {0} 在 {1} 处传送了 {2} 格",
"player.transform": "玩家 {0} 移动了",
"player.travelled": "玩家 {0} 在 {1} 处移动了 {2} 格",
"command.response": "返回结果:\n{0}",
"command.help": "§2--- Mcwss 指令帮助页 ---§r\n*/help §7- 显示 Mcwss 指令帮助页§r\n*/connect §7- 显示 WebSocket 连接时间§r\n*/about §7- 显示关于信息§r\n*/clears §7- 清除聊天栏内容§r\n*/func <path> §7- 执行服务器上的 mcfunction§r\n*/helph §7- 显示隐藏指令帮助页§r",
"command.helpf": "§2---- 隐藏指令帮助页 ----§r\n./closewebsocket §7- 关闭websocket连接§r\n./gettopsolidblock <x> <y> <z> §7- 获取坐标点最顶层固态方块坐标§r\n./querytarget <选择器> §7- 获取实体的精确浮点坐标§r\n./agent §7- 吉祥物§r\n./enableencryption §7- 未知§r\n./closechat §7- 关闭聊天栏§r\n./geteduclientinfo §7- 获取版本信息§r\n./getlocalplayername §7- 返回玩家名字§r",
"command.connect": "已正常连接:{0} 秒\n连接时间:{1}",
"command.about": "Mcwss\n作者:{0}\n版本:{1}\n连接 IP:{2}",
"command.function": "mcfunction 执行失败:不存在的文件 {0}"
}
29 changes: 29 additions & 0 deletions locales/zh_TW.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"none": "なし",
"block.broken": "プレイヤー{0}が{1}で{2} {3}ブロックを壊しました",
"block.placed": "プレイヤー{0}が{1}でツール{3}を使って{2}ブロックを設置しました",
"end.of.day": "プレイヤー{0}が{1}で夜を迎えました",
"entity.spawned": "プレイヤー{0}が{1}で{2}タイプのエンティティを生成しました",
"item.acquired": "プレイヤー{0}が{1}で{2}個の{3}を入手しました",
"item.crafted": "プレイヤー{0}が{1}で{2}個の{3}を作成しました",
"item.destroyed": "プレイヤー{0}が{1}で{2}個の{3}を破壊しました",
"item.smelted": "プレイヤー{0}が{1}で{2}を溶かしました",
"item.used": "プレイヤー{0}が{1}で{2}個の{3}を使用しました",
"jukebox.used": "プレイヤー{0}が{1}で{2}個の{3}レコードを再生しました",
"mob.interacted": "プレイヤー{0}が{1}で{2}と{3}の相互作用をしました",
"mob.killed": "プレイヤー{0}が{1}にいる{3}({4})を{2}で殺しました",
"mob.killed.unnamed": "無名",
"player.bounced": "プレイヤー{0}が{1}で{2}から跳ね返りました",
"player.died": "プレイヤー{0}が{1}で{2}に殺されました",
"player.message": "{0}が{1}に{2}メッセージを送信しました: {3}",
"player.message.all": "全員",
"player.teleported": "プレイヤー{0}が{1}で{2}ブロック分テレポートしました",
"player.transform": "プレイヤー{0}が変身しました",
"player.travelled": "プレイヤー{0}が{1}で{2}ブロック移動しました",
"command.response": "応答: \n{0}",
"command.help": "§2--- Mcwssコマンドヘルプ ---§r\n*/help §7- Mcwssコマンドヘルプを表示§r\n*/connect §7- WebSocketの接続時間を表示§r\n*/about §7- 情報を表示§r\n*/clears §7- チャット内容を消去§r\n*/func <path> §7- サーバー上でmcfunctionを実行§r\n*/helph §7- 非表示コマンドヘルプを表示§r",
"command.helpf": "§2---- 非表示コマンドヘルプ ----§r\n./closewebsocket §7- websocket接続を閉じる§r\n./gettopsolidblock <x> <y> <z> §7- 最上部の固体ブロック座標を取得§r\n./querytarget <selector> §7- エンティティの正確な浮動小数点座標を取得§r\n./agent §7- マスコット§r\n./enableencryption §7- 不明§r\n./closechat §7- チャットを閉じる§r\n./geteduclientinfo §7- バージョン情報を取得§r\n./getlocalplayername §7- プレイヤー名を返す§r",
"command.connect": "正常に接続しました: {0}秒\n接続時間: {1}",
"command.about": "Mcwss\n作成者: {0}\nバージョン: {1}\n接続IP: {2}",
"command.function": "mcfunctionの実行に失敗しました: ファイル{0}が存在しません"
}
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"author": "Hotaru <biyuehuya@gmail.com>",
"scripts": {
"dev": "ts-node --esm -r tsconfig-paths/register ./src/index.ts --no-signale",
"build": "tsc",
"build": "tsc --build",
"version": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0"
},
"bin": {
Expand All @@ -26,6 +26,7 @@
],
"files": [
"lib",
"bin.js",
"LICENSE",
"README.md",
"example"
Expand All @@ -45,6 +46,7 @@
"eslint": "^8.47.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-typescript": "^3.0.0",
"execa": "^8.0.1",
"prettier": "^3.0.2",
"tsconfig-paths": "^4.2.0"
Expand All @@ -53,7 +55,8 @@
"@kotori-bot/i18n": "^1.2.1",
"@kotori-bot/logger": "^1.2.0",
"@kotori-bot/tools": "^1.2.1",
"tsukiko": "^1.2.1",
"cac": "^6.7.14",
"tsukiko": "^1.2.2",
"ws": "^8.16.0"
}
}
Loading

0 comments on commit 6686a64

Please sign in to comment.