Skip to content

Commit 9c05018

Browse files
committed
Dont require ASWM/ASP
1 parent 3c51710 commit 9c05018

3 files changed

Lines changed: 218 additions & 185 deletions

File tree

‎src/main/java/dev/plex/Guilds.java‎

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
@Getter
2121
public class Guilds extends PlexModule
2222
{
23+
private static final String ASP_API_CLASS = "com.infernalsuite.asp.api.AdvancedSlimePaperAPI";
24+
private static final String ASP_LOADER_CLASS = "com.infernalsuite.asp.api.loaders.SlimeLoader";
25+
private static final String ASP_WORLD_SERVICE_CLASS = "dev.plex.world.AspGuildWorldService";
26+
2327
private static Guilds module;
2428
private final GuildHolder guildHolder = new GuildHolder();
2529
private final GuildMenuListener guildMenuListener = new GuildMenuListener();
@@ -45,15 +49,7 @@ public void load()
4549
@Override
4650
public void enable()
4751
{
48-
if (slimeWorldsAvailable())
49-
{
50-
guildWorldService = new GuildWorldService();
51-
guildWorldService.enable();
52-
}
53-
else
54-
{
55-
getLogger().warn("Advanced Slime Paper (ASP/ASWM) was not found; guild worlds are disabled.");
56-
}
52+
enableGuildWorlds();
5753
ModuleStorage storage = api().storage().forModule(this);
5854
try
5955
{
@@ -100,16 +96,23 @@ public boolean isGuildWorldsEnabled()
10096
return guildWorldService != null;
10197
}
10298

103-
private static boolean slimeWorldsAvailable()
99+
private void enableGuildWorlds()
104100
{
105101
try
106102
{
107-
Class.forName("com.infernalsuite.asp.api.AdvancedSlimePaperAPI", false, Guilds.class.getClassLoader());
108-
return true;
103+
ClassLoader classLoader = Guilds.class.getClassLoader();
104+
Class.forName(ASP_API_CLASS, false, classLoader);
105+
Class.forName(ASP_LOADER_CLASS, false, classLoader);
106+
107+
Class<? extends GuildWorldService> serviceClass = Class.forName(ASP_WORLD_SERVICE_CLASS, true, classLoader)
108+
.asSubclass(GuildWorldService.class);
109+
GuildWorldService service = serviceClass.getConstructor().newInstance();
110+
service.enable();
111+
guildWorldService = service;
109112
}
110-
catch (Throwable throwable)
113+
catch (ReflectiveOperationException | LinkageError | RuntimeException throwable)
111114
{
112-
return false;
115+
getLogger().warn("Advanced Slime Paper (ASP/ASWM) is unavailable or incompatible; guild worlds are disabled, but all other guild features will remain enabled.");
113116
}
114117
}
115118

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
package dev.plex.world;
2+
3+
import com.infernalsuite.asp.api.AdvancedSlimePaperAPI;
4+
import com.infernalsuite.asp.api.exceptions.CorruptedWorldException;
5+
import com.infernalsuite.asp.api.exceptions.NewerFormatException;
6+
import com.infernalsuite.asp.api.exceptions.UnknownWorldException;
7+
import com.infernalsuite.asp.api.loaders.SlimeLoader;
8+
import com.infernalsuite.asp.api.world.SlimeWorld;
9+
import com.infernalsuite.asp.api.world.SlimeWorldInstance;
10+
import com.infernalsuite.asp.api.world.properties.SlimeProperties;
11+
import com.infernalsuite.asp.api.world.properties.SlimePropertyMap;
12+
import com.infernalsuite.asp.loaders.file.FileLoader;
13+
import dev.plex.Guilds;
14+
import dev.plex.guild.Guild;
15+
import org.bukkit.Bukkit;
16+
import org.bukkit.Location;
17+
import org.bukkit.Material;
18+
import org.bukkit.World;
19+
20+
import java.io.File;
21+
import java.io.IOException;
22+
import java.util.Map;
23+
import java.util.UUID;
24+
import java.util.concurrent.CompletableFuture;
25+
import java.util.concurrent.ConcurrentHashMap;
26+
27+
public class AspGuildWorldService implements GuildWorldService
28+
{
29+
private final AdvancedSlimePaperAPI asp = AdvancedSlimePaperAPI.instance();
30+
private final Map<UUID, SlimeWorldInstance> loadedWorlds = new ConcurrentHashMap<>();
31+
private SlimeLoader loader;
32+
33+
@Override
34+
public void enable()
35+
{
36+
File worldDirectory = new File(Guilds.get().getDataFolder(), "slime-worlds");
37+
loader = new FileLoader(worldDirectory);
38+
}
39+
40+
@Override
41+
public CompletableFuture<World> ensureWorld(Guild guild)
42+
{
43+
SlimeWorldInstance loadedWorld = loadedWorlds.get(guild.getGuildUuid());
44+
if (loadedWorld != null)
45+
{
46+
return CompletableFuture.completedFuture(loadedWorld.getBukkitWorld());
47+
}
48+
49+
SlimeWorldInstance aspLoadedWorld = asp.getLoadedWorld(guild.getWorldName());
50+
if (aspLoadedWorld != null)
51+
{
52+
loadedWorlds.put(guild.getGuildUuid(), aspLoadedWorld);
53+
return CompletableFuture.completedFuture(aspLoadedWorld.getBukkitWorld());
54+
}
55+
56+
return CompletableFuture.supplyAsync(() -> readOrCreateWorld(guild), Guilds.get().api().scheduler().asyncExecutor())
57+
.thenCompose(slimeWorld -> loadWorld(guild, slimeWorld))
58+
.thenApply(world ->
59+
{
60+
initializeWorld(world);
61+
saveWorld(guild);
62+
return world;
63+
});
64+
}
65+
66+
@Override
67+
public void saveWorld(Guild guild)
68+
{
69+
SlimeWorldInstance loadedWorld = loadedWorlds.get(guild.getGuildUuid());
70+
if (loadedWorld == null)
71+
{
72+
return;
73+
}
74+
CompletableFuture.runAsync(() -> saveLoadedWorld(loadedWorld), Guilds.get().api().scheduler().asyncExecutor());
75+
}
76+
77+
@Override
78+
public void ejectNonMembers(Guild guild)
79+
{
80+
SlimeWorldInstance loadedWorld = loadedWorlds.get(guild.getGuildUuid());
81+
if (loadedWorld == null)
82+
{
83+
return;
84+
}
85+
Guilds.get().api().scheduler().executeGlobal(() ->
86+
{
87+
World fallback = Bukkit.getWorlds().getFirst();
88+
loadedWorld.getBukkitWorld().getPlayers().stream()
89+
.filter(player -> !guild.isMember(player.getUniqueId()))
90+
.forEach(player ->
91+
{
92+
player.teleportAsync(fallback.getSpawnLocation());
93+
player.sendMessage(Guilds.get().messageComponent("guildWorldNoAccess"));
94+
});
95+
});
96+
}
97+
98+
@Override
99+
public void disable()
100+
{
101+
loadedWorlds.values().forEach(loadedWorld ->
102+
{
103+
saveLoadedWorld(loadedWorld);
104+
Bukkit.unloadWorld(loadedWorld.getBukkitWorld(), false);
105+
});
106+
loadedWorlds.clear();
107+
}
108+
109+
private SlimeWorld readOrCreateWorld(Guild guild)
110+
{
111+
SlimePropertyMap propertyMap = createPropertyMap();
112+
try
113+
{
114+
return asp.readWorld(loader, guild.getWorldName(), false, propertyMap);
115+
}
116+
catch (UnknownWorldException ignored)
117+
{
118+
return asp.createEmptyWorld(guild.getWorldName(), false, propertyMap, loader);
119+
}
120+
catch (IOException | CorruptedWorldException | NewerFormatException e)
121+
{
122+
throw new GuildWorldException("Failed to read guild world " + guild.getWorldName(), e);
123+
}
124+
}
125+
126+
private CompletableFuture<World> loadWorld(Guild guild, SlimeWorld slimeWorld)
127+
{
128+
CompletableFuture<World> future = new CompletableFuture<>();
129+
Guilds.get().api().scheduler().executeGlobal(() ->
130+
{
131+
try
132+
{
133+
SlimeWorldInstance loadedWorld = asp.loadWorld(slimeWorld, true);
134+
loadedWorlds.put(guild.getGuildUuid(), loadedWorld);
135+
future.complete(loadedWorld.getBukkitWorld());
136+
}
137+
catch (Throwable throwable)
138+
{
139+
future.completeExceptionally(throwable);
140+
}
141+
});
142+
return future;
143+
}
144+
145+
private void initializeWorld(World world)
146+
{
147+
int y = world.getMaxHeight() / 2;
148+
Location spawn = new Location(world, 0.5, y + 1, 0.5);
149+
world.getBlockAt(0, y, 0).setType(Material.GRASS_BLOCK, false);
150+
world.setSpawnLocation(spawn);
151+
}
152+
153+
private void saveLoadedWorld(SlimeWorldInstance loadedWorld)
154+
{
155+
try
156+
{
157+
asp.saveWorld(loadedWorld.getSerializableCopy());
158+
}
159+
catch (IOException e)
160+
{
161+
throw new GuildWorldException("Failed to save guild world " + loadedWorld.getName(), e);
162+
}
163+
}
164+
165+
private SlimePropertyMap createPropertyMap()
166+
{
167+
SlimePropertyMap propertyMap = new SlimePropertyMap();
168+
propertyMap.setValue(SlimeProperties.DIFFICULTY, "peaceful");
169+
propertyMap.setValue(SlimeProperties.SPAWN_X, 0);
170+
propertyMap.setValue(SlimeProperties.SPAWN_Y, 65);
171+
propertyMap.setValue(SlimeProperties.SPAWN_Z, 0);
172+
propertyMap.setValue(SlimeProperties.ALLOW_ANIMALS, false);
173+
propertyMap.setValue(SlimeProperties.ALLOW_MONSTERS, false);
174+
propertyMap.setValue(SlimeProperties.DRAGON_BATTLE, false);
175+
propertyMap.setValue(SlimeProperties.PVP, false);
176+
propertyMap.setValue(SlimeProperties.ENVIRONMENT, "normal");
177+
propertyMap.setValue(SlimeProperties.WORLD_TYPE, "FLAT");
178+
propertyMap.setValue(SlimeProperties.DEFAULT_BIOME, "minecraft:plains");
179+
return propertyMap;
180+
}
181+
182+
public static class GuildWorldException extends RuntimeException
183+
{
184+
public GuildWorldException(String message, Throwable cause)
185+
{
186+
super(message, cause);
187+
}
188+
}
189+
}

0 commit comments

Comments
 (0)