Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions src/main/java/org/linia/linizen/Linizen.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package org.linia.linizen;

import com.denizenscript.denizencore.utilities.debugging.Debug;
import com.infernalsuite.asp.api.world.SlimeWorldInstance;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.linia.linizen.bridges.ASP.ASPBridge;
import org.linia.linizen.bridges.ASP.SlimeWorldFlagHandler;
import org.linia.linizen.extensions.ExtensionsRegistry;
import org.linia.linizen.oneblock.OneBlock;

import java.io.IOException;

public class Linizen extends JavaPlugin {

public static Plugin instance;
Expand All @@ -25,16 +23,9 @@ public void onEnable() {

@Override
public void onDisable() {

Debug.log("Saving slimeworlds...");
for (SlimeWorldInstance s : ASPBridge.instance.getLoadedWorlds()) {
try {
ASPBridge.instance.saveWorld(s);
}
catch (IOException e) {
Debug.echoError(e);
}
}
SlimeWorldFlagHandler.flushAll();
ASPBridge.saveAll();
}

}
26 changes: 25 additions & 1 deletion src/main/java/org/linia/linizen/bridges/ASP/ASPBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
import com.denizenscript.denizencore.objects.core.MapTag;
import com.denizenscript.denizencore.tags.PseudoObjectTagBase;
import com.denizenscript.denizencore.tags.TagManager;
import com.denizenscript.denizencore.utilities.debugging.Debug;
import com.denizenscript.denizencore.utilities.text.StringHolder;
import com.infernalsuite.asp.api.AdvancedSlimePaperAPI;
import com.infernalsuite.asp.api.exceptions.CorruptedWorldException;
import com.infernalsuite.asp.api.exceptions.NewerFormatException;
import com.infernalsuite.asp.api.exceptions.UnknownWorldException;
import com.infernalsuite.asp.api.loaders.SlimeLoader;
import com.infernalsuite.asp.api.world.SlimeWorld;
import com.infernalsuite.asp.api.world.SlimeWorldInstance;
import com.infernalsuite.asp.api.world.properties.SlimePropertyMap;
import org.linia.linizen.bridges.ASP.commands.FileLoaderCommand;
import org.linia.linizen.bridges.ASP.commands.SlimeWorldCommand;
Expand Down Expand Up @@ -48,7 +50,18 @@ public void init() {
});
}

static class ASPTagBase extends PseudoObjectTagBase<ASPTagBase> {
public static void saveAll() {
for (SlimeWorldInstance s : instance.getLoadedWorlds()) {
try {
instance.saveWorld(s);
}
catch (IOException e) {
Debug.echoError(e);
}
}
}

public static class ASPTagBase extends PseudoObjectTagBase<ASPTagBase> {

public static ASPTagBase instance;

Expand All @@ -71,6 +84,17 @@ public void register() {
return new ListTag(ASPBridge.instance.getLoadedWorlds(), SlimeWorldTag::new);
});

// <--[tag]
// @attribute <asp.is_loaded[<name>]>
// @returns ElementTag(Boolean)
// @plugin Linizen, ASP
// @description
// Returns whether the world with a given name is loaded.
// -->
tagProcessor.registerTag(ElementTag.class, ElementTag.class, "is_loaded", (attribute, object, input) -> {
return new ElementTag(ASPBridge.instance.getLoadedWorld(input.asString()) != null);
});

// <--[tag]
// @attribute <asp.worlds_in_use>
// @returns ListTag
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.linia.linizen.bridges.ASP;

import com.denizenscript.denizencore.flags.SavableMapFlagTracker;
import com.infernalsuite.asp.api.world.SlimeWorld;
import com.infernalsuite.asp.api.world.SlimeWorldInstance;
import net.kyori.adventure.nbt.BinaryTag;
import net.kyori.adventure.nbt.StringBinaryTag;

import java.util.HashMap;
import java.util.Map;

public class SlimeWorldFlagHandler {

static final String EXTRA_DATA_KEY = "denizen_flags";

public static final HashMap<String, SavableMapFlagTracker> trackers = new HashMap<>();

public static void loadFlags(SlimeWorld world) {
BinaryTag raw = world.getExtraData().get(EXTRA_DATA_KEY);
SavableMapFlagTracker tracker = (raw instanceof StringBinaryTag s) ? new SavableMapFlagTracker(s.value()) : new SavableMapFlagTracker();
tracker.doTotalClean();
trackers.put(world.getName(), tracker);
}

public static void initEmpty(String worldName) {
trackers.put(worldName, new SavableMapFlagTracker());
}

public static void flushToWorld(SlimeWorld world) {
SavableMapFlagTracker tracker = trackers.get(world.getName());
if (tracker == null || !tracker.modified) {
return;
}
world.getExtraData().put(EXTRA_DATA_KEY, StringBinaryTag.stringBinaryTag(tracker.toString()));
tracker.modified = false;
}

public static void flushAll() {
for (Map.Entry<String, SavableMapFlagTracker> entry : trackers.entrySet()) {
SlimeWorldInstance sw = ASPBridge.instance.getLoadedWorld(entry.getKey());
if (sw != null) {
flushToWorld(sw);
}
}
}

public static void unloadFlags(String worldName) {
trackers.remove(worldName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.bukkit.Material;
import org.bukkit.World;
import org.linia.linizen.bridges.ASP.ASPBridge;
import org.linia.linizen.bridges.ASP.SlimeWorldFlagHandler;
import org.linia.linizen.bridges.ASP.objects.FileWorldLoaderTag;
import org.linia.linizen.bridges.ASP.objects.SlimeWorldTag;
import org.linia.linizen.utils.ExecutorUtil;
Expand Down Expand Up @@ -94,6 +95,7 @@ public static void autoExecute(ScriptEntry scriptEntry,
ExecutorUtil.runSyncAndWait(() -> {
try {
ASPBridge.instance.loadWorld(slimeWorld, true);
SlimeWorldFlagHandler.loadFlags(slimeWorld);
World world = Bukkit.getWorld(name);
if (world != null) {
Location loc = new Location(world, 0, 61, 0);
Expand Down Expand Up @@ -127,6 +129,7 @@ public static void autoExecute(ScriptEntry scriptEntry,
ExecutorUtil.runSyncAndWait(() -> {
try {
ASPBridge.instance.loadWorld(slimeWorld, true);
SlimeWorldFlagHandler.loadFlags(slimeWorld);
scriptEntry.saveObject("loaded_world", new SlimeWorldTag(slimeWorld));
}
catch (IllegalArgumentException e) {
Expand Down Expand Up @@ -161,6 +164,7 @@ public static void autoExecute(ScriptEntry scriptEntry,
ExecutorUtil.runSyncAndWait(() -> {
try {
ASPBridge.instance.loadWorld(cloned, true);
SlimeWorldFlagHandler.initEmpty(cloned.getName());
scriptEntry.saveObject("cloned_world", new SlimeWorldTag(cloned));
}
catch (IllegalArgumentException e) {
Expand Down
113 changes: 84 additions & 29 deletions src/main/java/org/linia/linizen/bridges/ASP/objects/SlimeWorldTag.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.linia.linizen.bridges.ASP.objects;

import com.denizenscript.denizen.objects.WorldTag;
import com.denizenscript.denizencore.flags.AbstractFlagTracker;
import com.denizenscript.denizencore.flags.FlaggableObject;
import com.denizenscript.denizencore.objects.Adjustable;
import com.denizenscript.denizencore.objects.Fetchable;
import com.denizenscript.denizencore.objects.Mechanism;
Expand All @@ -14,10 +16,12 @@
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.linia.linizen.bridges.ASP.ASPBridge;
import org.linia.linizen.bridges.ASP.SlimeWorldFlagHandler;

import java.io.IOException;
import java.lang.ref.WeakReference;

public class SlimeWorldTag implements ObjectTag, Adjustable {
public class SlimeWorldTag implements ObjectTag, Adjustable, FlaggableObject {

@Fetchable("sw@")
public static SlimeWorldTag valueOf(String string, TagContext context) {
Expand All @@ -35,43 +39,48 @@ public static boolean matches(String string) {
return valueOf(string, null) != null;
}

/*
* Maybe in the future if it becomes RAM issue, we could save only worldsName
* and not whole instance. In which case we would need to reconstruct it each
* time we are calling it. (With something like SlimeWorldTag#getSlimeWorld)
*/
public SlimeWorld slimeWorld;
private final String worldName;
private final WeakReference<SlimeWorld> slimeWorldRef;

public SlimeWorldTag(SlimeWorld slimeWorld) {
this.slimeWorld = slimeWorld;
this.worldName = slimeWorld.getName();
this.slimeWorldRef = new WeakReference<>(slimeWorld);
}

public SlimeWorld getSlimeWorld() {
return slimeWorldRef.get();
}

@Override
public AbstractFlagTracker getFlagTracker() {
return SlimeWorldFlagHandler.trackers.get(worldName);
}

@Override
public void reapplyTracker(AbstractFlagTracker tracker) {
}

@Override
public String getReasonNotFlaggable() {
return "is the SlimeWorld loaded?";
}

public static void register() {

// <--[tag]
// @attribute <SlimeWorldTag.is_loaded>
// @returns ElementTag(Boolean)
// @plugin Linizen, ASP
// @description
// Returns whether the world is actually loaded.
// -->
tagProcessor.registerTag(ElementTag.class, "is_loaded", (attribute, object) -> {
try {
return new ElementTag(object.slimeWorld.getLoader().worldExists(object.slimeWorld.getName()));
} catch (IOException e) {
return new ElementTag(false);
}
});
AbstractFlagTracker.registerFlagHandlers(tagProcessor);

// <--[tag]
// @attribute <SlimeWorldTag.get_loader>
// @attribute <SlimeWorldTag.get_file_loader>
// @returns FileWorldLoaderTag
// @plugin Linizen, ASP
// @description
// Returns a file loader which this world is loaded from, if any.
// -->
tagProcessor.registerTag(FileWorldLoaderTag.class, "get_file_loader", (attribute, object) -> {
return object.slimeWorld.getLoader() instanceof FileWorldLoaderTag f ? f : null;
if (!requireLoadedWorld(object, attribute)) {
return null;
}
return (object.getSlimeWorld().getLoader() instanceof FileWorldLoaderTag f) ? f : null;
});

// <--[tag]
Expand All @@ -82,7 +91,18 @@ public static void register() {
// Returns a world representing this slimeworld.
// -->
tagProcessor.registerTag(WorldTag.class, "as_world", (attribute, object) -> {
return new WorldTag(object.getWorld());
return requireLoadedWorld(object, attribute) ? new WorldTag(object.getWorld()) : null;
});

// <--[tag]
// @attribute <SlimeWorldTag.name>
// @returns ElementTag
// @plugin Linizen, ASP
// @description
// Returns the name of the slimeworld. (Works even when unloaded)
// -->
tagProcessor.registerStaticTag(ElementTag.class, "name", (attribute, object) -> {
return new ElementTag(object.worldName);
});

// <--[mechanism]
Expand All @@ -93,8 +113,13 @@ public static void register() {
// Saves the world.
// -->
tagProcessor.registerMechanism("save", false, (object, mechanism) -> {
if (!requireLoadedWorld(object, mechanism)) {
return;
}
SlimeWorld sw = object.getSlimeWorld();
try {
ASPBridge.instance.saveWorld(object.slimeWorld);
SlimeWorldFlagHandler.flushToWorld(sw);
ASPBridge.instance.saveWorld(sw);
} catch (IOException e) {
mechanism.echoError("Could not save world");
}
Expand All @@ -109,6 +134,9 @@ public static void register() {
// Unloads a world
// -->
tagProcessor.registerMechanism("unload", false, ElementTag.class, (object, mechanism, input) -> {
if (!requireLoadedWorld(object, mechanism)) {
return;
}
if (!input.isBoolean()) {
mechanism.echoError("Must provide boolean");
return;
Expand All @@ -118,14 +146,41 @@ public static void register() {
mechanism.echoError("Could not unload world, players are there.");
return;
}
if (!Bukkit.unloadWorld(world, input.asBoolean())) {
boolean inp = input.asBoolean();
if (inp) {
SlimeWorldFlagHandler.flushToWorld(object.getSlimeWorld());
}
if (!Bukkit.unloadWorld(world, inp)) {
mechanism.echoError("Saving for SlimeWorld " + world.getName() + " refused by system.");
}
else {
SlimeWorldFlagHandler.unloadFlags(object.worldName);
}
});
}

public static boolean requireLoadedWorld(SlimeWorldTag slimeWorldTag, Mechanism mechanism) {
if (!slimeWorldTag.isLoaded()) {
mechanism.echoError("World '" + slimeWorldTag.worldName + "' is unloaded, cannot adjust mechanism.");
return false;
}
return true;
}

public static boolean requireLoadedWorld(SlimeWorldTag slimeWorldTag, Attribute attribute) {
if (!slimeWorldTag.isLoaded()) {
attribute.echoError("World '" + slimeWorldTag.worldName + "' is unloaded, cannot process tag.");
return false;
}
return true;
}

public boolean isLoaded() {
return getSlimeWorld() == null || !ASPBridge.instance.worldLoaded(getSlimeWorld());
}

public World getWorld() {
return Bukkit.getWorld(slimeWorld.getName());
return Bukkit.getWorld(worldName);
}

public String prefix = "SlimeWorld";
Expand All @@ -147,7 +202,7 @@ public boolean isUnique() {

@Override
public String identify() {
return "sw@" + slimeWorld.getName();
return "sw@" + worldName;
}

@Override
Expand Down
Loading