Skip to content

Commit

Permalink
Add ability for addons to provide a datapack
Browse files Browse the repository at this point in the history
  • Loading branch information
kyrptonaught committed Jun 18, 2024
1 parent e140920 commit b22c6ab
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package net.kyrptonaught.serverutils.customMapLoader;


import com.mojang.brigadier.CommandDispatcher;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.kyrptonaught.serverutils.CMDHelper;
import net.kyrptonaught.serverutils.ModuleWConfig;
import net.kyrptonaught.serverutils.ServerUtilsMod;
import net.kyrptonaught.serverutils.chestTracker.ChestTrackerMod;
import net.kyrptonaught.serverutils.customMapLoader.addons.BaseMapAddon;
import net.kyrptonaught.serverutils.customMapLoader.addons.BattleMapAddon;
import net.kyrptonaught.serverutils.customMapLoader.addons.LobbyMapAddon;
import net.kyrptonaught.serverutils.customMapLoader.addons.ResourcePackList;
import net.kyrptonaught.serverutils.customMapLoader.addons.*;
import net.kyrptonaught.serverutils.customMapLoader.voting.HostOptions;
import net.kyrptonaught.serverutils.customMapLoader.voting.Votebook;
import net.kyrptonaught.serverutils.customWorldBorder.CustomWorldBorderMod;
Expand Down Expand Up @@ -51,6 +49,8 @@ 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();

@Override
public void onInitialize() {
ServerLifecycleEvents.SERVER_STARTING.register(CustomMapLoaderMod::reloadAddonFiles);
Expand Down Expand Up @@ -88,6 +88,7 @@ public static void reloadAddonFiles(MinecraftServer server) {
players.get(i).networkHandler.reconfigure();
}
}

}

//todo fix
Expand Down Expand Up @@ -116,8 +117,9 @@ public static void serverTick(MinecraftServer server) {
continue;
}

if (instance.runPreTriggerCondition(server))
if (instance.runPreTriggerCondition(server)) {
instance.executeDatapack(server);
}
}
}

Expand All @@ -143,6 +145,8 @@ public static void battleLoad(MinecraftServer server, Identifier addon, Identifi
return true;
});

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

LOADED_BATTLE_MAPS.put(dimID, instance);
Expand Down Expand Up @@ -239,6 +243,9 @@ public static void prepareLobby(MinecraftServer server, Identifier addon, Identi

teleportToLobby(dimID, players, null);

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

if (functions != null) {
for (CommandFunction<ServerCommandSource> commandFunction : functions) {
server.getCommandFunctionManager().execute(commandFunction, server.getCommandSource().withLevel(2).withSilent());
Expand Down Expand Up @@ -313,15 +320,46 @@ private static void loadResourcePacks(BaseMapAddon addon, ServerPlayerEntity pla
SwitchableResourcepacksMod.addPacks(list.packs, player);
}

public static void tryEnableDatapack(MinecraftServer server, BaseMapAddon addon) {
server.getDataPackManager().scanPacks();
if (server.getDataPackManager().hasProfile(AddonResourcePackProvider.getID(addon.addon_id))) {
server.getDataPackManager().enable(AddonResourcePackProvider.getID(addon.addon_id));
server.reloadResources(server.getDataPackManager().getEnabledIds()).exceptionally(throwable -> {
throwable.printStackTrace();
return null;
});
}
}

public static void tryDisableDatapack(MinecraftServer server, BaseMapAddon addon) {
server.getDataPackManager().scanPacks();
if (server.getDataPackManager().hasProfile(AddonResourcePackProvider.getID(addon.addon_id))) {
server.getDataPackManager().disable(AddonResourcePackProvider.getID(addon.addon_id));
server.reloadResources(server.getDataPackManager().getEnabledIds()).exceptionally(throwable -> {
throwable.printStackTrace();
return null;
});
}
}

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);
}

LOADED_LOBBIES.remove(dimID);

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

public static void unloadBattleMap(MinecraftServer server, Identifier dimID, Collection<CommandFunction<ServerCommandSource>> functions) {
if (LOADED_BATTLE_MAPS.containsKey(dimID))
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);
}


DimensionLoaderMod.unLoadDimension(server, dimID, functions);
}
Expand Down
20 changes: 13 additions & 7 deletions src/main/java/net/kyrptonaught/serverutils/customMapLoader/IO.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import net.minecraft.util.Identifier;
import net.minecraft.world.dimension.DimensionType;

import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -95,13 +96,9 @@ public static void unZipMap(Path outputPath, Path filepath, String baseDirectory
ZipEntry entry = entries.nextElement();
String entryName = FileHelper.fixPathSeparator(entry.getName());
if (entryName.startsWith(baseDirectory)) {
Path newOut = outputPath.resolve(entryName.replace(baseDirectory, ""));
if (entry.isDirectory()) {
Files.createDirectories(newOut);
} else {
Files.createDirectories(newOut.getParent());
Files.copy(zip.getInputStream(entry), newOut, StandardCopyOption.REPLACE_EXISTING);
}
extractFile(zip, entry, outputPath.resolve(entryName.replace(baseDirectory, "")));
} else if (entryName.startsWith("datapack/")) {
extractFile(zip, entry, outputPath.resolve(entryName));
}
} catch (FileAlreadyExistsException ignored) {
} catch (Exception e) {
Expand All @@ -113,6 +110,15 @@ public static void unZipMap(Path outputPath, Path filepath, String baseDirectory
}
}

private static void extractFile(ZipFile zip, ZipEntry entry, Path newOut) throws IOException {
if (entry.isDirectory()) {
Files.createDirectories(newOut);
} else {
Files.createDirectories(newOut.getParent());
Files.copy(zip.getInputStream(entry), newOut, StandardCopyOption.REPLACE_EXISTING);
}
}

public static DimensionType addDimensionType(MinecraftServer server, Path addonPath, Identifier dimID) {
String dimJson = FileHelper.readFileFromZip(addonPath, "dimension_type.json");
if (dimJson != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package net.kyrptonaught.serverutils.customMapLoader.addons;

import net.minecraft.resource.*;
import net.minecraft.resource.fs.ResourceFileSystem;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.path.SymlinkEntry;
import net.minecraft.util.path.SymlinkFinder;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;

public class AddonResourcePackProvider implements ResourcePackProvider {
public static final ResourcePackSource LEMADDON = ResourcePackSource.create(name -> name, true);
private static final ResourcePackPosition POSITION = new ResourcePackPosition(false, ResourcePackProfile.InsertionPosition.TOP, false);

private final HashMap<Identifier, Path> loadedAddons = new HashMap<>();

public void loadAddon(Identifier id, Path path) {
loadedAddons.put(id, path.resolve("datapack"));
}

public void unloadAddon(Identifier id) {
loadedAddons.remove(id);
}

@Override
public void register(Consumer<ResourcePackProfile> profileAdder) {
loadedAddons.forEach((id, path) -> {
try {
ResourcePackProfile.PackFactory packFactory = new PackOpenerImpl(new SymlinkFinder(path2 -> true)).open(path, List.of());

ResourcePackInfo resourcePackInfo = new ResourcePackInfo(getID(id), Text.literal(id.toString()), LEMADDON, Optional.empty());
ResourcePackProfile resourcePackProfile = ResourcePackProfile.create(resourcePackInfo, packFactory, ResourceType.SERVER_DATA, POSITION);
if (resourcePackProfile != null) {
profileAdder.accept(resourcePackProfile);
}
} catch (IOException iOException) {
System.out.println("Error loading lemaddon data pack: " + id);
}

});

}

public static String getID(Identifier identifier) {
return "lemaddon/" + identifier;
}

static class PackOpenerImpl extends ResourcePackOpener<ResourcePackProfile.PackFactory> {
protected PackOpenerImpl(SymlinkFinder symlinkFinder) {
super(symlinkFinder);
}

@Nullable
@Override
public ResourcePackProfile.PackFactory open(Path path, List<SymlinkEntry> foundSymlinks) throws IOException {
return new DirectoryResourcePack.DirectoryBackedFactory(path);
}

@Nullable
@Override
protected ResourcePackProfile.PackFactory openZip(Path path) {
FileSystem fileSystem = path.getFileSystem();
if (fileSystem == FileSystems.getDefault() || fileSystem instanceof ResourceFileSystem) {
return new ZipResourcePack.ZipBackedFactory(path);
}
return null;
}

@Nullable
@Override
protected ResourcePackProfile.PackFactory openDirectory(Path path) {
return new DirectoryResourcePack.DirectoryBackedFactory(path);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package net.kyrptonaught.serverutils.mixin.customMapLoader;

import net.kyrptonaught.serverutils.customMapLoader.CustomMapLoaderMod;
import net.minecraft.resource.ResourcePackProvider;
import net.minecraft.resource.VanillaDataPackProvider;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArgs;
import org.spongepowered.asm.mixin.injection.invoke.arg.Args;

import java.util.Arrays;

@Mixin(VanillaDataPackProvider.class)
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;
args.set(0, packs);
}
}
1 change: 1 addition & 0 deletions src/main/resources/serverutils.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"critBlocker.PlayerEntityMixin",
"customMapLoader.ServerPlayNetworkHandlerMixin",
"customMapLoader.SimpleRegistryMixin",
"customMapLoader.VanillaDataPackProviderMixin",
"customWorldBorder.PlayerManagerMixin",
"customWorldBorder.WorldBorderMixin",
"dimensionLoader.PlayerManagerMixin",
Expand Down

0 comments on commit b22c6ab

Please sign in to comment.