From b29ed05f75aee3bd244298587866261d7f1a8dcd Mon Sep 17 00:00:00 2001 From: Neko Ayaka Date: Fri, 21 Nov 2025 17:09:49 +0800 Subject: [PATCH] feat(minecraft): support to auth with Microsoft auth, added docs --- services/minecraft/.env | 22 ++++++++++++++++- services/minecraft/README.md | 25 ++++++++++++++++++-- services/minecraft/src/composables/config.ts | 22 ++++++++--------- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/services/minecraft/.env b/services/minecraft/.env index 0380bee0b..7f32dcdce 100644 --- a/services/minecraft/.env +++ b/services/minecraft/.env @@ -6,5 +6,25 @@ OPENAI_REASONING_MODEL='deepseek-reasoner' BOT_USERNAME='' BOT_HOSTNAME='' BOT_PORT='' -BOT_PASSWORD='' +# # For all online accounts, un-comment the following line to toggle Microsoft authentication. +# # Link for authentication will popup when the bot starts. +# # +# # After signed in, according to [how Minecraft protocol was implemented](https://github.com/PrismarineJS/node-minecraft-protocol/blob/bf89f7e86526c54d8c43f555d8f6dfa4948fd2d9/src/client/microsoftAuth.js#L7-L16) +# # and also, [authentication flow implemented here](https://github.com/PrismarineJS/prismarine-auth/blob/1aef6e1387d94fca839f2811d17ac6659ae556b4/src/MicrosoftAuthFlow.js#L59-L69), +# # the token will be cached with [the cache IDs specified here](https://github.com/PrismarineJS/prismarine-auth/blob/1aef6e1387d94fca839f2811d17ac6659ae556b4/src/MicrosoftAuthFlow.js#L88-L93) +# # in split files: +# # +# # - ${hash}_live-cache.json +# # - ${hash}_mca-cache.json +# # - ${hash}_xbl-cache.json +# # +# # inside of the directory provided by [`minecraft-folder-path`](https://github.com/simonmeusel/minecraft-folder-path) +# # +# # Linux: ~/.minecraft +# # macOS: ~/Library/Application Support/minecraft +# # Windows: %appdata%/.minecraft +# # +# # where ${hash} is the sha1 hash of the username you signing in with (as Minecraft username). +# # +# BOT_AUTH='microsoft' BOT_VERSION='' diff --git a/services/minecraft/README.md b/services/minecraft/README.md index eca388a97..8c1d4ab80 100644 --- a/services/minecraft/README.md +++ b/services/minecraft/README.md @@ -46,6 +46,27 @@ pnpm install 3. Create a `.env.local` file with your configuration: +> [!NOTE] +> For all online accounts, un-comment the following line to toggle Microsoft authentication. +> Link for authentication will popup when the bot starts. +> +> After signed in, according to [how Minecraft protocol was implemented](https://github.com/PrismarineJS/node-minecraft-protocol/blob/bf89f7e86526c54d8c43f555d8f6dfa4948fd2d9/src/client/microsoftAuth.js#L7-L16) +> and also, [authentication flow implemented here](https://github.com/PrismarineJS/prismarine-auth/blob/1aef6e1387d94fca839f2811d17ac6659ae556b4/src/MicrosoftAuthFlow.js#L59-L69), +> the token will be cached with [the cache IDs specified here](https://github.com/PrismarineJS/prismarine-auth/blob/1aef6e1387d94fca839f2811d17ac6659ae556b4/src/MicrosoftAuthFlow.js#L88-L93) +> in split files: +> +> - `${hash}_live-cache.json` +> - `${hash}_mca-cache.json` +> - `${hash}_xbl-cache.json` +> +> inside of the directory provided by [`minecraft-folder-path`](https://github.com/simonmeusel/minecraft-folder-path) +> +> Linux: `~/.minecraft/nmp-cache/` +> macOS: `~/Library/Application Support/minecraft/nmp-cache/` +> Windows: `%appdata%/.minecraft/nmp-cache/` +> +> where `${hash}` is the `sha1` hash of the username you signing in with (as Minecraft username). + ```env OPENAI_API_KEY=your_openai_api_key OPENAI_API_BASEURL=your_openai_api_baseurl @@ -53,11 +74,11 @@ OPENAI_API_BASEURL=your_openai_api_baseurl BOT_USERNAME=your_bot_username BOT_HOSTNAME=localhost BOT_PORT=25565 -BOT_PASSWORD=optional_password +BOT_AUTH='microsoft' # comment if you use offline mode BOT_VERSION=1.20 ``` -4. Start the bot: +1. Start the bot: ```bash pnpm dev diff --git a/services/minecraft/src/composables/config.ts b/services/minecraft/src/composables/config.ts index e391eaf1f..e18cfa058 100644 --- a/services/minecraft/src/composables/config.ts +++ b/services/minecraft/src/composables/config.ts @@ -26,8 +26,8 @@ interface Config { } // Helper functions for type-safe environment variable parsing -function getEnvVar(key: string, defaultValue: string): string { - return env[key] || defaultValue +function getEnvVar(key: string, defaultValue?: V): V | undefined { + return (env[key] || defaultValue) as V | undefined } function getEnvNumber(key: string, defaultValue: number): number { @@ -64,23 +64,23 @@ export function initEnv(): void { // Update config with environment variables config.openai = { - apiKey: getEnvVar('OPENAI_API_KEY', defaultConfig.openai.apiKey), - baseUrl: getEnvVar('OPENAI_API_BASEURL', defaultConfig.openai.baseUrl), - model: getEnvVar('OPENAI_MODEL', defaultConfig.openai.model), - reasoningModel: getEnvVar('OPENAI_REASONING_MODEL', defaultConfig.openai.reasoningModel), + apiKey: getEnvVar('OPENAI_API_KEY', defaultConfig.openai.apiKey)!, + baseUrl: getEnvVar('OPENAI_API_BASEURL', defaultConfig.openai.baseUrl)!, + model: getEnvVar('OPENAI_MODEL', defaultConfig.openai.model)!, + reasoningModel: getEnvVar('OPENAI_REASONING_MODEL', defaultConfig.openai.reasoningModel)!, } config.bot = { - username: getEnvVar('BOT_USERNAME', defaultConfig.bot.username as string), - host: getEnvVar('BOT_HOSTNAME', defaultConfig.bot.host as string), + username: getEnvVar('BOT_USERNAME', defaultConfig.bot.username as string)!, + host: getEnvVar('BOT_HOSTNAME', defaultConfig.bot.host as string)!, port: getEnvNumber('BOT_PORT', defaultConfig.bot.port as number), - password: getEnvVar('BOT_PASSWORD', defaultConfig.bot.password as string), + auth: getEnvVar('BOT_AUTH', defaultConfig.bot.auth as string | undefined) as BotOptions['auth'], version: getEnvVar('BOT_VERSION', defaultConfig.bot.version as string), } config.airi = { - wsBaseUrl: getEnvVar('AIRI_WS_BASEURL', defaultConfig.airi.wsBaseUrl), - clientName: getEnvVar('AIRI_CLIENT_NAME', defaultConfig.airi.clientName), + wsBaseUrl: getEnvVar('AIRI_WS_BASEURL', defaultConfig.airi.wsBaseUrl)!, + clientName: getEnvVar('AIRI_CLIENT_NAME', defaultConfig.airi.clientName)!, } logger.withFields({ config }).log('Environment variables initialized')