fixed #129
This commit is contained in:
Color_yr committed 2026-08-01 15:36:41 +08:00
1 parent 22bf1334af
commit 1853b66d82
37 files changed
+1291 -13

No files matched your search

+63
View File
@@ -0,0 +1,63 @@
plugins {
id("fabric-loom") version Versions.fabricLoom
}
java.sourceCompatibility = JavaVersion.VERSION_21
java.targetCompatibility = JavaVersion.VERSION_21
// 直接引用 client 和 server 模块的源码目录,无需手动复制
val clientSourceDir = project(":client:fabric_1_21").projectDir.resolve("src/main/java/com/coloryr/allmusic/client")
val serverSourceDir = project(":server:fabric_1_21").projectDir.resolve("src/main/java/com/coloryr/allmusic/server")
val commSourceDir = project(":server:fabric_1_21").projectDir.resolve("src/main/java/com/coloryr/allmusic/comm")
val clientResDir = project(":client:fabric_1_21").projectDir.resolve("src/main/resources")
val serverResDir = project(":server:fabric_1_21").projectDir.resolve("src/main/resources")
sourceSets {
main {
java {
setSrcDirs(listOf(clientSourceDir, serverSourceDir, commSourceDir))
}
resources {
setSrcDirs(listOf(
file("src/main/resources"), // onejar 自己的合并资源(fabric.mod.json)
clientResDir,
serverResDir
))
}
}
}
dependencies {
minecraft("com.mojang:minecraft:1.21")
mappings(loom.officialMojangMappings())
modImplementation("net.fabricmc:fabric-loader:0.16.10")
modImplementation("net.fabricmc.fabric-api:fabric-api:0.100.1+1.21")
modImplementation(include("net.kyori:adventure-platform-fabric:5.14.1")!!)
}
tasks {
processResources {
// onejar 自己的 fabric.mod.json 优先(排在 srcDirs 第一位),
// client/server 的 fabric.mod.json 作为重复项被排除
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
filesMatching("fabric.mod.json") {
expand(
"version" to project.version
)
}
}
remapJar {
inputFile.set(shadowJar.get().archiveFile)
archiveFileName.set("[fabric-1.21]AllMusic-${project.version}.jar")
destinationDirectory.set(file("${parent!!.projectDir}/../build"))
}
build {
dependsOn(remapJar)
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

@@ -0,0 +1,36 @@
{
"schemaVersion": 1,
"id": "allmusic",
"version": "${version}",
"name": "AllMusic",
"description": "AllMusic Mod",
"authors": [
"Color_yr"
],
"contact": {
"homepage": "https://github.com/Coloryr/AllMusic",
"sources": "https://github.com/Coloryr/AllMusic"
},
"license": "GPL-3.0",
"icon": "assets/allmusic/icon.png",
"environment": "*",
"entrypoints": {
"main": [
"com.coloryr.allmusic.comm.AllMusicInit",
"com.coloryr.allmusic.server.AllMusicServer"
],
"client": [
"com.coloryr.allmusic.client.AllMusicClient"
]
},
"mixins": [
"allmusic_server.mixins.json",
"allmusic_client.mixins.json"
],
"depends": {
"fabricloader": ">=0.19.3",
"fabric": "*",
"minecraft": ">=1.21"
},
"suggests": {}
}
+66
View File
@@ -0,0 +1,66 @@
plugins {
id("dev.architectury.loom") version Versions.architecturyLoom
// id("architectury-plugin") version "3.5-SNAPSHOT"
}
java.sourceCompatibility = JavaVersion.VERSION_21
java.targetCompatibility = JavaVersion.VERSION_21
// 直接引用 client 和 server 模块的源码目录,无需手动复制
val clientSourceDir = project(":client:neoforge_1_21").projectDir.resolve("src/main/java/com/coloryr/allmusic/client")
val serverSourceDir = project(":server:neoforge_1_21").projectDir.resolve("src/main/java/com/coloryr/allmusic/server")
val commSourceDir = project(":server:neoforge_1_21").projectDir.resolve("src/main/java/com/coloryr/allmusic/comm")
val clientResDir = project(":client:neoforge_1_21").projectDir.resolve("src/main/resources")
sourceSets {
main {
java {
setSrcDirs(listOf(clientSourceDir, serverSourceDir, commSourceDir))
}
resources {
setSrcDirs(listOf(
file("src/main/resources"), // onejar 自己的合并资源(fabric.mod.json)
clientResDir,
))
}
}
}
//architectury {
// platformSetupLoomIde()
// neoForge()
//}
repositories {
maven("https://maven.neoforged.net/releases/")
}
dependencies {
minecraft("com.mojang:minecraft:1.21")
mappings(loom.officialMojangMappings())
neoForge("net.neoforged:neoforge:21.0.167")
modImplementation("net.kyori:adventure-platform-neoforge:6.0.1")
implementation(include("net.kyori:adventure-platform-neoforge:6.0.1")!!)
}
tasks {
processResources {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
filesMatching("META-INF/neoforge.mods.toml") {
expand("version" to project.version)
}
}
remapJar {
inputFile.set(shadowJar.get().archiveFile)
archiveFileName.set("[neoforge-1.21]AllMusic-${project.version}.jar")
destinationDirectory.set(file("${parent!!.projectDir}/../build"))
}
build {
dependsOn(remapJar)
}
}
+1
View File
@@ -0,0 +1 @@
loom.platform=neoforge
@@ -0,0 +1,59 @@
modLoader = "javafml"
loaderVersion = "[2,)"
license = "GPL-3.0"
issueTrackerURL = "https://github.com/Coloryr/AllMusic/issues/"
[[mods]]
modId = "allmusic"
version = "${version}"
displayName = "AllMusic"
displayURL = "https://github.com/Coloryr/AllMusic/"
logoFile = "icon.png"
authors = "Color_yr"
description = '''AllMusic Mod'''
[[mods]]
modId = "allmusic_client"
version = "${version}"
displayName = "AllMusic Client"
displayURL = "https://github.com/Coloryr/AllMusic/"
logoFile = "icon.png"
authors = "Color_yr"
description = '''AllMusic Client Mod'''
[[mods]]
modId = "allmusic_server"
version = "${version}"
displayName = "AllMusic Server"
displayURL = "https://github.com/Coloryr/AllMusic/"
logoFile = "icon.png"
authors = "Color_yr"
description = '''AllMusic Server Mod'''
[[dependencies.allmusic_client]]
modId = "neoforge"
type = "required"
versionRange = "[21.0.167,)"
ordering = "NONE"
side = "CLIENT"
[[dependencies.allmusic_client]]
modId = "minecraft"
type = "required"
versionRange = "[1.21,)"
ordering = "NONE"
side = "CLIENT"
[[dependencies.allmusic_server]]
modId = "neoforge"
type = "required"
versionRange = "[21.0.167,)"
ordering = "NONE"
side = "BOTH"
[[dependencies.allmusic_server]]
modId = "minecraft"
type = "required"
versionRange = "[1.21,)"
ordering = "NONE"
side = "BOTH"
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

+37
View File
@@ -0,0 +1,37 @@
plugins {
id("fabric-loom") version Versions.fabricLoom
}
java.sourceCompatibility = JavaVersion.VERSION_21
java.targetCompatibility = JavaVersion.VERSION_21
dependencies {
minecraft("com.mojang:minecraft:1.21.4")
mappings(loom.officialMojangMappings())
modImplementation("net.fabricmc:fabric-loader:0.19.3")
modImplementation("net.fabricmc.fabric-api:fabric-api:0.119.4+1.21.4")
modImplementation(include("net.kyori:adventure-platform-fabric:6.3.0")!!)
}
tasks {
processResources {
filesMatching("fabric.mod.json") {
expand(
"version" to project.version
)
}
}
remapJar {
inputFile.set(shadowJar.get().archiveFile)
archiveFileName.set("[fabric-1.21.4]AllMusic_Server-${project.version}.jar")
destinationDirectory.set(file("${parent!!.projectDir}/../build"))
}
build {
dependsOn(remapJar)
}
}
@@ -0,0 +1,11 @@
package com.coloryr.allmusic.comm;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
public class AllMusicInit implements ModInitializer {
@Override
public void onInitialize() {
PayloadTypeRegistry.playS2C().register(MusicCodec.ID, MusicCodec.CODEC);
}
}
@@ -0,0 +1,22 @@
package com.coloryr.allmusic.comm;
import com.coloryr.allmusic.codec.MusicPack;
import com.coloryr.allmusic.codec.MusicPacketCodec;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
public record MusicCodec(MusicPack pack) implements CustomPacketPayload {
public static final ResourceLocation ChannelID = ResourceLocation.fromNamespaceAndPath("allmusic", "channel");
public static final Type<MusicCodec> ID = new Type<>(ChannelID);
public static final StreamCodec<FriendlyByteBuf, MusicCodec> CODEC =
StreamCodec.of((buf, value) -> MusicPacketCodec.pack(buf, value.pack),
buf -> new MusicCodec(MusicPacketCodec.decode(buf)));
@Override
public Type<? extends CustomPacketPayload> type() {
return ID;
}
}
@@ -0,0 +1,34 @@
package com.coloryr.allmusic.server;
import com.coloryr.allmusic.server.core.AllMusic;
import net.fabricmc.api.DedicatedServerModInitializer;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.minecraft.server.MinecraftServer;
import java.io.File;
public class AllMusicServer implements ModInitializer {
public static MinecraftServer server;
@Override
public void onInitialize() {
AllMusic.log = new LogFabric();
AllMusic.side = new SideFabric();
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment)
-> CommandFabric.instance.register(dispatcher));
ServerLifecycleEvents.SERVER_STARTED.register((a) -> {
server = a;
AllMusic.init(new File(AllMusic.SERVER_DIR));
AllMusic.start();
Tasks.init();
});
ServerLifecycleEvents.SERVER_STOPPING.register((a) -> {
AllMusic.stop();
});
}
}
@@ -0,0 +1,69 @@
package com.coloryr.allmusic.server;
import com.coloryr.allmusic.server.core.command.CommandEX;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
public class CommandFabric implements Command<CommandSourceStack>, Predicate<CommandSourceStack>, SuggestionProvider<CommandSourceStack> {
public static CommandFabric instance = new CommandFabric();
public void register(CommandDispatcher<CommandSourceStack> dispatcher) {
dispatcher.register(((Commands.literal("music").requires(this)).executes(this))
.then(Commands.argument("args", StringArgumentType.greedyString())
.suggests(this).executes(this)));
}
@Override
public int run(CommandContext<CommandSourceStack> context) {
var item = context.getSource();
var input = context.getInput();
var temp = input.split(" ");
var arg = new String[temp.length - 1];
System.arraycopy(temp, 1, arg, 0, arg.length);
CommandEX.execute(item, context.getSource().getTextName(), arg);
return 0;
}
@Override
public boolean test(CommandSourceStack stack) {
return true;
}
@Override
public CompletableFuture<Suggestions> getSuggestions(CommandContext<CommandSourceStack> context, SuggestionsBuilder builder) {
var item = context.getSource();
var input = context.getInput();
var temp = input.split(" ");
var arg = new String[input.endsWith(" ") ? temp.length : temp.length - 1];
System.arraycopy(temp, 1, arg, 0, temp.length - 1);
builder = builder.createOffset(builder.getInput().lastIndexOf(32) + 1);
List<String> results = CommandEX.getTabList(item, item.getTextName(), arg);
String remaining = builder.getRemaining().trim();
for (String s : results) {
if (s.startsWith(remaining)) {
builder.suggest(s);
}
}
return builder.buildFuture();
}
}
@@ -0,0 +1,11 @@
package com.coloryr.allmusic.server;
import com.coloryr.allmusic.server.core.side.IAllMusicLogger;
import net.kyori.adventure.text.Component;
public class LogFabric implements IAllMusicLogger {
@Override
public void data(Component data) {
AllMusicServer.server.sendMessage(data);
}
}
@@ -0,0 +1,157 @@
package com.coloryr.allmusic.server;
import com.coloryr.allmusic.codec.MusicPack;
import com.coloryr.allmusic.comm.MusicCodec;
import com.coloryr.allmusic.server.core.AllMusic;
import com.coloryr.allmusic.server.core.objs.music.PlayerAddMusicObj;
import com.coloryr.allmusic.server.core.objs.music.SongInfoObj;
import com.coloryr.allmusic.server.core.side.BaseSide;
import com.coloryr.allmusic.server.event.MusicAddEvent;
import com.coloryr.allmusic.server.event.MusicPlayEvent;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionResult;
import java.io.File;
import java.util.Collection;
public class SideFabric extends BaseSide {
@Override
public void runTask(Runnable run) {
AllMusicServer.server.execute(run);
}
@Override
public void runTask(Runnable run1, int delay) {
Tasks.add(new TaskItem() {{
tick = delay;
run = run1;
}});
}
@Override
public boolean checkPermission(Object player) {
CommandSourceStack source = (CommandSourceStack) player;
return source.hasPermission(2);
}
@Override
public boolean isPlayer(Object player) {
CommandSourceStack source = (CommandSourceStack) player;
return source.isPlayer();
}
@Override
public boolean checkPermission(Object player, String permission) {
return checkPermission(player);
}
@Override
public boolean needPlay(boolean islist) {
for (var player : AllMusicServer.server.getPlayerList().getPlayers()) {
if (!AllMusic.isSkip(player.getName().getString(), null, false, islist)) {
return true;
}
}
return false;
}
@Override
public Collection<?> getPlayers() {
return AllMusicServer.server.getPlayerList().getPlayers();
}
@Override
public String getPlayerName(Object player) {
if (player instanceof ServerPlayer player1) {
return player1.getName().getString();
}
return null;
}
@Override
public String getPlayerServer(Object player) {
return null;
}
@Override
public void send(Object player, MusicPack pack) {
if (player instanceof ServerPlayer player1) {
send(player1, pack);
}
}
@Override
public Object getPlayer(String player) {
return AllMusicServer.server.getPlayerList().getPlayerByName(player);
}
@Override
public void sendBar(Object player, Component data) {
if (player instanceof ServerPlayer player1) {
player1.sendActionBar(data);
}
}
@Override
public File getFolder() {
return new File(AllMusic.SERVER_DIR);
}
@Override
public void broadcast(Component message) {
for (var player : AllMusicServer.server.getPlayerList().getPlayers()) {
if (!AllMusic.isSkip(player.getName().getString(), null, false)) {
player.sendMessage(message);
}
}
}
@Override
public void sendMessage(Object obj, Component message) {
if (obj instanceof CommandSourceStack source) {
source.sendMessage(message);
}
}
@Override
public boolean onMusicPlay(SongInfoObj obj) {
return MusicPlayEvent.EVENT.invoker().interact(obj) != InteractionResult.PASS;
}
@Override
public boolean onMusicAdd(Object obj, PlayerAddMusicObj music) {
CommandSourceStack source = (CommandSourceStack) obj;
return MusicAddEvent.EVENT.invoker().interact(source.getPlayer(), music) != InteractionResult.PASS;
}
@Override
public Component miniMessage(String input) {
MiniMessage mm = MiniMessage.miniMessage();
return mm.deserialize(input);
}
@Override
public Component miniMessageRun(String input, String command) {
Component component = miniMessage(input);
return component.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, command));
}
@Override
public Component miniMessageSuggest(String input, String command) {
Component component = miniMessage(input);
return component.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.SUGGEST_COMMAND, command));
}
private void send(ServerPlayer players, MusicPack data) {
if (players == null)
return;
runTask(() -> ServerPlayNetworking.send(players, new MusicCodec(data)));
}
}
@@ -0,0 +1,6 @@
package com.coloryr.allmusic.server;
public class TaskItem {
public int tick;
public Runnable run;
}
@@ -0,0 +1,27 @@
package com.coloryr.allmusic.server;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class Tasks {
private static final List<TaskItem> taskItems = new CopyOnWriteArrayList<>();
public static void init() {
AllMusicServer.server.addTickable(Tasks::tick);
}
public static void tick() {
for (var item : new ArrayList<>(taskItems)) {
item.tick--;
if (item.tick <= 0) {
taskItems.remove(item);
item.run.run();
}
}
}
public static void add(TaskItem item) {
taskItems.add(item);
}
}
@@ -0,0 +1,32 @@
package com.coloryr.allmusic.server.event;
import com.coloryr.allmusic.server.core.objs.music.PlayerAddMusicObj;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionResult;
public interface MusicAddEvent {
Event<MusicAddEvent> EVENT = EventFactory.createArrayBacked(MusicAddEvent.class,
(listeners) -> (player, music) -> {
for (MusicAddEvent listener : listeners) {
InteractionResult result = listener.interact(player, music);
if (result != InteractionResult.PASS) {
return result;
}
}
return InteractionResult.PASS;
});
/**
* 音乐添加事件,返回PASS表示通过
*
* @param player 玩家
* @param music 歌曲信息
* @return 是否通过
*/
InteractionResult interact(ServerPlayer player, PlayerAddMusicObj music);
}
@@ -0,0 +1,29 @@
package com.coloryr.allmusic.server.event;
import com.coloryr.allmusic.server.core.objs.music.SongInfoObj;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.world.InteractionResult;
public interface MusicPlayEvent {
Event<MusicPlayEvent> EVENT = EventFactory.createArrayBacked(MusicPlayEvent.class,
(listeners) -> (music) -> {
for (MusicPlayEvent listener : listeners) {
InteractionResult result = listener.interact(music);
if (result != InteractionResult.PASS) {
return result;
}
}
return InteractionResult.PASS;
});
/**
* 音乐播放事件,返回PASS表示通过
*
* @param music 歌曲信息
* @return 是否通过
*/
InteractionResult interact(SongInfoObj music);
}
@@ -0,0 +1,25 @@
package com.coloryr.allmusic.server.mixin;
import com.coloryr.allmusic.server.core.AllMusic;
import com.coloryr.allmusic.server.core.music.PlayMusic;
import net.minecraft.network.Connection;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.CommonListenerCookie;
import net.minecraft.server.players.PlayerList;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(PlayerList.class)
public class ServerPlayerMixin {
@Inject(at = @At("HEAD"), method = "remove")
private void remove(ServerPlayer entity, CallbackInfo info) {
PlayMusic.removeNowPlayPlayer(entity.getName().getString());
}
@Inject(at = @At("TAIL"), method = "placeNewPlayer")
private void add(Connection connection, ServerPlayer serverPlayer, CommonListenerCookie commonListenerCookie, CallbackInfo ci) {
AllMusic.joinPlay(serverPlayer.getName().getString());
}
}
@@ -0,0 +1,14 @@
{
"required": true,
"minVersion": "0.8",
"package": "com.coloryr.allmusic.server.mixin",
"compatibilityLevel": "JAVA_17",
"server": [
],
"mixins": [
"ServerPlayerMixin"
],
"injectors": {
"defaultRequire": 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

@@ -0,0 +1,33 @@
{
"schemaVersion": 1,
"id": "allmusic_server",
"version": "${version}",
"name": "AllMusic Server",
"description": "AllMusic Server Mod",
"authors": [
"Color_yr"
],
"contact": {
"homepage": "https://github.com/Coloryr/AllMusic",
"sources": "https://github.com/Coloryr/AllMusic"
},
"license": "GPL-3.0",
"icon": "assets/allmusic_server/icon.png",
"environment": "*",
"entrypoints": {
"main": [
"com.coloryr.allmusic.comm.AllMusicInit",
"com.coloryr.allmusic.server.AllMusicServer"
]
},
"mixins": [
"allmusic_server.mixins.json"
],
"depends": {
"fabricloader": ">=0.19.3",
"minecraft": ">=1.21.4",
"fabric-api": "*"
},
"suggests": {
}
}
+44
View File
@@ -0,0 +1,44 @@
plugins {
id("dev.architectury.loom") version Versions.architecturyLoom
// id("architectury-plugin") version "3.5-SNAPSHOT"
}
java.sourceCompatibility = JavaVersion.VERSION_21
java.targetCompatibility = JavaVersion.VERSION_21
//architectury {
// platformSetupLoomIde()
// neoForge()
//}
repositories {
maven("https://maven.neoforged.net/releases/")
}
dependencies {
minecraft("com.mojang:minecraft:1.21.4")
mappings(loom.officialMojangMappings())
neoForge("net.neoforged:neoforge:21.4.141")
modImplementation("net.kyori:adventure-platform-neoforge:6.3.0")
implementation(include("net.kyori:adventure-platform-neoforge:6.3.0")!!)
}
tasks {
processResources {
filesMatching("META-INF/neoforge.mods.toml") {
expand("version" to project.version)
}
}
remapJar {
inputFile.set(shadowJar.get().archiveFile)
archiveFileName.set("[neoforge-1.21.4]AllMusic_Server-${project.version}.jar")
destinationDirectory.set(file("${parent!!.projectDir}/../build"))
}
build {
dependsOn(remapJar)
}
}
+1
View File
@@ -0,0 +1 @@
loom.platform=neoforge
@@ -0,0 +1,33 @@
package com.coloryr.allmusic.comm;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.neoforged.neoforge.network.handling.IPayloadHandler;
@Mod(AllMusicInit.MODID)
public class AllMusicInit implements IPayloadHandler<MusicCodec> {
public static final String MODID = "allmusic";
public static IPayloadHandler<MusicCodec> handler;
public AllMusicInit(IEventBus modEventBus, ModContainer modContainer) {
modEventBus.addListener(this::register);
}
public void register(final RegisterPayloadHandlersEvent event) {
event.registrar("1.0")
.optional()
.playToClient(MusicCodec.TYPE, MusicCodec.CODEC, this);
}
@Override
public void handle(MusicCodec data, IPayloadContext iPayloadContext) {
if (handler != null) {
handler.handle(data, iPayloadContext);
}
}
}
@@ -0,0 +1,24 @@
package com.coloryr.allmusic.comm;
import com.coloryr.allmusic.codec.MusicPack;
import com.coloryr.allmusic.codec.MusicPacketCodec;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
public record MusicCodec(MusicPack pack) implements CustomPacketPayload {
public static final ResourceLocation channel =
ResourceLocation.fromNamespaceAndPath("allmusic", "channel");
public static final Type<MusicCodec> TYPE = new Type<>(channel);
public static final StreamCodec<RegistryFriendlyByteBuf, MusicCodec> CODEC = StreamCodec.of((buf, value) -> MusicPacketCodec.pack(buf, value.pack),
(buf) -> {
return new MusicCodec(MusicPacketCodec.decode(buf));
});
@Override
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}
}
@@ -0,0 +1,67 @@
package com.coloryr.allmusic.server;
import com.coloryr.allmusic.server.core.AllMusic;
import com.coloryr.allmusic.server.core.music.PlayMusic;
import com.mojang.brigadier.CommandDispatcher;
import net.kyori.adventure.platform.modcommon.MinecraftServerAudiences;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.MinecraftServer;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.neoforge.event.RegisterCommandsEvent;
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
import net.neoforged.neoforge.event.server.ServerStartedEvent;
import net.neoforged.neoforge.event.server.ServerStoppingEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
@EventBusSubscriber(modid = "allmusic_server")
public class AllMusicServer {
public static final Logger LOGGER = LoggerFactory.getLogger("AllMusic Server");
public static MinecraftServer server;
public static MinecraftServerAudiences audiences;
@SubscribeEvent
public static void commonSetup(final FMLCommonSetupEvent event) {
AllMusic.log = new LogForge();
AllMusic.side = new SideNeoForge();
}
@SubscribeEvent
public static void onRegisterCommands(RegisterCommandsEvent event) {
CommandDispatcher<CommandSourceStack> dispatcher = event.getDispatcher();
CommandNeoForge.instance.register(dispatcher);
}
@SubscribeEvent
public static void onServerStarting(ServerStartedEvent event) {
server = event.getServer();
audiences = MinecraftServerAudiences.of(server);
AllMusic.init(new File(AllMusic.SERVER_DIR));
AllMusic.start();
Tasks.init();
}
@SubscribeEvent
public static void onServerStopping(ServerStoppingEvent event) {
AllMusic.stop();
}
@SubscribeEvent
public static void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) {
if (server != null) {
PlayMusic.removeNowPlayPlayer(event.getEntity().getName().getString());
}
}
@SubscribeEvent
public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
if (server != null) {
AllMusic.joinPlay(event.getEntity().getName().getString());
}
}
}
@@ -0,0 +1,66 @@
package com.coloryr.allmusic.server;
import com.coloryr.allmusic.server.core.command.CommandEX;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
public class CommandNeoForge implements Command<CommandSourceStack>, Predicate<CommandSourceStack>, SuggestionProvider<CommandSourceStack> {
public static CommandNeoForge instance = new CommandNeoForge();
public void register(CommandDispatcher<CommandSourceStack> dispatcher) {
dispatcher.register(((Commands.literal("music").requires(this)).executes(this))
.then(Commands.argument("args", StringArgumentType.greedyString())
.suggests(this).executes(this)));
}
@Override
public int run(CommandContext<CommandSourceStack> context) {
var item = context.getSource();
var input = context.getInput();
var temp = input.split(" ");
var arg = new String[temp.length - 1];
System.arraycopy(temp, 1, arg, 0, arg.length);
CommandEX.execute(item, context.getSource().getTextName(), arg);
return 0;
}
@Override
public boolean test(CommandSourceStack stack) {
return true;
}
@Override
public CompletableFuture<Suggestions> getSuggestions(CommandContext<CommandSourceStack> context, SuggestionsBuilder builder) {
var item = context.getSource();
var input = context.getInput();
var temp = input.split(" ");
var arg = new String[input.endsWith(" ") ? temp.length : temp.length - 1];
System.arraycopy(temp, 1, arg, 0, temp.length - 1);
if (input.endsWith(" "))
builder = builder.createOffset(builder.getInput().lastIndexOf(32) + 1);
List<String> results = CommandEX.getTabList(item, item.getTextName(), arg);
for (String s : results) {
builder.suggest(s);
}
return builder.buildFuture();
}
}
@@ -0,0 +1,11 @@
package com.coloryr.allmusic.server;
import com.coloryr.allmusic.server.core.side.IAllMusicLogger;
import net.kyori.adventure.text.Component;
public class LogForge implements IAllMusicLogger {
@Override
public void data(Component data) {
AllMusicServer.audiences.console().sendMessage(data);
}
}
@@ -0,0 +1,165 @@
package com.coloryr.allmusic.server;
import com.coloryr.allmusic.codec.MusicPack;
import com.coloryr.allmusic.comm.MusicCodec;
import com.coloryr.allmusic.server.core.AllMusic;
import com.coloryr.allmusic.server.core.objs.music.PlayerAddMusicObj;
import com.coloryr.allmusic.server.core.objs.music.SongInfoObj;
import com.coloryr.allmusic.server.core.side.BaseSide;
import com.coloryr.allmusic.server.event.MusicAddEvent;
import com.coloryr.allmusic.server.event.MusicPlayEvent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.network.PacketDistributor;
import java.io.File;
import java.util.Collection;
public class SideNeoForge extends BaseSide {
@Override
public void runTask(Runnable run) {
AllMusicServer.server.execute(run);
}
@Override
public void runTask(Runnable run1, int delay) {
Tasks.add(new TaskItem() {{
tick = delay;
run = run1;
}});
}
@Override
public boolean checkPermission(Object player, String permission) {
return checkPermission(player);
}
@Override
public boolean checkPermission(Object player) {
CommandSourceStack source = (CommandSourceStack) player;
return source.hasPermission(2);
}
@Override
public boolean isPlayer(Object player) {
CommandSourceStack source = (CommandSourceStack) player;
return source.isPlayer();
}
@Override
public boolean needPlay(boolean islist) {
for (ServerPlayer player : AllMusicServer.server.getPlayerList().getPlayers()) {
if (!AllMusic.isSkip(player.getName().getString(), null, false, islist)) {
return true;
}
}
return false;
}
@Override
public Collection<?> getPlayers() {
return AllMusicServer.server.getPlayerList().getPlayers();
}
@Override
public String getPlayerName(Object player) {
if (player instanceof ServerPlayer player1) {
return player1.getName().getString();
}
return null;
}
@Override
public String getPlayerServer(Object player) {
return null;
}
@Override
public void send(Object player, MusicPack pack) {
if (player instanceof ServerPlayer player1) {
send(player1, pack);
}
}
@Override
public Object getPlayer(String player) {
return AllMusicServer.server.getPlayerList().getPlayerByName(player);
}
@Override
public void sendBar(Object player, Component data) {
if (player instanceof ServerPlayer player1) {
AllMusicServer.audiences.audience(player1).sendActionBar(data);
}
}
@Override
public File getFolder() {
return new File(AllMusic.SERVER_DIR);
}
@Override
public void broadcast(Component message) {
for (ServerPlayer player : AllMusicServer.server.getPlayerList().getPlayers()) {
if (!AllMusic.isSkip(player.getName().getString(), null, false)) {
AllMusicServer.audiences.audience(player).sendMessage(message);
}
}
}
@Override
public void sendMessage(Object obj, Component message) {
if (obj instanceof CommandSourceStack source) {
AllMusicServer.audiences.audience(source).sendMessage(message);
}
}
@Override
public boolean onMusicPlay(SongInfoObj obj) {
MusicPlayEvent event = new MusicPlayEvent(obj);
NeoForge.EVENT_BUS.post(event);
return event.isCancel();
}
@Override
public boolean onMusicAdd(Object obj, PlayerAddMusicObj music) {
CommandSourceStack source = (CommandSourceStack) obj;
MusicAddEvent event = new MusicAddEvent(music, source.getPlayer());
NeoForge.EVENT_BUS.post(event);
return event.isCancel();
}
@Override
public Component miniMessage(String input) {
MiniMessage mm = MiniMessage.miniMessage();
return mm.deserialize(input);
}
@Override
public Component miniMessageRun(String input, String command) {
Component component = miniMessage(input);
return component.clickEvent(ClickEvent.runCommand(command));
}
@Override
public Component miniMessageSuggest(String input, String command) {
Component component = miniMessage(input);
return component.clickEvent(ClickEvent.suggestCommand(command));
}
private void send(ServerPlayer players, MusicPack data) {
if (players == null)
return;
try {
runTask(() -> PacketDistributor.sendToPlayer(players, new MusicCodec(data)));
} catch (Exception e) {
AllMusic.log.data("数据发送发生错误");
e.printStackTrace();
}
}
}
@@ -0,0 +1,6 @@
package com.coloryr.allmusic.server;
public class TaskItem {
public int tick;
public Runnable run;
}
@@ -0,0 +1,27 @@
package com.coloryr.allmusic.server;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class Tasks {
private static final List<TaskItem> taskItems = new CopyOnWriteArrayList<>();
public static void init() {
AllMusicServer.server.addTickable(Tasks::tick);
}
public static void tick() {
for (TaskItem item : new ArrayList<>(taskItems)) {
item.tick--;
if (item.tick <= 0) {
taskItems.remove(item);
item.run.run();
}
}
}
public static void add(TaskItem item) {
taskItems.add(item);
}
}
@@ -0,0 +1,39 @@
package com.coloryr.allmusic.server.event;
import com.coloryr.allmusic.server.core.objs.music.PlayerAddMusicObj;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.bus.api.Event;
public class MusicAddEvent extends Event {
/**
* 添加的音乐
*/
private final PlayerAddMusicObj music;
/**
* 添加者
*/
private final ServerPlayer player;
private boolean cancel;
public MusicAddEvent(PlayerAddMusicObj id, ServerPlayer player) {
this.music = id;
this.player = player;
}
public boolean isCancel() {
return cancel;
}
public void setCancel(boolean cancel) {
this.cancel = cancel;
}
public ServerPlayer getPlayer() {
return player;
}
public PlayerAddMusicObj getMusic() {
return music;
}
}
@@ -0,0 +1,25 @@
package com.coloryr.allmusic.server.event;
import com.coloryr.allmusic.server.core.objs.music.SongInfoObj;
import net.neoforged.bus.api.Event;
public class MusicPlayEvent extends Event {
private final SongInfoObj music;
private boolean cancel;
public MusicPlayEvent(SongInfoObj music) {
this.music = music;
}
public boolean isCancel() {
return cancel;
}
public void setCancel(boolean cancel) {
this.cancel = cancel;
}
public SongInfoObj getMusic() {
return music;
}
}
@@ -0,0 +1,36 @@
modLoader = "javafml"
loaderVersion = "[2,)"
license = "GPL-3.0"
issueTrackerURL = "https://github.com/Coloryr/AllMusic/issues/"
[[mods]]
modId = "allmusic"
version = "${version}"
displayName = "AllMusic"
displayURL = "https://github.com/Coloryr/AllMusic/"
logoFile = "icon.png"
authors = "Color_yr"
description = '''AllMusic Mod'''
[[mods]]
modId = "allmusic_server"
version = "${version}"
displayName = "AllMusic Server"
displayURL = "https://github.com/Coloryr/AllMusic/"
logoFile = "icon.png"
authors = "Color_yr"
description = '''AllMusic Server Mod'''
[[dependencies.allmusic_server]]
modId = "neoforge"
type = "required"
versionRange = "[21.4.141,)"
ordering = "NONE"
side = "BOTH"
[[dependencies.allmusic_server]]
modId = "minecraft"
type = "required"
versionRange = "[1.21.4,)"
ordering = "NONE"
side = "BOTH"
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

+15 -13
View File
@@ -33,6 +33,7 @@ include(":server")
include(":server:fabric_1_16_5")
include(":server:fabric_1_20_1")
include(":server:fabric_1_21")
include(":server:fabric_1_21_4")
include(":server:fabric_1_21_6")
include(":server:fabric_1_21_11")
include(":server:fabric_26_1")
@@ -44,6 +45,7 @@ include(":server:forge_1_16_5")
include(":server:forge_1_20_1")
include(":server:neoforge_1_21")
include(":server:neoforge_1_21_4")
include(":server:neoforge_1_21_6")
include(":server:neoforge_1_21_11")
include(":server:neoforge_26_1")
@@ -55,19 +57,19 @@ include(":server:folia")
include(":server:paper")
include(":server:velocity")
include(":onejar")
include(":onejar:fabric_1_16_5")
include(":onejar:fabric_1_20_1")
include(":onejar:fabric_1_21")
include(":onejar:fabric_1_21_6")
include(":onejar:fabric_1_21_11")
include(":onejar:fabric_26_1")
include(":onejar:fabric_26_2")
include(":onejar:neoforge_1_21")
include(":onejar:neoforge_1_21_6")
include(":onejar:neoforge_1_21_11")
include(":onejar:neoforge_26_1")
//include(":onejar")
//
//include(":onejar:fabric_1_16_5")
//include(":onejar:fabric_1_20_1")
//include(":onejar:fabric_1_21")
//include(":onejar:fabric_1_21_6")
//include(":onejar:fabric_1_21_11")
//include(":onejar:fabric_26_1")
//include(":onejar:fabric_26_2")
//include(":onejar:neoforge_1_21")
//include(":onejar:neoforge_1_21_6")
//include(":onejar:neoforge_1_21_11")
//include(":onejar:neoforge_26_1")
pluginManagement {
repositories {