Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String -> UUID #7497

Merged
merged 13 commits into from
Feb 23, 2025
44 changes: 12 additions & 32 deletions src/main/java/ch/njol/skript/classes/data/BukkitClasses.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import ch.njol.skript.util.BlockUtils;
import ch.njol.skript.util.PotionEffectUtils;
import ch.njol.skript.util.StringMode;
import ch.njol.skript.util.Utils;
import ch.njol.util.StringUtils;
import ch.njol.yggdrasil.Fields;
import io.papermc.paper.world.MoonPhase;
Expand Down Expand Up @@ -71,10 +72,7 @@ public class BukkitClasses {

public BukkitClasses() {}

public static final Pattern UUID_PATTERN = Pattern.compile("(?i)[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}");

static {
final boolean GET_ENTITY_METHOD_EXISTS = Skript.methodExists(Bukkit.class, "getEntity", UUID.class);
Classes.registerClass(new ClassInfo<>(Entity.class, "entity")
.user("entit(y|ies)")
.name("Entity")
Expand All @@ -91,25 +89,10 @@ public BukkitClasses() {}
.defaultExpression(new EventValueExpression<>(Entity.class))
.parser(new Parser<Entity>() {
@Override
@Nullable
public Entity parse(final String s, final ParseContext context) {
UUID uuid;
try {
uuid = UUID.fromString(s);
} catch (IllegalArgumentException iae) {
return null;
}
if (GET_ENTITY_METHOD_EXISTS) {
return Bukkit.getEntity(uuid);
} else {
for (World world : Bukkit.getWorlds()) {
for (Entity entity : world.getEntities()) {
if (entity.getUniqueId().equals(uuid)) {
return entity;
}
}
}
}
public @Nullable Entity parse(final String s, final ParseContext context) {
if (Utils.isValidUUID(s))
return Bukkit.getEntity(UUID.fromString(s));

return null;
}

Expand Down Expand Up @@ -643,8 +626,10 @@ public Player parse(String string, ParseContext context) {
if (context == ParseContext.COMMAND || context == ParseContext.PARSE) {
if (string.isEmpty())
return null;
if (UUID_PATTERN.matcher(string).matches())

if (Utils.isValidUUID(string))
return Bukkit.getPlayer(UUID.fromString(string));

String name = string.toLowerCase(Locale.ENGLISH);
int nameLength = name.length(); // caching
List<Player> players = new ArrayList<>();
Expand Down Expand Up @@ -709,16 +694,11 @@ public String getDebugMessage(final Player p) {
.after("string", "world")
.parser(new Parser<OfflinePlayer>() {
@Override
@Nullable
public OfflinePlayer parse(final String s, final ParseContext context) {
if (context == ParseContext.COMMAND || context == ParseContext.PARSE) {
if (UUID_PATTERN.matcher(s).matches())
return Bukkit.getOfflinePlayer(UUID.fromString(s));
else if (!SkriptConfig.playerNameRegexPattern.value().matcher(s).matches())
return null;
public @Nullable OfflinePlayer parse(final String s, final ParseContext context) {
if (Utils.isValidUUID(s))
return Bukkit.getOfflinePlayer(UUID.fromString(s));
else if (!SkriptConfig.playerNameRegexPattern.value().matcher(s).matches())
return Bukkit.getOfflinePlayer(s);
}
assert false;
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.skriptlang.skript.lang.comparator.Relation;

import java.util.Objects;
import java.util.UUID;

@SuppressWarnings({"rawtypes"})
public class DefaultComparators {
Expand Down Expand Up @@ -665,6 +666,9 @@ public Relation compare(EntitySnapshot snap1, EntitySnapshot snap2) {
}
});
}

// UUID - UUID
Comparators.registerComparator(UUID.class, UUID.class, (one, two) -> Relation.get(one.equals(two)));
}

}
17 changes: 17 additions & 0 deletions src/main/java/ch/njol/skript/classes/data/DefaultConverters.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import ch.njol.skript.entity.XpOrbData;
import ch.njol.skript.lang.util.common.AnyAmount;
import ch.njol.skript.lang.util.common.AnyNamed;
import ch.njol.skript.lang.util.common.AnyValued;
import ch.njol.skript.util.*;
import ch.njol.skript.util.slot.Slot;
import org.bukkit.*;
Expand Down Expand Up @@ -39,6 +40,8 @@
import org.skriptlang.skript.lang.converter.Converters;
import org.skriptlang.skript.lang.script.Script;

import java.util.UUID;

public class DefaultConverters {

public DefaultConverters() {}
Expand Down Expand Up @@ -275,6 +278,20 @@ public void setAmount(Number amount) {
Converters.registerConverter(Script.class, Config.class, Script::getConfig);
Converters.registerConverter(Config.class, Node.class, Config::getMainNode);

// UUID -> String & AnyValued
Converters.registerConverter(UUID.class, String.class, UUID::toString);
Converters.registerConverter(UUID.class, AnyValued.class, uuid -> new AnyValued<String>() {
@Override
public String value() {
return uuid.toString();
}

@Override
public Class<String> valueType() {
return String.class;
}
});

// // Entity - String (UUID) // Very slow, thus disabled for now
// Converters.registerConverter(String.class, Entity.class, new Converter<String, Entity>() {
//
Expand Down
12 changes: 3 additions & 9 deletions src/main/java/ch/njol/skript/classes/data/DefaultFunctions.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@
import ch.njol.skript.lang.util.SimpleLiteral;
import ch.njol.skript.registrations.Classes;
import ch.njol.skript.registrations.DefaultClasses;
import ch.njol.skript.util.Color;
import ch.njol.skript.util.ColorRGB;
import ch.njol.skript.util.Contract;
import ch.njol.skript.util.Date;
import ch.njol.skript.util.*;
import ch.njol.util.Math2;
import ch.njol.util.StringUtils;
import ch.njol.util.coll.CollectionUtils;
Expand Down Expand Up @@ -544,9 +541,8 @@ public Player[] executeSimple(Object[][] params) {
boolean isExact = (boolean) params[1][0];
UUID uuid = null;
if (name.length() > 16 || name.contains("-")) { // shortcut
try {
if (Utils.isValidUUID(name))
uuid = UUID.fromString(name);
} catch (IllegalArgumentException ignored) {}
}
return CollectionUtils.array(uuid != null ? Bukkit.getPlayer(uuid) : (isExact ? Bukkit.getPlayerExact(name) : Bukkit.getPlayer(name)));
}
Expand All @@ -569,10 +565,8 @@ public OfflinePlayer[] executeSimple(Object[][] params) {
String name = (String) params[0][0];
UUID uuid = null;
if (name.length() > 16 || name.contains("-")) { // shortcut
try {
if (Utils.isValidUUID(name))
uuid = UUID.fromString(name);
} catch (IllegalArgumentException ignored) {
}
}
OfflinePlayer result;

Expand Down
31 changes: 31 additions & 0 deletions src/main/java/ch/njol/skript/classes/data/JavaClasses.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.jetbrains.annotations.Nullable;
import org.joml.Quaternionf;

import java.util.UUID;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -325,6 +326,36 @@ public String toVariableNameString(Quaternionf quaternion) {
return null;
}
}));

Classes.registerClass(new ClassInfo<>(UUID.class, "uuid")
.user("(uuid|universal(ly)? unique identifier)s?")
.name("UUID")
.description(
"A UUID is a universally unique identifier, which is a 128-bit number that is unique to each entity. "
+ "They are usually encoded as 36-character strings, which include 32 hexadecimal digits and "
+ "four hyphens, typically in this format: \"123e4567-e89b-12d3-a456-426614174000\"",
"In minecraft, it is used to identify entities (like players) in a way "
+ "that is unique across all entities, regardless of the entity's state.")
.since("INSERT VERSION")
.parser(new Parser<>() {
@Override
public @Nullable UUID parse(String string, ParseContext context) {
if (Utils.isValidUUID(string))
return UUID.fromString(string);
return null;
}

@Override
public String toString(UUID uuid, int flags) {
return "uuid \"" + uuid.toString() + "\"";
}

@Override
public String toVariableNameString(UUID uuid) {
return uuid.toString();
}
})
);
}

/**
Expand Down
139 changes: 139 additions & 0 deletions src/main/java/ch/njol/skript/expressions/ExprEntityFromUUID.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package ch.njol.skript.expressions;

import ch.njol.skript.Skript;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.SyntaxStringBuilder;
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.util.Kleenean;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Name("Entity/Player/World from UUID")
@Description({
"Get an entity, player or world from a UUID.",
"Use 'offline player' to get an offline player."
})
@Examples({
"set {_player} to player from \"a0789aeb-7b46-43f6-86fb-cb671fed5775\" parsed as uuid",
"set {_offline player} to offline player from {_some uuid}",
"set {_entity} to entity from {_some uuid}",
"set {_world} to world from {_some uuid}"
})
@Since("INSERT VERSION")
public class ExprEntityFromUUID extends SimpleExpression<Object> {

static {
Skript.registerExpression(ExprEntityFromUUID.class, Object.class, ExpressionType.SIMPLE,
"[:offline[ ]]player[s] from %uuids%",
"(entit(y|ies)|:world[s]) from %uuids%"
);
}

private Expression<UUID> uuids;
private boolean offline, player, world;

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
//noinspection unchecked
uuids = (Expression<UUID>) exprs[0];
offline = parseResult.hasTag("offline");
player = matchedPattern == 0;
world = parseResult.hasTag("world");
return true;
}

@Override
protected Object @Nullable [] get(Event event) {
List<Object> entities = new ArrayList<>();

for (UUID uuid : uuids.getArray(event)) {
if (player) {
if (offline) {
entities.add(Bukkit.getOfflinePlayer(uuid));
continue;
}

Player player = Bukkit.getPlayer(uuid);
if (player != null)
entities.add(player);

} else if (!world) {
Entity entity = Bukkit.getEntity(uuid);
if (entity != null)
entities.add(entity);

} else {
World world = Bukkit.getWorld(uuid);
if (world != null)
entities.add(world);
}
}

if (player) {
if (offline)
//noinspection SuspiciousToArrayCall
return entities.toArray(new OfflinePlayer[0]);
//noinspection SuspiciousToArrayCall
return entities.toArray(new Player[0]);
}

if (world)
//noinspection SuspiciousToArrayCall
return entities.toArray(new World[0]);
//noinspection SuspiciousToArrayCall
return entities.toArray(new Entity[0]);
}

@Override
public boolean isSingle() {
return uuids.isSingle();
}

@Override
public Class<?> getReturnType() {
if (world) {
return World.class;
} else if (player) {
if (offline)
return OfflinePlayer.class;
return Player.class;
}

return Entity.class;
}

@Override
public String toString(@Nullable Event event, boolean debug) {
SyntaxStringBuilder builder = new SyntaxStringBuilder(event, debug);

if (world) {
builder.append("worlds");
} else if (!player) {
builder.append("entities");
} else {
if (offline)
builder.append("offline");
builder.append("players");
}

builder.append("from", uuids);

return builder.toString();
}

}
14 changes: 7 additions & 7 deletions src/main/java/ch/njol/skript/expressions/ExprRandomUUID.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
@Name("Random UUID")
@Description("Returns a random UUID.")
@Examples("set {_uuid} to random uuid")
@Since("2.5.1")
public class ExprRandomUUID extends SimpleExpression<String> {
@Since("2.5.1, INSERT VERSION (return UUIDs)")
public class ExprRandomUUID extends SimpleExpression<UUID> {

static {
Skript.registerExpression(ExprRandomUUID.class, String.class, ExpressionType.SIMPLE, "[a] random uuid");
Skript.registerExpression(ExprRandomUUID.class, UUID.class, ExpressionType.SIMPLE, "[a] random uuid");
}

@Override
Expand All @@ -33,8 +33,8 @@ public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelaye

@Override
@Nullable
protected String[] get(Event e) {
return new String[] {UUID.randomUUID().toString()};
protected UUID[] get(Event e) {
return new UUID[]{ UUID.randomUUID() };
}

@Override
Expand All @@ -43,8 +43,8 @@ public boolean isSingle() {
}

@Override
public Class<? extends String> getReturnType() {
return String.class;
public Class<? extends UUID> getReturnType() {
return UUID.class;
}

@Override
Expand Down
Loading
Loading