Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 137 additions & 81 deletions src/main/java/ch/njol/skript/Skript.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,13 @@
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.skriptlang.skript.bukkit.BukkitModule;
import org.skriptlang.skript.bukkit.SkriptMetrics;
import org.skriptlang.skript.bukkit.breeding.BreedingModule;
import org.skriptlang.skript.bukkit.brewing.BrewingModule;
import org.skriptlang.skript.bukkit.damagesource.DamageSourceModule;
import org.skriptlang.skript.bukkit.displays.DisplayModule;
import org.skriptlang.skript.bukkit.fishing.FishingModule;
import org.skriptlang.skript.bukkit.furnace.FurnaceModule;
import org.skriptlang.skript.bukkit.input.InputModule;
import org.skriptlang.skript.bukkit.itemcomponents.ItemComponentModule;
import org.skriptlang.skript.bukkit.log.runtime.BukkitRuntimeErrorConsumer;
import org.skriptlang.skript.bukkit.loottables.LootTableModule;
import org.skriptlang.skript.bukkit.registration.BukkitRegistryKeys;
Expand All @@ -122,11 +120,13 @@
import org.skriptlang.skript.registration.SyntaxOrigin;
import org.skriptlang.skript.registration.SyntaxRegistry;
import org.skriptlang.skript.util.ClassLoader;
import org.skriptlang.skript.util.ReflectUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
Expand Down Expand Up @@ -187,6 +187,7 @@ public final class Skript extends JavaPlugin implements Listener {

private static org.skriptlang.skript.@UnknownNullability Skript skript = null;
private static org.skriptlang.skript.@UnknownNullability Skript unmodifiableSkript = null;
private static final ReflectUtils REFLECT_UTILS = new ReflectUtils();

private static boolean disabled = false;
private static boolean partDisabled = false;
Expand Down Expand Up @@ -596,10 +597,8 @@ public void onEnable() {
FurnaceModule.load();
LootTableModule.load();
skript.loadModules(
new DamageSourceModule(),
new ItemComponentModule(),
new BrewingModule(),
new CommonModule()
new CommonModule(),
new BukkitModule()
);
} catch (final Exception e) {
exception(e, "Could not load required .class files: " + e.getLocalizedMessage());
Expand Down Expand Up @@ -1125,80 +1124,6 @@ public static boolean isRunningMinecraft(final Version v) {
return minecraftVersion.compareTo(v) >= 0;
}

/**
* Tests whether a given class exists in the classpath.
*
* @param className The {@link Class#getCanonicalName() canonical name} of the class
* @return Whether the given class exists.
*/
public static boolean classExists(final String className) {
try {
Class.forName(className);
return true;
} catch (final ClassNotFoundException e) {
return false;
}
}

/**
* Tests whether a method exists in the given class.
*
* @param c The class
* @param methodName The name of the method
* @param parameterTypes The parameter types of the method
* @return Whether the given method exists.
*/
public static boolean methodExists(final Class<?> c, final String methodName, final Class<?>... parameterTypes) {
try {
c.getDeclaredMethod(methodName, parameterTypes);
return true;
} catch (final NoSuchMethodException e) {
return false;
} catch (final SecurityException e) {
return false;
}
}

/**
* Tests whether a method exists in the given class, and whether the return type matches the expected one.
* <p>
* Note that this method doesn't work properly if multiple methods with the same name and parameters exist but have different return types.
*
* @param c The class
* @param methodName The name of the method
* @param parameterTypes The parameter types of the method
* @param returnType The expected return type
* @return Whether the given method exists.
*/
public static boolean methodExists(final Class<?> c, final String methodName, final Class<?>[] parameterTypes, final Class<?> returnType) {
try {
final Method m = c.getDeclaredMethod(methodName, parameterTypes);
return m.getReturnType() == returnType;
} catch (final NoSuchMethodException e) {
return false;
} catch (final SecurityException e) {
return false;
}
}

/**
* Tests whether a field exists in the given class.
*
* @param c The class
* @param fieldName The name of the field
* @return Whether the given field exists.
*/
public static boolean fieldExists(final Class<?> c, final String fieldName) {
try {
c.getDeclaredField(fieldName);
return true;
} catch (final NoSuchFieldException e) {
return false;
} catch (final SecurityException e) {
return false;
}
}

@Nullable
static Metrics metrics;

Expand Down Expand Up @@ -2138,4 +2063,135 @@ public SkriptUpdater getUpdater() {
return updater;
}

//<editor-fold desc="Reflect Utils">
/**
* Tests whether a given class exists in the classpath.
*
* @param className The {@link Class#getCanonicalName() canonical name} of the class
* @return Whether the given class exists.
*/
public static boolean classExists(String className) {
return REFLECT_UTILS.classExists(className);
}

/**
* @param className The full package and class name.
* @return The resulting {@link Class} if found, otherwise {@code null}.
*/
public static @Nullable Class<?> getClass(String className) {
return REFLECT_UTILS.getClass(className);
}

/**
* Tests whether a method exists in the given class.
*
* @param c The class
* @param methodName The name of the method
* @param parameterTypes The parameter types of the method
* @return Whether the given method exists.
*/
public static boolean methodExists(Class<?> c, String methodName, Class<?> @Nullable ... parameterTypes) {
return REFLECT_UTILS.methodExists(c, methodName, parameterTypes);
}

/**
* Tests whether a method exists in the given class, and whether the return type matches the expected one.
* <p>
* Note that this method doesn't work properly if multiple methods with the same name and parameters exist but have different return types.
*
* @param c The class
* @param methodName The name of the method
* @param parameterTypes The parameter types of the method
* @param returnType The expected return type
* @return Whether the given method exists.
*/
public static boolean methodExists(Class<?> c, String methodName, Class<?> @Nullable [] parameterTypes, Class<?> returnType) {
return REFLECT_UTILS.methodExists(c, methodName, parameterTypes, returnType);
}

/**
* @param c The {@link Class} to get the method from.
* @param methodName The name of the method.
* @param params The {@link Class}es used as parameters for the desired method.
* @return The resulting {@link Method} if it exists, otherwise {@code null}.
*/
public static @Nullable Method getMethod(Class<?> c, String methodName, Class<?> @Nullable ... params) {
return REFLECT_UTILS.getMethod(c, methodName, params);
}

/**
* @param c The {@link Class} to get the method from.
* @param methodName The name of the method.
* @param params The {@link Class}es used as parameters for the desired method.
* @param returnType The return type of the desired method.
* @return The resulting {@link Method} if it exists, otherwise {@code null}.
*/
public static @Nullable Method getMethod(Class<?> c, String methodName, Class<?> @Nullable [] params, @Nullable Class<?> returnType) {
return REFLECT_UTILS.getMethod(c, methodName, params, returnType);
}

/**
* Tests whether a field exists in the given class.
*
* @param c The class
* @param fieldName The name of the field
* @return Whether the given field exists.
*/
public static boolean fieldExists(Class<?> c, String fieldName) {
return REFLECT_UTILS.fieldExists(c, fieldName);
}

/**
* @param c The {@link Class} to get the field from.
* @param fieldName The name of the field.
* @return The resulting {@link Field} if it exists, otherwise {@code null}.
*/
public static @Nullable Field getField(Class<?> c, String fieldName) {
return REFLECT_UTILS.getField(c, fieldName);
}

/**
* Invoke a static {@link Method}.
* @param method The {@link Method} to invoke.
* @return The result of the invocation if successful, otherwise {@code null}.
* @param <Type> The expected return type from the invocation.
*/
public static <Type> @Nullable Type invokeMethod(Method method) {
return REFLECT_UTILS.invokeMethod(method);
}

/**
* Invoke a {@link Method}.
* @param method The {@link Method} to invoke.
* @param holder The holder object to invoke for.
* @param params The parameters to pass into the invocation.
* @return The result of the invocation if successful, otherwise {@code null}.
* @param <Type> The expected return type from the invocation.
*/
public static <Type> @Nullable Type invokeMethod(Method method, @Nullable Object holder, Object @Nullable ... params) {
return REFLECT_UTILS.invokeMethod(method, holder, params);
}

/**
* Gets the values of a static {@link Field}.
* @param field The {@link Field} to get from.
* @return The value of the {@link Field}.
* @param <Type> The expected return type.
*/
public static <Type> @Nullable Type getFieldValue(Field field) {
return REFLECT_UTILS.getFieldValue(field);
}

/**
* Gets the values of a {@link Field}.
* @param field The {@link Field} to get from.
* @param holder The holder object to get the field for.
* @return The value of the {@link Field}.
* @param <Type> The expected return type.
*/
public static <Type> @Nullable Type getFieldValue(Field field, @Nullable Object holder) {
return REFLECT_UTILS.getFieldValue(field, holder);
}
//</editor-fold>

}
41 changes: 38 additions & 3 deletions src/main/java/ch/njol/skript/classes/data/BukkitClasses.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@
import ch.njol.skript.bukkitutil.BukkitUtils;
import ch.njol.skript.bukkitutil.EntityUtils;
import ch.njol.skript.bukkitutil.SkriptTeleportFlag;
import ch.njol.skript.classes.*;
import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.classes.EnumClassInfo;
import ch.njol.skript.classes.Parser;
import ch.njol.skript.classes.PatternedParser;
import ch.njol.skript.classes.Serializer;
import ch.njol.skript.classes.registry.RegistryClassInfo;
import ch.njol.skript.expressions.ExprDamageCause;
import ch.njol.skript.expressions.base.EventValueExpression;
import ch.njol.skript.lang.ParseContext;
import ch.njol.skript.lang.util.SimpleLiteral;
import org.skriptlang.skript.bukkit.paperutil.CopperState;
import ch.njol.skript.registrations.Classes;
import ch.njol.skript.util.BlockUtils;
import ch.njol.skript.util.PotionEffectUtils;
Expand All @@ -23,10 +28,16 @@
import org.bukkit.block.DoubleChest;
import org.bukkit.block.banner.PatternType;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.CopperGolemStatue;
import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentOffer;
import org.bukkit.entity.*;
import org.bukkit.entity.EntitySnapshot;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Vehicle;
import org.bukkit.entity.Villager;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityPotionEffectEvent;
Expand All @@ -52,8 +63,14 @@
import org.bukkit.util.CachedServerIcon;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.bukkit.base.types.*;
import org.skriptlang.skript.bukkit.base.types.BlockClassInfo;
import org.skriptlang.skript.bukkit.base.types.EntityClassInfo;
import org.skriptlang.skript.bukkit.base.types.EntityClassInfo.EntityChanger;
import org.skriptlang.skript.bukkit.base.types.InventoryClassInfo;
import org.skriptlang.skript.bukkit.base.types.ItemStackClassInfo;
import org.skriptlang.skript.bukkit.base.types.NameableClassInfo;
import org.skriptlang.skript.bukkit.base.types.OfflinePlayerClassInfo;
import org.skriptlang.skript.bukkit.base.types.PlayerClassInfo;
import org.skriptlang.skript.lang.properties.Property;
import org.skriptlang.skript.lang.properties.PropertyHandler.ExpressionPropertyHandler;

Expand Down Expand Up @@ -1140,5 +1157,23 @@ public String toVariableNameString(WorldBorder border) {
.since("2.12")
);

//noinspection unchecked,rawtypes
Classes.registerClass(new EnumClassInfo<>((Class) CopperState.getStateClass(), "weatheringcopperstate", "weathering copper states")
.user("(weathering ?)?copper ?states?")
.name("Weathering Copper State")
.description("The weathering state of a copper golem or copper block.")
.since("INSERT VERSION")
);

if (Skript.classExists("org.bukkit.block.data.type.CopperGolemStatue$Pose")) {
Classes.registerClass(new EnumClassInfo<>(CopperGolemStatue.Pose.class, "coppergolempose", "copper golem poses")
.user("copper ?golem ?(statue ?)?poses?")
.name("Copper Golem Pose")
.description("The pose of a copper golem statue.")
.requiredPlugins("Minecraft 1.21.9+")
.since("INSERT VERSION")
);
}

}
}
Loading