From 74212a170181699b380fc875c5fe8aa8ed636cc9 Mon Sep 17 00:00:00 2001
From: sovdee <10354869+sovdeeth@users.noreply.github.com>
Date: Wed, 2 Oct 2024 21:59:39 -0400
Subject: [PATCH 01/21] minecraft tags part 1
---
src/main/java/ch/njol/skript/Skript.java | 2 +
src/main/java/ch/njol/util/Pair.java | 72 ++++--------
.../skript/bukkit/tags/CondIsTagged.java | 90 +++++++++++++++
.../skript/bukkit/tags/ExprTag.java | 106 ++++++++++++++++++
.../skript/bukkit/tags/ExprTagContents.java | 70 ++++++++++++
.../skript/bukkit/tags/TagModule.java | 45 ++++++++
src/main/resources/lang/default.lang | 1 +
.../tests/syntaxes/conditions/CondIsTagged.sk | 16 +++
8 files changed, 354 insertions(+), 48 deletions(-)
create mode 100644 src/main/java/org/skriptlang/skript/bukkit/tags/CondIsTagged.java
create mode 100644 src/main/java/org/skriptlang/skript/bukkit/tags/ExprTag.java
create mode 100644 src/main/java/org/skriptlang/skript/bukkit/tags/ExprTagContents.java
create mode 100644 src/main/java/org/skriptlang/skript/bukkit/tags/TagModule.java
create mode 100644 src/test/skript/tests/syntaxes/conditions/CondIsTagged.sk
diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java
index c51112be9ac..deceb765d55 100644
--- a/src/main/java/ch/njol/skript/Skript.java
+++ b/src/main/java/ch/njol/skript/Skript.java
@@ -97,6 +97,7 @@
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.skriptlang.skript.bukkit.SkriptMetrics;
+import org.skriptlang.skript.bukkit.tags.TagModule;
import org.skriptlang.skript.lang.comparator.Comparator;
import org.skriptlang.skript.lang.comparator.Comparators;
import org.skriptlang.skript.lang.converter.Converter;
@@ -541,6 +542,7 @@ public void onEnable() {
try {
getAddonInstance().loadClasses("ch.njol.skript",
"conditions", "effects", "events", "expressions", "entity", "sections", "structures");
+ TagModule.load();
} catch (final Exception e) {
exception(e, "Could not load required .class files: " + e.getLocalizedMessage());
setEnabled(false);
diff --git a/src/main/java/ch/njol/util/Pair.java b/src/main/java/ch/njol/util/Pair.java
index c17887f9778..d3b79975861 100644
--- a/src/main/java/ch/njol/util/Pair.java
+++ b/src/main/java/ch/njol/util/Pair.java
@@ -1,39 +1,20 @@
-/**
- * This file is part of Skript.
- *
- * Skript is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Skript is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Skript. If not, see .
- *
- * Copyright Peter Güttinger, SkriptLang team and contributors
- */
package ch.njol.util;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.UnknownNullability;
+
+import java.io.Serial;
import java.io.Serializable;
import java.util.Map.Entry;
import java.util.Objects;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @author Peter Güttinger
- */
public class Pair implements Entry, Cloneable, Serializable {
+ @Serial
private static final long serialVersionUID = 8296563685697678334L;
-
- @Nullable
- protected T1 first;
- @Nullable
- protected T2 second;
+
+ protected @UnknownNullability T1 first;
+ protected @UnknownNullability T2 second;
public Pair() {
first = null;
@@ -45,22 +26,20 @@ public Pair(final @Nullable T1 first, final @Nullable T2 second) {
this.second = second;
}
- public Pair(final Entry e) {
+ public Pair(final @NotNull Entry e) {
this.first = e.getKey();
this.second = e.getValue();
}
-
- @Nullable
- public T1 getFirst() {
+
+ public @UnknownNullability T1 getFirst() {
return first;
}
public void setFirst(final @Nullable T1 first) {
this.first = first;
}
-
- @Nullable
- public T2 getSecond() {
+
+ public @UnknownNullability T2 getSecond() {
return second;
}
@@ -73,23 +52,22 @@ public void setSecond(final @Nullable T2 second) {
*/
@Override
public String toString() {
- return "" + first + "," + second;
+ return first + "," + second;
}
/**
* Checks for equality with Entries to match {@link #hashCode()}
*/
@Override
- public final boolean equals(final @Nullable Object obj) {
+ public final boolean equals(@Nullable Object obj) {
if (obj == this)
return true;
- if (!(obj instanceof Entry))
+ if (!(obj instanceof Entry, ?> entry))
return false;
- final Entry, ?> other = (Entry, ?>) obj;
final T1 first = this.first;
final T2 second = this.second;
- return (first == null ? other.getKey() == null : first.equals(other.getKey())) &&
- (second == null ? other.getValue() == null : second.equals(other.getValue()));
+ return (first == null ? entry.getKey() == null : first.equals(entry.getKey())) &&
+ (second == null ? entry.getValue() == null : second.equals(entry.getValue()));
}
/**
@@ -101,21 +79,19 @@ public final int hashCode() {
}
@Override
- @Nullable
- public T1 getKey() {
+ public @UnknownNullability T1 getKey() {
return first;
}
@Override
- @Nullable
- public T2 getValue() {
+ public @UnknownNullability T2 getValue() {
return second;
}
@Override
- @Nullable
- public T2 setValue(final @Nullable T2 value) {
- final T2 old = second;
+
+ public @UnknownNullability T2 setValue(@Nullable T2 value) {
+ T2 old = second;
second = value;
return old;
}
diff --git a/src/main/java/org/skriptlang/skript/bukkit/tags/CondIsTagged.java b/src/main/java/org/skriptlang/skript/bukkit/tags/CondIsTagged.java
new file mode 100644
index 00000000000..227f25d21d8
--- /dev/null
+++ b/src/main/java/org/skriptlang/skript/bukkit/tags/CondIsTagged.java
@@ -0,0 +1,90 @@
+package org.skriptlang.skript.bukkit.tags;
+
+import ch.njol.skript.aliases.ItemType;
+import ch.njol.skript.bukkitutil.EntityUtils;
+import ch.njol.skript.conditions.base.PropertyCondition;
+import ch.njol.skript.entity.EntityData;
+import ch.njol.skript.lang.Condition;
+import ch.njol.skript.lang.Expression;
+import ch.njol.skript.lang.SkriptParser.ParseResult;
+import ch.njol.skript.util.slot.Slot;
+import ch.njol.util.Kleenean;
+import org.bukkit.Keyed;
+import org.bukkit.Tag;
+import org.bukkit.block.Block;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.entity.Entity;
+import org.bukkit.event.Event;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.Nullable;
+
+public class CondIsTagged extends Condition {
+
+ static {
+ PropertyCondition.register(CondIsTagged.class, PropertyCondition.PropertyType.BE,
+ "tagged (as|with) %minecrafttags%",
+ "itemtypes/entities/entitydatas");
+ }
+
+ private Expression> tags;
+ private Expression> elements;
+
+ @Override
+ public boolean init(Expression>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
+ this.elements = expressions[0];
+ //noinspection unchecked
+ this.tags = (Expression>) expressions[1];
+ setNegated(matchedPattern == 1);
+ return true;
+ }
+
+ @Override
+ public boolean check(Event event) {
+ Tag[] tags = this.tags.getArray(event);
+ if (tags.length == 0)
+ return isNegated();
+ boolean and = this.tags.getAnd();
+ return elements.check(event, element -> {
+ Keyed value = null;
+ if (element instanceof Entity entity) {
+ value = entity.getType();
+ } if (element instanceof EntityData> data) {
+ value = EntityUtils.toBukkitEntityType(data);
+ } else if (element instanceof ItemType itemType) {
+ value = itemType.getMaterial();
+ } else if (element instanceof ItemStack itemStack) {
+ value = itemStack.getType();
+ } else if (element instanceof Slot slot) {
+ ItemStack stack = slot.getItem();
+ if (stack == null)
+ return false;
+ value = stack.getType();
+ } else if (element instanceof Block block) {
+ value = block.getType();
+ } else if (element instanceof BlockData data) {
+ value = data.getMaterial();
+ }
+
+ if (value == null)
+ return false;
+
+ for (Tag tag : tags) {
+ if (tag.isTagged(value)) {
+ if (!and)
+ return true;
+ } else if (and) {
+ return false;
+ }
+ }
+ return and;
+ }, isNegated());
+ }
+
+ @Override
+ public String toString(@Nullable Event event, boolean debug) {
+ String plural = elements.isSingle() ? "is" : "are";
+ String negated = isNegated() ? " not" : "";
+ return elements.toString(event, debug) + " " + plural + negated + " tagged as " + tags.toString(event, debug);
+ }
+
+}
diff --git a/src/main/java/org/skriptlang/skript/bukkit/tags/ExprTag.java b/src/main/java/org/skriptlang/skript/bukkit/tags/ExprTag.java
new file mode 100644
index 00000000000..07547c3b0f8
--- /dev/null
+++ b/src/main/java/org/skriptlang/skript/bukkit/tags/ExprTag.java
@@ -0,0 +1,106 @@
+package org.skriptlang.skript.bukkit.tags;
+
+import ch.njol.skript.Skript;
+import ch.njol.skript.lang.Expression;
+import ch.njol.skript.lang.ExpressionType;
+import ch.njol.skript.lang.SkriptParser;
+import ch.njol.skript.lang.util.SimpleExpression;
+import ch.njol.util.Kleenean;
+import org.bukkit.Bukkit;
+import org.bukkit.Keyed;
+import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
+import org.bukkit.Tag;
+import org.bukkit.entity.EntityType;
+import org.bukkit.event.Event;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class ExprTag extends SimpleExpression {
+
+ private record RegistryInfo(String registry, String pattern, Class extends Keyed> type) {}
+
+ // Fluid and GameEvent registries also exist, but are not useful at this time.
+ // Any new types added here must be handled in CondIsTagged
+ private static final List REGISTRIES = new ArrayList<>(List.of(
+ new RegistryInfo(Tag.REGISTRY_ITEMS, "item", Material.class),
+ new RegistryInfo(Tag.REGISTRY_BLOCKS, "block", Material.class),
+ new RegistryInfo(Tag.REGISTRY_ENTITY_TYPES, "entity [type]", EntityType.class)
+ ));
+
+ static {
+ // build pattern
+ StringBuilder registriesPattern = new StringBuilder("[");
+ int numRegistries = REGISTRIES.size();
+ for (int i = 0; i < numRegistries; i++) {
+ registriesPattern.append(i + 1).append(":").append(REGISTRIES.get(i).pattern());
+ if (i + 1 != numRegistries)
+ registriesPattern.append("|");
+ }
+ registriesPattern.append("]");
+
+ Skript.registerExpression(ExprTag.class, Tag.class, ExpressionType.COMBINED, "[minecraft] " + registriesPattern + " tag %string%");
+ }
+
+ Expression name;
+ int type;
+
+ @Override
+ public boolean init(Expression>[] expressions, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) {
+ //noinspection unchecked
+ name = (Expression) expressions[0];
+ type = parseResult.mark - 1;
+ return true;
+ }
+
+ @Override
+ protected Tag> @Nullable [] get(Event event) {
+ String name = this.name.getSingle(event);
+ if (name == null)
+ return null;
+
+ NamespacedKey key = NamespacedKey.fromString(name);
+ if (key == null)
+ return null;
+
+
+ List registries;
+ if (type == -1) {
+ registries = REGISTRIES;
+ } else if (type < REGISTRIES.size()) {
+ registries = Collections.singletonList(REGISTRIES.get(type));
+ } else {
+ return null;
+ }
+
+ Tag> tag;
+ for (RegistryInfo registry : registries) {
+ tag = Bukkit.getTag(registry.registry(), key, registry.type());
+ if (tag != null)
+ return new Tag[]{tag};
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean isSingle() {
+ return true;
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public Class extends Tag> getReturnType() {
+ return Tag.class;
+ }
+
+ @Override
+ public String toString(@Nullable Event event, boolean debug) {
+ String registry = type == -1 ? "" : REGISTRIES.get(type).pattern();
+ return "minecraft " + registry + "tag " + name.toString(event, debug);
+ }
+
+}
diff --git a/src/main/java/org/skriptlang/skript/bukkit/tags/ExprTagContents.java b/src/main/java/org/skriptlang/skript/bukkit/tags/ExprTagContents.java
new file mode 100644
index 00000000000..84e20aee099
--- /dev/null
+++ b/src/main/java/org/skriptlang/skript/bukkit/tags/ExprTagContents.java
@@ -0,0 +1,70 @@
+package org.skriptlang.skript.bukkit.tags;
+
+import ch.njol.skript.Skript;
+import ch.njol.skript.aliases.ItemType;
+import ch.njol.skript.bukkitutil.EntityUtils;
+import ch.njol.skript.lang.Expression;
+import ch.njol.skript.lang.ExpressionType;
+import ch.njol.skript.lang.SkriptParser.ParseResult;
+import ch.njol.skript.lang.util.SimpleExpression;
+import ch.njol.util.Kleenean;
+import org.bukkit.Material;
+import org.bukkit.Tag;
+import org.bukkit.entity.EntityType;
+import org.bukkit.event.Event;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Objects;
+
+public class ExprTagContents extends SimpleExpression