diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 51b5e5c..57caf26 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ on: - main paths: - - "mianfest.json" + - "manifest.json" - '**.cs' - '**.csproj' - '**.slnx' @@ -157,4 +157,4 @@ jobs: with: create_attestations: ${{github.ref == env.RELEASE_REF}} create_combined_zip: "Mods-package" - \ No newline at end of file + diff --git a/Lixeer.ValleyServer.slnx b/Lixeer.ValleyServer.slnx index 8e29a40..3d2ef7e 100644 --- a/Lixeer.ValleyServer.slnx +++ b/Lixeer.ValleyServer.slnx @@ -4,4 +4,5 @@ - \ No newline at end of file + + diff --git a/Mods/AutoPause/AutoPause.csproj b/Mods/AutoPause/AutoPause.csproj new file mode 100644 index 0000000..2f60133 --- /dev/null +++ b/Mods/AutoPause/AutoPause.csproj @@ -0,0 +1,13 @@ + + + AutoPause + AutoPause + AnyCPU + net6.0 + latest + + + + + + diff --git a/Mods/AutoPause/ModConfig.cs b/Mods/AutoPause/ModConfig.cs new file mode 100644 index 0000000..a8d44fc --- /dev/null +++ b/Mods/AutoPause/ModConfig.cs @@ -0,0 +1,11 @@ +namespace AutoPause +{ + public class ModConfig + { + // 默认配置,第一次运行后可在生成的 config.json 中修改 + public string ServerIP { get; set; } = "127.0.0.1"; + public int ServerPort { get; set; } = 29103; + // public string AccessToken { get; set; } = "在这里填入你的Token"; + public string Command { get; set; } = "alos.pause"; + } +} diff --git a/Mods/AutoPause/ModEntry.cs b/Mods/AutoPause/ModEntry.cs new file mode 100644 index 0000000..f7f9951 --- /dev/null +++ b/Mods/AutoPause/ModEntry.cs @@ -0,0 +1,78 @@ +using System; +using System.Net.WebSockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using StardewModdingAPI; +using StardewModdingAPI.Events; +using StardewValley; + +namespace AutoPause +{ + public class ModEntry : Mod + { + private ModConfig Config; + private bool _isPausedByMod = false; + + public override void Entry(IModHelper helper) + { + // 加载配置并确保生成文件 + this.Config = helper.ReadConfig(); + helper.WriteConfig(this.Config); + + // 监听菜单变化 + helper.Events.Display.MenuChanged += this.OnMenuChanged; + + this.Monitor.Log($"AutoPause (WebSocket版) 已启动。目标: ws://{this.Config.ServerIP}:{this.Config.ServerPort}/ws", LogLevel.Info); + } + + private void OnMenuChanged(object sender, MenuChangedEventArgs e) + { + if (!Context.IsMultiplayer || Context.IsMainPlayer) + return; + + if (e.NewMenu != null && !_isPausedByMod) + { + _ = this.TriggerWebSocketCommand("暂停"); + _isPausedByMod = true; + } + else if (e.NewMenu == null && _isPausedByMod) + { + _ = this.TriggerWebSocketCommand("恢复"); + _isPausedByMod = false; + } + } + + private async Task TriggerWebSocketCommand(string action) + { + // 使用 using 确保 WebSocket 用完后正确释放 + using (var ws = new ClientWebSocket()) + { + try + { + // CommandWebUI 的 WebSocket 地址固定为 /ws + Uri serverUri = new Uri($"ws://{this.Config.ServerIP}:{this.Config.ServerPort}/ws"); + + // 1. 建立连接 + await ws.ConnectAsync(serverUri, CancellationToken.None); + + // 2. 将命令转换为字节流 + // 注意:因为是直接推送到控制台 Reader.PushInput,如果需要前缀请在 config 中配置好,比如 "!cmd>alos.pause" 或 "alos.pause" + byte[] commandBytes = Encoding.UTF8.GetBytes(this.Config.Command); + ArraySegment bytesToSend = new ArraySegment(commandBytes); + + // 3. 发送命令 + await ws.SendAsync(bytesToSend, WebSocketMessageType.Text, true, CancellationToken.None); + this.Monitor.Log($"[AutoPause] {action} 指令 ({this.Config.Command}) 已通过 WebSocket 发送成功", LogLevel.Info); + + // 4. 正常关闭连接 + await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Command Sent", CancellationToken.None); + } + catch (Exception ex) + { + this.Monitor.Log($"[AutoPause] WebSocket 发送失败: {ex.Message}", LogLevel.Error); + } + } + } + } +} diff --git a/Mods/AutoPause/README.md b/Mods/AutoPause/README.md new file mode 100644 index 0000000..a8a92c9 --- /dev/null +++ b/Mods/AutoPause/README.md @@ -0,0 +1,38 @@ +# AutoPause (客机自动暂停增强 Mod) + +本 Mod 是针对《星露谷物语》(Stardew Valley)多人联机模式下自动暂停功能的增强扩展。主要为**客机玩家**(非房主/非服务端)提供在特定界面下的时间暂停功能,让你在整理物品或阅读剧情时不再手忙脚乱。 + +## ⚠️ 重要警告 (使用前必读) + +1. **非必选 Mod**:本 Mod 为按需使用的增强型补丁,并非基础运行的必须组件。 +2. **严重依赖 CommandWebUI**:本 Mod 本质上是一个 WebSocket 客户端,它**完全依赖**于本仓库中的 `CommandWebUI` 模组。在使用前,请务必确保服务端的 `CommandWebUI` 已正确安装、配置,并且单独测试通过(没有任何网络阻碍)。 +3. **影响联机体验**:由于星露谷的机制,客机触发暂停会导致**整个服务器的时间停止**。这必然会打断其他正在活动的玩家,严重影响多人的连贯游戏体验。**请务必与服务器内的其他小伙伴沟通一致后,谨慎使用!** +4. **AI 生成**:本 Mod 的核心代码由 AI 辅助生成并经过基础测试,但在极其复杂的网络环境或极限操作下可能仍存在未知的边界问题,请知悉。 +5. **涉及安全问题**:详见本项目CommandWebUI Mod说明 https://github.com/Lixeer/ValleyServer/blob/main/Mods/CommandWebUI/README.md + +## ⚙️ 当前阶段与功能支持 + +本 Mod 目前处于**测试阶段**,暂未覆盖游戏内的所有 UI 界面。 +目前**仅支持**在客机打开和关闭以下界面时,自动向服务器发送暂停/恢复指令: +* **菜单界面** (Menu) +* **库存/背包界面** (Inventory / Chests) +* **对话界面** (Dialogue) + +## 📦 安装说明 + +**【本 Mod 仅需安装在客机端】** 服务端**不需要**(也不建议)安装本 Mod,服务端只需正常运行 `CommandWebUI` 即可。 + +1. 下载编译好的 `AutoPause` 压缩包。 +2. 将解压后的 `AutoPause` 文件夹放入你本地游戏目录的 `Mods/` 文件夹下。 +3. 启动一次游戏,让 Mod 自动生成 `config.json` 配置文件。 + +## 🛠️ 配置指南 (`config.json`) + +第一次运行后,打开 `Mods/AutoPause/config.json`,根据你的服务器情况进行修改: + +```json +{ + "ServerIP": "127.0.0.1", // 请修改为服务端的真实 IP (公网或局域网IP) + "ServerPort": 29103, // 必须与服务端 CommandWebUI 监听的端口一致 + "Command": "alos.pause" // 触发暂停/恢复的指令,通常保持默认即可 +} diff --git a/Mods/AutoPause/manifest.json b/Mods/AutoPause/manifest.json new file mode 100644 index 0000000..b065eb3 --- /dev/null +++ b/Mods/AutoPause/manifest.json @@ -0,0 +1,10 @@ +{ + "Name": "AutoPause", + "Author": "i-Eureka", + "Version": "1.0.0", + "Description": "当客机打开界面时自动发送暂停命令", + "UniqueID": "i-Eureka.AutoPause", + "EntryDll": "AutoPause.dll", + "MinimumApiVersion": "4.0.0", + "UpdateKeys": [] +}