Skip to content

Commit 90c7372

Browse files
committed
Implement Traveling Mimo automation for supported games, including task completion, reward claiming, and currency exchange. Update configuration and documentation to reflect new features.
1 parent 66c3d02 commit 90c7372

16 files changed

Lines changed: 1265 additions & 14 deletions

File tree

README.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,15 @@ If you don't have a server to run this script and simply just want to use it for
6363
- **Expedition check**: Check your expeditions and sends a notification if they're done.
6464
- **Code Redeems**: Search for codes and redeem them automatically.
6565
- **Trailblazer Monthly Calendar**: Check your monthly currency income.
66+
- **Traveling Mimo**: Automatically complete Mimo tasks, claim points, and exchange for Stellar Jade.
6667
- **Zenless Zone Zero**:
6768
- **Daily check-in**: Runs every midnight local time.
6869
- **Dailies**: Reminds you to do your dailies, such as commissions if you haven't done them at 09:00 (local time).
6970
- **Stamina check**: Reminds you to spend your stamina if you're at your set threshold or capped.
7071
- **Howl Scracth Card**: Notifies you if you haven't scratched the card for the day at 09:00 (local time).
7172
- **Shop Status**: Notifies you if the shop has finished selling videos.
7273
- **Code Redeems**: Search for codes and redeem them automatically.
74+
- **Traveling Mimo**: Automatically complete Mimo tasks, claim points, and exchange for Polychrome.
7375

7476
## Prerequisites
7577
- [Git](https://git-scm.com/downloads)
@@ -152,7 +154,7 @@ For setting up Discord or Telegram notifications, refer to the [setup folder](ht
152154
153155
## Running with Docker
154156
155-
This application can be easily managed and run using Docker. We provide a Makefile
157+
This application can be easily managed and run using Docker. We provide a Makefile
156158
for convenience, but you can also use Docker commands directly.
157159
158160
**1. Prerequisites**
@@ -194,12 +196,12 @@ You can configure your config using one of the following methods:
194196

195197
**Using the Makefile (Recommended):**
196198

197-
The provided Makefile simplifies common Docker tasks.
199+
The provided Makefile simplifies common Docker tasks.
198200

199201
- **Build the image:**
200202
```bash
201-
make build
202-
```
203+
make build
204+
```
203205
- **Start the application:**
204206
```bash
205207
make up
@@ -210,13 +212,13 @@ The provided Makefile simplifies common Docker tasks.
210212
```
211213
- **View logs:**
212214
```bash
213-
make logs
215+
make logs
214216
```
215217
- **Rebuild and restart:**
216218
```bash
217-
make update
219+
make update
218220
```
219-
221+
220222
For a complete list of available Makefile targets, run:
221223

222224
```bash

commands/mimo/index.js

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
module.exports = {
2+
name: "mimo",
3+
description: "Manually run Traveling Mimo automation for all games or a specific game.",
4+
params: [
5+
{
6+
name: "game",
7+
description: "The game you want to run Mimo for. Leave empty for all games.",
8+
type: "string",
9+
choices: [
10+
{ name: "All Games", value: "all" },
11+
{ name: "Honkai: Star Rail", value: "starrail" },
12+
{ name: "Zenless Zone Zero", value: "nap" }
13+
],
14+
required: false
15+
}
16+
],
17+
run: (async function mimo (context, game) {
18+
const { interaction } = context;
19+
20+
const gameMapping = {
21+
zenless: "nap",
22+
zzz: "nap",
23+
hsr: "starrail"
24+
};
25+
26+
if (game) {
27+
game = gameMapping[game.toLowerCase()] || game.toLowerCase();
28+
}
29+
30+
const supportedGames = ["starrail", "nap"];
31+
const gamesToRun = game && game !== "all"
32+
? [game].filter(g => supportedGames.includes(g))
33+
: supportedGames;
34+
35+
if (gamesToRun.length === 0) {
36+
const message = "Invalid game specified. Supported games are: Star Rail, ZZZ";
37+
return interaction
38+
? interaction.reply({ content: message, ephemeral: true })
39+
: { success: false, reply: message };
40+
}
41+
42+
if (interaction) {
43+
await interaction.deferReply({ ephemeral: true });
44+
}
45+
46+
const results = [];
47+
const errors = [];
48+
49+
for (const gameName of gamesToRun) {
50+
const accounts = app.HoyoLab.getActiveAccounts({ whitelist: gameName });
51+
if (accounts.length === 0) {
52+
continue;
53+
}
54+
55+
const gamePlatform = app.HoyoLab.get(gameName);
56+
if (!gamePlatform || typeof gamePlatform.mimo !== "function") {
57+
errors.push({ game: gameName, error: "Mimo not supported" });
58+
continue;
59+
}
60+
61+
for (const account of accounts) {
62+
try {
63+
app.Logger.info("Command:Mimo", `Running Mimo for ${gameName} - ${account.uid}`);
64+
65+
const result = await gamePlatform.mimo(account);
66+
if (!result.success) {
67+
errors.push({
68+
game: gameName,
69+
uid: account.uid,
70+
error: result.message || "Unknown error"
71+
});
72+
continue;
73+
}
74+
75+
results.push({
76+
game: gameName,
77+
uid: account.uid,
78+
nickname: account.nickname,
79+
...result.data
80+
});
81+
}
82+
catch (e) {
83+
app.Logger.error("Command:Mimo", {
84+
message: "Mimo automation failed",
85+
game: gameName,
86+
uid: account.uid,
87+
error: e.message
88+
});
89+
errors.push({
90+
game: gameName,
91+
uid: account.uid,
92+
error: e.message
93+
});
94+
}
95+
}
96+
}
97+
98+
if (results.length === 0 && errors.length === 0) {
99+
const message = "No accounts found with Mimo enabled.";
100+
return interaction
101+
? interaction.editReply({ content: message })
102+
: { success: false, reply: message };
103+
}
104+
105+
// Build response
106+
const summaryLines = ["🐾 **Traveling Mimo Results**\n"];
107+
108+
for (const r of results) {
109+
const gameShort = { genshin: "GI", starrail: "HSR", nap: "ZZZ" }[r.game] || r.game;
110+
summaryLines.push(`**${gameShort}** - ${r.nickname} (${r.uid})`);
111+
112+
if (r.tasksClaimed.length > 0) {
113+
const totalPoints = r.tasksClaimed.reduce((sum, t) => sum + t.points, 0);
114+
summaryLines.push(` 🎯 Tasks Claimed: ${r.tasksClaimed.length} (+${totalPoints} pts)`);
115+
}
116+
117+
if (r.tasksFinished.length > 0) {
118+
summaryLines.push(` ✅ Tasks Finished: ${r.tasksFinished.length}`);
119+
}
120+
121+
if (r.itemsExchanged.length > 0) {
122+
summaryLines.push(` 🎁 Items Exchanged: ${r.itemsExchanged.map(i => i.name).join(", ")}`);
123+
}
124+
125+
if (r.codesRedeemed.length > 0) {
126+
summaryLines.push(` 🔑 Codes Redeemed: ${r.codesRedeemed.join(", ")}`);
127+
}
128+
129+
summaryLines.push(` 💎 Current Points: ${r.points}`, "");
130+
}
131+
132+
if (errors.length > 0) {
133+
summaryLines.push("**❌ Errors:**");
134+
for (const e of errors) {
135+
summaryLines.push(` • ${e.game} ${e.uid ? `(${e.uid})` : ""}: ${e.error}`);
136+
}
137+
}
138+
139+
const summary = summaryLines.join("\n").slice(0, 2000);
140+
141+
if (interaction) {
142+
await interaction.editReply({ content: summary });
143+
return;
144+
}
145+
146+
return { success: true, reply: summary };
147+
})
148+
};

crons/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const CodeRedeem = require("./code-redeem/index.js");
55
const DailiesReminder = require("./dailies-reminder/index.js");
66
const Expedition = require("./expedition/index.js");
77
const HowlScratchCard = require("./howl-scratch-card/index.js");
8+
const Mimo = require("./mimo/index.js");
89
const MissedCheckIn = require("./missed-check-in/index.js");
910
const RealmCurrency = require("./realm-currency/index.js");
1011
const ShopStatus = require("./shop-status/index.js");
@@ -20,6 +21,7 @@ const definitions = [
2021
DailiesReminder,
2122
Expedition,
2223
HowlScratchCard,
24+
Mimo,
2325
MissedCheckIn,
2426
RealmCurrency,
2527
ShopStatus,
@@ -35,7 +37,7 @@ const BlacklistedCrons = [
3537
];
3638

3739
const initCrons = () => {
38-
const { blacklist = [], whitelist = [] } = config.crons;
40+
const { blacklist = [], whitelist = []} = config.crons;
3941
if (blacklist.length > 0 && whitelist.length > 0) {
4042
throw new Error(`Cannot have both a blacklist and a whitelist for crons`);
4143
}

0 commit comments

Comments
 (0)