diff --git a/build.gradle b/build.gradle index c31de64..977aeac 100644 --- a/build.gradle +++ b/build.gradle @@ -25,10 +25,15 @@ apply plugin: 'forge' [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' -version = "1.8" +version = "1.7.10-1.9" group= "com.gamerforea" archivesBaseName = "EventHelper" +sourceCompatibility = targetCompatibility = '1.8' +compileJava { + sourceCompatibility = targetCompatibility = '1.8' +} + minecraft { version = "1.7.10-10.13.4.1614-1.7.10" runDir = "eclipse" @@ -39,6 +44,7 @@ dependencies { compile name: 'bukkit-1.7.10' compile name: 'worldedit-6.1' compile name: 'worldguard-6.1' + compile name: 'GriefPreventionPlus-13.3' } task devJar(type: Jar) { diff --git a/lib/GriefPreventionPlus-13.3-sources.jar b/lib/GriefPreventionPlus-13.3-sources.jar new file mode 100644 index 0000000..facc369 Binary files /dev/null and b/lib/GriefPreventionPlus-13.3-sources.jar differ diff --git a/lib/GriefPreventionPlus-13.3.jar b/lib/GriefPreventionPlus-13.3.jar new file mode 100644 index 0000000..86c0938 Binary files /dev/null and b/lib/GriefPreventionPlus-13.3.jar differ diff --git a/src/main/java/com/gamerforea/eventhelper/EventHelper.java b/src/main/java/com/gamerforea/eventhelper/EventHelper.java index cb54ba9..f1106f2 100644 --- a/src/main/java/com/gamerforea/eventhelper/EventHelper.java +++ b/src/main/java/com/gamerforea/eventhelper/EventHelper.java @@ -1,20 +1,8 @@ package com.gamerforea.eventhelper; -import static net.minecraftforge.common.config.Configuration.CATEGORY_GENERAL; - -import java.io.File; -import java.util.List; - -import org.bukkit.Bukkit; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.bukkit.plugin.PluginManager; -import org.bukkit.plugin.RegisteredListener; - -import com.gamerforea.eventhelper.util.FastUtils; -import com.gamerforea.eventhelper.wg.WGReflection; +import com.gamerforea.eventhelper.config.ConfigUtils; +import com.gamerforea.eventhelper.inject.InjectionManager; import com.google.common.collect.Lists; - import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; @@ -22,36 +10,61 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraftforge.common.config.Configuration; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.message.FormattedMessage; +import org.bukkit.Bukkit; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.RegisteredListener; + +import java.io.File; +import java.util.List; + +import static net.minecraftforge.common.config.Configuration.CATEGORY_GENERAL; @SideOnly(Side.SERVER) @Mod(modid = "EventHelper", name = "EventHelper", version = "@VERSION@", acceptableRemoteVersions = "*") public final class EventHelper { + public static final Logger LOGGER = LogManager.getLogger("EventHelper"); public static final File cfgDir = new File(Loader.instance().getConfigDir(), "Events"); public static final List listeners = Lists.newArrayList(); - public static String craftPackage = "org/bukkit/craftbukkit/v1_7_R4"; - public static boolean debug = false; + public static String craftPackage = "org.bukkit.craftbukkit.v1_7_R4"; + public static boolean explosions = true; + public static boolean debug = true; @EventHandler public final void serverStarted(FMLServerStartedEvent event) { - Configuration cfg = FastUtils.getConfig("EventHelper"); - String[] plugins = cfg.getStringList("plugins", CATEGORY_GENERAL, new String[] { "WorldGuard" }, "Plugins for sending events"); - boolean wgHooking = cfg.getBoolean("wgHooking", CATEGORY_GENERAL, true, "Hooking WorldGuard plugin (allow checking regions)"); - craftPackage = cfg.getString("craftPackage", CATEGORY_GENERAL, craftPackage, "CraftBukkit package (for reflection)"); - debug = cfg.getBoolean("debug", CATEGORY_GENERAL, debug, "Debugging enabled"); + Configuration cfg = ConfigUtils.getConfig("EventHelper"); + String c = CATEGORY_GENERAL; + String[] plugins = cfg.getStringList("plugins", c, new String[] { "WorldGuard", "GriefPreventionPlus" }, "Plugins for sending events"); + boolean pluginHooking = cfg.getBoolean("pluginHooking", c, true, "Hooking plugins (allow checking regions)"); + craftPackage = cfg.getString("craftPackage", c, craftPackage, "CraftBukkit package (for reflection)"); + explosions = cfg.getBoolean("explosions", c, explosions, "Explosions enabled"); + debug = cfg.getBoolean("debug", c, debug, "Debugging enabled"); cfg.save(); PluginManager plManager = Bukkit.getPluginManager(); for (String plName : plugins) - listeners.addAll(HandlerList.getRegisteredListeners(plManager.getPlugin(plName))); - if (wgHooking) - WGReflection.setWG(plManager.getPlugin("WorldGuard")); + { + Plugin plugin = plManager.getPlugin(plName); + if (plugin == null) + LOGGER.warn("Plugin {} not found!", plName); + else + listeners.addAll(HandlerList.getRegisteredListeners(plugin)); + } + if (pluginHooking) + InjectionManager.init(); } - public static final void callEvent(Event event) + public static void callEvent(Event event) { for (RegisteredListener listener : listeners) + { try { listener.callEvent(event); @@ -59,7 +72,16 @@ public static final void callEvent(Event event) catch (Throwable throwable) { if (debug) - throwable.printStackTrace(); + LOGGER.error("Failed event call", throwable); } + } + } + + public static void error(Throwable throwable, String message, Object... args) + { + if (debug) + LOGGER.error(new FormattedMessage(message, args), throwable); + else + LOGGER.error(message, args); } } diff --git a/src/main/java/com/gamerforea/eventhelper/config/ClassSet.java b/src/main/java/com/gamerforea/eventhelper/config/ClassSet.java new file mode 100644 index 0000000..41705b5 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/config/ClassSet.java @@ -0,0 +1,103 @@ +package com.gamerforea.eventhelper.config; + +import com.gamerforea.eventhelper.EventHelper; +import com.google.common.base.Preconditions; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.stream.Collectors; + +public final class ClassSet implements Iterable> +{ + private final Set> classes = new HashSet<>(); + private final Class baseClass; + + public ClassSet(@Nonnull Class baseClass) + { + this.baseClass = baseClass; + Preconditions.checkArgument(baseClass != Class.class, "baseClass must not be java.lang.Class"); + } + + public boolean isEmpty() + { + return this.classes.isEmpty(); + } + + public boolean contains(@Nullable T instance) + { + return instance != null && this.contains((Class) instance.getClass()); + } + + public boolean contains(@Nonnull Class clazz) + { + return this.contains(clazz, true); + } + + public boolean contains(@Nullable T instance, boolean checkHierarchy) + { + return instance != null && this.contains((Class) instance.getClass(), checkHierarchy); + } + + public boolean contains(@Nonnull Class clazz, boolean checkHierarchy) + { + if (this.baseClass.isAssignableFrom(clazz)) + { + if (this.classes.contains(clazz)) + return true; + + if (checkHierarchy) + for (Class aClass : this.classes) + { + if (aClass.isAssignableFrom(clazz)) + return true; + } + } + + return false; + } + + @Override + public Iterator> iterator() + { + return this.classes.iterator(); + } + + public void clear() + { + this.classes.clear(); + } + + public boolean add(@Nonnull Class clazz) + { + return this.baseClass.isAssignableFrom(clazz) && this.classes.add(clazz); + } + + public void addRaw(@Nonnull Collection classNames) + { + for (String className : classNames) + { + try + { + Class clazz = Class.forName(className); + if (this.baseClass.isAssignableFrom(clazz)) + this.add((Class) clazz); + else if (EventHelper.debug) + EventHelper.LOGGER.warn("Class {} is not assignable from {}", className, this.baseClass.getName()); + } + catch (ClassNotFoundException e) + { + if (EventHelper.debug) + EventHelper.LOGGER.warn("Class {} not found", className); + } + } + } + + public Set getRaw() + { + return this.classes.stream().map(Class::getName).collect(Collectors.toSet()); + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/config/Config.java b/src/main/java/com/gamerforea/eventhelper/config/Config.java new file mode 100644 index 0000000..f6aeb70 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/config/Config.java @@ -0,0 +1,13 @@ +package com.gamerforea.eventhelper.config; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Config +{ + String name() default ""; +} diff --git a/src/main/java/com/gamerforea/eventhelper/config/ConfigBoolean.java b/src/main/java/com/gamerforea/eventhelper/config/ConfigBoolean.java new file mode 100644 index 0000000..8a66f50 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/config/ConfigBoolean.java @@ -0,0 +1,23 @@ +package com.gamerforea.eventhelper.config; + +import net.minecraftforge.common.config.Configuration; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ConfigBoolean +{ + String name() default ""; + + String category() default Configuration.CATEGORY_GENERAL; + + String comment() default ""; + + String oldName() default ""; + + String oldCategory() default ""; +} diff --git a/src/main/java/com/gamerforea/eventhelper/config/ConfigClassSet.java b/src/main/java/com/gamerforea/eventhelper/config/ConfigClassSet.java new file mode 100644 index 0000000..2ea6b78 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/config/ConfigClassSet.java @@ -0,0 +1,23 @@ +package com.gamerforea.eventhelper.config; + +import net.minecraftforge.common.config.Configuration; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ConfigClassSet +{ + String name() default ""; + + String category() default Configuration.CATEGORY_GENERAL; + + String comment() default ""; + + String oldName() default ""; + + String oldCategory() default ""; +} diff --git a/src/main/java/com/gamerforea/eventhelper/config/ConfigEnum.java b/src/main/java/com/gamerforea/eventhelper/config/ConfigEnum.java new file mode 100644 index 0000000..a321443 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/config/ConfigEnum.java @@ -0,0 +1,23 @@ +package com.gamerforea.eventhelper.config; + +import net.minecraftforge.common.config.Configuration; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ConfigEnum +{ + String name() default ""; + + String category() default Configuration.CATEGORY_GENERAL; + + String comment() default ""; + + String oldName() default ""; + + String oldCategory() default ""; +} diff --git a/src/main/java/com/gamerforea/eventhelper/config/ConfigFloat.java b/src/main/java/com/gamerforea/eventhelper/config/ConfigFloat.java new file mode 100644 index 0000000..36f6778 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/config/ConfigFloat.java @@ -0,0 +1,27 @@ +package com.gamerforea.eventhelper.config; + +import net.minecraftforge.common.config.Configuration; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ConfigFloat +{ + String name() default ""; + + String category() default Configuration.CATEGORY_GENERAL; + + String comment() default ""; + + float min() default Float.MIN_VALUE; + + float max() default Float.MAX_VALUE; + + String oldName() default ""; + + String oldCategory() default ""; +} diff --git a/src/main/java/com/gamerforea/eventhelper/config/ConfigInt.java b/src/main/java/com/gamerforea/eventhelper/config/ConfigInt.java new file mode 100644 index 0000000..71a9e0a --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/config/ConfigInt.java @@ -0,0 +1,27 @@ +package com.gamerforea.eventhelper.config; + +import net.minecraftforge.common.config.Configuration; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ConfigInt +{ + String name() default ""; + + String category() default Configuration.CATEGORY_GENERAL; + + String comment() default ""; + + int min() default Integer.MIN_VALUE; + + int max() default Integer.MAX_VALUE; + + String oldName() default ""; + + String oldCategory() default ""; +} diff --git a/src/main/java/com/gamerforea/eventhelper/config/ConfigItemBlockList.java b/src/main/java/com/gamerforea/eventhelper/config/ConfigItemBlockList.java new file mode 100644 index 0000000..390e553 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/config/ConfigItemBlockList.java @@ -0,0 +1,23 @@ +package com.gamerforea.eventhelper.config; + +import net.minecraftforge.common.config.Configuration; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ConfigItemBlockList +{ + String name() default ""; + + String category() default Configuration.CATEGORY_GENERAL; + + String comment() default ""; + + String oldName() default ""; + + String oldCategory() default ""; +} diff --git a/src/main/java/com/gamerforea/eventhelper/config/ConfigString.java b/src/main/java/com/gamerforea/eventhelper/config/ConfigString.java new file mode 100644 index 0000000..ece95d5 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/config/ConfigString.java @@ -0,0 +1,23 @@ +package com.gamerforea.eventhelper.config; + +import net.minecraftforge.common.config.Configuration; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ConfigString +{ + String name() default ""; + + String category() default Configuration.CATEGORY_GENERAL; + + String comment() default ""; + + String oldName() default ""; + + String oldCategory() default ""; +} diff --git a/src/main/java/com/gamerforea/eventhelper/config/ConfigStringCollection.java b/src/main/java/com/gamerforea/eventhelper/config/ConfigStringCollection.java new file mode 100644 index 0000000..a05a43a --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/config/ConfigStringCollection.java @@ -0,0 +1,23 @@ +package com.gamerforea.eventhelper.config; + +import net.minecraftforge.common.config.Configuration; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ConfigStringCollection +{ + String name() default ""; + + String category() default Configuration.CATEGORY_GENERAL; + + String comment() default ""; + + String oldName() default ""; + + String oldCategory() default ""; +} diff --git a/src/main/java/com/gamerforea/eventhelper/config/ConfigUtils.java b/src/main/java/com/gamerforea/eventhelper/config/ConfigUtils.java new file mode 100644 index 0000000..3b23515 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/config/ConfigUtils.java @@ -0,0 +1,276 @@ +package com.gamerforea.eventhelper.config; + +import com.gamerforea.eventhelper.EventHelper; +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import net.minecraftforge.common.config.ConfigCategory; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.common.config.Property; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.*; + +public final class ConfigUtils +{ + private static final String PACKAGE_DEFAULT = "default"; + private static final Set> LOADED_CONFIG_CLASSES = new HashSet<>(); + + @Nonnull + public static > T readStringCollection( + @Nonnull Configuration cfg, + @Nonnull String name, @Nonnull String category, @Nonnull String comment, @Nonnull T def) + { + String[] temp = cfg.getStringList(name, category, def.toArray(new String[0]), comment); + def.clear(); + Collections.addAll(def, temp); + return def; + } + + @Nonnull + public static Configuration getConfig(@Nonnull Class configClass) + { + return getConfig(getConfigName(configClass)); + } + + @Nonnull + public static Configuration getConfig(@Nonnull String cfgName) + { + Configuration cfg = new Configuration(new File(EventHelper.cfgDir, cfgName + ".cfg")); + cfg.load(); + return cfg; + } + + public static void readConfig(@Nonnull Class configClass) + { + readConfig(configClass, false); + } + + public static void readConfig(@Nonnull Class configClass, @Nonnull String configName) + { + readConfig(configClass, configName, false); + } + + public static void readConfig(@Nonnull Class configClass, boolean reload) + { + readConfig(configClass, getConfigName(configClass), reload); + } + + public static void readConfig(@Nonnull Class configClass, @Nonnull String configName, boolean reload) + { + if (!LOADED_CONFIG_CLASSES.add(configClass) && !reload) + return; + + Configuration cfg = getConfig(configName); + try + { + for (Field field : configClass.getDeclaredFields()) + { + int modifiers = field.getModifiers(); + if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) + { + Class type = field.getType(); + if (type == boolean.class) + { + ConfigBoolean annotation = field.getAnnotation(ConfigBoolean.class); + if (annotation != null) + { + String name = annotation.name().isEmpty() ? field.getName() : annotation.name(); + tryMoveProperty(cfg, name, annotation.category(), annotation.oldName(), annotation.oldCategory()); + + boolean defaultValue = field.getBoolean(null); + boolean value = cfg.getBoolean(name, annotation.category(), defaultValue, annotation.comment()); + field.setBoolean(null, value); + } + } + else if (type == float.class) + { + ConfigFloat annotation = field.getAnnotation(ConfigFloat.class); + if (annotation != null) + { + String name = annotation.name().isEmpty() ? field.getName() : annotation.name(); + tryMoveProperty(cfg, name, annotation.category(), annotation.oldName(), annotation.oldCategory()); + + float defaultValue = field.getFloat(null); + float value = cfg.getFloat(name, annotation.category(), defaultValue, annotation.min(), annotation.max(), annotation.comment()); + field.setFloat(null, value); + } + } + else if (type == int.class) + { + ConfigInt annotation = field.getAnnotation(ConfigInt.class); + if (annotation != null) + { + String name = annotation.name().isEmpty() ? field.getName() : annotation.name(); + tryMoveProperty(cfg, name, annotation.category(), annotation.oldName(), annotation.oldCategory()); + + int defaultValue = field.getInt(null); + int value = cfg.getInt(name, annotation.category(), defaultValue, annotation.min(), annotation.max(), annotation.comment()); + field.setInt(null, value); + } + } + else if (type == String.class) + { + ConfigString annotation = field.getAnnotation(ConfigString.class); + if (annotation != null) + { + String name = annotation.name().isEmpty() ? field.getName() : annotation.name(); + tryMoveProperty(cfg, name, annotation.category(), annotation.oldName(), annotation.oldCategory()); + + String defaultValue = (String) field.get(null); + String value = cfg.getString(name, annotation.category(), defaultValue, annotation.comment()); + field.set(null, value); + } + } + else if (type == ItemBlockList.class) + { + ConfigItemBlockList annotation = field.getAnnotation(ConfigItemBlockList.class); + if (annotation != null) + { + String name = annotation.name().isEmpty() ? field.getName() : annotation.name(); + tryMoveProperty(cfg, name, annotation.category(), annotation.oldName(), annotation.oldCategory()); + + ItemBlockList list = (ItemBlockList) field.get(null); + Objects.requireNonNull(list, "ItemBlockList " + configClass.getName() + '.' + field.getName() + " must not be null"); + Set values = readStringCollection(cfg, name, annotation.category(), annotation.comment(), new HashSet<>(list.getRaw())); + list.clear(); + list.addRaw(values); + } + } + else if (type == ClassSet.class) + { + ConfigClassSet annotation = field.getAnnotation(ConfigClassSet.class); + if (annotation != null) + { + String name = annotation.name().isEmpty() ? field.getName() : annotation.name(); + tryMoveProperty(cfg, name, annotation.category(), annotation.oldName(), annotation.oldCategory()); + + ClassSet classSet = (ClassSet) field.get(null); + Objects.requireNonNull(classSet, "ClassSet " + configClass.getName() + '.' + field.getName() + " must not be null"); + Set values = readStringCollection(cfg, name, annotation.category(), annotation.comment(), new HashSet<>(classSet.getRaw())); + classSet.clear(); + classSet.addRaw(values); + } + } + else if (Enum.class.isAssignableFrom(type)) + { + ConfigEnum annotation = field.getAnnotation(ConfigEnum.class); + if (annotation != null) + { + String name = annotation.name().isEmpty() ? field.getName() : annotation.name(); + tryMoveProperty(cfg, name, annotation.category(), annotation.oldName(), annotation.oldCategory()); + + Enum defaultValue = (Enum) field.get(null); + Objects.requireNonNull(defaultValue, "Enum " + configClass.getName() + '.' + field.getName() + " must not be null"); + String valueName = cfg.getString(name, annotation.category(), defaultValue.name(), annotation.comment()); + try + { + Enum value = Enum.valueOf(defaultValue.getDeclaringClass(), valueName); + field.set(null, value); + } + catch (IllegalArgumentException e) + { + e.printStackTrace(); + } + } + } + else if (Collection.class.isAssignableFrom(type)) + { + // TODO Check generic type + ConfigStringCollection annotation = field.getAnnotation(ConfigStringCollection.class); + if (annotation != null) + { + String name = annotation.name().isEmpty() ? field.getName() : annotation.name(); + tryMoveProperty(cfg, name, annotation.category(), annotation.oldName(), annotation.oldCategory()); + + Collection collection = (Collection) field.get(null); + Objects.requireNonNull(collection, "Collection " + configClass.getName() + '.' + field.getName() + " must not be null"); + readStringCollection(cfg, name, annotation.category(), annotation.comment(), collection); + } + } + } + } + } + catch (Throwable throwable) + { + EventHelper.LOGGER.error("Failed reading config " + cfg.getConfigFile().getName(), throwable); + } + cfg.save(); + } + + private static boolean tryMoveProperty( + @Nonnull Configuration cfg, + @Nonnull String newName, + @Nonnull String newCategory, @Nullable String oldName, @Nullable String oldCategory) + { + if (newName.isEmpty() || newCategory.isEmpty()) + return false; + + if (Strings.isNullOrEmpty(oldCategory)) + oldCategory = newCategory; + if (Strings.isNullOrEmpty(oldName)) + oldName = newName; + + if (newName.equalsIgnoreCase(oldName) && newCategory.equalsIgnoreCase(oldCategory)) + return false; + + if (cfg.hasKey(newCategory, newName) || !cfg.hasKey(oldCategory, oldName)) + return false; + + ConfigCategory prevCategory = cfg.getCategory(oldCategory); + if (prevCategory.containsKey(oldName)) + { + Property property = prevCategory.remove(oldName); + property.setName(newName); + + ConfigCategory category; + if (newCategory.equalsIgnoreCase(oldCategory)) + category = prevCategory; + else + { + category = cfg.getCategory(newCategory); + if (prevCategory.isEmpty()) + cfg.removeCategory(prevCategory); + } + + category.put(newName, property); + + return true; + } + + return false; + } + + @Nonnull + private static String getConfigName(@Nonnull Class configClass) + { + Config annotation = configClass.getAnnotation(Config.class); + Objects.requireNonNull(annotation, "Annotaion " + Config.class.getName() + " not found for class " + configClass.getName()); + String cfgName = annotation.name(); + if (Strings.isNullOrEmpty(cfgName)) + cfgName = getPackageName(configClass.getName()); + Preconditions.checkArgument(!Strings.isNullOrEmpty(cfgName), "Config name for class " + configClass.getName() + " is not determined"); + return cfgName; + } + + @Nonnull + private static String getPackageName(@Nullable String className) + { + if (Strings.isNullOrEmpty(className)) + return PACKAGE_DEFAULT; + int classDelimeterIndex = className.lastIndexOf('.'); + if (classDelimeterIndex == -1) + return PACKAGE_DEFAULT; + String packageName = className.substring(0, classDelimeterIndex); + if (Strings.isNullOrEmpty(packageName)) + return PACKAGE_DEFAULT; + int packageDelimeterIndex = packageName.lastIndexOf('.'); + if (packageDelimeterIndex == -1) + return packageName; + String simplePackageName = packageName.substring(packageDelimeterIndex + 1); + return Strings.isNullOrEmpty(simplePackageName) ? PACKAGE_DEFAULT : simplePackageName; + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/config/ItemBlockList.java b/src/main/java/com/gamerforea/eventhelper/config/ItemBlockList.java new file mode 100644 index 0000000..78534d8 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/config/ItemBlockList.java @@ -0,0 +1,143 @@ +package com.gamerforea.eventhelper.config; + +import com.gamerforea.eventhelper.EventHelper; +import cpw.mods.fml.common.registry.FMLControlledNamespacedRegistry; +import cpw.mods.fml.common.registry.GameData; +import gnu.trove.set.TIntSet; +import gnu.trove.set.hash.TIntHashSet; +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import org.apache.commons.lang3.StringUtils; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.*; + +public final class ItemBlockList +{ + private static final String[] DEFAULT_VALUES = { "minecraft:bedrock", "modid:block_name@meta" }; + private static final char SEPARATOR = '@'; + private static final int ALL_META = -1; + + private final Set rawSet = new HashSet<>(); + private final Map items = new HashMap<>(); + private final Map blocks = new HashMap<>(); + private boolean loaded = true; + + public ItemBlockList() + { + this(false); + } + + public ItemBlockList(boolean initWithDefaultValues) + { + if (initWithDefaultValues) + this.addRaw(Arrays.asList(DEFAULT_VALUES)); + } + + public void clear() + { + this.loaded = true; + this.items.clear(); + this.blocks.clear(); + this.rawSet.clear(); + } + + public Set getRaw() + { + return Collections.unmodifiableSet(this.rawSet); + } + + public void addRaw(@Nonnull Collection strings) + { + this.loaded = false; + this.items.clear(); + this.blocks.clear(); + this.rawSet.addAll(strings); + } + + public boolean isEmpty() + { + return this.items.isEmpty() && this.blocks.isEmpty(); + } + + public boolean contains(@Nullable ItemStack stack) + { + return stack != null && this.contains(stack.getItem(), stack.getItemDamage()); + } + + public boolean contains(@Nonnull Item item, int meta) + { + this.load(); + return item instanceof ItemBlock && this.contains(((ItemBlock) item).field_150939_a, meta) || contains(this.items, item, meta); + } + + public boolean contains(@Nonnull Block block, int meta) + { + this.load(); + return contains(this.blocks, block, meta); + } + + private void load() + { + if (!this.loaded) + { + this.loaded = true; + + FMLControlledNamespacedRegistry itemRegistry = GameData.getItemRegistry(); + FMLControlledNamespacedRegistry blockRegistry = GameData.getBlockRegistry(); + + for (String s : this.rawSet) + { + s = s.trim(); + if (!s.isEmpty()) + { + String[] parts = StringUtils.split(s, SEPARATOR); + if (parts != null && parts.length > 0) + { + String name = parts[0]; + int meta = parts.length > 1 ? safeParseInt(parts[1]) : ALL_META; + Item item = itemRegistry.getObject(name); + if (item != null) + put(this.items, item, meta); + Block block = blockRegistry.getObject(name); + if (block != null && block != Blocks.air) + put(this.blocks, block, meta); + + if (EventHelper.debug && item == null && (block == null || block == Blocks.air)) + EventHelper.LOGGER.warn("Item/block {} not found", name); + } + } + } + } + } + + private static boolean put(Map map, K key, int value) + { + TIntSet set = map.get(key); + if (set == null) + map.put(key, set = new TIntHashSet()); + return set.add(value); + } + + private static boolean contains(Map map, K key, int value) + { + TIntSet set = map.get(key); + return set != null && (set.contains(value) || set.contains(ALL_META)); + } + + private static int safeParseInt(String s) + { + try + { + return Integer.parseInt(s); + } + catch (Throwable throwable) + { + return ALL_META; + } + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainer.java b/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainer.java index 6e5a821..59d5823 100644 --- a/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainer.java +++ b/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainer.java @@ -1,12 +1,10 @@ package com.gamerforea.eventhelper.fake; -import java.lang.ref.WeakReference; -import java.util.UUID; - import com.gamerforea.eventhelper.util.EventUtils; +import com.gamerforea.eventhelper.util.ExplosionByPlayer; import com.gamerforea.eventhelper.util.FastUtils; +import com.google.common.base.Preconditions; import com.mojang.authlib.GameProfile; - import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -14,24 +12,40 @@ import net.minecraft.world.World; import net.minecraftforge.common.util.FakePlayer; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.lang.ref.WeakReference; +import java.util.UUID; + public abstract class FakePlayerContainer { + private static final String NBT_OWNER_NAME = "eventhelper_fakeName"; + private static final String NBT_OWNER_UUID = "eventhelper_fakeUUID"; private final GameProfile modFakeProfile; private FakePlayer modFake; + @Nullable public GameProfile profile; private FakePlayer player; private WeakReference realPlayer; - protected FakePlayerContainer(FakePlayer modFake) + protected FakePlayerContainer(@Nonnull FakePlayer modFake) { - this.modFakeProfile = modFake.getGameProfile(); + this(modFake.getGameProfile()); this.modFake = modFake; } - protected FakePlayerContainer(GameProfile modFakeProfile) + protected FakePlayerContainer(@Nonnull FakePlayerContainer fake) { + this(fake.modFakeProfile); + this.modFake = fake.modFake; + this.setParent(fake); + } + + protected FakePlayerContainer(@Nonnull GameProfile modFakeProfile) + { + Preconditions.checkArgument(modFakeProfile.isComplete(), "modFakeProfile is incomplete"); this.modFakeProfile = modFakeProfile; } @@ -55,29 +69,33 @@ public final FakePlayer getPlayer() { if (this.player != null) return FastUtils.getFake(this.getWorld(), this.player); - else if (this.profile != null) + if (this.profile != null) return this.player = FastUtils.getFake(this.getWorld(), this.profile); - else if (this.modFake != null) + if (this.modFake != null) return FastUtils.getFake(this.getWorld(), this.modFake); - else - return this.modFake = FastUtils.getFake(this.getWorld(), this.modFakeProfile); + return this.modFake = FastUtils.getFake(this.getWorld(), this.modFakeProfile); } - public final void setRealPlayer(EntityPlayer player) + public final void setRealPlayer(@Nullable Entity entity) + { + this.setRealPlayer(entity instanceof EntityPlayer ? (EntityPlayer) entity : null); + } + + public final void setRealPlayer(@Nullable EntityPlayer player) { this.reset(); if (player != null) { - this.profile = player.getGameProfile(); - if (!(player instanceof FakePlayer)) - this.realPlayer = new WeakReference(player); + this.setProfile(player); + if (this.profile != null && !(player instanceof FakePlayer)) + this.realPlayer = new WeakReference<>(player); } } - public final void setParent(FakePlayerContainer container) + public final void setParent(@Nullable FakePlayerContainer container) { this.reset(); - if (container.profile != null) + if (container != null && container.profile != null) { this.profile = container.profile; this.player = container.player; @@ -85,15 +103,26 @@ public final void setParent(FakePlayerContainer container) } } + @Nullable public final GameProfile getProfile() { return this.profile; } - public final void setProfile(GameProfile profile) + public final void setProfile(@Nullable Entity entity) + { + this.setProfile(entity instanceof EntityPlayer ? (EntityPlayer) entity : null); + } + + public final void setProfile(@Nullable EntityPlayer player) + { + this.setProfile(player == null ? null : player.getGameProfile()); + } + + public final void setProfile(@Nullable GameProfile profile) { this.reset(); - this.profile = profile; + this.profile = profile == null || !profile.isComplete() ? null : profile; } public final boolean cantBreak(int x, int y, int z) @@ -101,12 +130,31 @@ public final boolean cantBreak(int x, int y, int z) return EventUtils.cantBreak(this.get(), x, y, z); } - public final boolean cantDamage(Entity target) + public final boolean cantBreak(double x, double y, double z) + { + return EventUtils.cantBreak(this.get(), x, y, z); + } + + public final boolean cantDamage(@Nonnull Entity target) { return EventUtils.cantDamage(this.get(), target); } - private final void reset() + @Nonnull + public final ExplosionByPlayer createExplosion( + @Nullable Entity entityIn, double x, double y, double z, float strength, boolean isSmoking) + { + return ExplosionByPlayer.createExplosion(this, this.getWorld(), entityIn, x, y, z, strength, isSmoking); + } + + @Nonnull + public final ExplosionByPlayer newExplosion(@Nullable + Entity entityIn, double x, double y, double z, float strength, boolean isFlaming, boolean isSmoking) + { + return ExplosionByPlayer.newExplosion(this, this.getWorld(), entityIn, x, y, z, strength, isFlaming, isSmoking); + } + + private void reset() { this.profile = null; this.player = null; @@ -117,19 +165,19 @@ public final void writeToNBT(NBTTagCompound nbt) { if (this.profile != null) { - nbt.setString("eventhelper_fakeName", this.profile.getName()); - nbt.setString("eventhelper_fakeUUID", this.profile.getId().toString()); + nbt.setString(NBT_OWNER_NAME, this.profile.getName()); + nbt.setString(NBT_OWNER_UUID, this.profile.getId().toString()); } } public final void readFromNBT(NBTTagCompound nbt) { - this.profile = readProfile(nbt, "eventhelper_fakeName", "eventhelper_fakeUUID"); + this.profile = readProfile(nbt, NBT_OWNER_NAME, NBT_OWNER_UUID); if (this.profile == null) this.profile = readProfile(nbt, "ownerName", "ownerUUID"); } - private static final GameProfile readProfile(NBTTagCompound nbt, String nameKey, String uuidKey) + private static GameProfile readProfile(NBTTagCompound nbt, String nameKey, String uuidKey) { String name = nbt.getString(nameKey); if (!name.isEmpty()) diff --git a/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainerEntity.java b/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainerEntity.java index 69b084e..c98f414 100644 --- a/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainerEntity.java +++ b/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainerEntity.java @@ -1,25 +1,37 @@ package com.gamerforea.eventhelper.fake; import com.mojang.authlib.GameProfile; - import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; import net.minecraftforge.common.util.FakePlayer; +import javax.annotation.Nonnull; + public final class FakePlayerContainerEntity extends FakePlayerContainer { private final Entity entity; - public FakePlayerContainerEntity(FakePlayer modFake, Entity entity) + public FakePlayerContainerEntity(@Nonnull FakePlayer modFake, @Nonnull Entity entity) { super(modFake); this.entity = entity; + this.setRealPlayer(entity); + } + + public FakePlayerContainerEntity(@Nonnull FakePlayerContainer fake, @Nonnull Entity entity) + { + super(fake); + this.entity = entity; + if (entity instanceof EntityPlayer) + this.setRealPlayer(entity); } - public FakePlayerContainerEntity(GameProfile modFakeProfile, Entity entity) + public FakePlayerContainerEntity(@Nonnull GameProfile modFakeProfile, @Nonnull Entity entity) { super(modFakeProfile); this.entity = entity; + this.setRealPlayer(entity); } @Override diff --git a/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainerTileEntity.java b/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainerTileEntity.java index a67074c..619ed2d 100644 --- a/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainerTileEntity.java +++ b/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainerTileEntity.java @@ -1,22 +1,29 @@ package com.gamerforea.eventhelper.fake; import com.mojang.authlib.GameProfile; - import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraftforge.common.util.FakePlayer; +import javax.annotation.Nonnull; + public final class FakePlayerContainerTileEntity extends FakePlayerContainer { private final TileEntity tile; - public FakePlayerContainerTileEntity(FakePlayer modFake, TileEntity tile) + public FakePlayerContainerTileEntity(@Nonnull FakePlayer modFake, @Nonnull TileEntity tile) { super(modFake); this.tile = tile; } - public FakePlayerContainerTileEntity(GameProfile modFakeProfile, TileEntity tile) + public FakePlayerContainerTileEntity(@Nonnull FakePlayerContainer fake, @Nonnull TileEntity tile) + { + super(fake); + this.tile = tile; + } + + public FakePlayerContainerTileEntity(@Nonnull GameProfile modFakeProfile, @Nonnull TileEntity tile) { super(modFakeProfile); this.tile = tile; diff --git a/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainerWorld.java b/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainerWorld.java index dc14481..0a1f29a 100644 --- a/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainerWorld.java +++ b/src/main/java/com/gamerforea/eventhelper/fake/FakePlayerContainerWorld.java @@ -1,21 +1,28 @@ package com.gamerforea.eventhelper.fake; import com.mojang.authlib.GameProfile; - import net.minecraft.world.World; import net.minecraftforge.common.util.FakePlayer; +import javax.annotation.Nonnull; + public final class FakePlayerContainerWorld extends FakePlayerContainer { private final World world; - public FakePlayerContainerWorld(FakePlayer modFake, World world) + public FakePlayerContainerWorld(@Nonnull FakePlayer modFake, @Nonnull World world) { super(modFake); this.world = world; } - public FakePlayerContainerWorld(GameProfile modFakeProfile, World world) + public FakePlayerContainerWorld(@Nonnull FakePlayerContainer fake, @Nonnull World world) + { + super(fake); + this.world = world; + } + + public FakePlayerContainerWorld(@Nonnull GameProfile modFakeProfile, @Nonnull World world) { super(modFakeProfile); this.world = world; diff --git a/src/main/java/com/gamerforea/eventhelper/inject/InjectionManager.java b/src/main/java/com/gamerforea/eventhelper/inject/InjectionManager.java new file mode 100644 index 0000000..1e3d42b --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/inject/InjectionManager.java @@ -0,0 +1,55 @@ +package com.gamerforea.eventhelper.inject; + +import com.gamerforea.eventhelper.inject.gpp.GPPInjection; +import com.gamerforea.eventhelper.inject.wg.WGInjection; +import org.bukkit.World; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +public final class InjectionManager +{ + private static final List injections = new ArrayList<>(); + + public static void init() + { + PluginInjection wgInj = WGInjection.getInjection(); + if (wgInj != null) + injections.add(wgInj); + + PluginInjection gppInj = GPPInjection.getInjection(); + if (gppInj != null) + injections.add(gppInj); + } + + public static boolean isInPrivate(World world, int x, int y, int z) + { + for (PluginInjection inj : injections) + { + if (inj.isInPrivate(world, x, y, z)) + return true; + } + return false; + } + + public static boolean isPrivateMember(Player player, int x, int y, int z) + { + for (PluginInjection inj : injections) + { + if (!inj.isPrivateMember(player, x, y, z)) + return false; + } + return true; + } + + public static boolean isPrivateOwner(Player player, int x, int y, int z) + { + for (PluginInjection inj : injections) + { + if (!inj.isPrivateOwner(player, x, y, z)) + return false; + } + return true; + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/inject/PluginInjection.java b/src/main/java/com/gamerforea/eventhelper/inject/PluginInjection.java new file mode 100644 index 0000000..cf49f08 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/inject/PluginInjection.java @@ -0,0 +1,13 @@ +package com.gamerforea.eventhelper.inject; + +import org.bukkit.World; +import org.bukkit.entity.Player; + +public interface PluginInjection +{ + boolean isInPrivate(World world, int x, int y, int z); + + boolean isPrivateMember(Player player, int x, int y, int z); + + boolean isPrivateOwner(Player player, int x, int y, int z); +} diff --git a/src/main/java/com/gamerforea/eventhelper/inject/gpp/GPPInjection.java b/src/main/java/com/gamerforea/eventhelper/inject/gpp/GPPInjection.java new file mode 100644 index 0000000..fd79715 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/inject/gpp/GPPInjection.java @@ -0,0 +1,52 @@ +package com.gamerforea.eventhelper.inject.gpp; + +import com.gamerforea.eventhelper.inject.PluginInjection; +import com.gamerforea.eventhelper.util.InjectionUtils; +import net.kaikk.mc.gpp.Claim; +import net.kaikk.mc.gpp.GriefPreventionPlus; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; + +public final class GPPInjection +{ + public static PluginInjection getInjection() + { + Class clazz = InjectionUtils.injectClass("GriefPreventionPlus", GPPInjection.class); + if (clazz != null) + try + { + return (PluginInjection) clazz.newInstance(); + } + catch (Throwable throwable) + { + throwable.printStackTrace(); + } + return null; + } + + public static final class Inj implements PluginInjection + { + @Override + public boolean isInPrivate(World world, int x, int y, int z) + { + GriefPreventionPlus plugin = GriefPreventionPlus.getInstance(); + Claim claim = plugin.getDataStore().getClaimAt(new Location(world, x, y, z), false); + return claim != null; + } + + @Override + public boolean isPrivateMember(Player player, int x, int y, int z) + { + return this.isPrivateOwner(player, x, y, z); + } + + @Override + public boolean isPrivateOwner(Player player, int x, int y, int z) + { + GriefPreventionPlus plugin = GriefPreventionPlus.getInstance(); + Claim claim = plugin.getDataStore().getClaimAt(new Location(player.getWorld(), x, y, z), false); + return claim != null && player.getUniqueId().equals(claim.getOwnerID()); + } + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/inject/wg/WGInjection.java b/src/main/java/com/gamerforea/eventhelper/inject/wg/WGInjection.java new file mode 100644 index 0000000..c6b1dc4 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/inject/wg/WGInjection.java @@ -0,0 +1,55 @@ +package com.gamerforea.eventhelper.inject.wg; + +import com.gamerforea.eventhelper.inject.PluginInjection; +import com.gamerforea.eventhelper.util.InjectionUtils; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import org.bukkit.World; +import org.bukkit.entity.Player; + +public final class WGInjection +{ + public static PluginInjection getInjection() + { + Class clazz = InjectionUtils.injectClass("WorldGuard", WGInjection.class); + if (clazz != null) + try + { + return (PluginInjection) clazz.newInstance(); + } + catch (Throwable throwable) + { + throwable.printStackTrace(); + } + return null; + } + + public static final class Inj implements PluginInjection + { + @Override + public boolean isInPrivate(World world, int x, int y, int z) + { + for (ProtectedRegion region : WorldGuardPlugin.inst().getRegionManager(world).getApplicableRegions(new Vector(x, y, z))) + { + if (!region.getId().equals(ProtectedRegion.GLOBAL_REGION)) + return true; + } + return false; + } + + @Override + public boolean isPrivateMember(Player player, int x, int y, int z) + { + WorldGuardPlugin wg = WorldGuardPlugin.inst(); + return wg.getRegionManager(player.getWorld()).getApplicableRegions(new Vector(x, y, z)).isMemberOfAll(wg.wrapPlayer(player, true)); + } + + @Override + public boolean isPrivateOwner(Player player, int x, int y, int z) + { + WorldGuardPlugin wg = WorldGuardPlugin.inst(); + return wg.getRegionManager(player.getWorld()).getApplicableRegions(new Vector(x, y, z)).isOwnerOfAll(wg.wrapPlayer(player, true)); + } + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/nexus/ModNexus.java b/src/main/java/com/gamerforea/eventhelper/nexus/ModNexus.java new file mode 100644 index 0000000..9a9d891 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/nexus/ModNexus.java @@ -0,0 +1,15 @@ +package com.gamerforea.eventhelper.nexus; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModNexus +{ + String name(); + + String uuid() default ""; +} diff --git a/src/main/java/com/gamerforea/eventhelper/nexus/ModNexusFactory.java b/src/main/java/com/gamerforea/eventhelper/nexus/ModNexusFactory.java new file mode 100644 index 0000000..408237c --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/nexus/ModNexusFactory.java @@ -0,0 +1,55 @@ +package com.gamerforea.eventhelper.nexus; + +import com.gamerforea.eventhelper.fake.FakePlayerContainerEntity; +import com.gamerforea.eventhelper.fake.FakePlayerContainerTileEntity; +import com.gamerforea.eventhelper.fake.FakePlayerContainerWorld; +import com.gamerforea.eventhelper.util.FastUtils; +import com.google.common.base.Preconditions; +import com.mojang.authlib.GameProfile; +import net.minecraft.entity.Entity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraftforge.common.util.FakePlayer; + +import javax.annotation.Nonnull; + +public final class ModNexusFactory +{ + private final GameProfile modFakeProfile; + + public ModNexusFactory(@Nonnull GameProfile modFakeProfile) + { + Preconditions.checkArgument(modFakeProfile.isComplete(), "modFakeProfile is incomplete"); + this.modFakeProfile = modFakeProfile; + } + + @Nonnull + public GameProfile getProfile() + { + return this.modFakeProfile; + } + + @Nonnull + public FakePlayer getFake(@Nonnull World world) + { + return FastUtils.getFake(world, this.modFakeProfile); + } + + @Nonnull + public FakePlayerContainerEntity wrapFake(@Nonnull Entity entity) + { + return new FakePlayerContainerEntity(this.modFakeProfile, entity); + } + + @Nonnull + public FakePlayerContainerTileEntity wrapFake(@Nonnull TileEntity tile) + { + return new FakePlayerContainerTileEntity(this.modFakeProfile, tile); + } + + @Nonnull + public FakePlayerContainerWorld wrapFake(@Nonnull World world) + { + return new FakePlayerContainerWorld(this.modFakeProfile, world); + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/nexus/NexusUtils.java b/src/main/java/com/gamerforea/eventhelper/nexus/NexusUtils.java new file mode 100644 index 0000000..db9ed28 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/nexus/NexusUtils.java @@ -0,0 +1,90 @@ +package com.gamerforea.eventhelper.nexus; + +import com.gamerforea.eventhelper.util.ReflectionUtils; +import com.google.common.base.Preconditions; +import com.google.common.hash.Hashing; +import com.mojang.authlib.GameProfile; + +import javax.annotation.Nonnull; +import java.nio.charset.StandardCharsets; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +public final class NexusUtils +{ + @Nonnull + public static ModNexusFactory getFactory() + { + return getFactory(getGameProfile()); + } + + @Nonnull + public static ModNexusFactory getFactory(@Nonnull Class modNexusClass) + { + return getFactory(getGameProfile(modNexusClass)); + } + + @Nonnull + public static ModNexusFactory getFactory(@Nonnull GameProfile profile) + { + return new ModNexusFactory(profile); + } + + @Nonnull + public static GameProfile getGameProfile() + { + Class[] callingClasses = ReflectionUtils.getCallingClasses(); + Set> visitedClasses = new HashSet<>(callingClasses.length); + for (Class callerClass : callingClasses) + { + if (visitedClasses.add(callerClass)) + { + ModNexus annotation = callerClass.getAnnotation(ModNexus.class); + if (annotation != null) + return getGameProfile(callerClass); + } + } + throw new IllegalStateException("Class with ModNexus annotation not found in StackTrace"); + } + + @Nonnull + public static GameProfile getGameProfile(@Nonnull Class modNexusClass) + { + ModNexus annotation = getModNexusAnnotation(modNexusClass); + return annotation.uuid().isEmpty() ? getGameProfile(annotation.name()) : getGameProfile(annotation.name(), UUID.fromString(annotation.uuid())); + } + + @Nonnull + public static GameProfile getGameProfile(@Nonnull String fakeName) + { + Preconditions.checkArgument(!fakeName.isEmpty(), "fakeName must not be empty"); + if (fakeName.charAt(0) != '[') + fakeName = '[' + fakeName + ']'; + return getGameProfile(fakeName, stringToId(fakeName)); + } + + @Nonnull + public static GameProfile getGameProfile(@Nonnull String fakeName, @Nonnull UUID fakeId) + { + Preconditions.checkArgument(!fakeName.isEmpty(), "fakeName must not be empty"); + if (fakeName.charAt(0) != '[') + fakeName = '[' + fakeName + ']'; + return new GameProfile(fakeId, fakeName); + } + + @Nonnull + private static UUID stringToId(@Nonnull String fakeName) + { + return new UUID(Hashing.md5().hashBytes(fakeName.getBytes(StandardCharsets.UTF_8)).asLong(), Hashing.sha1().hashBytes(fakeName.getBytes(StandardCharsets.UTF_8)).asLong()); + } + + @Nonnull + private static ModNexus getModNexusAnnotation(@Nonnull Class modNexusClass) + { + ModNexus annotation = modNexusClass.getAnnotation(ModNexus.class); + Preconditions.checkNotNull(annotation, "ModNexus annotation not found in class " + modNexusClass.getName()); + Preconditions.checkArgument(!annotation.name().isEmpty(), "ModNexus.name() must not be empty"); + return annotation; + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/util/ConvertUtils.java b/src/main/java/com/gamerforea/eventhelper/util/ConvertUtils.java index b5f328d..a3b65af 100644 --- a/src/main/java/com/gamerforea/eventhelper/util/ConvertUtils.java +++ b/src/main/java/com/gamerforea/eventhelper/util/ConvertUtils.java @@ -1,43 +1,42 @@ package com.gamerforea.eventhelper.util; -import java.lang.reflect.Method; - -import org.bukkit.Bukkit; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.Player; - import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; +import org.bukkit.Bukkit; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; + +import java.lang.reflect.Method; public final class ConvertUtils { private static final Method getBukkitEntity; private static final Method asCraftMirror; - public static final org.bukkit.entity.Entity toBukkitEntity(Entity entity) throws Exception + public static org.bukkit.entity.Entity toBukkitEntity(Entity entity) throws Exception { return (org.bukkit.entity.Entity) getBukkitEntity.invoke(entity); } - public static final Player toBukkitEntity(EntityPlayer player) throws Exception + public static Player toBukkitEntity(EntityPlayer player) throws Exception { return (Player) getBukkitEntity.invoke(player); } - public static final org.bukkit.World toBukkitWorld(World world) + public static org.bukkit.World toBukkitWorld(World world) { return Bukkit.getWorld(world.getWorldInfo().getWorldName()); } - public static final org.bukkit.inventory.ItemStack toBukkitItemStackMirror(ItemStack stack) throws Exception + public static org.bukkit.inventory.ItemStack toBukkitItemStackMirror(ItemStack stack) throws Exception { return (org.bukkit.inventory.ItemStack) asCraftMirror.invoke(null, stack); } - public static final BlockFace toBukkitFace(ForgeDirection direction) + public static BlockFace toBukkitFace(ForgeDirection direction) { switch (direction) { @@ -67,7 +66,7 @@ public static final BlockFace toBukkitFace(ForgeDirection direction) getBukkitEntity = Entity.class.getDeclaredMethod("getBukkitEntity"); getBukkitEntity.setAccessible(true); - asCraftMirror = CraftUtils.getCraftClass("inventory/CraftItemStack").getDeclaredMethod("asCraftMirror", ItemStack.class); + asCraftMirror = CraftUtils.getCraftClass("inventory.CraftItemStack").getDeclaredMethod("asCraftMirror", ItemStack.class); asCraftMirror.setAccessible(true); } catch (Throwable throwable) diff --git a/src/main/java/com/gamerforea/eventhelper/util/CooldownManager.java b/src/main/java/com/gamerforea/eventhelper/util/CooldownManager.java new file mode 100644 index 0000000..e1d1833 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/util/CooldownManager.java @@ -0,0 +1,65 @@ +package com.gamerforea.eventhelper.util; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent; +import gnu.trove.iterator.TObjectLongIterator; +import gnu.trove.map.TObjectLongMap; +import gnu.trove.map.hash.TObjectLongHashMap; +import net.minecraftforge.common.MinecraftForge; + +import javax.annotation.Nonnull; +import java.util.concurrent.TimeUnit; + +public class CooldownManager +{ + private final TObjectLongMap cooldowns = new TObjectLongHashMap<>(); + private final long cooldown; + + public CooldownManager(long cooldown, @Nonnull TimeUnit timeUnit) + { + this(cooldown <= 0 ? 0 : timeUnit.toSeconds(cooldown) * 20); + } + + public CooldownManager(long cooldownInTicks) + { + this.cooldown = Math.max(0, cooldownInTicks); + if (this.cooldown > 0) + MinecraftForge.EVENT_BUS.register(this); + } + + public boolean canAdd(@Nonnull T key) + { + return this.cooldown <= 0 || !this.cooldowns.containsKey(key); + } + + public boolean add(@Nonnull T key) + { + if (this.cooldown <= 0) + return true; + if (this.canAdd(key)) + { + this.cooldowns.put(key, this.cooldown); + return true; + } + return false; + } + + public long getCooldown(@Nonnull T key) + { + return this.cooldown <= 0 ? 0 : this.cooldowns.get(key); + } + + @SubscribeEvent + public void onTick(TickEvent.ServerTickEvent event) + { + for (TObjectLongIterator iterator = this.cooldowns.iterator(); iterator.hasNext(); ) + { + iterator.advance(); + long timer = iterator.value() - 1; + if (timer <= 0) + iterator.remove(); + else + iterator.setValue(timer); + } + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/util/CraftUtils.java b/src/main/java/com/gamerforea/eventhelper/util/CraftUtils.java index 75bb18d..a9f5e57 100644 --- a/src/main/java/com/gamerforea/eventhelper/util/CraftUtils.java +++ b/src/main/java/com/gamerforea/eventhelper/util/CraftUtils.java @@ -4,8 +4,8 @@ public final class CraftUtils { - public static final Class getCraftClass(String name) throws ClassNotFoundException + public static Class getCraftClass(String name) throws ClassNotFoundException { - return Class.forName((EventHelper.craftPackage + '/' + name).replace("//", ".").replace('/', '.')); + return Class.forName((EventHelper.craftPackage + '.' + name).replace("//", ".").replace('/', '.')); } } diff --git a/src/main/java/com/gamerforea/eventhelper/util/EventUtils.java b/src/main/java/com/gamerforea/eventhelper/util/EventUtils.java index a1f67dc..fafcf1a 100644 --- a/src/main/java/com/gamerforea/eventhelper/util/EventUtils.java +++ b/src/main/java/com/gamerforea/eventhelper/util/EventUtils.java @@ -1,10 +1,14 @@ package com.gamerforea.eventhelper.util; -import static com.gamerforea.eventhelper.util.ConvertUtils.toBukkitEntity; -import static com.gamerforea.eventhelper.util.ConvertUtils.toBukkitFace; -import static com.gamerforea.eventhelper.util.ConvertUtils.toBukkitItemStackMirror; -import static com.gamerforea.eventhelper.util.ConvertUtils.toBukkitWorld; - +import com.gamerforea.eventhelper.EventHelper; +import com.gamerforea.eventhelper.inject.InjectionManager; +import com.google.common.base.Strings; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; @@ -13,19 +17,16 @@ import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.player.PlayerInteractEvent; -import com.gamerforea.eventhelper.EventHelper; -import com.gamerforea.eventhelper.wg.WGRegionChecker; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.UUID; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.util.MathHelper; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; +import static com.gamerforea.eventhelper.util.ConvertUtils.*; +import static net.minecraft.util.MathHelper.floor_double; public final class EventUtils { - public static final boolean cantBreak(EntityPlayer player, int x, int y, int z) + public static boolean cantBreak(@Nonnull EntityPlayer player, int x, int y, int z) { try { @@ -36,39 +37,36 @@ public static final boolean cantBreak(EntityPlayer player, int x, int y, int z) } catch (Throwable throwable) { - err("Failed call BlockBreakEvent: [Player: %s, X:%d, Y:%d, Z:%d]", String.valueOf(player), x, y, z); - if (EventHelper.debug) - throwable.printStackTrace(); + EventHelper.error(throwable, "Failed call BlockBreakEvent: [Player: {}, X:{}, Y:{}, Z:{}]", String.valueOf(player), x, y, z); return true; } } - public static final boolean cantBreak(EntityPlayer player, double x, double y, double z) + public static boolean cantBreak(@Nonnull EntityPlayer player, double x, double y, double z) { - int xx = MathHelper.floor_double(x); - int yy = MathHelper.floor_double(y); - int zz = MathHelper.floor_double(z); + int xx = floor_double(x); + int yy = floor_double(y); + int zz = floor_double(z); return cantBreak(player, xx, yy, zz); } - public static final boolean cantDamage(Entity damager, Entity damagee) + public static boolean cantDamage(@Nonnull Entity attacker, @Nonnull Entity victim) { try { - EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(toBukkitEntity(damager), toBukkitEntity(damagee), DamageCause.ENTITY_ATTACK, 0D); + EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(toBukkitEntity(attacker), toBukkitEntity(victim), DamageCause.ENTITY_ATTACK, 0D); EventHelper.callEvent(event); return event.isCancelled(); } catch (Throwable throwable) { - err("Failed call EntityDamageByEntityEvent: [Damager: %s, Damagee: %s]", String.valueOf(damager), String.valueOf(damagee)); - if (EventHelper.debug) - throwable.printStackTrace(); + EventHelper.error(throwable, "Failed call EntityDamageByEntityEvent: [Attacker: {}, Victim: {}]", String.valueOf(attacker), String.valueOf(victim)); return true; } } - public static final boolean cantInteract(EntityPlayer player, ItemStack stack, int x, int y, int z, ForgeDirection side) + public static boolean cantInteract( + @Nonnull EntityPlayer player, @Nullable ItemStack stack, int x, int y, int z, @Nonnull ForgeDirection side) { try { @@ -79,14 +77,12 @@ public static final boolean cantInteract(EntityPlayer player, ItemStack stack, i } catch (Throwable throwable) { - err("Failed call PlayerInteractEvent: [Player: %s, Item: %s, X:%d, Y:%d, Z:%d, Side: %s]", String.valueOf(player), String.valueOf(stack), x, y, z, String.valueOf(side)); - if (EventHelper.debug) - throwable.printStackTrace(); + EventHelper.error(throwable, "Failed call PlayerInteractEvent: [Player: {}, Item: {}, X:{}, Y:{}, Z:{}, Side: {}]", String.valueOf(player), String.valueOf(stack), x, y, z, String.valueOf(side)); return true; } } - public static final boolean cantFromTo(World world, int fromX, int fromY, int fromZ, int toX, int toY, int toZ) + public static boolean cantFromTo(@Nonnull World world, int fromX, int fromY, int fromZ, int toX, int toY, int toZ) { try { @@ -97,14 +93,13 @@ public static final boolean cantFromTo(World world, int fromX, int fromY, int fr } catch (Throwable throwable) { - err("Failed call BlockFromToEvent: [FromX: %d, FromY: %d, FromZ: %d, ToX: %d, ToY: %d, ToZ: %d]", fromX, fromY, fromZ, toX, toY, toZ); - if (EventHelper.debug) - throwable.printStackTrace(); + EventHelper.error(throwable, "Failed call BlockFromToEvent: [FromX: {}, FromY: {}, FromZ: {}, ToX: {}, ToY: {}, ToZ: {}]", fromX, fromY, fromZ, toX, toY, toZ); return true; } } - public static final boolean cantFromTo(World world, int fromX, int fromY, int fromZ, ForgeDirection direction) + public static boolean cantFromTo( + @Nonnull World world, int fromX, int fromY, int fromZ, @Nonnull ForgeDirection direction) { try { @@ -115,38 +110,122 @@ public static final boolean cantFromTo(World world, int fromX, int fromY, int fr } catch (Throwable throwable) { - err("Failed call BlockFromToEvent: [FromX: %d, FromY: %d, FromZ: %d, Direction: %s]", fromX, fromY, fromZ, String.valueOf(direction)); - if (EventHelper.debug) - throwable.printStackTrace(); + EventHelper.error(throwable, "Failed call BlockFromToEvent: [FromX: {}, FromY: {}, FromZ: {}, Direction: {}]", fromX, fromY, fromZ, String.valueOf(direction)); + return true; + } + } + + public static boolean isInPrivate(@Nonnull World world, int x, int y, int z) + { + try + { + return InjectionManager.isInPrivate(toBukkitWorld(world), x, y, z); + } + catch (Throwable throwable) + { + EventHelper.error(throwable, "Failed check private: [World: {}, X: {}, Y: {}, Z: {}]", world.getWorldInfo().getWorldName(), x, y, z); return true; } } - public static final boolean isInPrivate(World world, int x, int y, int z) + public static boolean isPrivateMember(@Nonnull EntityPlayer player, double x, double y, double z) + { + int xx = floor_double(x); + int yy = floor_double(y); + int zz = floor_double(z); + return isPrivateMember(player, xx, yy, zz); + } + + public static boolean isPrivateMember(@Nonnull EntityPlayer player, int x, int y, int z) { try { - return WGRegionChecker.isInPrivate(toBukkitWorld(world), x, y, z); + return InjectionManager.isPrivateMember(toBukkitEntity(player), x, y, z); } catch (Throwable throwable) { - err("Failed check private: [World: %s, X: %d, Y: %d, Z: %d]", world.getWorldInfo().getWorldName(), x, y, z); - if (EventHelper.debug) - throwable.printStackTrace(); + EventHelper.error(throwable, "Failed check private member: [Player: {}, X: {}, Y: {}, Z: {}]", String.valueOf(player), x, y, z); return true; } } - public static final boolean isInPrivate(Entity entity) + public static boolean isPrivateOwner(@Nonnull EntityPlayer player, double x, double y, double z) { - int x = MathHelper.floor_double(entity.posX); - int y = MathHelper.floor_double(entity.posY); - int z = MathHelper.floor_double(entity.posZ); + int xx = floor_double(x); + int yy = floor_double(y); + int zz = floor_double(z); + return isPrivateOwner(player, xx, yy, zz); + } + + public static boolean isPrivateOwner(@Nonnull EntityPlayer player, int x, int y, int z) + { + try + { + return InjectionManager.isPrivateOwner(toBukkitEntity(player), x, y, z); + } + catch (Throwable throwable) + { + EventHelper.error(throwable, "Failed check private owner: [Player: {}, X: {}, Y: {}, Z: {}]", String.valueOf(player), x, y, z); + return true; + } + } + + public static boolean isInPrivate(@Nonnull Entity entity) + { + int x = floor_double(entity.posX); + int y = floor_double(entity.posY); + int z = floor_double(entity.posZ); return isInPrivate(entity.worldObj, x, y, z); } - private static final void err(String format, Object... args) + public static boolean hasPermission(@Nullable EntityPlayer player, @Nonnull String permission) { - System.err.println(String.format(format, args)); + if (player == null) + return false; + + try + { + Player bPlayer = toBukkitEntity(player); + return bPlayer != null && bPlayer.hasPermission(permission); + } + catch (Throwable throwable) + { + EventHelper.error(throwable, "Failed checking permission: [Player: {}, Permission: {}]", player, permission); + return false; + } + } + + public static boolean hasPermission(@Nullable UUID playerId, @Nonnull String permission) + { + if (playerId == null) + return false; + + try + { + Player player = Bukkit.getPlayer(playerId); + return player != null && player.hasPermission(permission); + } + catch (Throwable throwable) + { + EventHelper.error(throwable, "Failed checking permission: [Player name: {}, Permission: {}]", playerId, permission); + return false; + } + } + + public static boolean hasPermission(@Nullable String playerName, @Nonnull String permission) + { + if (Strings.isNullOrEmpty(playerName)) + return false; + + try + { + Player player = Bukkit.getPlayerExact(playerName); + return player != null && player.hasPermission(permission); + } + catch (Throwable throwable) + { + EventHelper.error(throwable, "Failed checking permission: [Player UUID: {}, Permission: {}]", playerName, permission); + return false; + } } } diff --git a/src/main/java/com/gamerforea/eventhelper/util/ExplosionByPlayer.java b/src/main/java/com/gamerforea/eventhelper/util/ExplosionByPlayer.java new file mode 100644 index 0000000..b59afca --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/util/ExplosionByPlayer.java @@ -0,0 +1,280 @@ +package com.gamerforea.eventhelper.util; + +import com.gamerforea.eventhelper.EventHelper; +import com.gamerforea.eventhelper.fake.FakePlayerContainer; +import com.mojang.authlib.GameProfile; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.enchantment.EnchantmentProtection; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.play.server.S27PacketExplosion; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MathHelper; +import net.minecraft.util.Vec3; +import net.minecraft.world.ChunkPosition; +import net.minecraft.world.Explosion; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraftforge.common.util.FakePlayer; +import net.minecraftforge.event.ForgeEventFactory; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.*; + +public final class ExplosionByPlayer extends Explosion +{ + private final EntityPlayer player; + private final World world; + private final Map playerKnockbackMap = new HashMap<>(); + + public ExplosionByPlayer( + @Nonnull GameProfile modFakeProfile, + @Nullable EntityPlayer player, + @Nonnull World world, @Nullable Entity exploder, double x, double y, double z, float size) + { + this(player == null ? exploder instanceof EntityPlayer ? (EntityPlayer) exploder : FastUtils.getFake(world, modFakeProfile) : player, world, exploder, x, y, z, size); + } + + public ExplosionByPlayer( + @Nonnull FakePlayer modFake, + @Nullable EntityPlayer player, + @Nonnull World world, @Nullable Entity exploder, double x, double y, double z, float size) + { + this(player == null ? exploder instanceof EntityPlayer ? (EntityPlayer) exploder : modFake : player, world, exploder, x, y, z, size); + } + + public ExplosionByPlayer( + @Nonnull FakePlayerContainer fake, + @Nonnull World world, @Nullable Entity exploder, double x, double y, double z, float size) + { + this(fake.get(), world, exploder, x, y, z, size); + } + + public ExplosionByPlayer( + @Nonnull EntityPlayer player, + @Nonnull World world, @Nullable Entity exploder, double x, double y, double z, float size) + { + super(world, exploder, x, y, z, size); + this.world = world; + this.player = player; + } + + @Override + public final void doExplosionA() + { + if (!EventHelper.explosions) + return; + + this.affectedBlockPositions.addAll(this.getPositions()); + float size = this.explosionSize; + this.explosionSize *= 2; + int minX = MathHelper.floor_double(this.explosionX - this.explosionSize - 1); + int maxX = MathHelper.floor_double(this.explosionX + this.explosionSize + 1); + int minY = MathHelper.floor_double(this.explosionY - this.explosionSize - 1); + int maxY = MathHelper.floor_double(this.explosionY + this.explosionSize + 1); + int minZ = MathHelper.floor_double(this.explosionZ - this.explosionSize - 1); + int maxZ = MathHelper.floor_double(this.explosionZ + this.explosionSize + 1); + List entities = this.world.getEntitiesWithinAABBExcludingEntity(this.exploder, AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ)); + Vec3 vec3 = Vec3.createVectorHelper(this.explosionX, this.explosionY, this.explosionZ); + + for (Entity entity : entities) + { + double distance = entity.getDistance(this.explosionX, this.explosionY, this.explosionZ) / this.explosionSize; + + if (distance <= 1) + { + double distanceX = entity.posX - this.explosionX; + double distanceY = entity.posY + entity.getEyeHeight() - this.explosionY; + double distanceZ = entity.posZ - this.explosionZ; + double distance1 = MathHelper.sqrt_double(distanceX * distanceX + distanceY * distanceY + distanceZ * distanceZ); + + if (distance1 != 0) + { + if (EventUtils.cantDamage(this.player, entity)) + continue; + + distanceX /= distance1; + distanceY /= distance1; + distanceZ /= distance1; + double density = this.world.getBlockDensity(vec3, entity.boundingBox); + double d5 = (1 - distance) * density; + entity.attackEntityFrom(DamageSource.setExplosionSource(this), (int) ((d5 * d5 + d5) / 2 * 8 * this.explosionSize + 1)); + double d6 = EnchantmentProtection.func_92092_a(entity, d5); + entity.motionX += distanceX * d6; + entity.motionY += distanceY * d6; + entity.motionZ += distanceZ * d6; + + if (entity instanceof EntityPlayer) + { + EntityPlayer player = (EntityPlayer) entity; + this.playerKnockbackMap.put(player, Vec3.createVectorHelper(distanceX * d5, distanceY * d5, distanceZ * d5)); + } + } + } + } + + this.explosionSize = size; + } + + private Set getPositions() + { + Set set = new HashSet<>(); + for (int i = 0; i < 16; ++i) + { + for (int j = 0; j < 16; ++j) + { + for (int k = 0; k < 16; ++k) + { + if (i == 0 || i == 15 || j == 0 || j == 15 || k == 0 || k == 15) + { + double distanceX = i / 30F - 1F; + double distanceY = j / 30F - 1F; + double distanceZ = k / 30F - 1F; + double distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY + distanceZ * distanceZ); + distanceX /= distance; + distanceY /= distance; + distanceZ /= distance; + float size = this.explosionSize * (0.7F + this.world.rand.nextFloat() * 0.6F); + double dX = this.explosionX; + double dY = this.explosionY; + double dZ = this.explosionZ; + + for (float f = 0.3F; size > 0F; size -= f * 0.75F) + { + int x = MathHelper.floor_double(dX); + int y = MathHelper.floor_double(dY); + int z = MathHelper.floor_double(dZ); + Block block = this.world.getBlock(x, y, z); + + if (block.getMaterial() != Material.air) + { + float resistance = this.exploder != null ? this.exploder.func_145772_a(this, this.world, x, y, z, block) : block.getExplosionResistance(this.exploder, this.world, x, y, z, this.explosionX, this.explosionY, this.explosionZ); + size -= (resistance + 0.3F) * f; + } + + if (size > 0 && (this.exploder == null || this.exploder.func_145774_a(this, this.world, x, y, z, block, size))) + if (!EventUtils.cantBreak(this.player, x, y, z)) + set.add(new ChunkPosition(x, y, z)); + + dX += distanceX * f; + dY += distanceY * f; + dZ += distanceZ * f; + } + } + } + } + } + return set; + } + + @Override + public final Map func_77277_b() + { + return this.playerKnockbackMap; + } + + public static ExplosionByPlayer createExplosion( + @Nonnull GameProfile modFakeProfile, + @Nullable EntityPlayer player, + @Nonnull World world, @Nullable Entity exploder, double x, double y, double z, float size, boolean smoke) + { + return newExplosion(modFakeProfile, player, world, exploder, x, y, z, size, false, smoke); + } + + public static ExplosionByPlayer createExplosion( + @Nonnull FakePlayer modFake, + @Nullable EntityPlayer player, + @Nonnull World world, @Nullable Entity exploder, double x, double y, double z, float size, boolean smoke) + { + return newExplosion(modFake, player, world, exploder, x, y, z, size, false, smoke); + } + + @Nonnull + public static ExplosionByPlayer createExplosion( + @Nonnull FakePlayerContainer fake, + @Nonnull World world, @Nullable Entity exploder, double x, double y, double z, float size, boolean smoke) + { + return newExplosion(fake, world, exploder, x, y, z, size, false, smoke); + } + + @Nonnull + public static ExplosionByPlayer createExplosion( + @Nonnull EntityPlayer player, + @Nonnull World world, @Nullable Entity exploder, double x, double y, double z, float size, boolean smoke) + { + return newExplosion(player, world, exploder, x, y, z, size, false, smoke); + } + + public static ExplosionByPlayer newExplosion( + @Nonnull GameProfile modFakeProfile, + @Nullable EntityPlayer player, + @Nonnull World world, + @Nullable Entity exploder, double x, double y, double z, float size, boolean flame, boolean smoke) + { + ExplosionByPlayer explosion = new ExplosionByPlayer(modFakeProfile, player, world, exploder, x, y, z, size); + return newExplosion(explosion, world, x, y, z, size, flame, smoke); + } + + public static ExplosionByPlayer newExplosion( + @Nonnull FakePlayer modFake, + @Nullable EntityPlayer player, + @Nonnull World world, + @Nullable Entity exploder, double x, double y, double z, float size, boolean flame, boolean smoke) + { + ExplosionByPlayer explosion = new ExplosionByPlayer(modFake, player, world, exploder, x, y, z, size); + return newExplosion(explosion, world, x, y, z, size, flame, smoke); + } + + @Nonnull + public static ExplosionByPlayer newExplosion( + @Nonnull FakePlayerContainer fake, + @Nonnull World world, + @Nullable Entity exploder, double x, double y, double z, float size, boolean flame, boolean smoke) + { + ExplosionByPlayer explosion = new ExplosionByPlayer(fake, world, exploder, x, y, z, size); + return newExplosion(explosion, world, x, y, z, size, flame, smoke); + } + + @Nonnull + public static ExplosionByPlayer newExplosion( + @Nonnull EntityPlayer player, + @Nonnull World world, + @Nullable Entity exploder, double x, double y, double z, float size, boolean flame, boolean smoke) + { + ExplosionByPlayer explosion = new ExplosionByPlayer(player, world, exploder, x, y, z, size); + return newExplosion(explosion, world, x, y, z, size, flame, smoke); + } + + private static ExplosionByPlayer newExplosion( + @Nonnull ExplosionByPlayer explosion, + @Nonnull World world, double x, double y, double z, float size, boolean flame, boolean smoke) + { + explosion.isFlaming = flame; + explosion.isSmoking = smoke; + + if (ForgeEventFactory.onExplosionStart(world, explosion)) + return explosion; + + boolean isServerWorld = world instanceof WorldServer; + explosion.doExplosionA(); + explosion.doExplosionB(!isServerWorld); + + if (isServerWorld) + { + if (!smoke) + explosion.affectedBlockPositions.clear(); + + for (EntityPlayer target : (Iterable) world.playerEntities) + { + if (target.getDistanceSq(x, y, z) < 4096) + ((EntityPlayerMP) target).playerNetServerHandler.sendPacket(new S27PacketExplosion(x, y, z, size, explosion.affectedBlockPositions, (Vec3) explosion.func_77277_b().get(target))); + } + } + + return explosion; + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/util/FastUtils.java b/src/main/java/com/gamerforea/eventhelper/util/FastUtils.java index 62f18d4..ab029c5 100644 --- a/src/main/java/com/gamerforea/eventhelper/util/FastUtils.java +++ b/src/main/java/com/gamerforea/eventhelper/util/FastUtils.java @@ -1,91 +1,142 @@ package com.gamerforea.eventhelper.util; -import java.io.File; - -import com.gamerforea.eventhelper.EventHelper; +import com.gamerforea.eventhelper.config.ConfigUtils; +import com.gamerforea.eventhelper.fake.FakePlayerContainer; import com.mojang.authlib.GameProfile; - import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.relauncher.ReflectionHelper; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.projectile.EntityThrowable; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; import net.minecraft.server.MinecraftServer; +import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.common.config.Configuration; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.FakePlayerFactory; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.function.Function; + public final class FastUtils { - public static final Configuration getConfig(String cfgName) + @Deprecated + @Nonnull + public static Configuration getConfig(@Nonnull String cfgName) + { + return ConfigUtils.getConfig(cfgName); + } + + public static void stopPotionEffect(@Nonnull EntityLivingBase entity, @Nonnull Potion potion) + { + stopPotionEffect(entity.getActivePotionEffect(potion)); + } + + public static void stopPotionEffect(@Nullable PotionEffect potionEffect) { - Configuration cfg = new Configuration(new File(EventHelper.cfgDir, cfgName + ".cfg")); - cfg.load(); - return cfg; + if (potionEffect != null && potionEffect.getDuration() > 0) + ReflectionHelper.setPrivateValue(PotionEffect.class, potionEffect, 0, "field_76460_b", "duration"); + } + + public static boolean setProfile( + @Nonnull World world, int x, int y, int z, + @Nonnull Entity entity, Class tileClass, Function mapper) + { + if (entity instanceof EntityPlayer && world.blockExists(x, y, z)) + { + TileEntity tile = world.getTileEntity(x, y, z); + if (tile != null && tileClass.isInstance(tile)) + { + FakePlayerContainer fake = mapper.apply((T) tile); + fake.setProfile(entity); + return true; + } + } + return false; } - public static final boolean isOnline(EntityPlayer player) + public static boolean isOnline(@Nonnull EntityPlayer player) { if (player instanceof FakePlayer) return true; for (EntityPlayer playerOnline : (Iterable) getServer().getConfigurationManager().playerEntityList) + { if (playerOnline.equals(player)) return true; + } return false; } - public static final FakePlayer getFake(World world, FakePlayer fake) + @Nonnull + public static FakePlayer getFake(@Nullable World world, @Nonnull FakePlayer fake) { fake.worldObj = world == null ? getEntityWorld() : world; return fake; } - public static final FakePlayer getFake(World world, GameProfile profile) + @Nonnull + public static FakePlayer getFake(@Nullable World world, @Nonnull GameProfile profile) { return getFake(world, FakePlayerFactory.get((WorldServer) (world == null ? getEntityWorld() : world), profile)); } - public static final EntityPlayer getLivingPlayer(EntityLivingBase entity, FakePlayer modFake) + @Nonnull + public static EntityPlayer getLivingPlayer(@Nullable EntityLivingBase entity, @Nonnull FakePlayer modFake) { return entity instanceof EntityPlayer ? (EntityPlayer) entity : getFake(entity == null ? null : entity.worldObj, modFake); } - public static final EntityPlayer getLivingPlayer(EntityLivingBase entity, GameProfile modFakeProfile) + @Nonnull + public static EntityPlayer getLivingPlayer(@Nullable EntityLivingBase entity, @Nonnull GameProfile modFakeProfile) { return entity instanceof EntityPlayer ? (EntityPlayer) entity : getFake(entity == null ? null : entity.worldObj, modFakeProfile); } - public static final EntityPlayer getThrowerPlayer(EntityThrowable entity, FakePlayer modFake) + @Nonnull + public static EntityPlayer getThrowerPlayer(@Nullable EntityThrowable entity, @Nonnull FakePlayer modFake) { - return getLivingPlayer(entity.getThrower(), modFake); + return getLivingPlayer(entity == null ? null : entity.getThrower(), modFake); } - public static final EntityPlayer getThrowerPlayer(EntityThrowable entity, GameProfile modFakeProfile) + @Nonnull + public static EntityPlayer getThrowerPlayer(@Nullable EntityThrowable entity, @Nonnull GameProfile modFakeProfile) { - return getLivingPlayer(entity.getThrower(), modFakeProfile); + return getLivingPlayer(entity == null ? null : entity.getThrower(), modFakeProfile); } - public static final EntityLivingBase getThrower(EntityThrowable entity, FakePlayer modFake) + @Nonnull + public static EntityLivingBase getThrower(@Nullable EntityThrowable entity, @Nonnull FakePlayer modFake) { + if (entity == null) + return getFake(getEntityWorld(), modFake); EntityLivingBase thrower = entity.getThrower(); - return thrower != null ? thrower : getFake(entity == null ? null : entity.worldObj, modFake); + return thrower == null ? getFake(entity.worldObj, modFake) : thrower; } - public static final EntityLivingBase getThrower(EntityThrowable entity, GameProfile modFakeProfile) + @Nonnull + public static EntityLivingBase getThrower(@Nullable EntityThrowable entity, @Nonnull GameProfile modFakeProfile) { + if (entity == null) + return getFake(getEntityWorld(), modFakeProfile); EntityLivingBase thrower = entity.getThrower(); - return thrower != null ? thrower : getFake(entity == null ? null : entity.worldObj, modFakeProfile); + return thrower == null ? getFake(entity.worldObj, modFakeProfile) : thrower; } - private static final MinecraftServer getServer() + @Nonnull + private static MinecraftServer getServer() { return FMLCommonHandler.instance().getMinecraftServerInstance(); } - private static final World getEntityWorld() + @Nonnull + private static World getEntityWorld() { return getServer().getEntityWorld(); } diff --git a/src/main/java/com/gamerforea/eventhelper/util/InjectionUtils.java b/src/main/java/com/gamerforea/eventhelper/util/InjectionUtils.java new file mode 100644 index 0000000..9994bfb --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/util/InjectionUtils.java @@ -0,0 +1,45 @@ +package com.gamerforea.eventhelper.util; + +import com.google.common.io.ByteStreams; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +import java.io.InputStream; +import java.lang.reflect.Method; + +public final class InjectionUtils +{ + private static final Method defineClass; + + // Need Inj subclass + public static Class injectClass(String pluginName, Class clazz) + { + Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName); + if (plugin == null) + return null; + + try (InputStream in = clazz.getClassLoader().getResourceAsStream(clazz.getName().replace('.', '/') + "$Inj.class")) + { + byte[] bytes = ByteStreams.toByteArray(in); + return (Class) defineClass.invoke(plugin.getClass().getClassLoader(), null, bytes, 0, bytes.length); + } + catch (Throwable throwable) + { + throwable.printStackTrace(); + return null; + } + } + + static + { + try + { + defineClass = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class); + defineClass.setAccessible(true); + } + catch (Throwable throwable) + { + throw new RuntimeException("Failed hooking ClassLoader.defineClass(String, byte[], int, int) method!", throwable); + } + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/util/ItemInventoryValidator.java b/src/main/java/com/gamerforea/eventhelper/util/ItemInventoryValidator.java new file mode 100644 index 0000000..91bf2d2 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/util/ItemInventoryValidator.java @@ -0,0 +1,174 @@ +package com.gamerforea.eventhelper.util; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import org.apache.commons.lang3.StringUtils; + +import java.util.Random; +import java.util.function.Function; +import java.util.function.Predicate; + +public final class ItemInventoryValidator +{ + public static final String NBT_KEY_ID = "UID"; + private static final Random RANDOM = new Random(); + + private final ItemStack stack; + private final String nbtIdKey; + private final Predicate itemValidator; + private final Function stackGetter; + + private boolean itemInHotbar = true; + private int slotIndex = -1; + private int slotNumber = -1; + + public ItemInventoryValidator(ItemStack stack) + { + this(stack, null, true); + } + + public ItemInventoryValidator(ItemStack stack, Predicate itemValidator) + { + this(stack, null, true, itemValidator); + } + + public ItemInventoryValidator(ItemStack stack, Function stackGetter) + { + this(stack, null, true, stackGetter); + } + + public ItemInventoryValidator(ItemStack stack, Predicate itemValidator, Function stackGetter) + { + this(stack, null, true, itemValidator, stackGetter); + } + + public ItemInventoryValidator(ItemStack stack, String nbtKeyId, boolean generateIdIfAbsent) + { + this(stack, nbtKeyId, generateIdIfAbsent, null, null); + } + + public ItemInventoryValidator(ItemStack stack, String nbtKeyId, boolean generateIdIfAbsent, Predicate itemValidator) + { + this(stack, nbtKeyId, generateIdIfAbsent, itemValidator, null); + } + + public ItemInventoryValidator(ItemStack stack, String nbtKeyId, boolean generateIdIfAbsent, Function stackGetter) + { + this(stack, nbtKeyId, generateIdIfAbsent, null, stackGetter); + } + + public ItemInventoryValidator(ItemStack stack, String nbtKeyId, boolean generateIdIfAbsent, Predicate itemValidator, Function stackGetter) + { + this.stack = stack; + this.nbtIdKey = nbtKeyId = StringUtils.defaultIfBlank(nbtKeyId, NBT_KEY_ID); + this.itemValidator = itemValidator; + this.stackGetter = stackGetter; + + if (generateIdIfAbsent && stack != null && (itemValidator == null || itemValidator.test(stack.getItem()))) + { + NBTTagCompound nbt = stack.getTagCompound(); + if (nbt == null) + { + nbt = new NBTTagCompound(); + stack.setTagCompound(nbt); + } + if (!nbt.hasKey(nbtKeyId)) + nbt.setInteger(nbtKeyId, RANDOM.nextInt()); + } + } + + public boolean isItemInHotbar() + { + return this.itemInHotbar; + } + + public void setItemInHotbar(boolean itemInHotbar) + { + this.itemInHotbar = itemInHotbar; + } + + public int getSlotIndex() + { + return this.slotIndex; + } + + public void setSlotIndex(int slotIndex) + { + this.slotIndex = slotIndex; + } + + public void setSlotIndex(int slotIndex, boolean itemInHotbar) + { + this.setSlotIndex(slotIndex); + this.setItemInHotbar(itemInHotbar); + } + + public int getSlotNumber() + { + return this.slotNumber; + } + + public void setSlotNumber(int slotNumber) + { + this.slotNumber = slotNumber; + } + + public boolean tryGetSlotNumberFromPlayerSlot(Slot slot) + { + if (this.slotIndex >= 0 && slot.inventory instanceof InventoryPlayer && slot.getSlotIndex() == this.slotIndex) + { + this.setSlotNumber(slot.slotNumber); + return true; + } + return false; + } + + public boolean canInteractWith(EntityPlayer player) + { + if (this.itemInHotbar && this.slotIndex >= 0 && this.slotIndex != player.inventory.currentItem) + return false; + if (this.stack != null) + { + ItemStack stackToCheck; + if (this.stackGetter == null) + { + if (this.slotIndex < 0) + return true; + stackToCheck = player.inventory.getStackInSlot(this.slotIndex); + } + else + stackToCheck = this.stackGetter.apply(player); + return stackToCheck != null && (this.itemValidator == null || this.itemValidator.test(stackToCheck.getItem())) && this.isSameItemInventory(this.stack, stackToCheck); + } + return true; + } + + public boolean canSlotClick(int slot, int button, int buttonType, EntityPlayer player) + { + if (this.slotNumber >= 0 && slot == this.slotNumber) + return false; + if (buttonType == 2 && this.itemInHotbar && this.slotIndex >= 0 && button == this.slotIndex) + return false; + return this.canInteractWith(player); + } + + private boolean isSameItemInventory(ItemStack base, ItemStack comparison) + { + if (base == null || comparison == null) + return false; + + if (base.getItem() != comparison.getItem()) + return false; + + if (!base.hasTagCompound() || !comparison.hasTagCompound()) + return false; + + String baseUID = base.getTagCompound().getString(this.nbtIdKey); + String comparisonUID = comparison.getTagCompound().getString(this.nbtIdKey); + return baseUID != null && baseUID.equals(comparisonUID); + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/util/PlayerCooldownManager.java b/src/main/java/com/gamerforea/eventhelper/util/PlayerCooldownManager.java new file mode 100644 index 0000000..543a006 --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/util/PlayerCooldownManager.java @@ -0,0 +1,35 @@ +package com.gamerforea.eventhelper.util; + +import net.minecraft.entity.player.EntityPlayer; + +import javax.annotation.Nonnull; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +public final class PlayerCooldownManager extends CooldownManager +{ + public PlayerCooldownManager(long cooldown, @Nonnull TimeUnit timeUnit) + { + super(cooldown, timeUnit); + } + + public PlayerCooldownManager(long cooldownInTicks) + { + super(cooldownInTicks); + } + + public boolean canAdd(@Nonnull EntityPlayer player) + { + return this.canAdd(player.getUniqueID()); + } + + public boolean add(@Nonnull EntityPlayer player) + { + return this.add(player.getUniqueID()); + } + + public long getCooldown(@Nonnull EntityPlayer player) + { + return this.getCooldown(player.getUniqueID()); + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/util/ReflectionUtils.java b/src/main/java/com/gamerforea/eventhelper/util/ReflectionUtils.java new file mode 100644 index 0000000..c9e5a2a --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/util/ReflectionUtils.java @@ -0,0 +1,11 @@ +package com.gamerforea.eventhelper.util; + +public final class ReflectionUtils extends SecurityManager +{ + private static final ReflectionUtils INSTANCE = new ReflectionUtils(); + + public static Class[] getCallingClasses() + { + return INSTANCE.getClassContext(); + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/util/WorldCooldownManager.java b/src/main/java/com/gamerforea/eventhelper/util/WorldCooldownManager.java new file mode 100644 index 0000000..7f54dbf --- /dev/null +++ b/src/main/java/com/gamerforea/eventhelper/util/WorldCooldownManager.java @@ -0,0 +1,34 @@ +package com.gamerforea.eventhelper.util; + +import net.minecraft.world.World; + +import javax.annotation.Nonnull; +import java.util.concurrent.TimeUnit; + +public final class WorldCooldownManager extends CooldownManager +{ + public WorldCooldownManager(long cooldown, @Nonnull TimeUnit timeUnit) + { + super(cooldown, timeUnit); + } + + public WorldCooldownManager(long cooldownInTicks) + { + super(cooldownInTicks); + } + + public boolean canAdd(@Nonnull World world) + { + return this.canAdd(world.provider.dimensionId); + } + + public boolean add(@Nonnull World world) + { + return this.add(world.provider.dimensionId); + } + + public long getCooldown(@Nonnull World world) + { + return this.getCooldown(world.provider.dimensionId); + } +} diff --git a/src/main/java/com/gamerforea/eventhelper/wg/WGReflection.java b/src/main/java/com/gamerforea/eventhelper/wg/WGReflection.java deleted file mode 100644 index e7b84c7..0000000 --- a/src/main/java/com/gamerforea/eventhelper/wg/WGReflection.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.gamerforea.eventhelper.wg; - -import java.lang.reflect.Method; - -import org.bukkit.plugin.Plugin; - -import com.google.common.base.Preconditions; -import com.google.common.io.ByteStreams; - -public final class WGReflection -{ - private static Plugin wgPlugin; - private static ClassLoader wgClassLoader; - - public static final void setWG(Plugin plugin) - { - Preconditions.checkNotNull(plugin, "WorldGuard not installed!"); - wgPlugin = plugin; - wgClassLoader = plugin.getClass().getClassLoader(); - } - - public static final ClassLoader getWGClassLoader() - { - if (wgClassLoader == null) - throw new IllegalStateException("WorldGuard ClassLoader not found!"); - return wgClassLoader; - } - - public static final Plugin getWGPlugin() - { - if (wgPlugin == null) - throw new IllegalStateException("WorldGuard not found!"); - return wgPlugin; - } - - // Need Inj subclass - public static final Class injectIntoWG(Class clazz) throws Throwable - { - byte[] bytes = ByteStreams.toByteArray(clazz.getClassLoader().getResourceAsStream(clazz.getName().replace('.', '/') + "$Inj.class")); - Method m = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class); - m.setAccessible(true); - return (Class) m.invoke(getWGClassLoader(), null, bytes, 0, bytes.length); - } -} diff --git a/src/main/java/com/gamerforea/eventhelper/wg/WGRegionChecker.java b/src/main/java/com/gamerforea/eventhelper/wg/WGRegionChecker.java deleted file mode 100644 index 456dd70..0000000 --- a/src/main/java/com/gamerforea/eventhelper/wg/WGRegionChecker.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.gamerforea.eventhelper.wg; - -import java.lang.reflect.Method; - -import org.bukkit.World; - -import com.sk89q.worldedit.Vector; -import com.sk89q.worldguard.bukkit.WorldGuardPlugin; -import com.sk89q.worldguard.protection.regions.ProtectedRegion; - -public final class WGRegionChecker -{ - private static final Method isInPrivate; - - public static final boolean isInPrivate(World world, int x, int y, int z) throws Throwable - { - return (Boolean) isInPrivate.invoke(null, world, x, y, z); - } - - static - { - try - { - Class clazz = WGReflection.injectIntoWG(WGRegionChecker.class); - isInPrivate = clazz.getDeclaredMethod("isInPrivateInj", World.class, int.class, int.class, int.class); - isInPrivate.setAccessible(true); - } - catch (Throwable throwable) - { - throw new RuntimeException("Failed injecting WGRegionChecker$Inj.isInPrivateInj() method!", throwable); - } - } - - public static final class Inj - { - public static final Boolean isInPrivateInj(World world, int x, int y, int z) - { - for (ProtectedRegion region : WorldGuardPlugin.inst().getRegionManager(world).getApplicableRegions(new Vector(x, y, z))) - if (!region.getId().equals(ProtectedRegion.GLOBAL_REGION)) - return true; - return false; - } - } -}