Ursprung
58241602f1
Commit
e2f5817d1e
@ -194,7 +194,7 @@ public class TinyProtocol implements Listener {
|
|||||||
private Object filterPacket(Player player, Object packet) {
|
private Object filterPacket(Player player, Object packet) {
|
||||||
List<BiFunction<Player, Object, Object>> filters = packetFilters.getOrDefault(packet.getClass(), Collections.emptyList());
|
List<BiFunction<Player, Object, Object>> filters = packetFilters.getOrDefault(packet.getClass(), Collections.emptyList());
|
||||||
|
|
||||||
for(BiFunction<Player, Object, Object> filter : filters) {
|
for(BiFunction<Player, Object, Object> filter : filters) { //TODO spurious concurrentModificationException
|
||||||
packet = filter.apply(player, packet);
|
packet = filter.apply(player, packet);
|
||||||
|
|
||||||
if(packet == null)
|
if(packet == null)
|
||||||
|
@ -26,6 +26,7 @@ import de.steamwar.core.events.*;
|
|||||||
import de.steamwar.message.Message;
|
import de.steamwar.message.Message;
|
||||||
import de.steamwar.network.NetworkReceiver;
|
import de.steamwar.network.NetworkReceiver;
|
||||||
import de.steamwar.network.handlers.ServerDataHandler;
|
import de.steamwar.network.handlers.ServerDataHandler;
|
||||||
|
import de.steamwar.plugin.SteamWarClassLoader;
|
||||||
import de.steamwar.sql.SchematicNode;
|
import de.steamwar.sql.SchematicNode;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.sql.internal.Statement;
|
import de.steamwar.sql.internal.Statement;
|
||||||
@ -44,10 +45,9 @@ public class Core extends JavaPlugin{
|
|||||||
|
|
||||||
public static final Message MESSAGE = new Message("SpigotCore", Core.class.getClassLoader());
|
public static final Message MESSAGE = new Message("SpigotCore", Core.class.getClassLoader());
|
||||||
|
|
||||||
private static final int VERSION = Integer.parseInt(Bukkit.getServer().getClass().getPackage().getName().split("_", 3)[1]);
|
@Deprecated
|
||||||
|
|
||||||
public static int getVersion(){
|
public static int getVersion(){
|
||||||
return VERSION;
|
return SteamWarClassLoader.MINECAFT_MAJOR_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JavaPlugin instance;
|
private static JavaPlugin instance;
|
||||||
@ -68,7 +68,14 @@ public class Core extends JavaPlugin{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
errorHandler = new ErrorHandler();
|
try {
|
||||||
|
System.out.println(new SteamWarClassLoader(this.getClassLoader()).loadClass("org.bukkit.craftbukkit.CraftServer").getName());
|
||||||
|
new SteamWarClassLoader(this.getClassLoader()).loadClass("de.steamwar.SteamWarPlugin");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
errorHandler = new ErrorHandler();
|
||||||
crashDetector = new CrashDetector();
|
crashDetector = new CrashDetector();
|
||||||
|
|
||||||
SWCommandUtils.init((SWTypeMapperCreator<TypeMapper<Object>, CommandSender, Object>) (mapper, tabCompleter) -> new TypeMapper<Object>() {
|
SWCommandUtils.init((SWTypeMapperCreator<TypeMapper<Object>, CommandSender, Object>) (mapper, tabCompleter) -> new TypeMapper<Object>() {
|
||||||
|
198
SpigotCore_Main/src/de/steamwar/plugin/Reflection.java
Normale Datei
198
SpigotCore_Main/src/de/steamwar/plugin/Reflection.java
Normale Datei
@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.plugin;
|
||||||
|
|
||||||
|
import de.steamwar.core.Core;
|
||||||
|
import jdk.internal.misc.Unsafe;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public final class Reflection {
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class Constructor {
|
||||||
|
private final java.lang.reflect.Constructor<?> constructor;
|
||||||
|
public Object newInstance(Object... arguments) {
|
||||||
|
try {
|
||||||
|
return constructor.newInstance(arguments);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException("Cannot invoke constructor " + constructor, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class Method {
|
||||||
|
private final java.lang.reflect.Method method;
|
||||||
|
public Object invoke(Object target, Object... arguments) {
|
||||||
|
try {
|
||||||
|
return method.invoke(target, arguments);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException("Cannot invoke method " + method, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Object invokeStatic(Object... arguments) {
|
||||||
|
return invoke(null, arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class FieldAccessor<T> {
|
||||||
|
private final Field field;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public T get(Object target) {
|
||||||
|
try {
|
||||||
|
return (T) field.get(target);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new IllegalArgumentException("Cannot access reflection.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void set(Object target, Object value) {
|
||||||
|
try {
|
||||||
|
field.set(target, value);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new IllegalArgumentException("Cannot access reflection.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> FieldAccessor<T> getField(Class<?> target, String name, Class<T> fieldType) {
|
||||||
|
return getField(target, name, fieldType, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> FieldAccessor<T> getField(String className, String name, Class<T> fieldType) {
|
||||||
|
return getField(getClass(className), name, fieldType, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> FieldAccessor<T> getField(Class<?> target, Class<T> fieldType, int index) {
|
||||||
|
return getField(target, null, fieldType, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> FieldAccessor<T> getField(String className, Class<T> fieldType, int index) {
|
||||||
|
return getField(getClass(className), fieldType, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> FieldAccessor<T> getField(Class<?> target, Class<T> fieldType, int index, Class<?>... parameters) {
|
||||||
|
return getField(target, null, fieldType, index, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> FieldAccessor<T> getField(Class<?> target, String name, Class<T> fieldType, int index, Class<?>... parameters) {
|
||||||
|
for (final Field field : target.getDeclaredFields()) {
|
||||||
|
if(matching(field, name, fieldType, parameters) && index-- <= 0) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
return new FieldAccessor<T>(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search in parent classes
|
||||||
|
if (target.getSuperclass() != null)
|
||||||
|
return getField(target.getSuperclass(), name, fieldType, index);
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Cannot find field with type " + fieldType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> boolean matching(Field field, String name, Class<T> fieldType, Class<?>... parameters) {
|
||||||
|
if(name != null && !field.getName().equals(name))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!fieldType.isAssignableFrom(field.getType()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(parameters.length > 0) {
|
||||||
|
Type[] arguments = ((ParameterizedType)field.getGenericType()).getActualTypeArguments();
|
||||||
|
|
||||||
|
for(int i = 0; i < parameters.length; i++) {
|
||||||
|
if(arguments[i] instanceof ParameterizedType ? ((ParameterizedType) arguments[i]).getRawType() != parameters[i] : arguments[i] != parameters[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Method getMethod(String className, String methodName, Class<?>... params) {
|
||||||
|
return getTypedMethod(getClass(className), methodName, null, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Method getMethod(Class<?> clazz, String methodName, Class<?>... params) {
|
||||||
|
return getTypedMethod(clazz, methodName, null, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Method getTypedMethod(Class<?> clazz, Class<?> returnType, Class<?>... params) {
|
||||||
|
return getTypedMethod(clazz, null, returnType, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Method getTypedMethod(Class<?> clazz, String methodName, Class<?> returnType, Class<?>... params) {
|
||||||
|
for (final java.lang.reflect.Method method : clazz.getDeclaredMethods()) {
|
||||||
|
if ((methodName == null || method.getName().equals(methodName))
|
||||||
|
&& (returnType == null || method.getReturnType().equals(returnType))
|
||||||
|
&& Arrays.equals(method.getParameterTypes(), params)) {
|
||||||
|
method.setAccessible(true);
|
||||||
|
return new Method(method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search in every superclass
|
||||||
|
if (clazz.getSuperclass() != null)
|
||||||
|
return getTypedMethod(clazz.getSuperclass(), methodName, returnType, params);
|
||||||
|
|
||||||
|
throw new IllegalStateException(String.format("Unable to find method %s (%s).", methodName, Arrays.asList(params)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Constructor getConstructor(String className, Class<?>... params) {
|
||||||
|
return getConstructor(getClass(className), params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Constructor getConstructor(Class<?> clazz, Class<?>... params) {
|
||||||
|
for (final java.lang.reflect.Constructor<?> constructor : clazz.getDeclaredConstructors()) {
|
||||||
|
if (Arrays.equals(constructor.getParameterTypes(), params)) {
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
return new Constructor(constructor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalStateException(String.format("Unable to find constructor for %s (%s).", clazz, Arrays.asList(params)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class<?> getClass(String name) {
|
||||||
|
try {
|
||||||
|
return Class.forName(name);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new IllegalArgumentException("Cannot find " + name, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object newInstance(Class<?> clazz) {
|
||||||
|
try {
|
||||||
|
if (Core.getVersion() > 15) {
|
||||||
|
return Unsafe.getUnsafe().allocateInstance(clazz);
|
||||||
|
} else {
|
||||||
|
return clazz.newInstance();
|
||||||
|
}
|
||||||
|
} catch (InstantiationException | IllegalAccessException e) {
|
||||||
|
throw new SecurityException("Could not create object", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
139
SpigotCore_Main/src/de/steamwar/plugin/SWPlugin.java
Normale Datei
139
SpigotCore_Main/src/de/steamwar/plugin/SWPlugin.java
Normale Datei
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.plugin;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
|
import de.steamwar.core.CommandRemover;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.SimpleCommandMap;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.plugin.PluginLogger;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||||
|
import org.bukkit.scheduler.BukkitScheduler;
|
||||||
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SWPlugin {
|
||||||
|
private final JavaPlugin bukkit;
|
||||||
|
private final PluginLogger logger;
|
||||||
|
private final File dataFolder;
|
||||||
|
|
||||||
|
private final Map<Runnable, BukkitTask> tasks = new HashMap<>();
|
||||||
|
private final List<String> commands = new ArrayList<>();
|
||||||
|
private final Set<Listener> listeners = new HashSet<>();
|
||||||
|
private final List<String> outgoingChannels = new ArrayList<>();
|
||||||
|
private final List<String> incomingChannels = new ArrayList<>();
|
||||||
|
//TODO commands
|
||||||
|
|
||||||
|
public void load() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unload() {
|
||||||
|
tasks.values().forEach(BukkitTask::cancel);
|
||||||
|
tasks.clear();
|
||||||
|
outgoingChannels.forEach(channel -> bukkit.getServer().getMessenger().unregisterOutgoingPluginChannel(bukkit, channel));
|
||||||
|
outgoingChannels.clear();
|
||||||
|
incomingChannels.forEach(channel -> bukkit.getServer().getMessenger().unregisterIncomingPluginChannel(bukkit, channel));
|
||||||
|
incomingChannels.clear();
|
||||||
|
listeners.forEach(HandlerList::unregisterAll);
|
||||||
|
listeners.clear();
|
||||||
|
commands.forEach(CommandRemover::removeAll);
|
||||||
|
commands.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public YamlConfiguration getConfig() {
|
||||||
|
return YamlConfiguration.loadConfiguration(new File(dataFolder, "config.yml"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runTask(Runnable runnable) {
|
||||||
|
getScheduler().runTask(bukkit, runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Runnable runTaskLater(Runnable runnable, long delay) {
|
||||||
|
return makeCancellable(runnable, getScheduler().runTaskLater(bukkit, runnable, delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Runnable runTaskTimer(Runnable runnable, long delay, long frequency) {
|
||||||
|
return makeCancellable(runnable, getScheduler().runTaskTimer(bukkit, runnable, delay, frequency));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerOutgoingPluginChannel(String channel) {
|
||||||
|
outgoingChannels.add(channel);
|
||||||
|
bukkit.getServer().getMessenger().registerOutgoingPluginChannel(bukkit, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerIncomingPluginChannel(String channel, PluginMessageListener listener) {
|
||||||
|
incomingChannels.add(channel);
|
||||||
|
bukkit.getServer().getMessenger().registerIncomingPluginChannel(bukkit, channel, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerEvents(Listener listener) {
|
||||||
|
listeners.add(listener);
|
||||||
|
bukkit.getServer().getPluginManager().registerEvents(listener, bukkit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unregisterEvents(Listener listener) {
|
||||||
|
HandlerList.unregisterAll(listener);
|
||||||
|
listeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void callEvent(Event event) {
|
||||||
|
bukkit.getServer().getPluginManager().callEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final com.comphenix.tinyprotocol.Reflection.FieldAccessor<SimpleCommandMap> craftServerCommandMap = Reflection.getField("{obc}.CraftServer", "commandMap", SimpleCommandMap.class);
|
||||||
|
public void setExecutor(String name, CommandExecutor executor) {
|
||||||
|
//TODO tab completes
|
||||||
|
SimpleCommandMap commandMap = craftServerCommandMap.get(bukkit.getServer());
|
||||||
|
commandMap.register(bukkit.getName(), new Command(name) {
|
||||||
|
@Override
|
||||||
|
public boolean execute(CommandSender commandSender, String s, String[] strings) {
|
||||||
|
return executor.onCommand(commandSender, this, s, strings);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private BukkitScheduler getScheduler() {
|
||||||
|
return bukkit.getServer().getScheduler();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Runnable makeCancellable(Runnable runnable, BukkitTask task) {
|
||||||
|
tasks.put(runnable, task);
|
||||||
|
return () -> {
|
||||||
|
task.cancel();
|
||||||
|
tasks.remove(runnable);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
98
SpigotCore_Main/src/de/steamwar/plugin/SpigotCore.java
Normale Datei
98
SpigotCore_Main/src/de/steamwar/plugin/SpigotCore.java
Normale Datei
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.plugin;
|
||||||
|
|
||||||
|
|
||||||
|
import org.bukkit.plugin.InvalidDescriptionException;
|
||||||
|
import org.bukkit.plugin.InvalidPluginException;
|
||||||
|
import org.bukkit.plugin.PluginLogger;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
public class SpigotCore extends JavaPlugin {
|
||||||
|
|
||||||
|
public static SpigotCore getInstance() {
|
||||||
|
return JavaPlugin.getPlugin(SpigotCore.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String BUKKIT_INDICATOR = "bukkit:";
|
||||||
|
private static final String STEAMWAR_INDICATOR = "steamwar:";
|
||||||
|
|
||||||
|
private final SteamWarClassLoader loader;
|
||||||
|
|
||||||
|
private final List<SWPlugin> loaded = new ArrayList<>();
|
||||||
|
private final List<SWPlugin> enabled = new ArrayList<>();
|
||||||
|
|
||||||
|
public SpigotCore() {
|
||||||
|
loader = new SteamWarClassLoader(this.getClassLoader());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
//TODO more dynamic than file
|
||||||
|
File file = new File("plugins.properties");
|
||||||
|
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||||
|
while(true) {
|
||||||
|
String plugin = reader.readLine();
|
||||||
|
if(plugin == null)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(plugin.startsWith(BUKKIT_INDICATOR))
|
||||||
|
loadBukkit(plugin.substring(BUKKIT_INDICATOR.length()));
|
||||||
|
else if(plugin.startsWith(STEAMWAR_INDICATOR))
|
||||||
|
loadSteamWar(plugin.substring(STEAMWAR_INDICATOR.length()));
|
||||||
|
}
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
getLogger().log(Level.WARNING, "Did not load any plugins due to missing plugins.properties file.");
|
||||||
|
} catch (IOException e) {
|
||||||
|
getLogger().log(Level.WARNING, "Unhandled error reading plugins.properties file.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSteamWar(String path) {
|
||||||
|
loader.loadPlugin(new File(path));
|
||||||
|
loaded.add(new SWPlugin(this, plugin, new PluginLogger(todo), ));
|
||||||
|
//TODO multiple plugins per file
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadBukkit(String path) {
|
||||||
|
try {
|
||||||
|
//Default plugin config folder is generated from parent file folder
|
||||||
|
getServer().getPluginManager().loadPlugin(new File(path));
|
||||||
|
} catch (InvalidPluginException | InvalidDescriptionException e) {
|
||||||
|
getLogger().log(Level.SEVERE, e, () -> "Unhandled error loading plugin: " + path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
87
SpigotCore_Main/src/de/steamwar/plugin/SteamWarClassLoader.java
Normale Datei
87
SpigotCore_Main/src/de/steamwar/plugin/SteamWarClassLoader.java
Normale Datei
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.plugin;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
public class SteamWarClassLoader extends URLClassLoader {
|
||||||
|
static {
|
||||||
|
registerAsParallelCapable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SteamWarClassLoader(ClassLoader parent) {
|
||||||
|
super(new URL[0], parent);
|
||||||
|
/*new URL();
|
||||||
|
ZipFile zipFile = new ZipFile("string");
|
||||||
|
addURL();
|
||||||
|
getResources("").nextElement().openStream();*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadPlugin(File file, String name, SWPlugin context) {
|
||||||
|
//TODO SteamWarPlugin as Class with constructor taking Context (unregister methods for disable)
|
||||||
|
try {
|
||||||
|
addURL(file.toURI().toURL());
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int MINECAFT_MAJOR_VERSION;
|
||||||
|
public static final int MINECAFT_MINOR_VERSION;
|
||||||
|
static {
|
||||||
|
String[] version = Bukkit.getServer().getBukkitVersion().split("-")[0].split("\\.");
|
||||||
|
MINECAFT_MAJOR_VERSION = Integer.parseInt(version[1]);
|
||||||
|
MINECAFT_MINOR_VERSION = version.length > 2 ? Integer.parseInt(version[2]) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String CRAFTBUKKIT_PREFIX = "org.bukkit.craftbukkit";
|
||||||
|
private static final String CRAFTBUKKIT_RELOCATED_PREFIX = Bukkit.getServer().getClass().getPackage().getName();
|
||||||
|
private static final boolean CRAFTBUKKIT_RELOCATED = !CRAFTBUKKIT_RELOCATED_PREFIX.substring(CRAFTBUKKIT_PREFIX.length()).isEmpty();
|
||||||
|
|
||||||
|
private static final boolean NET_MINECRAFT_RELOCATED = MINECAFT_MAJOR_VERSION < 17;
|
||||||
|
private static final String NET_MINECRAFT_RELOCATED_PREFIX = "net.minecraft.server" + CRAFTBUKKIT_RELOCATED_PREFIX.substring(CRAFTBUKKIT_PREFIX.length());
|
||||||
|
public static Class<?> getClass(String name) {
|
||||||
|
//TODO running on mojang mapped servers (mojang mappings only available starting with 1.14.4)
|
||||||
|
if(CRAFTBUKKIT_RELOCATED && name.startsWith(CRAFTBUKKIT_PREFIX)) {
|
||||||
|
return Class.forName(CRAFTBUKKIT_RELOCATED_PREFIX + name.substring(CRAFTBUKKIT_PREFIX.length()));
|
||||||
|
}else if(NET_MINECRAFT_RELOCATED && name.startsWith("net.minecraft")) {
|
||||||
|
return Class.forName(NET_MINECRAFT_RELOCATED_PREFIX + "." + name.substring(name.lastIndexOf('.')));
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ClassNotFoundException(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||||
|
//TODO running on mojang mapped servers
|
||||||
|
if(CRAFTBUKKIT_RELOCATED && name.startsWith(CRAFTBUKKIT_PREFIX)) {
|
||||||
|
return super.loadClass(CRAFTBUKKIT_RELOCATED_PREFIX + name.substring(CRAFTBUKKIT_PREFIX.length()));
|
||||||
|
}else if(NET_MINECRAFT_RELOCATED && name.startsWith("net.minecraft")) {
|
||||||
|
return super.loadClass(NET_MINECRAFT_RELOCATED_PREFIX + "." + name.substring(name.lastIndexOf('.')));
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ClassNotFoundException(name);
|
||||||
|
}
|
||||||
|
}
|
In neuem Issue referenzieren
Einen Benutzer sperren