Skip to content

Commit eaf8d47

Browse files
committed
* Completely removed old task scheduling utility for newly optimized alternative.
* Optimized task execution handling. * Added new isModded check to LegacyCheckService * Added new toBlockFace method to DirectivePoint * Optimized internal Unity task executions. * Finalized OrdinalProcedure service. * Completely removed old PaginatedList.java utility. * Finalized sub-command injection handling. * Optimized and fixed remaining issues with Message.java abstraction in tandem with ComponentUtil. * Optimized labyrinth provided placeholder system. * Added version support for 1.18+ (1.19 & future versions) * Added new AbstractClassLoader for alternative class loading from external jars than AddonLoader * Added class unloading to AddonLoader * Added new multi-object isNull checking method to Check.java * Finalized SubCommandList.java and made its internal referencing to depend on localization. * Added new docket interfacing to unity gui library. Purposed to create ultimate fluidity in menu creation through configuration. * Added new FormattedString.java class to help act as more of a modular StringUtils utility class. * Added json string to json object conversion method to JsonIntermediate.java * Optimized unity menu interaction, fixed resulting item inventory duplication bug in modded environments. * Fixed TablistInstance.java player list name default. * Fixed reflection problems 1.18+ with Task.java * Added simple UnknownGeneric.java interface. * Fixed WebResponse.java * Optimized key and value listing for all Node.java related services. * Enabled atlas map types to allow for custom '.' node separation placeholders. * Removed deprecated Message.java class. * Removed deprecated methods from Item.java class. * Added new MapDecompressionUtils service. * Finalized Registry.java * Finalized ExternalDataService.java and switched to new AbstractClassLoader.
1 parent a96c666 commit eaf8d47

File tree

30 files changed

+911
-895
lines changed

30 files changed

+911
-895
lines changed

labyrinth-common/src/main/java/com/github/sanctum/labyrinth/api/MessagingService.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,6 @@
2222
*/
2323
public interface MessagingService extends Service, Message.Factory {
2424

25-
/**
26-
* Get a new message operation instance.
27-
*
28-
* @see MessagingService#getEmptyMailer()
29-
* @deprecated This utility is being replaced, use {@link MessagingService#getEmptyMailer()} instead.
30-
* @return A new message instance.
31-
*/
32-
@Deprecated()
33-
@NotNull com.github.sanctum.labyrinth.library.Message getNewMessage();
34-
35-
3625
/**
3726
* Get a new object for sending numerous types of displayable messages!
3827
*
@@ -59,7 +48,7 @@ default <T> Deployable<Object> sendPluginMessage(Plugin plugin, T object) {
5948
}
6049

6150
default <T> Deployable<Object> sendPluginMessage(Plugin plugin, T object, @FieldsFrom(LabyrinthPluginChannel.class) LabyrinthPluginChannel<?> channel) {
62-
return Deployable.of(null, unused -> unused = new Vent.Call<>(new LabyrinthPluginMessageEvent(new LabyrinthPluginMessage<T>() {
51+
return Deployable.of(() -> new Vent.Call<>(new LabyrinthPluginMessageEvent(new LabyrinthPluginMessage<T>() {
6352
@Override
6453
public Plugin getPlugin() {
6554
return plugin;

labyrinth-common/src/main/java/com/github/sanctum/labyrinth/data/AbstractClassLoader.java

Lines changed: 69 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
package com.github.sanctum.labyrinth.data;
22

3+
import com.github.sanctum.labyrinth.LabyrinthProvider;
4+
import com.github.sanctum.labyrinth.annotation.Experimental;
5+
import com.github.sanctum.labyrinth.library.EasyTypeAdapter;
6+
import com.github.sanctum.labyrinth.library.TypeFlag;
7+
import com.google.common.collect.ImmutableList;
38
import java.io.File;
49
import java.io.IOException;
510
import java.lang.reflect.Constructor;
@@ -14,27 +19,31 @@
1419
import java.util.zip.ZipEntry;
1520
import org.bukkit.plugin.Plugin;
1621

22+
/**
23+
* A class dedicated to allowing developers to load external jars into memory.
24+
*
25+
* @param <T> The optional main class this loader needs to locate and instantiate.
26+
*/
1727
public abstract class AbstractClassLoader<T> extends URLClassLoader {
1828

19-
private static final Field PLUGIN_CLASS_MAP;
29+
protected final Field PLUGIN_CLASS_MAP;
30+
protected final List<Class<?>> classes;
31+
protected final ClassLoader pluginClassLoader;
32+
protected final T mainClass;
2033

21-
private final List<Class<?>> classes;
22-
private final Plugin plugin;
23-
final T mainClass;
24-
25-
static {
34+
protected AbstractClassLoader(File file, ClassLoader parent, Object... args) throws IOException {
35+
super(new URL[]{file.toURI().toURL()}, parent);
36+
TypeFlag<T> flag = new EasyTypeAdapter<>();
37+
Class<T> main = flag.getType();
2638
try {
2739
PLUGIN_CLASS_MAP = Class.forName("org.bukkit.plugin.java.PluginClassLoader").getDeclaredField("classes");
2840
PLUGIN_CLASS_MAP.setAccessible(true);
2941
} catch (NoSuchFieldException | ClassNotFoundException e) {
30-
throw new IllegalStateException("Unable to reach class map", e);
42+
throw new IllegalStateException("Unable to reach plugin class map", e);
3143
}
32-
}
33-
34-
protected AbstractClassLoader(Plugin plugin, File file, ClassLoader parent, Class<T> main, Object... args) throws IOException {
35-
super(new URL[]{file.toURI().toURL()}, parent);
3644
final List<Class<?>> loadedClasses = new ArrayList<>();
37-
this.plugin = plugin;
45+
final Plugin plugin = LabyrinthProvider.getInstance().getPluginInstance();
46+
this.pluginClassLoader = plugin.getClass().getClassLoader();
3847
if (!file.isFile()) throw new IllegalArgumentException("The provided file is not a jar file!");
3948
new JarFile(file).stream()
4049
.map(ZipEntry::getName)
@@ -50,7 +59,7 @@ protected AbstractClassLoader(Plugin plugin, File file, ClassLoader parent, Clas
5059
plugin.getLogger().warning(e::getMessage);
5160
return;
5261
}
53-
getClassMap().put(s, resolvedClass);
62+
getPluginClassMap().put(s, resolvedClass);
5463
plugin.getLogger().finest(() -> "Loaded '" + s + "' successfully.");
5564
loadedClasses.add(resolvedClass);
5665
});
@@ -76,7 +85,7 @@ protected AbstractClassLoader(Plugin plugin, File file, ClassLoader parent, Clas
7685
}
7786
}
7887
}
79-
this.mainClass = addonClass.getDeclaredConstructor(constructor.getParameterTypes()).newInstance(args);
88+
this.mainClass = constructor != null ? constructor.newInstance(args) : addonClass.getDeclaredConstructor().newInstance();
8089
} else {
8190
this.mainClass = addonClass.getDeclaredConstructor().newInstance();
8291
}
@@ -88,26 +97,61 @@ protected AbstractClassLoader(Plugin plugin, File file, ClassLoader parent, Clas
8897
} else this.mainClass = null;
8998
}
9099

91-
public AbstractClassLoader(Plugin plugin, File file, ClassLoader parent) throws IOException {
92-
this(plugin, file, parent, null);
100+
/**
101+
* Get the main class for this class loader.
102+
*
103+
* @return the main class for this class loader if one exists.
104+
*/
105+
public T getMainClass() {
106+
return mainClass;
93107
}
94108

95-
public Plugin getPlugin() {
96-
return plugin;
109+
/**
110+
* Get a list of all classes loaded by this class loader.
111+
*
112+
* @return all classes loaded by this class loader.
113+
*/
114+
public List<Class<?>> getClasses() {
115+
return ImmutableList.copyOf(classes);
97116
}
98117

99-
public T getMain() {
100-
return mainClass;
118+
/**
119+
* Unload a class from memory. If the provided class is not found an exception will occur, if the provided string results in a path
120+
* this method will switch in an attempt at locating and removing the relative class files it belongs to.
121+
*
122+
* @param name The name of the class file or path.
123+
* @return true if the class(es) got removed from memory.
124+
* @throws ClassNotFoundException if the attempted class resolve fails and the included text doesn't result in a valid directory.
125+
*/
126+
@Experimental
127+
public boolean unload(String name) throws ClassNotFoundException {
128+
Map<String, Class<?>> classes = getPluginClassMap();
129+
if (classes.containsKey(name)) {
130+
classes.remove(name);
131+
return true;
132+
} else throw new ClassNotFoundException("Class " + name + " not found, cannot unload.");
101133
}
102134

103-
public List<Class<?>> getClasses() {
104-
return classes;
135+
/**
136+
* Simply unload a loaded class from this addon loader.
137+
*
138+
* @param clazz The class to unload.
139+
* @throws WrongLoaderUsedException when the class attempting removal belongs to a different loader instance.
140+
* @return true if the class was able to unload.
141+
*/
142+
@Experimental
143+
public boolean unload(Class<?> clazz) throws WrongLoaderUsedException {
144+
Map<String, Class<?>> classes = getPluginClassMap();
145+
String name = clazz.getName().replace("/", ".").substring(0, clazz.getName().length() - 6);
146+
classes.remove(name);
147+
if (!this.classes.contains(clazz)) throw new WrongLoaderUsedException("Class " + clazz.getName() + " does not belong to this loader!");
148+
return this.classes.remove(clazz);
105149
}
106150

107-
public Map<String, Class<?>> getClassMap() throws IllegalStateException {
151+
public final Map<String, Class<?>> getPluginClassMap() throws IllegalStateException {
108152
try {
109153
//noinspection unchecked
110-
return (Map<String, Class<?>>) PLUGIN_CLASS_MAP.get(plugin.getClass().getClassLoader());
154+
return (Map<String, Class<?>>) PLUGIN_CLASS_MAP.get(this.pluginClassLoader);
111155
} catch (ClassCastException | IllegalAccessException e) {
112156
throw new IllegalStateException(e);
113157
}
@@ -116,7 +160,7 @@ public Map<String, Class<?>> getClassMap() throws IllegalStateException {
116160
@Override
117161
public String toString() {
118162
return "AbstractFileLoader{" +
119-
"Main=" + (mainClass == null ? "N/A" : mainClass) +
163+
"Main=" + mainClass +
120164
'}';
121165
}
122166

labyrinth-common/src/main/java/com/github/sanctum/labyrinth/data/Atlas.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@ default String getPath() {
1414
return null;
1515
}
1616

17+
char getDivider();
18+
1719
}

labyrinth-common/src/main/java/com/github/sanctum/labyrinth/data/AtlasMap.java

Lines changed: 34 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,25 @@
1414

1515
public class AtlasMap implements Atlas {
1616

17-
private final Map<String, Object> SOURCE = new HashMap<>();
17+
protected final Map<String, Object> SOURCE = new HashMap<>();
1818
protected final Map<String, MemorySpace> QUERY = new HashMap<>();
19+
protected final char divider;
20+
21+
public AtlasMap(char divider) {
22+
this.divider = divider;
23+
}
24+
25+
public AtlasMap() {
26+
this.divider = '.';
27+
}
28+
29+
String dividerAdapt() {
30+
return divider == '.' ? "[" + divider + "]" : divider + "";
31+
}
1932

2033
@Override
2134
public boolean isNode(String key) {
22-
String[] a = key.split("\\.");
35+
String[] a = key.split(dividerAdapt());
2336
String k = a[Math.max(0, a.length - 1)];
2437
Map<String, Object> o = SOURCE;
2538
for (int i = 0; i < a.length - 1; i++) {
@@ -49,76 +62,34 @@ public Node getNode(String key) {
4962
@Override
5063
public Set<String> getKeys(boolean deep) {
5164
Set<String> keys = new HashSet<>();
52-
for (Object o : SOURCE.entrySet()) {
53-
Map.Entry<String, Object> entry = (Map.Entry<String, Object>) o;
65+
SOURCE.forEach((key, value) -> {
5466
if (deep) {
55-
if (entry.getValue() instanceof Map) {
56-
Map<String, Object> obj = (Map<String, Object>) entry.getValue();
57-
for (Object ob : obj.entrySet()) {
58-
Map.Entry<String, Object> en = (Map.Entry<String, Object>) ob;
59-
if (en.getValue() instanceof Map) {
60-
Map<String, Object> j = (Map<String, Object>) entry.getValue();
61-
for (Object e : j.entrySet()) {
62-
Map.Entry<String, Object> ent = (Map.Entry<String, Object>) e;
63-
if (ent.getValue() instanceof Map) {
64-
Map<String, Object> ja = (Map<String, Object>) ent.getValue();
65-
for (Object ex : ja.entrySet()) {
66-
Map.Entry<String, Object> entr = (Map.Entry<String, Object>) ex;
67-
keys.add(entry.getKey() + "." + en.getKey() + "." + ent.getKey() + "." + entr.getKey());
68-
}
69-
} else {
70-
keys.add(entry.getKey() + "." + en.getKey() + "." + ent.getKey());
71-
}
72-
}
73-
} else {
74-
keys.add(entry.getKey() + "." + en.getKey());
75-
}
76-
}
67+
if (value instanceof Map) {
68+
keys.addAll(MapDecompressionUtils.getInstance().decompress(((Map<String, Object>) value).entrySet(), divider, null).toSet());
7769
} else {
78-
keys.add(entry.getKey());
70+
keys.add(key);
7971
}
8072
} else {
81-
keys.add(entry.getKey());
73+
keys.add(key);
8274
}
83-
}
75+
});
8476
return keys;
8577
}
8678

8779
@Override
8880
public Map<String, Object> getValues(boolean deep) {
8981
Map<String, Object> map = new HashMap<>();
90-
for (Object o : SOURCE.entrySet()) {
91-
Map.Entry<String, Object> entry = (Map.Entry<String, Object>) o;
82+
SOURCE.forEach((key, value) -> {
9283
if (deep) {
93-
if (entry.getValue() instanceof Map) {
94-
Map<String, Object> obj = (Map<String, Object>) entry.getValue();
95-
for (Object ob : obj.entrySet()) {
96-
Map.Entry<String, Object> en = (Map.Entry<String, Object>) ob;
97-
if (en.getValue() instanceof Map) {
98-
Map<String, Object> j = (Map<String, Object>) entry.getValue();
99-
for (Object e : j.entrySet()) {
100-
Map.Entry<String, Object> ent = (Map.Entry<String, Object>) e;
101-
if (ent.getValue() instanceof Map) {
102-
Map<String, Object> ja = (Map<String, Object>) ent.getValue();
103-
for (Object ex : ja.entrySet()) {
104-
Map.Entry<String, Object> entr = (Map.Entry<String, Object>) ex;
105-
map.put(entry.getKey() + "." + en.getKey() + "." + ent.getKey() + "." + entr.getKey(), entr.getValue());
106-
}
107-
} else {
108-
map.put(entry.getKey() + "." + en.getKey() + "." + ent.getKey(), ent.getValue());
109-
}
110-
}
111-
} else {
112-
map.put(entry.getKey() + "." + en.getKey(), en.getValue());
113-
}
114-
}
84+
if (value instanceof Map) {
85+
map.putAll(MapDecompressionUtils.getInstance().decompress(((Map<String, Object>) value).entrySet(), divider, null).toMap());
11586
} else {
116-
map.put(entry.getKey(), entry.getValue());
87+
map.put(key, value);
11788
}
11889
} else {
119-
map.put(entry.getKey(), entry.getValue());
90+
map.put(key, value);
12091
}
121-
}
92+
});
12293
return map;
12394
}
12495

@@ -145,7 +116,7 @@ public boolean containsValue(Object value) {
145116
@Override
146117
public Object get(Object key) {
147118
String ke = (String) key;
148-
String[] a = ke.split("\\.");
119+
String[] a = ke.split(dividerAdapt());
149120
String k = a[Math.max(0, a.length - 1)];
150121
Map<String, Object> o = SOURCE;
151122
for (int i = 0; i < a.length - 1; i++) {
@@ -168,7 +139,7 @@ public Object get(Object key) {
168139
@Nullable
169140
@Override
170141
public Object put(String key, Object o) {
171-
String[] a = key.split("\\.");
142+
String[] a = key.split(dividerAdapt());
172143
String k = a[Math.max(0, a.length - 1)];
173144
Map<String, Object> ob = SOURCE;
174145
for (int i = 0; i < a.length - 1; i++) {
@@ -312,4 +283,9 @@ public Object compute(String key, @NotNull BiFunction<? super String, ? super Ob
312283
public Object merge(String key, @NotNull Object value, @NotNull BiFunction<? super Object, ? super Object, ?> remappingFunction) {
313284
return SOURCE.merge(key, value, remappingFunction);
314285
}
286+
287+
@Override
288+
public char getDivider() {
289+
return divider;
290+
}
315291
}

0 commit comments

Comments
 (0)