Skip to content

Commit

Permalink
Add support for new custom nbs player
Browse files Browse the repository at this point in the history
  • Loading branch information
kyrptonaught committed Jun 20, 2024
1 parent 97dd58b commit be02364
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 151 deletions.
6 changes: 4 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ repositories {
maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
maven { url "https://masa.dy.fi/maven" }
maven { url "https://repo.opencollab.dev/main/" }
maven { url 'https://maven.lenni0451.net/snapshots'}
mavenCentral()
}

Expand Down Expand Up @@ -44,8 +45,9 @@ dependencies {
//NoChatReports
modImplementation('maven.modrinth:no-chat-reports:Fabric-1.21-v2.8.0') { exclude group: "net.fabricmc.fabric-api" }

//NOTA
modImplementation include("ru.pinkgoosik:nota:0.2.0-lem-v2-1.20.5") { exclude group: "net.fabricmc.fabric-api" }
//NBS
modImplementation include("net.kyrptonaught:NoteBlockPlayer:0.0.2") { exclude group: "net.fabricmc.fabric-api" }
implementation include('net.raphimc:NoteBlockLib:2.1.2-SNAPSHOT');

//Discord Bridge
shadow implementation("net.dv8tion:JDA:5.0.0-beta.24") { exclude module: 'opus-java' }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import net.kyrptonaught.serverutils.dimensionLoader.CustomDimHolder;
import net.kyrptonaught.serverutils.dimensionLoader.DimensionLoaderMod;
import net.kyrptonaught.serverutils.discordBridge.MessageSender;
import net.kyrptonaught.serverutils.noteblockMusic.NoteblockMusicMod;
import net.kyrptonaught.serverutils.playerJoinLocation.PlayerJoinLocationMod;
import net.kyrptonaught.serverutils.playerlockdown.PlayerLockdownMod;
import net.kyrptonaught.serverutils.switchableresourcepacks.ResourcePack;
Expand Down Expand Up @@ -49,7 +50,7 @@ public class CustomMapLoaderMod extends ModuleWConfig<CustomMapLoaderConfig> {
private static final HashMap<Identifier, LoadedBattleMapInstance> LOADED_BATTLE_MAPS = new HashMap<>();
private static final HashMap<Identifier, LobbyMapAddon> LOADED_LOBBIES = new HashMap<>();

public static final AddonResourcePackProvider ADDON_PROVIDER = new AddonResourcePackProvider();
public static final AddonResourcePackProvider ADDON_DATAPACK_PROVIDER = new AddonResourcePackProvider();

@Override
public void onInitialize() {
Expand Down Expand Up @@ -144,7 +145,9 @@ public static void battleLoad(MinecraftServer server, Identifier addon, Identifi
return true;
});

ADDON_PROVIDER.loadAddon(addon, path);
NoteblockMusicMod.cacheAll(path.resolve("nbs"));

ADDON_DATAPACK_PROVIDER.loadAddon(addon, path);
tryEnableDatapack(server, config);
instance.setDatapackFunctions(functions);

Expand Down Expand Up @@ -242,7 +245,9 @@ public static void prepareLobby(MinecraftServer server, Identifier addon, Identi

teleportToLobby(dimID, players, null);

ADDON_PROVIDER.loadAddon(addon, path);
NoteblockMusicMod.cacheAll(path.resolve("nbs"));

ADDON_DATAPACK_PROVIDER.loadAddon(addon, path);
tryEnableDatapack(server, config);

if (functions != null) {
Expand Down Expand Up @@ -343,8 +348,9 @@ public static void tryDisableDatapack(MinecraftServer server, BaseMapAddon addon

public static void unloadLobbyMap(MinecraftServer server, Identifier dimID, Collection<CommandFunction<ServerCommandSource>> functions) {
if (LOADED_LOBBIES.containsKey(dimID)) {
// tryDisableDatapack(server, LOADED_LOBBIES.get(dimID));
ADDON_PROVIDER.unloadAddon(LOADED_LOBBIES.get(dimID).addon_id);
tryDisableDatapack(server, LOADED_LOBBIES.get(dimID));
ADDON_DATAPACK_PROVIDER.unloadAddon(LOADED_LOBBIES.get(dimID).addon_id);
NoteblockMusicMod.clearCache();
}

LOADED_LOBBIES.remove(dimID);
Expand All @@ -356,10 +362,10 @@ public static void unloadBattleMap(MinecraftServer server, Identifier dimID, Col
if (LOADED_BATTLE_MAPS.containsKey(dimID)) {
LOADED_BATTLE_MAPS.get(dimID).scheduleToRemove = true;
tryDisableDatapack(server, LOADED_BATTLE_MAPS.get(dimID).getAddon());
ADDON_PROVIDER.unloadAddon(LOADED_BATTLE_MAPS.get(dimID).getAddon().addon_id);
ADDON_DATAPACK_PROVIDER.unloadAddon(LOADED_BATTLE_MAPS.get(dimID).getAddon().addon_id);
NoteblockMusicMod.clearCache();
}


DimensionLoaderMod.unLoadDimension(server, dimID, functions);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public static void unZipMap(Path outputPath, Path filepath, String baseDirectory
String entryName = FileHelper.fixPathSeparator(entry.getName());
if (entryName.startsWith(baseDirectory)) {
extractFile(zip, entry, outputPath.resolve(entryName.replace(baseDirectory, "")));
} else if (entryName.startsWith("datapack/")) {
} else if (entryName.startsWith("datapack/") || entryName.startsWith("nbs/")) {
extractFile(zip, entry, outputPath.resolve(entryName));
}
} catch (FileAlreadyExistsException ignored) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class VanillaDataPackProviderMixin {
@ModifyArgs(method = "createManager(Ljava/nio/file/Path;Lnet/minecraft/util/path/SymlinkFinder;)Lnet/minecraft/resource/ResourcePackManager;", at = @At(value = "INVOKE", target = "Lnet/minecraft/resource/ResourcePackManager;<init>([Lnet/minecraft/resource/ResourcePackProvider;)V"))
private static void registerAddonProvider(Args args) {
ResourcePackProvider[] packs = Arrays.copyOf(((ResourcePackProvider[]) args.get(0)), ((ResourcePackProvider[]) args.get(0)).length + 1);
packs[packs.length - 1] = CustomMapLoaderMod.ADDON_PROVIDER;
packs[packs.length - 1] = CustomMapLoaderMod.ADDON_DATAPACK_PROVIDER;
args.set(0, packs);
}
}
Original file line number Diff line number Diff line change
@@ -1,159 +1,34 @@
package net.kyrptonaught.serverutils.noteblockMusic;

import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.BoolArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.kyrptonaught.noteblockplayer.Commands;
import net.kyrptonaught.serverutils.Module;
import net.kyrptonaught.serverutils.ServerUtilsMod;
import net.minecraft.command.argument.BlockPosArgumentType;
import net.minecraft.command.argument.EntityArgumentType;
import net.minecraft.entity.Entity;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.level.storage.LevelStorage;
import nota.event.SongEndEvent;
import nota.model.RepeatMode;
import nota.model.Song;
import nota.player.EntitySongPlayer;
import nota.player.PositionSongPlayer;
import nota.player.RadioSongPlayer;
import nota.player.SongPlayer;
import nota.utils.NBSDecoder;
import xyz.nucleoid.fantasy.mixin.MinecraftServerAccess;
import net.raphimc.noteblocklib.format.nbs.NbsSong;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.HashMap;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;

public class NoteblockMusicMod extends Module {

private static final HashMap<String, SongPlayer> songPlayers = new HashMap<>();

@Override
public void onInitialize() {
SongEndEvent.EVENT.register(songPlayer -> {
String song = songPlayer.getId().getPath();
songPlayers.remove(song).destroy();
});
}

@Override
public void registerCommands(CommandDispatcher<ServerCommandSource> dispatcher) {
dispatcher.register(CommandManager.literal("playnbs")
.requires((source) -> source.hasPermissionLevel(2))
.then(CommandManager.argument("song", StringArgumentType.word())
.suggests(NoteblockMusicMod::getAvailableNBSFiles)
.then(CommandManager.argument("looping", BoolArgumentType.bool())
.then(CommandManager.argument("listeners", EntityArgumentType.players())
.then(CommandManager.literal("GLOBAL")
.executes(context -> {
Song song = getSong(context);
RadioSongPlayer songPlayer = new RadioSongPlayer(song);

primeSongPlayer(songPlayer, context);
songPlayer.setPlaying(true);
return 1;
}))
.then(CommandManager.literal("BLOCKPOS")
.then(CommandManager.argument("blockpos", BlockPosArgumentType.blockPos())
.then(CommandManager.argument("distance", IntegerArgumentType.integer(1))
.executes(context -> {
BlockPos blockPos = BlockPosArgumentType.getBlockPos(context, "blockpos");
int distance = IntegerArgumentType.getInteger(context, "distance");

Song song = getSong(context);
PositionSongPlayer songPlayer = new PositionSongPlayer(song, context.getSource().getWorld());
songPlayer.setBlockPos(blockPos);
songPlayer.setDistance(distance);

primeSongPlayer(songPlayer, context);
songPlayer.setPlaying(true);
return 1;
}))))
.then(CommandManager.literal("ENTITY")
.then(CommandManager.argument("entity", EntityArgumentType.entity())
.then(CommandManager.argument("distance", IntegerArgumentType.integer(1))
.executes(context -> {
Entity entity = EntityArgumentType.getEntity(context, "entity");
int distance = IntegerArgumentType.getInteger(context, "distance");

Song song = getSong(context);
EntitySongPlayer songPlayer = new EntitySongPlayer(song);
songPlayer.setEntity(entity);
songPlayer.setDistance(distance);

primeSongPlayer(songPlayer, context);
songPlayer.setPlaying(true);
return 1;
}))))))));
dispatcher.register(CommandManager.literal("stopnbs")
.requires((source) -> source.hasPermissionLevel(2))
.then(CommandManager.literal("ALL")
.executes(context -> {
songPlayers.values().forEach(SongPlayer::destroy);
songPlayers.clear();
return 1;
}))
.then(CommandManager.argument("song", StringArgumentType.word())
.suggests((context, builder) -> {
songPlayers.keySet().forEach(builder::suggest);
return builder.buildFuture();
})
.executes(context -> {
String songFile = StringArgumentType.getString(context, "song");
songPlayers.remove(songFile).destroy();
return 1;
})));
public static void cacheSong(String id, Path songPath) {
NbsSong song = Commands.loadSong(songPath);
Commands.songCache.put(id, song);
}

private static Song getSong(CommandContext<ServerCommandSource> context) {
String songFile = StringArgumentType.getString(context, "song");
ServerWorld world = context.getSource().getWorld();
LevelStorage.Session session = ((MinecraftServerAccess) context.getSource().getServer()).getSession();
Path path = session.getWorldDirectory(world.getRegistryKey()).resolve("nbs").resolve(songFile + ".nbs");

return NBSDecoder.parse(path.toFile());
public static void clearCache() {
Commands.songCache.clear();
}

private static void primeSongPlayer(SongPlayer songPlayer, CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
Collection<ServerPlayerEntity> players = EntityArgumentType.getPlayers(context, "listeners");
boolean looping = BoolArgumentType.getBool(context, "looping");
String songFile = StringArgumentType.getString(context, "song").toLowerCase().replaceAll("[^a-z0-9_.-]", "");

songPlayer.setEnable10Octave(true);
songPlayer.setAutoDestroy(true);
songPlayer.setRepeatMode(looping ? RepeatMode.ALL : RepeatMode.NONE);
songPlayer.setId(Identifier.of(ServerUtilsMod.MOD_ID, songFile));
players.forEach(songPlayer::addPlayer);

if (songPlayers.containsKey(songFile)) songPlayers.remove(songFile).destroy();
songPlayers.put(songFile, songPlayer);
}

private static CompletableFuture<Suggestions> getAvailableNBSFiles(CommandContext<ServerCommandSource> context, final SuggestionsBuilder builder) {
ServerWorld world = context.getSource().getWorld();
LevelStorage.Session session = ((MinecraftServerAccess) context.getSource().getServer()).getSession();
Path path = session.getWorldDirectory(world.getRegistryKey()).resolve("nbs");

try (Stream<Path> files = Files.walk(path)) {
files.forEach(path1 -> {
if (path1.getFileName().toString().endsWith(".nbs"))
builder.suggest(path1.getFileName().toString().replace(".nbs", ""));
public static void cacheAll(Path input) {
clearCache();
try (Stream<Path> files = Files.walk(input)) {
files.forEach(path -> {
if (path.getFileName().toString().endsWith(".nbs")) {
String id = path.getFileName().toString().replace(".nbs", "");
cacheSong(id, path);
}
});
} catch (Exception ignored) {
}
return builder.buildFuture();
}
}

0 comments on commit be02364

Please sign in to comment.