PluginManager class
Пакет: com.hypixel.hytale.server.core.plugin
Файл: com/hypixel/hytale/server/core/plugin/PluginManager.java
Поля (202)
| Модификаторы | Тип | Имя |
|---|---|---|
|
|
break |
|
|
break |
|
|
break |
|
|
break |
|
|
break |
|
|
continue |
|
|
instance |
|
private final PluginManager |
pluginManager |
|
|
return |
|
|
return |
|
|
return |
|
|
return |
|
HashMap |
var1 |
|
boolean |
var1 |
|
|
var1 |
|
List |
var1 |
|
List |
var1 |
|
URLClassLoader |
var1 |
|
PluginBase |
var10 |
|
char[] |
var10 |
|
PluginManifest[] |
var10 |
|
|
var10 |
|
RawJsonReader |
var10 |
|
PluginBase |
var11 |
|
RawJsonReader |
var11 |
|
URL |
var11 |
|
ExtraInfo |
var11 |
|
int |
var12 |
|
SemverRange |
var12 |
|
ExtraInfo |
var12 |
|
Path |
var12 |
|
PluginManifest |
var12 |
|
String |
var13 |
|
PluginManifest |
var13 |
|
|
var13 |
|
PluginClassLoader |
var13 |
|
PluginClassLoader |
var13 |
|
PendingLoadJavaPlugin |
var14 |
|
|
var14 |
|
|
var14 |
|
PendingLoadJavaPlugin |
var14 |
|
Message |
var15 |
|
Message |
var16 |
|
URL |
var16 |
|
PluginClassLoader |
var16 |
|
PluginBase |
var16 |
|
PluginBase |
var16 |
|
PluginBase |
var16 |
|
Path |
var17 |
|
PendingLoadJavaPlugin |
var17 |
|
PluginBase |
var17 |
|
URL |
var17 |
|
URL |
var17 |
|
PluginClassLoader |
var18 |
|
PendingLoadJavaPlugin |
var18 |
|
Class |
var18 |
|
PluginClassLoader |
var19 |
|
Class |
var19 |
|
PluginIdentifier |
var2 |
|
PlayerRef |
var2 |
|
AssetPack |
var2 |
|
boolean |
var2 |
|
|
var2 |
|
int |
var2 |
|
PluginManifest |
var2 |
|
AssetModule |
var2 |
|
boolean |
var2 |
|
Path |
var2 |
|
PluginBase |
var2 |
|
InputStream |
var2 |
|
PluginBase |
var2 |
|
PluginState |
var2 |
|
URL |
var22 |
|
PluginClassLoader |
var23 |
|
URI |
var26 |
|
Path |
var27 |
|
URL |
var28 |
|
URI |
var28 |
|
Boolean |
var29 |
|
|
var29 |
|
PluginManifest |
var3 |
|
PendingLoadPlugin |
var3 |
|
StringBuilder |
var3 |
|
PluginBase |
var3 |
|
String |
var3 |
|
Path |
var3 |
|
URI |
var3 |
|
|
var3 |
|
PluginBase |
var3 |
|
Path |
var3 |
|
String |
var3 |
|
PluginBase |
var3 |
|
PluginClassLoader |
var3 |
|
InputStreamReader |
var3 |
|
CompletableFuture |
var3 |
|
boolean |
var3 |
|
PluginClassLoader |
var3 |
|
ObjectArrayList |
var3 |
|
Iterator |
var30 |
|
List |
var31 |
|
ClassLoader |
var31 |
|
PendingLoadPlugin |
var33 |
|
URL |
var34 |
|
ObjectArrayList |
var35 |
|
InputStream |
var35 |
|
ObjectArrayList |
var36 |
|
InputStreamReader |
var36 |
|
boolean |
var37 |
|
char[] |
var37 |
|
RawJsonReader |
var38 |
|
StringBuilder |
var39 |
|
ExtraInfo |
var39 |
|
ModConfig |
var4 |
|
SemverRange |
var4 |
|
PluginManifest |
var4 |
|
|
var4 |
|
ClassLoader |
var4 |
|
|
var4 |
|
HashSet |
var4 |
|
AssetModule |
var4 |
|
AssetPack |
var4 |
|
ArrayList |
var4 |
|
HashSet |
var4 |
|
char[] |
var4 |
|
boolean |
var4 |
|
AssetModule |
var4 |
|
String |
var4 |
|
Class |
var4 |
|
ObjectArrayList |
var4 |
|
PluginClassLoader |
var4 |
|
boolean |
var40 |
|
|
var40 |
|
PluginManifest[] |
var40 |
|
ObjectListIterator |
var42 |
|
Message |
var43 |
|
boolean |
var44 |
|
|
var44 |
|
PluginIdentifier |
var45 |
|
StringBuilder |
var47 |
|
int |
var49 |
|
boolean |
var5 |
|
|
var5 |
|
|
var5 |
|
PluginBase |
var5 |
|
Throwable |
var5 |
|
PluginManifest.ServerVersionCheck |
var5 |
|
InputStream |
var5 |
|
ArrayList |
var5 |
|
InputStream |
var5 |
|
String |
var5 |
|
RawJsonReader |
var5 |
|
IEventDispatcher |
var5 |
|
Message |
var5 |
|
PluginBase |
var5 |
|
URL |
var5 |
|
Message |
var50 |
|
HytaleServerConfig |
var6 |
|
PluginClassLoader |
var6 |
|
PluginIdentifier |
var6 |
|
String |
var6 |
|
PluginIdentifier |
var6 |
|
InputStreamReader |
var6 |
|
URL |
var6 |
|
InputStreamReader |
var6 |
|
PluginManifest |
var6 |
|
ExtraInfo |
var6 |
|
Class |
var6 |
|
PluginBase |
var6 |
|
URL |
var6 |
|
URL |
var6 |
|
PluginClassLoader |
var7 |
|
ModConfig |
var7 |
|
PluginManifest |
var7 |
|
|
var7 |
|
|
var7 |
|
char[] |
var7 |
|
URLConnection |
var7 |
|
char[] |
var7 |
|
boolean |
var7 |
|
InputStream |
var7 |
|
PendingLoadJavaPlugin |
var7 |
|
PluginManifest |
var7 |
|
PluginBase |
var7 |
|
Class |
var7 |
|
URL |
var7 |
|
URL |
var7 |
|
PluginBase |
var8 |
|
SemverRange |
var8 |
|
PendingLoadPlugin |
var8 |
|
PendingLoadJavaPlugin |
var8 |
|
RawJsonReader |
var8 |
|
InputStream |
var8 |
|
RawJsonReader |
var8 |
|
InputStreamReader |
var8 |
|
URL |
var8 |
|
CompletableFuture |
var9 |
|
StringBuilder |
var9 |
|
|
var9 |
|
ExtraInfo |
var9 |
|
InputStreamReader |
var9 |
|
ExtraInfo |
var9 |
|
char[] |
var9 |
Методы (119)
| Модификаторы | Возврат | Сигнатура |
|---|---|---|
abstract |
throw new |
ClassNotFoundExceptionthrow new ClassNotFoundException() |
public |
record |
ClasspathAssetPackrecord ClasspathAssetPack(@Nonnull Path path, @Nonnull PluginManifest manifest) |
abstract |
throw new |
IllegalStateExceptionthrow new IllegalStateException("Expected PluginState.NONE but found " + this.state) |
abstract |
throw new |
IllegalStateExceptionthrow new IllegalStateException("Expected PluginState.SETUP but found " + this.state) |
abstract |
throw new |
IllegalStateExceptionthrow new IllegalStateException("unreachable") |
abstract |
return new |
PendingLoadJavaPluginreturn new PendingLoadJavaPlugin(var1, var4, var23) |
|
public |
PluginBridgeClassLoaderpublic PluginBridgeClassLoader(PluginManager var1, ClassLoader var2) |
private |
boolean |
canLoadOnBootboolean canLoadOnBoot(@Nonnull PendingLoadPlugin var1) |
private |
int |
collectFailedPluginsint collectFailedPlugins(StringBuilder var1) |
private |
boolean |
dependenciesMatchStateboolean dependenciesMatchState(PluginBase var1, PluginState var2, PluginState var3) |
private |
boolean |
failedToLoadboolean failedToLoad(@Nonnull PendingLoadPlugin var1, @Nonnull List<PluginIdentifier> var2) |
private |
boolean |
findAndLoadPluginboolean findAndLoadPlugin(PluginIdentifier var1) |
|
|
for for(PluginIdentifier var5 : this.outdatedPlugins) |
|
|
for for(PendingLoadPlugin var4 : this.loadOrder) |
|
|
for for(PendingLoadPlugin var41 : this.loadOrder) |
|
|
for for(PendingLoadPlugin var48 : this.loadOrder) |
|
|
for for(PendingLoadPlugin var4 : this.loadOrder) |
|
|
for for(Path var7 : var5) |
|
|
for for(URL var6 : var3) |
|
|
for for(PluginManifest var17 : var10) |
|
|
for for(PendingLoadPlugin var3 : this.corePlugins) |
|
|
for for(PluginManifest var44 : var40) |
|
|
for for(Path var5 : var3) |
abstract |
|
for for(int var2 = 0; var2 < this.corePlugins.size() |
static |
PluginManager |
getPluginManager get() |
|
public URL |
getResource0public URL getResource0(@Nonnull String var1, @Nullable PluginClassLoader var2) |
|
public URL |
getResource0public URL getResource0(@Nonnull String var1, @Nullable PluginClassLoader var2, @Nonnull PluginManifest var3) |
|
public Enumeration<URL> |
getResources0public Enumeration<URL> getResources0(@Nonnull String var1, @Nullable PluginClassLoader var2) |
|
public Enumeration<URL> |
getResources0public Enumeration<URL> getResources0(@Nonnull String var1, @Nullable PluginClassLoader var2, @Nonnull PluginManifest var3) |
public |
ComponentType<EntityStore, PluginListPageManager.SessionSettings> |
getSessionSettingsComponentTypeComponentType<EntityStore, PluginListPageManager.SessionSettings> getSessionSettingsComponentType() |
public |
boolean |
hasPluginboolean hasPlugin(PluginIdentifier var1, @Nonnull SemverRange var2) |
|
|
if if(var5) |
|
|
if if(this.state != PluginState.NONE) |
|
|
if if(var2 != null) |
|
|
if if(var9 != null) |
|
|
if if(this.state != PluginState.SETUP) |
|
|
if if(this.loading == null) |
|
|
if if(var5 != PluginManifest.ServerVersionCheck.COMPATIBLE) |
|
|
if if(var2 != null) |
|
|
if if(var8 != null) |
|
|
if if(var7 == null) |
|
|
if if(var11 != null) |
|
|
if if(var7 == null) |
|
|
if if(var3) |
|
|
if if(var8 != null) |
|
|
if if(var4 == null) |
|
|
if if(var6 == null) |
|
|
if if(var13 == null) |
|
|
if if(var7 instanceof JarURLConnection var15) |
|
|
if if(var3 == null) |
|
|
if if(var4 == null) |
|
|
if if(var2 != null) |
|
|
if if(var4 != null) |
|
|
if if(var3 instanceof JavaPlugin var10) |
|
|
if if(var2 == null) |
|
|
if if(var3 != null) |
|
|
if if(var2 != null) |
|
|
if if(var34 != null) |
|
|
if if(var29 != null) |
|
|
if if(var29 != null) |
|
|
if if(var7 == null) |
|
|
if if(var1 == null) |
|
|
if if(var3 == null) |
|
|
if if(var4 != null) |
|
|
if if(var6 != null) |
|
|
if if(var7 != null) |
|
|
if if(var16 != null) |
|
|
if if(var18 != null) |
|
|
if if(var19 != null) |
|
|
if if(var3 != var1) |
|
|
if if(var4 != null) |
|
|
if if(var5 != null) |
|
|
if if(var6 != null) |
|
|
if if(var16 != null) |
|
|
if if(var7 != null) |
|
|
if if(var17 != null) |
|
|
if if(var6 != null) |
|
|
if if(var7 != null) |
|
|
if if(var16 != null) |
|
|
if if(var8 != null) |
|
|
if if(var17 != null) |
|
|
if if(var2 instanceof JavaPlugin var3) |
static |
boolean |
isCorePluginboolean isCorePlugin(@Nonnull PendingLoadPlugin var0) |
abstract |
return |
isCorePluginreturn isCorePlugin(var1) |
public |
boolean |
loadboolean load(@Nonnull PluginIdentifier var1) |
private |
boolean |
loadboolean load(@Nullable PendingLoadPlugin var1) |
private |
void |
loadClasspathPluginsFromBundlevoid loadClasspathPluginsFromBundle(@Nonnull Map<PluginIdentifier, PendingLoadPlugin> var1, @Nonnull Map<PluginIdentifier, PluginManifest> var2, @Nonnull URL var3, @Nonnull URI var4) |
private |
boolean |
loadClasspathPluginsFromManifestsboolean loadClasspathPluginsFromManifests(@Nonnull Map<PluginIdentifier, PendingLoadPlugin> var1, @Nonnull Map<PluginIdentifier, PluginManifest> var2, @Nonnull List<URL> var3) |
static |
void |
loadPendingPluginvoid loadPendingPlugin(@Nonnull Map<PluginIdentifier, PendingLoadPlugin> var0, @Nonnull PendingLoadPlugin var1) |
abstract |
|
loadPendingPlugin loadPendingPlugin(var1, var3) |
abstract |
|
loadPendingPlugin loadPendingPlugin(var1, var8) |
abstract |
|
loadPendingPlugin loadPendingPlugin(var1, var14) |
abstract |
|
loadPendingPlugin loadPendingPlugin(var1, var18) |
abstract |
|
loadPendingPlugin loadPendingPlugin(var0, var3) |
private |
void |
loadPluginsFromDirectoryvoid loadPluginsFromDirectory(@Nonnull Map<PluginIdentifier, PendingLoadPlugin> var1, @Nonnull Path var2, boolean var3, @Nonnull Map<PluginIdentifier, PluginManifest> var4) |
private |
void |
loadPluginsInClasspathvoid loadPluginsInClasspath(@Nonnull Map<PluginIdentifier, PendingLoadPlugin> var1, @Nonnull Map<PluginIdentifier, PluginManifest> var2) |
abstract |
|
registerAsParallelCapable registerAsParallelCapable() |
private |
boolean |
registerAssetPackIfNeededboolean registerAssetPackIfNeeded(@Nonnull PendingLoadPlugin var1) |
public |
void |
registerCorePluginvoid registerCorePlugin(@Nonnull PluginManifest var1) |
protected |
void |
releasePluginClassLoadervoid releasePluginClassLoader(JavaPlugin var1) |
public |
boolean |
reloadboolean reload(@Nonnull PluginIdentifier var1) |
public |
void |
setupvoid setup() |
private |
boolean |
setupboolean setup(@Nonnull PluginBase var1) |
public |
void |
shutdownvoid shutdown() |
public |
void |
startvoid start() |
private |
boolean |
startboolean start(@Nonnull PluginBase var1) |
abstract |
|
super super(var2) |
|
|
switch switch(var5) |
abstract |
|
try try(InputStream var5 = Files.newInputStream(var3) |
abstract |
|
try try(InputStream var8 = var7.getInputStream() |
abstract |
|
try try(InputStream var5 = var3.openStream() |
abstract |
|
try try(InputStream var7 = var6.openStream() |
abstract |
|
try try(InputStream var35 = var34.openStream() |
|
private static URL |
tryGetResourceprivate static URL tryGetResource(@Nonnull String var0, @Nullable PluginClassLoader var1, @Nullable PluginBase var2) |
public |
boolean |
unloadboolean unload(@Nonnull PluginIdentifier var1) |
private |
boolean |
unloadboolean unload(@Nonnull PluginIdentifier var1, @Nonnull Set<PluginIdentifier> var2) |
private |
void |
unregisterAssetPackIfNeededvoid unregisterAssetPackIfNeeded(@Nonnull JavaPlugin var1) |
private |
void |
validatePluginDepsvoid validatePluginDeps(@Nonnull PendingLoadPlugin var1, @Nullable Map<PluginIdentifier, PendingLoadPlugin> var2) |
static |
Throwable |
wrapIfThirdPartyThrowable wrapIfThirdParty(@Nonnull PendingLoadPlugin var0, @Nonnull Throwable var1) |
Исходный код
Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.plugin;
class="kw">import com.hypixel.hytale.assetstore.AssetPack;
class="kw">import com.hypixel.hytale.assetstore.AssetRegistry;
class="kw">import com.hypixel.hytale.assetstore.AssetStore;
class="kw">import com.hypixel.hytale.codec.ExtraInfo;
class="kw">import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
class="kw">import com.hypixel.hytale.codec.exception.CodecException;
class="kw">import com.hypixel.hytale.codec.util.RawJsonReader;
class="kw">import com.hypixel.hytale.common.plugin.Mod;
class="kw">import com.hypixel.hytale.common.plugin.ModLoadOrderException;
class="kw">import com.hypixel.hytale.common.plugin.PluginIdentifier;
class="kw">import com.hypixel.hytale.common.plugin.PluginManifest;
class="kw">import com.hypixel.hytale.common.semver.SemverRange;
class="kw">import com.hypixel.hytale.common.util.java.ManifestUtil;
class="kw">import com.hypixel.hytale.component.ComponentType;
class="kw">import com.hypixel.hytale.event.IEventDispatcher;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.logger.sentry.SkipSentryException;
class="kw">import com.hypixel.hytale.metrics.MetricsRegistry;
class="kw">import com.hypixel.hytale.server.core.HytaleServer;
class="kw">import com.hypixel.hytale.server.core.HytaleServerConfig;
class="kw">import com.hypixel.hytale.server.core.Message;
class="kw">import com.hypixel.hytale.server.core.Options;
class="kw">import com.hypixel.hytale.server.core.ShutdownReason;
class="kw">import com.hypixel.hytale.server.core.asset.AssetModule;
class="kw">import com.hypixel.hytale.server.core.command.system.CommandManager;
class="kw">import com.hypixel.hytale.server.core.config.ModConfig;
class="kw">import com.hypixel.hytale.server.core.event.events.player.AddPlayerToWorldEvent;
class="kw">import com.hypixel.hytale.server.core.permissions.HytalePermissions;
class="kw">import com.hypixel.hytale.server.core.plugin.commands.PluginCommand;
class="kw">import com.hypixel.hytale.server.core.plugin.event.PluginSetupEvent;
class="kw">import com.hypixel.hytale.server.core.plugin.pending.PendingLoadJavaPlugin;
class="kw">import com.hypixel.hytale.server.core.plugin.pending.PendingLoadPlugin;
class="kw">import com.hypixel.hytale.server.core.universe.PlayerRef;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectListIterator;
class="kw">import java.awt.Color;
class="kw">import java.io.IOException;
class="kw">import java.io.InputStream;
class="kw">import java.io.InputStreamReader;
class="kw">import java.net.JarURLConnection;
class="kw">import java.net.MalformedURLException;
class="kw">import java.net.URI;
class="kw">import java.net.URISyntaxException;
class="kw">import java.net.URL;
class="kw">import java.net.URLClassLoader;
class="kw">import java.net.URLConnection;
class="kw">import java.nio.charset.StandardCharsets;
class="kw">import java.nio.file.DirectoryStream;
class="kw">import java.nio.file.FileSystem;
class="kw">import java.nio.file.FileSystems;
class="kw">import java.nio.file.Files;
class="kw">import java.nio.file.Path;
class="kw">import java.nio.file.Paths;
class="kw">import java.util.ArrayList;
class="kw">import java.util.Collections;
class="kw">import java.util.Enumeration;
class="kw">import java.util.HashMap;
class="kw">import java.util.HashSet;
class="kw">import java.util.Iterator;
class="kw">import java.util.List;
class="kw">import java.util.Locale;
class="kw">import java.util.Map;
class="kw">import java.util.Set;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.ConcurrentHashMap;
class="kw">import java.util.concurrent.CopyOnWriteArrayList;
class="kw">import java.util.concurrent.locks.ReentrantReadWriteLock;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">public class PluginManager {
@Nonnull
class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
@Nonnull
class="kw">public class="kw">static class="kw">final Path MODS_PATH = Path.of("mods");
@Nonnull
class="kw">public class="kw">static class="kw">final MetricsRegistry<PluginManager> METRICS_REGISTRY = new MetricsRegistry<PluginManager>()
.register("Plugins", var0 -> var0.getPlugins().toArray(PluginBase[]::new), new ArrayCodec<>(PluginBase.METRICS_REGISTRY, PluginBase[]::new));
class="kw">private class="kw">static PluginManager instance;
@Nonnull
class="kw">private class="kw">final PluginClassLoader corePluginClassLoader = new PluginClassLoader(this, null, true);
@Nonnull
class="kw">private class="kw">final List<PendingLoadPlugin> corePlugins = new ObjectArrayList();
class="kw">private class="kw">final PluginManager.PluginBridgeClassLoader bridgeClassLoader = new PluginManager.PluginBridgeClassLoader(this, PluginManager.class.getClassLoader());
class="kw">private class="kw">final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
class="kw">private class="kw">final Map<PluginIdentifier, PluginBase> plugins = new Object2ObjectLinkedOpenHashMap();
class="kw">private class="kw">final Map<Path, PluginClassLoader> classLoaders = new ConcurrentHashMap<>();
class="kw">private class="kw">final List<PluginIdentifier> outdatedPlugins = new ArrayList<>();
class="kw">private class="kw">final List<PluginManager.ClasspathAssetPack> classpathAssetPacks = new CopyOnWriteArrayList<>();
class="kw">private class="kw">final boolean loadExternalPlugins = true;
@Nonnull
class="kw">private PluginState state = PluginState.NONE;
@Nullable
class="kw">private List<PendingLoadPlugin> loadOrder;
@Nullable
class="kw">private Map<PluginIdentifier, PluginBase> loading;
@Nonnull
class="kw">private class="kw">final Map<PluginIdentifier, PluginManifest> availablePlugins = new Object2ObjectLinkedOpenHashMap();
class="kw">public PluginListPageManager pluginListPageManager;
class="kw">private ComponentType<EntityStore, PluginListPageManager.SessionSettings> sessionSettingsComponentType;
class="kw">public class="kw">static PluginManager get() {
class="kw">return instance;
}
class="kw">public PluginManager() {
instance = this;
this.pluginListPageManager = new PluginListPageManager();
}
class="kw">public void registerCorePlugin(@Nonnull PluginManifest var1) {
this.corePlugins.add(new PendingLoadJavaPlugin(null, var1, this.corePluginClassLoader));
}
class="kw">private boolean canLoadOnBoot(@Nonnull PendingLoadPlugin var1) {
PluginIdentifier var2 = var1.getIdentifier();
PluginManifest var3 = var1.getManifest();
ModConfig var4 = HytaleServer.get().getConfig().getModConfig().get(var2);
boolean var5;
if (var4 != null && var4.getEnabled() != null) {
var5 = var4.getEnabled();
} else {
HytaleServerConfig var6 = HytaleServer.get().getConfig();
var5 = !var3.isDisabledByDefault() && (var1.isCoreMod() || var6.getDefaultModsEnabled());
}
if (var5) {
class="kw">return true;
}
LOGGER.at(Level.WARNING).log("Skipping mod %s (Disabled by server config)", var2);
class="kw">return false;
}
class="kw">public void setup() class="kw">throws ModLoadOrderException {
if (this.state != PluginState.NONE) {
throw new IllegalStateException("Expected PluginState.NONE but found " + this.state);
}
this.state = PluginState.SETUP;
CommandManager.get().registerSystemCommand(new PluginCommand());
this.sessionSettingsComponentType = EntityStore.REGISTRY
.registerComponent(PluginListPageManager.SessionSettings.class, PluginListPageManager.SessionSettings::new);
HashMap var1 = new HashMap<>();
this.availablePlugins.clear();
LOGGER.at(Level.INFO).log("Loading pending core plugins!");
for (int var2 = 0; var2 < this.corePlugins.size(); var2++) {
PendingLoadPlugin var3 = this.corePlugins.get(var2);
LOGGER.at(Level.INFO).log("- %s", var3.getIdentifier());
if (this.canLoadOnBoot(var3)) {
loadPendingPlugin(var1, var3);
} else {
this.availablePlugins.put(var3.getIdentifier(), var3.getManifest());
}
}
if (!Options.getOptionSet().has(Options.BOOTSTRAP)) {
this.loadPluginsInClasspath(var1, this.availablePlugins);
this.loadPluginsFromDirectory(var1, MODS_PATH, !Options.isBare(), this.availablePlugins);
for (Path var32 : Options.getOptionSet().valuesOf(Options.MODS_DIRECTORIES)) {
this.loadPluginsFromDirectory(var1, var32, false, this.availablePlugins);
}
}
this.lock.readLock().lock();
try {
this.plugins.keySet().forEach(var1x -> {
var1.remove(var1x);
LOGGER.at(Level.WARNING).log("Skipping loading of %s because it is already loaded!", var1x);
});
Iterator var30 = var1.values().iterator();
while (var30.hasNext()) {
PendingLoadPlugin var33 = var30.next();
try {
this.validatePluginDeps(var33, var1);
} catch (MissingPluginDependencyException var26) {
LOGGER.at(Level.SEVERE).log("%s", var26.getMessage());
var30.remove();
}
}
} class="kw">finally {
this.lock.readLock().unlock();
}
if (!this.outdatedPlugins.isEmpty() && System.getProperty("hytale.allow_outdated_mods") == null) {
LOGGER.at(Level.SEVERE)
.log("One or more plugins are targeting a different server version. It is recommended to update these plugins to ensure compatibility.");
HytaleServer.get()
.getEventBus()
.registerGlobal(
AddPlayerToWorldEvent.class,
var1x -> {
PlayerRef var2 = var1x.getHolder().getComponent(PlayerRef.getComponentType());
if (var2 != null) {
if (var2.hasPermission(HytalePermissions.MODS_OUTDATED_NOTIFY)) {
StringBuilder var3 = new StringBuilder();
for (PluginIdentifier var5 : this.outdatedPlugins) {
var3.append("\n - ").append(var5);
}
var2.sendMessage(
Message.translation("server.pluginManager.outOfDatePlugins")
.param("count", this.outdatedPlugins.size())
.param("mods", var3.toString())
.color(Color.RED)
);
}
}
}
);
}
List var31 = List.of(HytaleServer.get().getConfig().getModLoadOrder());
this.loadOrder = Mod.calculateLoadOrder(var1, (var0, var1x) -> {
AssetPack var2 = AssetModule.get().getAssetPack(var0.toString());
class="kw">return var2 != null && var2.getManifest().getVersion().satisfies(var1x);
}, var31);
for (PendingLoadPlugin var4 : this.loadOrder) {
if (var4 class="kw">instanceof PendingLoadJavaPlugin var5 && var5.isCoreMod() && !isCorePlugin(var5)) {
PluginClassLoader var6 = var5.getClassLoader();
PluginClassLoader var7 = new PluginClassLoader(this, var5.getIdentifier(), true, true, var6.getURLs());
var5.setClassLoader(var7);
LOGGER.at(Level.FINE).log("Using child-first classloader for classpath plugin %s", var5.getIdentifier());
}
}
this.loading = new Object2ObjectOpenHashMap();
var1.forEach((var1x, var2x) -> this.availablePlugins.put(var1x, var2x.getManifest()));
ObjectArrayList var35 = new ObjectArrayList();
ObjectArrayList var36 = new ObjectArrayList();
boolean var37 = false;
this.lock.writeLock().lock();
try {
LOGGER.at(Level.FINE).log("Loading plugins!");
for (PendingLoadPlugin var41 : this.loadOrder) {
LOGGER.at(Level.FINE).log("- %s", var41.getIdentifier());
try {
PluginBase var8 = var41.load();
this.plugins.put(var8.getIdentifier(), var8);
this.loading.put(var8.getIdentifier(), var8);
CompletableFuture var9 = var8.preLoad();
if (var9 != null) {
var35.add(var9);
}
} catch (ClassNotFoundException var23) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(wrapIfThirdParty(var41, var23)))
.log("Failed to load plugin %s. Failed to find main class!", var41.getPath());
var37 |= this.failedToLoad(var41, var36);
} catch (NoSuchMethodException var24) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(wrapIfThirdParty(var41, var24)))
.log("Failed to load plugin %s. Requires class="kw">default constructor!", var41.getPath());
var37 |= this.failedToLoad(var41, var36);
} catch (Throwable var25) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(wrapIfThirdParty(var41, var25))).log("Failed to load plugin %s", var41.getPath());
var37 |= this.failedToLoad(var41, var36);
}
}
} class="kw">finally {
this.lock.writeLock().unlock();
}
if (var36.isEmpty() || !var37 && Options.getOptionSet().has(Options.IGNORE_BROKEN_MODS)) {
CompletableFuture.allOf((CompletableFuture<?>[])var35.toArray(CompletableFuture[]::new)).join();
boolean var40 = false;
boolean var44 = false;
for (PendingLoadPlugin var48 : this.loadOrder) {
if (HytaleServer.get().isShuttingDown()) {
break;
}
PluginBase var10 = this.loading.get(var48.getIdentifier());
if (var10 != null && !this.setup(var10)) {
var40 = true;
if (isCorePlugin(var48)) {
var44 = true;
}
}
}
if (var40 && (var44 || !Options.getOptionSet().has(Options.IGNORE_BROKEN_MODS))) {
StringBuilder var47 = new StringBuilder();
int var49 = this.collectFailedPlugins(var47);
Message var50 = Message.translation("client.disconnection.shutdownReason.pluginError.detail")
.param("count", var49)
.param("detail", var47.toString().trim());
HytaleServer.get().shutdownServer(ShutdownReason.MOD_ERROR.withMessage(var50));
} else {
this.loading.values().removeIf(var0 -> var0.getState().isInactive());
}
} else {
StringBuilder var39 = new StringBuilder();
ObjectListIterator var42 = var36.iterator();
while (var42.hasNext()) {
PluginIdentifier var45 = (PluginIdentifier)var42.next();
var39.append(" - ").append(var45).append('\n');
}
Message var43 = Message.translation("client.disconnection.shutdownReason.pluginError.detail")
.param("count", var36.size())
.param("detail", var39.toString().trim());
HytaleServer.get().shutdownServer(ShutdownReason.MOD_ERROR.withMessage(var43));
}
}
class="kw">public void start() {
if (this.state != PluginState.SETUP) {
throw new IllegalStateException("Expected PluginState.SETUP but found " + this.state);
}
this.state = PluginState.START;
boolean var1 = false;
boolean var2 = false;
for (PendingLoadPlugin var4 : this.loadOrder) {
if (HytaleServer.get().isShuttingDown()) {
break;
}
PluginBase var5 = this.loading.get(var4.getIdentifier());
if (var5 != null && !this.start(var5)) {
var1 = true;
if (isCorePlugin(var4)) {
var2 = true;
}
}
}
StringBuilder var9 = new StringBuilder();
for (Entry var14 : HytaleServer.get().getConfig().getModConfig().entrySet()) {
PluginIdentifier var6 = var14.getKey();
ModConfig var7 = var14.getValue();
SemverRange var8 = var7.getRequiredVersion();
if (var8 != null && !this.hasPlugin(var6, var8)) {
var9.append(String.format("%s, Version: %s\n", var6, var7));
}
}
if (!var9.isEmpty()) {
String var13 = "Failed to start server! Missing Mods:\n" + var9;
LOGGER.at(Level.SEVERE).log("%s", var13);
Message var16 = Message.translation("client.disconnection.shutdownReason.missingRequiredPlugin.detail").param("detail", var9.toString());
HytaleServer.get().shutdownServer(ShutdownReason.MISSING_REQUIRED_PLUGIN.withMessage(var16));
} else if (var1 && (var2 || !Options.getOptionSet().has(Options.IGNORE_BROKEN_MODS))) {
var9 = new StringBuilder();
int var12 = this.collectFailedPlugins(var9);
Message var15 = Message.translation("client.disconnection.shutdownReason.pluginError.detail")
.param("count", var12)
.param("detail", var9.toString().trim());
HytaleServer.get().shutdownServer(ShutdownReason.MOD_ERROR.withMessage(var15));
} else {
this.loadOrder = null;
this.loading = null;
}
}
class="kw">private boolean failedToLoad(@Nonnull PendingLoadPlugin var1, @Nonnull List<PluginIdentifier> var2) {
var2.add(var1.getIdentifier());
this.plugins.remove(var1.getIdentifier());
this.loading.remove(var1.getIdentifier());
class="kw">return isCorePlugin(var1);
}
class="kw">private class="kw">static boolean isCorePlugin(@Nonnull PendingLoadPlugin var0) {
class="kw">return var0.isCoreMod() && "Hytale".equals(var0.getIdentifier().getGroup());
}
class="kw">private int collectFailedPlugins(StringBuilder var1) {
int var2 = 0;
if (this.loading == null) {
class="kw">return var2;
}
for (Entry var4 : this.loading.entrySet()) {
if (var4.getValue().getState() == PluginState.FAILED) {
Throwable var5 = var4.getValue().getFailureCause();
String var6 = var5 != null ? var5.toString() : "Unknown";
var1.append(" - ").append(var4.getKey()).append(": ").append(var6).append('\n');
var2++;
}
}
class="kw">return var2;
}
class="kw">public void shutdown() {
this.state = PluginState.SHUTDOWN;
LOGGER.at(Level.INFO).log("Saving plugins config...");
this.lock.writeLock().lock();
try {
List var1 = new ObjectArrayList(this.plugins.values());
for (int var2 = var1.size() - 1; var2 >= 0; var2--) {
PluginBase var3 = var1.get(var2);
if (var3.getState() == PluginState.ENABLED) {
LOGGER.at(Level.FINE).log("Shutting down %s %s", var3.getType().getDisplayName(), var3.getIdentifier());
var3.shutdown0(true);
HytaleServer.get().doneStop(var3);
LOGGER.at(Level.INFO).log("Shut down plugin %s", var3.getIdentifier());
}
}
this.plugins.clear();
} class="kw">finally {
this.lock.writeLock().unlock();
}
}
@Nonnull
class="kw">public PluginState getState() {
class="kw">return this.state;
}
@Nonnull
class="kw">public PluginManager.PluginBridgeClassLoader getBridgeClassLoader() {
class="kw">return this.bridgeClassLoader;
}
class="kw">private void validatePluginDeps(@Nonnull PendingLoadPlugin var1, @Nullable Map<PluginIdentifier, PendingLoadPlugin> var2) {
String var3 = ManifestUtil.getVersion();
if (!var1.getManifest().getGroup().equals("Hytale")) {
SemverRange var4 = var1.getManifest().getServerVersion();
PluginManifest.ServerVersionCheck var5 = PluginManifest.checkServerVersionCompatibility(var4, var3);
if (var5 != PluginManifest.ServerVersionCheck.COMPATIBLE) {
class="kw">switch (var5) {
case MISSING:
LOGGER.at(Level.WARNING)
.log(
"Plugin '%s' does not specify a target server version. You may encounter issues, please check for plugin updates. This will be a hard error in the future",
var1.getIdentifier()
);
break;
case PARSE_FAILED:
LOGGER.at(Level.WARNING)
.log(
"Plugin '%s' targets server version range '%s' but the running server version '%s' could not be parsed.",
var1.getIdentifier(),
var4,
var3
);
break;
case INCOMPATIBLE:
LOGGER.at(Level.WARNING)
.log(
"Plugin '%s' targets server version range '%s' which does not match the running server version '%s'. You may encounter issues, please check for plugin updates.",
var1.getIdentifier(),
var4,
var3
);
break;
case COMPATIBLE:
throw new IllegalStateException("unreachable");
}
this.outdatedPlugins.add(var1.getIdentifier());
}
}
for (Entry var10 : var1.getManifest().getDependencies().entrySet()) {
PluginIdentifier var6 = var10.getKey();
PluginManifest var7 = null;
if (var2 != null) {
PendingLoadPlugin var8 = var2.get(var6);
if (var8 != null) {
var7 = var8.getManifest();
}
}
if (var7 == null) {
PluginBase var11 = this.plugins.get(var6);
if (var11 != null) {
var7 = var11.getManifest();
}
}
if (var7 == null) {
throw new MissingPluginDependencyException(
String.format("Failed to load '%s' because the dependency '%s' could not be found!", var1.getIdentifier(), var6)
);
}
SemverRange var12 = var10.getValue();
if (!var7.getVersion().satisfies(var12)) {
throw new MissingPluginDependencyException(
String.format(
"Failed to load '%s' because version of dependency '%s'(%s) does not satisfy '%s'!", var1.getIdentifier(), var6, var7.getVersion(), var12
)
);
}
}
}
class="kw">private void loadPluginsFromDirectory(
@Nonnull Map<PluginIdentifier, PendingLoadPlugin> var1, @Nonnull Path var2, boolean var3, @Nonnull Map<PluginIdentifier, PluginManifest> var4
) {
if (!Files.isDirectory(var2)) {
if (var3) {
try {
Files.createDirectories(var2);
} catch (IOException var9) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var9)).log("Failed to create directory: %s", var2);
}
}
} else {
LOGGER.at(Level.INFO).log("Loading pending plugins from directory: %s", var2);
try (DirectoryStream var5 = Files.newDirectoryStream(var2)) {
for (Path var7 : var5) {
if (Files.isRegularFile(var7) && var7.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".jar")) {
PendingLoadJavaPlugin var8 = this.loadPendingJavaPlugin(var7);
if (var8 != null) {
assert var8.getPath() != null;
LOGGER.at(Level.INFO).log("- %s from path %s", var8.getIdentifier(), var2.relativize(var8.getPath()));
if (this.canLoadOnBoot(var8)) {
loadPendingPlugin(var1, var8);
} else {
var4.put(var8.getIdentifier(), var8.getManifest());
}
}
}
}
} catch (IOException var12) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var12)).log("Failed to find pending plugins from: %s", var2);
}
}
}
@Nullable
class="kw">private PendingLoadJavaPlugin loadPendingJavaPlugin(@Nonnull Path var1) {
try (FileSystem var2 = FileSystems.newFileSystem(var1)) {
Path var3 = var2.getPath("manifest.json");
if (!Files.exists(var3)) {
LOGGER.at(Level.SEVERE).log("Failed to load pending plugin from '%s'. Failed to load manifest file!", var1.toString());
class="kw">return null;
}
PluginManifest var4;
try (
InputStream var5 = Files.newInputStream(var3);
InputStreamReader var6 = new InputStreamReader(var5, StandardCharsets.UTF_8);
) {
char[] var7 = RawJsonReader.READ_BUFFER.get();
RawJsonReader var8 = new RawJsonReader(var6, var7);
ExtraInfo var9 = ExtraInfo.THREAD_LOCAL.get();
try {
var4 = PluginManifest.CODEC.decodeJson(var8, var9);
} catch (CodecException var15) {
((HytaleLogger.Api)LOGGER.at(Level.WARNING).withCause(new SkipSentryException(var15))).log("Failed to load manifest for plugin at %s", var1);
class="kw">return null;
}
if (var4 == null) {
LOGGER.at(Level.SEVERE).log("Failed to load pending plugin from '%s'. Failed to decode manifest file!", var1.toString());
class="kw">return null;
}
var9.getValidationResults().logOrThrowValidatorExceptions(LOGGER);
}
URL var22 = var1.toUri().toURL();
PluginClassLoader var23 = this.classLoaders.computeIfAbsent(var1, var3x -> new PluginClassLoader(this, new PluginIdentifier(var4), false, var22));
class="kw">return new PendingLoadJavaPlugin(var1, var4, var23);
} catch (MalformedURLException var19) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var19))
.log("Failed to load pending plugin from '%s'. Failed to create URLClassLoader!", var1.toString());
} catch (IOException var20) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var20)).log("Failed to load pending plugin %s. Failed to load manifest file!", var1.toString());
}
class="kw">return null;
}
class="kw">private void loadPluginsInClasspath(@Nonnull Map<PluginIdentifier, PendingLoadPlugin> var1, @Nonnull Map<PluginIdentifier, PluginManifest> var2) {
LOGGER.at(Level.INFO).log("Loading pending classpath plugins!");
URI var3;
ClassLoader var4;
try {
var3 = PluginManager.class.getProtectionDomain().getCodeSource().getLocation().toURI();
var4 = PluginManager.class.getClassLoader();
} catch (URISyntaxException var9) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var9)).log("Failed to get jar path!");
class="kw">return;
}
try {
ArrayList var5 = Collections.list(var4.getResources("manifest.json"));
if (!this.loadClasspathPluginsFromManifests(var1, var2, var5)) {
class="kw">return;
}
URL var6 = var4.getResource("manifests.json");
if (var6 == null) {
class="kw">return;
}
this.loadClasspathPluginsFromBundle(var1, var2, var6, var3);
} catch (IOException var7) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var7))
.log("Failed to load pending classpath plugin from '%s'. Failed to load manifest file!", var3.toString());
} catch (URISyntaxException var8) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var8)).log("Failed to get jar path!");
}
}
class="kw">private boolean loadClasspathPluginsFromManifests(
@Nonnull Map<PluginIdentifier, PendingLoadPlugin> var1, @Nonnull Map<PluginIdentifier, PluginManifest> var2, @Nonnull List<URL> var3
) class="kw">throws IOException, URISyntaxException {
HashSet var4 = new HashSet<>();
for (URL var6 : var3) {
if (var4.add(var6.toExternalForm())) {
URLConnection var7 = var6.openConnection();
try (
InputStream var8 = var7.getInputStream();
InputStreamReader var9 = new InputStreamReader(var8, StandardCharsets.UTF_8);
) {
char[] var10 = RawJsonReader.READ_BUFFER.get();
RawJsonReader var11 = new RawJsonReader(var9, var10);
ExtraInfo var12 = ExtraInfo.THREAD_LOCAL.get();
PluginManifest var13;
try {
var13 = PluginManifest.CODEC.decodeJson(var11, var12);
} catch (CodecException var22) {
((HytaleLogger.Api)LOGGER.at(Level.WARNING).withCause(new SkipSentryException(var22))).log("Failed to load manifest for plugin at %s", var6);
class="kw">continue;
}
var12.getValidationResults().logOrThrowValidatorExceptions(LOGGER);
if (var13 == null) {
LOGGER.at(Level.SEVERE).log("Failed to load pending plugin from '%s'. Failed to decode manifest file!", var6);
class="kw">return false;
}
PendingLoadJavaPlugin var14;
if (var7 class="kw">instanceof JarURLConnection var15) {
URL var16 = var15.getJarFileURL();
Path var17 = Path.of(var16.toURI());
PluginClassLoader var18 = this.classLoaders
.computeIfAbsent(var17, var3x -> new PluginClassLoader(this, new PluginIdentifier(var13), true, var16));
var14 = new PendingLoadJavaPlugin(var17, var13, var18);
} else {
URI var26 = var6.toURI().resolve(".");
Path var27 = Paths.get(var26);
URL var28 = var26.toURL();
PluginClassLoader var19 = this.classLoaders
.computeIfAbsent(var27, var3x -> new PluginClassLoader(this, new PluginIdentifier(var13), true, var28));
var14 = new PendingLoadJavaPlugin(var27, var13, var19);
}
LOGGER.at(Level.INFO).log("- %s", var14.getIdentifier());
if (var13.includesAssetPack() && var14.getPath() != null) {
this.classpathAssetPacks.add(new PluginManager.ClasspathAssetPack(var14.getPath(), var13));
}
if (this.canLoadOnBoot(var14)) {
loadPendingPlugin(var1, var14);
} else {
var2.put(var14.getIdentifier(), var14.getManifest());
}
}
}
}
class="kw">return true;
}
class="kw">private void loadClasspathPluginsFromBundle(
@Nonnull Map<PluginIdentifier, PendingLoadPlugin> var1, @Nonnull Map<PluginIdentifier, PluginManifest> var2, @Nonnull URL var3, @Nonnull URI var4
) class="kw">throws IOException {
try (
InputStream var5 = var3.openStream();
InputStreamReader var6 = new InputStreamReader(var5, StandardCharsets.UTF_8);
) {
char[] var7 = RawJsonReader.READ_BUFFER.get();
RawJsonReader var8 = new RawJsonReader(var6, var7);
ExtraInfo var9 = ExtraInfo.THREAD_LOCAL.get();
PluginManifest[] var10;
try {
var10 = PluginManifest.ARRAY_CODEC.decodeJson(var8, var9);
} catch (CodecException var21) {
((HytaleLogger.Api)LOGGER.at(Level.WARNING).withCause(new SkipSentryException(var21))).log("Failed to load manifests bundle at %s", var3);
class="kw">return;
}
var9.getValidationResults().logOrThrowValidatorExceptions(LOGGER);
URL var11 = var4.toURL();
Path var12 = Paths.get(var4);
PluginClassLoader var13 = this.classLoaders.computeIfAbsent(var12, var2x -> new PluginClassLoader(this, null, true, var11));
for (PluginManifest var17 : var10) {
PendingLoadJavaPlugin var18 = new PendingLoadJavaPlugin(var12, var17, var13);
LOGGER.at(Level.INFO).log("- %s", var18.getIdentifier());
if (var17.includesAssetPack() && var12 != null) {
this.classpathAssetPacks.add(new PluginManager.ClasspathAssetPack(var12, var17));
}
if (this.canLoadOnBoot(var18)) {
loadPendingPlugin(var1, var18);
} else {
var2.put(var18.getIdentifier(), var18.getManifest());
}
}
}
}
@Nonnull
class="kw">public List<PluginBase> getPlugins() {
this.lock.readLock().lock();
try {
class="kw">return new ObjectArrayList(this.plugins.values());
} class="kw">finally {
this.lock.readLock().unlock();
}
}
@Nullable
class="kw">public PluginBase getPlugin(PluginIdentifier var1) {
this.lock.readLock().lock();
try {
class="kw">return this.plugins.get(var1);
} class="kw">finally {
this.lock.readLock().unlock();
}
}
@Nullable
class="kw">public <T class="kw">extends PluginBase> T getPlugin(@Nonnull Class<T> var1) {
this.lock.readLock().lock();
try {
for (PluginBase var3 : this.plugins.values()) {
if (var1.isInstance(var3)) {
class="kw">return var1.cast(var3);
}
}
class="kw">return null;
} class="kw">finally {
this.lock.readLock().unlock();
}
}
class="kw">public boolean hasPlugin(PluginIdentifier var1, @Nonnull SemverRange var2) {
PluginBase var3 = this.getPlugin(var1);
class="kw">return var3 != null && var3.getManifest().getVersion().satisfies(var2);
}
@Nonnull
class="kw">public List<PluginManager.ClasspathAssetPack> consumeClasspathAssetPacks() {
List var1 = List.copyOf(this.classpathAssetPacks);
this.classpathAssetPacks.clear();
class="kw">return var1;
}
class="kw">private boolean registerAssetPackIfNeeded(@Nonnull PendingLoadPlugin var1) {
PluginManifest var2 = var1.getManifest();
if (!var2.includesAssetPack()) {
class="kw">return true;
}
Path var3 = var1.getPath();
if (var3 == null) {
class="kw">return true;
}
AssetModule var4 = AssetModule.get();
if (var4 == null) {
class="kw">return true;
}
String var5 = new PluginIdentifier(var2).toString();
try {
class="kw">return var4.registerPack(var5, var3, var2, AssetPack.PackSource.RUNTIME);
} catch (Exception var7) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var7)).log("Failed to register asset pack for plugin %s", var1.getPath());
class="kw">return false;
}
}
class="kw">private void unregisterAssetPackIfNeeded(@Nonnull JavaPlugin var1) {
if (var1.getManifest().includesAssetPack()) {
AssetModule var2 = AssetModule.get();
if (var2 != null) {
String var3 = new PluginIdentifier(var1.getManifest()).toString();
AssetPack var4 = var2.getAssetPack(var3);
if (var4 != null) {
if (var4.getPackLocation().equals(var1.getFile())) {
var2.unregisterPack(var3);
}
}
}
}
}
class="kw">public boolean reload(@Nonnull PluginIdentifier var1) {
boolean var2 = this.unload(var1) && this.load(var1);
this.pluginListPageManager.notifyPluginChange(this.plugins, var1);
class="kw">return var2;
}
class="kw">public boolean unload(@Nonnull PluginIdentifier var1) {
class="kw">return this.unload(var1, new HashSet<>());
}
class="kw">private boolean unload(@Nonnull PluginIdentifier var1, @Nonnull Set<PluginIdentifier> var2) {
this.lock.writeLock().lock();
AssetRegistry.ASSET_LOCK.writeLock().lock();
try {
PluginBase var3 = this.plugins.get(var1);
if (var3 != null && var3.getState() == PluginState.ENABLED) {
var2.add(var1);
ArrayList var4 = new ArrayList<>();
for (PluginBase var6 : this.plugins.values()) {
if (var6.getManifest().getDependencies().containsKey(var1) && !var2.contains(var6.getIdentifier())) {
var4.add(var6.getIdentifier());
}
}
var4.forEach(var2x -> this.unload(var2x, var2));
var3.shutdown0(false);
HytaleServer.get().doneStop(var3);
this.plugins.remove(var1);
if (var3 class="kw">instanceof JavaPlugin var10) {
this.unregisterAssetPackIfNeeded(var10);
this.releasePluginClassLoader(var10);
}
this.pluginListPageManager.notifyPluginChange(this.plugins, var1);
class="kw">return true;
} else {
this.pluginListPageManager.notifyPluginChange(this.plugins, var1);
class="kw">return false;
}
} class="kw">finally {
AssetRegistry.ASSET_LOCK.writeLock().unlock();
this.lock.writeLock().unlock();
}
}
class="kw">protected void releasePluginClassLoader(JavaPlugin var1) {
Path var2 = var1.getFile();
if (var2 == null) {
LOGGER.at(Level.FINE).log("Plugin %s has no jar path to unload; skipping classloader release", var1.getIdentifier());
} else {
PluginClassLoader var3 = this.classLoaders.remove(var2);
if (var3 != null) {
try {
var3.close();
} catch (IOException var5) {
LOGGER.at(Level.SEVERE).log("Failed to close Class Loader for JavaPlugin %s", var1.getIdentifier());
}
}
}
}
class="kw">public boolean load(@Nonnull PluginIdentifier var1) {
this.lock.readLock().lock();
try {
PluginBase var2 = this.plugins.get(var1);
if (var2 != null) {
this.pluginListPageManager.notifyPluginChange(this.plugins, var1);
class="kw">return false;
}
} class="kw">finally {
this.lock.readLock().unlock();
}
boolean var7 = this.findAndLoadPlugin(var1);
this.pluginListPageManager.notifyPluginChange(this.plugins, var1);
class="kw">return var7;
}
class="kw">private boolean findAndLoadPlugin(PluginIdentifier var1) {
for (PendingLoadPlugin var3 : this.corePlugins) {
if (var3.getIdentifier().equals(var1)) {
class="kw">return this.load(var3);
}
}
try {
URI var28 = PluginManager.class.getProtectionDomain().getCodeSource().getLocation().toURI();
ClassLoader var31 = PluginManager.class.getClassLoader();
HashSet var4 = new HashSet<>();
for (URL var6 : Collections.list(var31.getResources("manifest.json"))) {
if (var4.add(var6.toExternalForm())) {
try (
InputStream var7 = var6.openStream();
InputStreamReader var8 = new InputStreamReader(var7, StandardCharsets.UTF_8);
) {
char[] var9 = RawJsonReader.READ_BUFFER.get();
RawJsonReader var10 = new RawJsonReader(var8, var9);
ExtraInfo var11 = ExtraInfo.THREAD_LOCAL.get();
PluginManifest var12 = PluginManifest.CODEC.decodeJson(var10, var11);
var11.getValidationResults().logOrThrowValidatorExceptions(LOGGER);
if (new PluginIdentifier(var12).equals(var1)) {
PluginClassLoader var13 = new PluginClassLoader(this, var1, true, var28.toURL());
PendingLoadJavaPlugin var14 = new PendingLoadJavaPlugin(Paths.get(var28), var12, var13);
class="kw">return this.load(var14);
}
}
}
}
URL var34 = var31.getResource("manifests.json");
if (var34 != null) {
try (
InputStream var35 = var34.openStream();
InputStreamReader var36 = new InputStreamReader(var35, StandardCharsets.UTF_8);
) {
char[] var37 = RawJsonReader.READ_BUFFER.get();
RawJsonReader var38 = new RawJsonReader(var36, var37);
ExtraInfo var39 = ExtraInfo.THREAD_LOCAL.get();
PluginManifest[] var40 = PluginManifest.ARRAY_CODEC.decodeJson(var38, var39);
var39.getValidationResults().logOrThrowValidatorExceptions(LOGGER);
for (PluginManifest var44 : var40) {
if (new PluginIdentifier(var44).equals(var1)) {
PluginClassLoader var16 = new PluginClassLoader(this, var1, true, var28.toURL());
PendingLoadJavaPlugin var17 = new PendingLoadJavaPlugin(Paths.get(var28), var44, var16);
class="kw">return this.load(var17);
}
}
}
}
} catch (IOException | URISyntaxException var27) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var27)).log("Failed to load pending classpath plugin. Failed to load manifest file!");
}
Boolean var29 = this.findPluginInDirectory(var1, MODS_PATH);
if (var29 != null) {
class="kw">return var29;
}
for (Path var33 : Options.getOptionSet().valuesOf(Options.MODS_DIRECTORIES)) {
var29 = this.findPluginInDirectory(var1, var33);
if (var29 != null) {
class="kw">return var29;
}
}
class="kw">return false;
}
@Nullable
class="kw">private Boolean findPluginInDirectory(@Nonnull PluginIdentifier var1, @Nonnull Path var2) {
if (!Files.isDirectory(var2)) {
class="kw">return null;
}
try (DirectoryStream var3 = Files.newDirectoryStream(var2)) {
for (Path var5 : var3) {
if (Files.isRegularFile(var5) && var5.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".jar")) {
PluginManifest var6 = loadManifest(var5);
if (var6 != null && new PluginIdentifier(var6).equals(var1)) {
PendingLoadJavaPlugin var7 = this.loadPendingJavaPlugin(var5);
if (var7 == null) {
class="kw">return false;
}
class="kw">return this.load(var7);
}
}
}
} catch (IOException var11) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var11)).log("Failed to find plugins in %s!", var2);
}
class="kw">return null;
}
@Nullable
class="kw">private class="kw">static PluginManifest loadManifest(@Nonnull Path var0) {
try (
URLClassLoader var1 = new URLClassLoader(new URL[]{var0.toUri().toURL()}, PluginManager.class.getClassLoader());
InputStream var2 = var1.findResource("manifest.json").openStream();
InputStreamReader var3 = new InputStreamReader(var2, StandardCharsets.UTF_8);
) {
char[] var4 = RawJsonReader.READ_BUFFER.get();
RawJsonReader var5 = new RawJsonReader(var3, var4);
ExtraInfo var6 = ExtraInfo.THREAD_LOCAL.get();
PluginManifest var7 = PluginManifest.CODEC.decodeJson(var5, var6);
var6.getValidationResults().logOrThrowValidatorExceptions(LOGGER);
class="kw">return var7;
} catch (IOException var15) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(var15)).log("Failed to load manifest %s.", var0);
class="kw">return null;
}
}
class="kw">private boolean load(@Nullable PendingLoadPlugin var1) {
if (var1 == null) {
class="kw">return false;
}
try {
this.validatePluginDeps(var1, null);
PluginBase var2 = var1.load();
this.lock.writeLock().lock();
try {
this.plugins.put(var2.getIdentifier(), var2);
} class="kw">finally {
this.lock.writeLock().unlock();
}
CompletableFuture var3 = var2.preLoad();
if (var3 == null) {
if (!this.setup(var2)) {
this.pluginListPageManager.notifyPluginChange(this.plugins, var2.getIdentifier());
class="kw">return false;
}
if (!this.registerAssetPackIfNeeded(var1)) {
var2.shutdown0(false);
this.plugins.remove(var2.getIdentifier());
this.pluginListPageManager.notifyPluginChange(this.plugins, var2.getIdentifier());
class="kw">return false;
}
boolean var4 = this.start(var2);
this.pluginListPageManager.notifyPluginChange(this.plugins, var2.getIdentifier());
class="kw">return var4;
}
var3.thenAccept(var3x -> {
if (!this.setup(var2)) {
this.pluginListPageManager.notifyPluginChange(this.plugins, var2.getIdentifier());
} else if (!this.registerAssetPackIfNeeded(var1)) {
var2.shutdown0(false);
this.plugins.remove(var2.getIdentifier());
this.pluginListPageManager.notifyPluginChange(this.plugins, var2.getIdentifier());
} else if (!this.start(var2)) {
this.pluginListPageManager.notifyPluginChange(this.plugins, var2.getIdentifier());
} else {
this.pluginListPageManager.notifyPluginChange(this.plugins, var2.getIdentifier());
}
});
this.pluginListPageManager.notifyPluginChange(this.plugins, var1.getIdentifier());
} catch (ClassNotFoundException var10) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(wrapIfThirdParty(var1, var10)))
.log("Failed to load plugin %s. Failed to find main class!", var1.getPath());
} catch (NoSuchMethodException var11) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(wrapIfThirdParty(var1, var11)))
.log("Failed to load plugin %s. Requires class="kw">default constructor!", var1.getPath());
} catch (Throwable var12) {
((HytaleLogger.Api)LOGGER.at(Level.SEVERE).withCause(wrapIfThirdParty(var1, var12))).log("Failed to load plugin %s", var1.getPath());
}
class="kw">return false;
}
class="kw">private class="kw">static Throwable wrapIfThirdParty(@Nonnull PendingLoadPlugin var0, @Nonnull Throwable var1) {
class="kw">return var0.isCoreMod() ? var1 : new SkipSentryException(var1);
}
class="kw">private boolean setup(@Nonnull PluginBase var1) {
PluginState var2 = this.state == PluginState.SETUP ? PluginState.SETUP : PluginState.ENABLED;
if (var1.getState() == PluginState.NONE && this.dependenciesMatchState(var1, var2, PluginState.SETUP)) {
LOGGER.at(Level.FINE).log("Setting up plugin %s", var1.getIdentifier());
boolean var3 = AssetStore.DISABLE_DYNAMIC_DEPENDENCIES;
AssetStore.DISABLE_DYNAMIC_DEPENDENCIES = false;
try {
var1.setup0();
} class="kw">finally {
AssetStore.DISABLE_DYNAMIC_DEPENDENCIES = var3;
}
AssetModule var4 = AssetModule.get();
if (var4 != null) {
var4.initPendingStores();
}
HytaleServer.get().doneSetup(var1);
if (!var1.getState().isInactive()) {
IEventDispatcher var5 = HytaleServer.get().getEventBus().dispatchFor(PluginSetupEvent.class, (Class<? class="kw">extends PluginBase>)var1.getClass());
if (var5.hasListener()) {
var5.dispatch(new PluginSetupEvent(var1));
}
class="kw">return true;
}
var1.shutdown0(false);
this.plugins.remove(var1.getIdentifier());
} else {
var1.shutdown0(false);
this.plugins.remove(var1.getIdentifier());
}
class="kw">return false;
}
class="kw">private boolean start(@Nonnull PluginBase var1) {
if (var1.getState() == PluginState.SETUP && this.dependenciesMatchState(var1, PluginState.ENABLED, PluginState.START)) {
LOGGER.at(Level.FINE).log("Starting plugin %s", var1.getIdentifier());
var1.start0();
HytaleServer.get().doneStart(var1);
if (!var1.getState().isInactive()) {
LOGGER.at(Level.INFO).log("Enabled plugin %s", var1.getIdentifier());
class="kw">return true;
}
var1.shutdown0(false);
this.plugins.remove(var1.getIdentifier());
} else {
var1.shutdown0(false);
this.plugins.remove(var1.getIdentifier());
}
class="kw">return false;
}
class="kw">private boolean dependenciesMatchState(PluginBase var1, PluginState var2, PluginState var3) {
for (PluginIdentifier var6 : var1.getManifest().getDependencies().keySet()) {
PluginBase var7 = this.plugins.get(var6);
if (var7 == null || var7.getState() != var2) {
LOGGER.at(Level.SEVERE).log("%s is lacking dependency %s at stage %s", var1.getName(), var6.getName(), var3);
LOGGER.at(Level.SEVERE).log("%s DISABLED!", var1.getName());
var1.setFailureCause(new Exception("Missing dependency " + var6.getName()));
class="kw">return false;
}
}
class="kw">return true;
}
class="kw">private class="kw">static void loadPendingPlugin(@Nonnull Map<PluginIdentifier, PendingLoadPlugin> var0, @Nonnull PendingLoadPlugin var1) {
if (var0.putIfAbsent(var1.getIdentifier(), var1) != null) {
String var4 = "Tried to load duplicate plugin: " + var1.getIdentifier();
LOGGER.at(Level.SEVERE).log("%s", var4);
Message var5 = Message.translation("client.disconnection.shutdownReason.pluginDuplicate").param("plugin", var1.getIdentifier().toString());
HytaleServer.get().shutdownServer(ShutdownReason.MOD_ERROR.withMessage(var5));
} else {
for (PendingLoadPlugin var3 : var1.createSubPendingLoadPlugins()) {
loadPendingPlugin(var0, var3);
}
}
}
@Nonnull
class="kw">public Map<PluginIdentifier, PluginManifest> getAvailablePlugins() {
class="kw">return this.availablePlugins;
}
class="kw">public ComponentType<EntityStore, PluginListPageManager.SessionSettings> getSessionSettingsComponentType() {
class="kw">return this.sessionSettingsComponentType;
}
class="kw">public record ClasspathAssetPack(@Nonnull Path path, @Nonnull PluginManifest manifest) {
class="kw">public ClasspathAssetPack {
}
}
class="kw">public class="kw">static class PluginBridgeClassLoader class="kw">extends ClassLoader {
class="kw">private class="kw">final PluginManager pluginManager;
class="kw">public PluginBridgeClassLoader(PluginManager var1, ClassLoader var2) {
super(var2);
this.pluginManager = var1;
}
@Nonnull
@Override
class="kw">protected Class<?> loadClass(@Nonnull String var1, boolean var2) class="kw">throws ClassNotFoundException {
class="kw">return this.loadClass0(var1, null);
}
@Nonnull
class="kw">public Class<?> loadClass0(@Nonnull String var1, PluginClassLoader var2) class="kw">throws ClassNotFoundException {
this.pluginManager.lock.readLock().lock();
try {
for (Entry var4 : this.pluginManager.plugins.entrySet()) {
PluginBase var5 = var4.getValue();
Class var6 = tryGetClass(var1, var2, var5);
if (var6 != null) {
class="kw">return var6;
}
}
} class="kw">finally {
this.pluginManager.lock.readLock().unlock();
}
throw new ClassNotFoundException();
}
@Nonnull
class="kw">public Class<?> loadClass0(@Nonnull String var1, PluginClassLoader var2, @Nonnull PluginManifest var3) class="kw">throws ClassNotFoundException {
this.pluginManager.lock.readLock().lock();
try {
for (PluginIdentifier var5 : var3.getDependencies().keySet()) {
PluginBase var6 = this.pluginManager.plugins.get(var5);
Class var7 = tryGetClass(var1, var2, var6);
if (var7 != null) {
class="kw">return var7;
}
}
for (PluginIdentifier var14 : var3.getOptionalDependencies().keySet()) {
if (!var3.getDependencies().containsKey(var14)) {
PluginBase var16 = this.pluginManager.plugins.get(var14);
if (var16 != null) {
Class var18 = tryGetClass(var1, var2, var16);
if (var18 != null) {
class="kw">return var18;
}
}
}
}
for (Entry var15 : this.pluginManager.plugins.entrySet()) {
if (!var3.getDependencies().containsKey(var15.getKey()) && !var3.getOptionalDependencies().containsKey(var15.getKey())) {
PluginBase var17 = var15.getValue();
Class var19 = tryGetClass(var1, var2, var17);
if (var19 != null) {
class="kw">return var19;
}
}
}
} class="kw">finally {
this.pluginManager.lock.readLock().unlock();
}
throw new ClassNotFoundException();
}
class="kw">public class="kw">static Class<?> tryGetClass(@Nonnull String var0, PluginClassLoader var1, PluginBase var2) {
if (!(var2 class="kw">instanceof JavaPlugin)) {
class="kw">return null;
}
try {
PluginClassLoader var3 = ((JavaPlugin)var2).getClassLoader();
if (var3 != var1) {
Class var4 = var3.loadLocalClass(var0);
if (var4 != null) {
class="kw">return var4;
}
}
} catch (ClassNotFoundException var5) {
}
class="kw">return null;
}
@Nullable
class="kw">public URL getResource0(@Nonnull String var1, @Nullable PluginClassLoader var2) {
this.pluginManager.lock.readLock().lock();
try {
for (Entry var4 : this.pluginManager.plugins.entrySet()) {
URL var5 = tryGetResource(var1, var2, var4.getValue());
if (var5 != null) {
class="kw">return var5;
}
}
} class="kw">finally {
this.pluginManager.lock.readLock().unlock();
}
class="kw">return null;
}
@Nullable
class="kw">public URL getResource0(@Nonnull String var1, @Nullable PluginClassLoader var2, @Nonnull PluginManifest var3) {
this.pluginManager.lock.readLock().lock();
try {
for (PluginIdentifier var5 : var3.getDependencies().keySet()) {
URL var6 = tryGetResource(var1, var2, this.pluginManager.plugins.get(var5));
if (var6 != null) {
class="kw">return var6;
}
}
for (PluginIdentifier var14 : var3.getOptionalDependencies().keySet()) {
if (!var3.getDependencies().containsKey(var14)) {
PluginBase var16 = this.pluginManager.plugins.get(var14);
if (var16 != null) {
URL var7 = tryGetResource(var1, var2, var16);
if (var7 != null) {
class="kw">return var7;
}
}
}
}
for (Entry var15 : this.pluginManager.plugins.entrySet()) {
if (!var3.getDependencies().containsKey(var15.getKey()) && !var3.getOptionalDependencies().containsKey(var15.getKey())) {
URL var17 = tryGetResource(var1, var2, var15.getValue());
if (var17 != null) {
class="kw">return var17;
}
}
}
} class="kw">finally {
this.pluginManager.lock.readLock().unlock();
}
class="kw">return null;
}
@Nonnull
class="kw">public Enumeration<URL> getResources0(@Nonnull String var1, @Nullable PluginClassLoader var2) {
ObjectArrayList var3 = new ObjectArrayList();
this.pluginManager.lock.readLock().lock();
try {
for (Entry var5 : this.pluginManager.plugins.entrySet()) {
URL var6 = tryGetResource(var1, var2, var5.getValue());
if (var6 != null) {
var3.add(var6);
}
}
} class="kw">finally {
this.pluginManager.lock.readLock().unlock();
}
class="kw">return Collections.enumeration(var3);
}
@Nonnull
class="kw">public Enumeration<URL> getResources0(@Nonnull String var1, @Nullable PluginClassLoader var2, @Nonnull PluginManifest var3) {
ObjectArrayList var4 = new ObjectArrayList();
this.pluginManager.lock.readLock().lock();
try {
for (PluginIdentifier var6 : var3.getDependencies().keySet()) {
URL var7 = tryGetResource(var1, var2, this.pluginManager.plugins.get(var6));
if (var7 != null) {
var4.add(var7);
}
}
for (PluginIdentifier var14 : var3.getOptionalDependencies().keySet()) {
if (!var3.getDependencies().containsKey(var14)) {
PluginBase var16 = this.pluginManager.plugins.get(var14);
if (var16 != null) {
URL var8 = tryGetResource(var1, var2, var16);
if (var8 != null) {
var4.add(var8);
}
}
}
}
for (Entry var15 : this.pluginManager.plugins.entrySet()) {
if (!var3.getDependencies().containsKey(var15.getKey()) && !var3.getOptionalDependencies().containsKey(var15.getKey())) {
URL var17 = tryGetResource(var1, var2, var15.getValue());
if (var17 != null) {
var4.add(var17);
}
}
}
} class="kw">finally {
this.pluginManager.lock.readLock().unlock();
}
class="kw">return Collections.enumeration(var4);
}
@Nullable
class="kw">private class="kw">static URL tryGetResource(@Nonnull String var0, @Nullable PluginClassLoader var1, @Nullable PluginBase var2) {
if (var2 class="kw">instanceof JavaPlugin var3) {
PluginClassLoader var4 = var3.getClassLoader();
class="kw">return var4 != var1 ? var4.findResource(var0) : null;
} else {
class="kw">return null;
}
}
class="kw">static {
registerAsParallelCapable();
}
}
}