From 3eabe96e6fc13842ef60123224c3593e9aaf5d02 Mon Sep 17 00:00:00 2001 From: BRanulf Date: Thu, 17 Jul 2025 09:40:22 +0800 Subject: [PATCH] weeeeee --- README.md | 75 +++++++++++++++-- common.gradle | 2 +- gradle.properties | 2 +- libs/LibGui-12.0.1+1.21.2.pom | 78 ------------------ libs/modmenu-13.0.3.pom | 8 -- .../disc_jockey_revive/DebugLogger.java | 2 +- .../semmiedev/disc_jockey_revive/Main.java | 4 + .../gui/screen/DiscJockeyScreen.java | 5 +- .../assets/disc_jockey/sounds/hello_test.ogg | Bin 0 -> 12764 bytes 9 files changed, 78 insertions(+), 98 deletions(-) delete mode 100644 libs/LibGui-12.0.1+1.21.2.pom delete mode 100644 libs/modmenu-13.0.3.pom create mode 100644 src/main/resources/assets/disc_jockey/sounds/hello_test.ogg diff --git a/README.md b/README.md index 7833501..bcc181e 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,75 @@ # 源README Download the mod at [Modrinth](https://modrinth.com/mod/disc-jockey) or [CurseForge](https://www.curseforge.com/minecraft/mc-mods/disc-jockey) # 该版本附加 -## 关于此项目 -此 Mod 是基于 [Disc-Jockey](https://github.com/SemmieDev/Disc-Jockey)(由 [SemmieDev](https://github.com/SemmieDev/) 开发)的修改版本,适配了 Minecraft 1.21.4。 -原始代码版权归原作者所有,修改部分版权归 BRanulf 所有。 +___ +# Disc Jockey Revive -同时,该二改版本我本人并没有上传至任何其他网站(包括 Modrinth 、CurseForge 、Github 等),请勿用于商业用途及其他非法用途。 +一个 Minecraft Fabric 模组,旨在为音符盒音乐爱好者提供强大的播放和即兴演奏功能。 -目前[Modrinth](https://modrinth.com/mod/disc_jockey_revive)上的这个版本非本人上传,就当允许上传了罢,毕竟我比较懒XD +## 模组特性 -[最新版本下载:Release](https://git.branulf.top/Branulf/DIsc_Jockey_revive/releases) +### 🎵 歌曲播放 +- **播放 `.nbs` 歌曲文件**:支持标准的 Note Block Studio (`.nbs`) 歌曲文件(暂不支持带变速的)。 +- **文件夹管理**:支持歌曲文件夹,方便组织和浏览您的音乐库。 +- **多种播放模式**: + - **单曲循环**:重复播放当前歌曲。 + - **列表循环**:按顺序循环播放当前文件夹或列表中的歌曲。 + - **随机播放**:随机播放当前文件夹或列表中的歌曲。 + - **播完停止**:歌曲播放完毕后自动停止。 +- **播放进度条**:在 HUD 上显示歌曲播放进度和时间。 +- **实时调速**:在播放界面通过滑块实时调整歌曲播放速度(0.25x - 4.0x)。 +- **播放失败处理**:当附近音符盒配置不正确时,可选择停止播放或自动播放下一首。 +- **音符盒材料清单**:显示播放当前歌曲所需的所有音符盒材料及数量。 +- **自动调音**:模组会自动识别并调音附近的音符盒以匹配歌曲音高。 +- **全向音符盒音效 (客户端)**: + - **常规模式**:在播放歌曲或预览时,使音符盒音效全向传播,提供更沉浸的听觉体验。 + - **强制模式**:强制所有音符盒音效(包括手动触发的)始终全向传播。 -~~这边建议去给原作者点个Star~~ \ No newline at end of file +### 🎹 即兴演奏 (Live DJ) +- **独立界面**:通过专用快捷键打开一个独立界面,用于即兴演奏。 +- **键盘弹奏**:利用键盘按键直接弹奏音符盒,就像在 FL Studio 中一样。 +- **自定义键位映射**: + - 独立的键位映射配置界面,允许您为每个键盘按键设置特定的音符(乐器和音高)。 + - 默认提供类似于 FL Studio 的键盘布局预设。 +- **即兴演奏调音**:在即兴演奏界面中,可以一键对周围的音符盒进行调音,以确保弹奏的音符准确无误。 +- **独立于歌曲播放**:即兴演奏功能与歌曲播放功能完全独立,互不干扰。 + +### ⚙️ 配置与调试 +- **Mod Menu 集成**:通过 Mod Menu 轻松访问模组配置。 +- **快捷键**: + - 打开歌曲选择界面 (默认 `J`)。 + - 打开即兴演奏界面 (默认 `UNKNOW(未指定)`)。 +- **调试模式**:可配置的调试模式,开启后会在日志中输出详细的调试信息,方便排查问题。 + +## 如何使用 + +1. **安装**:将 `Disc Jockey Revive` 模组文件和 Fabric API 放入您的 Minecraft `mods` 文件夹。 +2. **添加歌曲**: + * 在游戏中打开歌曲选择界面 (默认 `J` 键)。 + * 点击“打开文件夹”按钮,将 `.nbs` 歌曲文件放入弹出的 `disc_jockey/songs` 文件夹中。 + * 您也可以直接将 `.nbs` 文件拖放到歌曲选择界面中。 + * 点击“重新加载”按钮以加载新添加的歌曲。 +3. **播放歌曲**: + * 在歌曲选择界面中选择一首歌曲。 + * 点击“播放”按钮。模组将自动寻找并调音附近的音符盒。 + * 确保您处于生存模式或创造模式,并且附近有足够的音符盒。 + * 您可以通过滑块调整播放速度,并通过播放模式按钮切换循环方式。 +4. **即兴演奏**: + * 在游戏中打开即兴演奏界面 (默认 `UNKNOW` 键)。 + * 点击“开始调音”按钮,模组将自动调音附近的音符盒。 + * 调音完成后,您可以使用键盘按键直接弹奏音符盒。 + * 点击“编辑键位映射”按钮可以自定义每个按键对应的音符。 + +## 注意事项 + +* **服务器兼容性**:此模组通过发送玩家交互数据包来控制音符盒。在某些服务器上,这可能被反作弊插件误判为作弊行为。**强烈建议在使用前联系服务器管理员。** +* **音符盒数量**:为了获得最佳播放效果,请确保您周围有足够数量且种类齐全的音符盒。 +* **非官方版本**:此版本为非官方修订版,仅供学习和参考。请支持原版模组作者。 + +## 贡献与支持 + +如果您有任何问题、建议或发现 Bug,请联系[BRanulf](https://space.bilibili.com/479966868)(仅限于改二改版本,原版本请前往[原作者GitHub](https://github.com/SemmieDev/Disc-Jockey))。 + +不回复是正常现象,因为我也只是随便做做,并没有打算正经地维护,真要搞的化我估计会去GitHub创建分支,而不是只在自己仓库中修改。 + +--- diff --git a/common.gradle b/common.gradle index 401808c..387b801 100644 --- a/common.gradle +++ b/common.gradle @@ -10,7 +10,7 @@ repositories { url 'https://maven.fabricmc.net/' // loom } maven { - url 'https://masa.dy.fi/maven' // mama(随便加的) + url 'https://masa.dy.fi/maven' // masa(随便加的) } maven { url 'https://maven.fallenbreath.me/releases' // preprocessor diff --git a/gradle.properties b/gradle.properties index acb0478..8170a49 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ loader_version=0.16.10 mod_name=Disc Jockey Revive mod_id=disc_jockey_revive # Mod Properties -mod_version=1.14.514.047 +mod_version=1.14.514.048 maven_group=semmiedev archives_base_name=disc_jockey_revive # Dependencies diff --git a/libs/LibGui-12.0.1+1.21.2.pom b/libs/LibGui-12.0.1+1.21.2.pom deleted file mode 100644 index 0bd6e7c..0000000 --- a/libs/LibGui-12.0.1+1.21.2.pom +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - 4.0.0 - io.github.cottonmc - LibGui - 12.0.1+1.21.2 - LibGui - Minecraft GUI Library - https://github.com/CottonMC/LibGui - - - MIT - https://github.com/CottonMC/LibGui/blob/HEAD/LICENSE - - - - - CottonMC - https://github.com/CottonMC - - - - - io.github.juuxel - libninepatch - 1.2.0 - compile - - - net.fabricmc.fabric-api - fabric-api-base - 0.4.48+c47b9d4373 - compile - - - net.fabricmc.fabric-api - fabric-networking-api-v1 - 4.3.3+56ec7ac673 - compile - - - net.fabricmc - fabric-loader - 0.16.7 - runtime - - - net.fabricmc.fabric-api - fabric-lifecycle-events-v1 - 2.3.22+c47b9d4373 - runtime - - - net.fabricmc.fabric-api - fabric-rendering-v1 - 8.0.5+c47b9d4373 - runtime - - - net.fabricmc.fabric-api - fabric-resource-loader-v0 - 3.0.5+c47b9d4373 - runtime - - - io.github.cottonmc - Jankson-Fabric - 9.0.0+j1.2.3 - runtime - - - diff --git a/libs/modmenu-13.0.3.pom b/libs/modmenu-13.0.3.pom deleted file mode 100644 index 4e0cc7a..0000000 --- a/libs/modmenu-13.0.3.pom +++ /dev/null @@ -1,8 +0,0 @@ - - - 4.0.0 - com.terraformersmc - modmenu - 13.0.3 - diff --git a/src/main/java/semmiedev/disc_jockey_revive/DebugLogger.java b/src/main/java/semmiedev/disc_jockey_revive/DebugLogger.java index d626f5e..6dccb2f 100644 --- a/src/main/java/semmiedev/disc_jockey_revive/DebugLogger.java +++ b/src/main/java/semmiedev/disc_jockey_revive/DebugLogger.java @@ -36,7 +36,7 @@ public class DebugLogger { if (client != null && client.inGameHud != null && client.inGameHud.getChatHud() != null) { MinecraftClient.getInstance().inGameHud.getChatHud().addMessage(Text.of("[DiscJockeyRevive-调试]"+message.formatted(Formatting.GRAY))); } else { - Main.LOGGER.error("[DiscJockeyRevive-调试] 聊天窗口未初始化,{}",message); +// Main.LOGGER.error("[DiscJockeyRevive-调试] 聊天窗口未初始化,{}",message); } } } diff --git a/src/main/java/semmiedev/disc_jockey_revive/Main.java b/src/main/java/semmiedev/disc_jockey_revive/Main.java index 04fb957..2465345 100644 --- a/src/main/java/semmiedev/disc_jockey_revive/Main.java +++ b/src/main/java/semmiedev/disc_jockey_revive/Main.java @@ -14,9 +14,13 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.util.InputUtil; import net.minecraft.client.world.ClientWorld; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.sound.SoundEvent; import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.lwjgl.glfw.GLFW; diff --git a/src/main/java/semmiedev/disc_jockey_revive/gui/screen/DiscJockeyScreen.java b/src/main/java/semmiedev/disc_jockey_revive/gui/screen/DiscJockeyScreen.java index 3431bb9..2e324e6 100644 --- a/src/main/java/semmiedev/disc_jockey_revive/gui/screen/DiscJockeyScreen.java +++ b/src/main/java/semmiedev/disc_jockey_revive/gui/screen/DiscJockeyScreen.java @@ -325,7 +325,8 @@ public class DiscJockeyScreen extends Screen { int screenWidth = context.getScaledWindowWidth(); - // 进度条 + // 播放进度条 + // TODO 关于可拖动什么的以后再加,这里放个TODO防止以后忘了 if (Main.SONG_PLAYER.running && Main.SONG_PLAYER.song != null) { int progressBarX = 10; int progressBarY = height - 52; // 按钮上方 @@ -343,7 +344,7 @@ public class DiscJockeyScreen extends Screen { ); } - // 进度条 + // 预览进度条 if (Main.PREVIEWER.running && Main.PREVIEWER.song != null) { int progressBarX = 10; int progressBarY = height - 37; // 比上一个低一点 diff --git a/src/main/resources/assets/disc_jockey/sounds/hello_test.ogg b/src/main/resources/assets/disc_jockey/sounds/hello_test.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ff46aecc4513da4de22a898b1d664979028d0899 GIT binary patch literal 12764 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 literal 0 HcmV?d00001