diff --git a/build.gradle.kts b/build.gradle.kts index b00a7de4..be0e957a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -26,7 +26,7 @@ repositories { dependencies { compileOnly("com.hypixel.hytale:Server:${hytaleVersion}") compileOnly("org.jetbrains:annotations:26.0.2") - implementation("com.github.SkriptDev:skript-parser:1.0.5") { + implementation("com.github.SkriptDev:skript-parser:1.0.6") { isTransitive = false } implementation("com.github.Zoltus:TinyMessage:2.0.1") { diff --git a/src/main/java/com/github/skriptdev/skript/api/hytale/Block.java b/src/main/java/com/github/skriptdev/skript/api/hytale/Block.java index 4465846e..949cc67f 100644 --- a/src/main/java/com/github/skriptdev/skript/api/hytale/Block.java +++ b/src/main/java/com/github/skriptdev/skript/api/hytale/Block.java @@ -165,6 +165,10 @@ public String toTypeString() { this.getType().getId(), this.pos.getX(), this.pos.getY(), this.pos.getZ(), this.world.getName()); } + public String toVariableNameString() { + return String.format("%s_%s_%s_%s_%s", this.world.getName(), this.getType().getId(), this.pos.getX(), this.pos.getY(), this.pos.getZ()); + } + @Override public String toString() { return "Block{" + diff --git a/src/main/java/com/github/skriptdev/skript/api/hytale/Direction.java b/src/main/java/com/github/skriptdev/skript/api/hytale/Direction.java index efcb8fea..98f8d90d 100644 --- a/src/main/java/com/github/skriptdev/skript/api/hytale/Direction.java +++ b/src/main/java/com/github/skriptdev/skript/api/hytale/Direction.java @@ -44,6 +44,10 @@ public String getName() { return this.name; } + public String getVariableName() { + return "direction:" + this.name.toLowerCase(Locale.ROOT); + } + private static Location create(Location location, Number offset, int x, int y, int z) { double value = offset.doubleValue(); Vector3d add = location.getPosition().add(x * value, y * value, z * value); diff --git a/src/main/java/com/github/skriptdev/skript/api/hytale/EntityComponentUtils.java b/src/main/java/com/github/skriptdev/skript/api/hytale/EntityUtils.java similarity index 61% rename from src/main/java/com/github/skriptdev/skript/api/hytale/EntityComponentUtils.java rename to src/main/java/com/github/skriptdev/skript/api/hytale/EntityUtils.java index 702101c3..3f776e55 100644 --- a/src/main/java/com/github/skriptdev/skript/api/hytale/EntityComponentUtils.java +++ b/src/main/java/com/github/skriptdev/skript/api/hytale/EntityUtils.java @@ -10,9 +10,10 @@ import com.hypixel.hytale.math.vector.Vector3d; import com.hypixel.hytale.math.vector.Vector3f; import com.hypixel.hytale.server.core.entity.Entity; -import com.hypixel.hytale.server.core.entity.EntityUtils; import com.hypixel.hytale.server.core.entity.LivingEntity; +import com.hypixel.hytale.server.core.entity.UUIDComponent; import com.hypixel.hytale.server.core.entity.movement.MovementStatesComponent; +import com.hypixel.hytale.server.core.entity.nameplate.Nameplate; import com.hypixel.hytale.server.core.inventory.ItemStack; import com.hypixel.hytale.server.core.modules.entity.item.ItemComponent; import com.hypixel.hytale.server.core.modules.entitystats.EntityStatMap; @@ -23,11 +24,79 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.UUID; + /** * Quick utility class for accessing entity components. */ @SuppressWarnings("UnusedReturnValue") -public class EntityComponentUtils { +public class EntityUtils { + + /** + * Get the UUID of an {@link Entity} + * + * @param entity Entity to get UUID from + * @return UUID of the entity, or null if the entity has no UUID component + */ + public static @Nullable UUID getUUID(@NotNull Entity entity) { + Ref reference = entity.getReference(); + if (reference == null) return null; + + Store store = reference.getStore(); + UUIDComponent component = store.getComponent(reference, UUIDComponent.getComponentType()); + if (component == null) return null; + return component.getUuid(); + } + + /** + * Get the name of an {@link Entity}. + * + * @param entity Entity to get name from + * @return Name of the entity, or null if the entity has no name component + */ + @SuppressWarnings("removal") + public static @NotNull String getName(Entity entity) { + Ref reference = entity.getReference(); + if (reference == null) return "no-reference"; + + Store store = reference.getStore(); + Nameplate component = store.getComponent(reference, Nameplate.getComponentType()); + if (component != null) { + return component.getText(); + } + // REMOVAL (we shouldn't be using this as a backup) + return entity.getLegacyDisplayName(); + } + + public static @NotNull String getVariableName(Entity entity) { + UUID uuid = getUUID(entity); + if (uuid == null) return ""; + return uuid.toString(); + } + + /** + * Set the name of an {@link Entity}. + * + * @param entity Entity to set name on + * @param name New name for the entity + */ + public static void setNameplateName(Entity entity, @Nullable String name) { + Ref reference = entity.getReference(); + if (reference == null) return; + + Store store = reference.getStore(); + if (name == null) { + store.removeComponent(reference, Nameplate.getComponentType()); + return; + } + Nameplate component = store.getComponent(reference, Nameplate.getComponentType()); + if (component != null) { + component.setText(name); + } else { + Nameplate n = new Nameplate(name); + store.addComponent(reference, Nameplate.getComponentType(), n); + } + } /** * Get a component from an Entity @@ -101,7 +170,7 @@ public class EntityComponentUtils { store.addEntity(itemEntityHolder, AddReason.SPAWN); - return new Pair<>(EntityUtils.getEntity(itemEntityHolder), itemComponent); + return new Pair<>(com.hypixel.hytale.server.core.entity.EntityUtils.getEntity(itemEntityHolder), itemComponent); } } diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/addon/HySkriptAddon.java b/src/main/java/com/github/skriptdev/skript/api/skript/addon/HySkriptAddon.java index b446348e..fad80fae 100644 --- a/src/main/java/com/github/skriptdev/skript/api/skript/addon/HySkriptAddon.java +++ b/src/main/java/com/github/skriptdev/skript/api/skript/addon/HySkriptAddon.java @@ -1,7 +1,9 @@ package com.github.skriptdev.skript.api.skript.addon; +import com.github.skriptdev.skript.api.utils.Utils; import com.hypixel.hytale.logger.HytaleLogger; import com.hypixel.hytale.server.core.Message; +import fi.sulku.hytale.TinyMsg; import io.github.syst3ms.skriptparser.registration.SkriptAddon; import org.jetbrains.annotations.Nullable; @@ -18,7 +20,7 @@ public abstract class HySkriptAddon extends SkriptAddon { public HySkriptAddon(String name) { super(name); - this.hytaleLogger = HytaleLogger.get("HySkript|" + name + "|A"); + this.hytaleLogger = Utils.getAddonLogger(name); } /** @@ -47,16 +49,17 @@ public final Manifest getManifest() { public final Message[] getInfo() { List info = new ArrayList<>(); - info.add(Message.raw("Version: " + this.manifest.getVersion())); + info.add(TinyMsg.parse("Version: " + this.manifest.getVersion())); String description = this.manifest.getDescription(); - if (description != null) info.add(Message.raw("Description: " + description)); + if (description != null) info.add(TinyMsg.parse("Description: " + description)); @Nullable String[] authors = this.manifest.getAuthors(); - if (authors != null) info.add(Message.raw("Authors: " + String.join(", ", authors))); + if (authors != null) + info.add(TinyMsg.parse("Authors: " + String.join(", ", authors))); String website = this.manifest.getWebsite(); - if (website != null) info.add(Message.raw("Website: ").insert(Message.raw(website).link(website))); + if (website != null) info.add(TinyMsg.parse("Website: " + website)); return info.toArray(Message[]::new); } diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/command/ScriptCommandBuilder.java b/src/main/java/com/github/skriptdev/skript/api/skript/command/ScriptCommandBuilder.java index 954b19c1..2da67934 100644 --- a/src/main/java/com/github/skriptdev/skript/api/skript/command/ScriptCommandBuilder.java +++ b/src/main/java/com/github/skriptdev/skript/api/skript/command/ScriptCommandBuilder.java @@ -1,6 +1,7 @@ package com.github.skriptdev.skript.api.skript.command; import com.github.skriptdev.skript.plugin.HySk; +import com.github.skriptdev.skript.plugin.Skript; import com.github.skriptdev.skript.plugin.elements.command.ScriptCommand.PlayerScriptCommandContext; import com.github.skriptdev.skript.plugin.elements.command.ScriptCommand.ScriptCommandContext; import com.github.skriptdev.skript.plugin.elements.command.ScriptCommand.WorldScriptCommandContext; @@ -44,6 +45,8 @@ */ public class ScriptCommandBuilder { + private static final boolean CAN_GENERATE_PERMISSION_DEFAULT = Skript.getInstance().getSkriptConfig().getCommandsGeneratePermissions(); + public static ScriptCommandBuilder create(int commandType, SkriptLogger logger) { return new ScriptCommandBuilder(commandType, logger); } @@ -56,6 +59,7 @@ public static ScriptCommandBuilder create(int commandType, SkriptLogger logger) private AbstractCommand hyCommand; private final SectionConfiguration sec = new SectionConfiguration.Builder() + .addOptionalLiteral("can-generate-permission", Boolean.class) .addOptionalKey("permission") .addOptionalKey("description") .addOptionalList("aliases") @@ -111,6 +115,9 @@ public List setupCommand(FileSection section, ParserState parserState description = ""; } + Boolean canGeneratePermission = this.sec.getValue("can-generate-permission", Boolean.class) + .orElse(CAN_GENERATE_PERMISSION_DEFAULT); + if (hasTrigger) { CodeSection trigger = triggerSec.get(); if (trigger.getItems().isEmpty()) { @@ -120,6 +127,11 @@ public List setupCommand(FileSection section, ParserState parserState this.hyCommand = switch (commandType) { case 1 -> new AbstractPlayerCommand(this.commandName, description) { + @Override + protected boolean canGeneratePermission() { + return canGeneratePermission; + } + @Override protected void execute(@NotNull CommandContext commandContext, @NotNull Store store, @NotNull Ref ref, @NotNull PlayerRef playerRef, @NotNull World world) { @@ -134,6 +146,10 @@ protected void execute(@NotNull CommandContext commandContext, @NotNull Store new AbstractWorldCommand(this.commandName, description) { + @Override + protected boolean canGeneratePermission() { + return canGeneratePermission; + } @Override protected void execute(@NotNull CommandContext commandContext, @NotNull World world, @@ -147,7 +163,10 @@ protected void execute(@NotNull CommandContext commandContext, @NotNull World wo } }; default -> new AbstractCommand(this.commandName, description) { - + @Override + protected boolean canGeneratePermission() { + return canGeneratePermission; + } @Override protected @Nullable CompletableFuture execute(@NotNull CommandContext commandContext) { CompletableFuture.runAsync(() -> { @@ -167,7 +186,10 @@ protected void execute(@NotNull CommandContext commandContext, @NotNull World wo }; } else { this.hyCommand = new AbstractCommandCollection(this.commandName, description) { - + @Override + protected boolean canGeneratePermission() { + return canGeneratePermission; + } }; } this.args.forEach((key, arg) -> { diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/config/SkriptConfig.java b/src/main/java/com/github/skriptdev/skript/api/skript/config/SkriptConfig.java new file mode 100644 index 00000000..60c51157 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/api/skript/config/SkriptConfig.java @@ -0,0 +1,138 @@ +package com.github.skriptdev.skript.api.skript.config; + +import com.github.skriptdev.skript.api.utils.Utils; +import com.github.skriptdev.skript.plugin.Skript; +import com.hypixel.hytale.common.semver.Semver; +import io.github.syst3ms.skriptparser.config.Config; +import io.github.syst3ms.skriptparser.config.Config.ConfigSection; +import io.github.syst3ms.skriptparser.log.ErrorType; +import io.github.syst3ms.skriptparser.log.LogEntry; +import io.github.syst3ms.skriptparser.log.SkriptLogger; +import org.jetbrains.annotations.Nullable; + +import java.nio.file.Path; + +/** + * Config for Skript + */ +public class SkriptConfig { + + private final Config config; + private final boolean debug; + private final int maxTargetBlockDistance; + private final ConfigSection effectCommands; + private final ConfigSection databases; + private final boolean commandsGeneratePermissions; + + public SkriptConfig(Skript skript) { + Path skriptConfigPath = skript.getPlugin().getDataDirectory().resolve("config.sk"); + SkriptLogger logger = new SkriptLogger(true); + this.config = new Config(skriptConfigPath, "/config.sk", logger); + + // Set up debug mode + this.debug = this.config.getBoolean("debug"); + Utils.setDebug(this.debug); + + // Check for update + String string = this.config.getString("hyskript-version"); + if (string != null) { + Semver configVersion = Semver.fromString(string); + logger.debug("Checking for update from: " + configVersion); + Semver hySkriptVersion = skript.getPlugin().getManifest().getVersion(); + if (configVersion.compareTo(hySkriptVersion) < 0) { + logger.debug("Updating config to version: " + hySkriptVersion); + updateConfig(); + } else { + logger.debug("Config is up to date"); + } + } else { + logger.error("hyskript-version not found in config.sk, no update checking can be performed.", ErrorType.STRUCTURE_ERROR); + } + + // Set up max-target-block-distance + this.maxTargetBlockDistance = this.config.getInt("max-target-block-distance"); + if (this.maxTargetBlockDistance == -1) { + // This would happen if the config is missing this value + // TODO update config + } else if (this.maxTargetBlockDistance < 0) { + logger.error("max-target-block-distance must be greater than or equal to 0", ErrorType.STRUCTURE_ERROR); + } + + // Set up effect commands + this.effectCommands = this.config.getConfigSection("effect-commands"); + if (this.effectCommands == null) { + logger.error("Effect commands section not found in config.sk", ErrorType.STRUCTURE_ERROR); + // TODO update config + } + + // Set up databases + this.databases = this.config.getConfigSection("databases"); + if (this.databases == null) { + logger.error("Databases section not found in config.sk", ErrorType.STRUCTURE_ERROR); + // TODO update config + } + + // Set up commands generate permissions + this.commandsGeneratePermissions = this.config.getBoolean("commands-generate-permissions", true); + + logger.finalizeLogs(); + for (LogEntry logEntry : logger.close()) { + Utils.log(null, logEntry); + } + } + + @SuppressWarnings("unused") + public Config getBaseConfig() { + return this.config; + } + + /** + * Get whether debug mode is enabled + * + * @return Whether debug mode is enabled + */ + public boolean getDebug() { + return this.debug; + } + + /** + * Get the maximum target block distance. + * + * @return Maximum target block distance. + */ + public int getMaxTargetBlockDistance() { + return this.maxTargetBlockDistance; + } + + /** + * Get the effect commands section. + * + * @return Effect commands section. + */ + public @Nullable ConfigSection getEffectCommands() { + return this.effectCommands; + } + + /** + * Get the databases section. + * + * @return Databases section. + */ + public @Nullable ConfigSection getDatabases() { + return this.databases; + } + + /** + * Get whether commands should generate permissions. + * + * @return Whether commands should generate permissions. + */ + public boolean getCommandsGeneratePermissions() { + return this.commandsGeneratePermissions; + } + + private void updateConfig() { + // TODO update config + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/docs/JsonDocPrinter.java b/src/main/java/com/github/skriptdev/skript/api/skript/docs/JsonDocPrinter.java index dea9e8f5..a5096e3a 100644 --- a/src/main/java/com/github/skriptdev/skript/api/skript/docs/JsonDocPrinter.java +++ b/src/main/java/com/github/skriptdev/skript/api/skript/docs/JsonDocPrinter.java @@ -143,9 +143,10 @@ private void printEvents(BsonDocument mainDocs, SkriptRegistration registration) BsonDocument eventDoc = new BsonDocument(); - if (!Structure.class.isAssignableFrom(event.getSyntaxClass())) { - printDocumentation("event", eventDoc, event); + if (Structure.class.isAssignableFrom(event.getSyntaxClass())) { + return; } + printDocumentation("event", eventDoc, event); AtomicBoolean cancellable = new AtomicBoolean(false); event.getContexts().forEach(context -> { @@ -161,13 +162,14 @@ private void printEvents(BsonDocument mainDocs, SkriptRegistration registration) valuesForThisEvent.add(contextValue); } }); - BsonArray eventValues = eventDoc.getArray("event values", new BsonArray()); + BsonArray eventValues = eventDoc.getArray("context values", new BsonArray()); if (!valuesForThisEvent.isEmpty()) { valuesForThisEvent.forEach(contextValue -> { - eventValues.add(new BsonString(contextValue.getPattern().toString())); + eventValues.add(new BsonString("context-" + contextValue.getPattern().toString())); }); } + eventDoc.put("context values", eventValues); eventsArray.add(eventDoc); }); mainDocs.put("events", eventsArray); @@ -180,11 +182,13 @@ private void printStructures(BsonDocument mainDocs, SkriptRegistration registrat Documentation documentation = event.getDocumentation(); if (documentation.isNoDoc()) return; - if (Structure.class.isAssignableFrom(event.getSyntaxClass())) { - BsonDocument structureDoc = new BsonDocument(); - printDocumentation("structure", structureDoc, event); - structuresArray.add(structureDoc); + if (!Structure.class.isAssignableFrom(event.getSyntaxClass())) { + return; } + + BsonDocument structureDoc = new BsonDocument(); + printDocumentation("structure", structureDoc, event); + structuresArray.add(structureDoc); }); mainDocs.put("structures", structuresArray); @@ -202,18 +206,24 @@ private void printExpressions(BsonDocument mainDocs, SkriptRegistration registra if (documentation.isNoDoc()) return; BsonDocument expressionDoc = new BsonDocument(); - printDocumentation("effect-expression", expressionDoc, expressionInfo); - String returnType = expressionInfo.getReturnType().getType().getBaseName(); - expressionDoc.put("return type", new BsonString(returnType)); + + // Return Type + Type returnType = expressionInfo.getReturnType().getType(); + String returnTypeName = returnType.getDocumentation().getName(); + if (returnTypeName == null) returnTypeName = returnType.getBaseName(); + expressionDoc.put("return type", new BsonString(returnTypeName)); Class syntaxClass = expressionInfo.getSyntaxClass(); if (ExecutableExpression.class.isAssignableFrom(syntaxClass)) { // TODO new section on the docs?!?!?! exprsArray.add(expressionDoc); + printDocumentation("executable-expression", expressionDoc, expressionInfo); } else if (ConditionalExpression.class.isAssignableFrom(syntaxClass)) { condArray.add(expressionDoc); + printDocumentation("condition", expressionDoc, expressionInfo); } else { exprsArray.add(expressionDoc); + printDocumentation("expression", expressionDoc, expressionInfo); } }); diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/registration/SkriptRegistration.java b/src/main/java/com/github/skriptdev/skript/api/skript/registration/SkriptRegistration.java index ba0dd3e0..387e7366 100644 --- a/src/main/java/com/github/skriptdev/skript/api/skript/registration/SkriptRegistration.java +++ b/src/main/java/com/github/skriptdev/skript/api/skript/registration/SkriptRegistration.java @@ -1,11 +1,12 @@ package com.github.skriptdev.skript.api.skript.registration; import com.github.skriptdev.skript.api.utils.Utils; +import com.github.skriptdev.skript.plugin.Skript; import com.hypixel.hytale.assetstore.JsonAsset; import com.hypixel.hytale.assetstore.map.DefaultAssetMap; import io.github.syst3ms.skriptparser.docs.Documentation; import io.github.syst3ms.skriptparser.log.LogEntry; -import io.github.syst3ms.skriptparser.registration.SkriptAddon; +import io.github.syst3ms.skriptparser.log.SkriptLogger; import io.github.syst3ms.skriptparser.types.Type; import io.github.syst3ms.skriptparser.types.TypeManager; import io.github.syst3ms.skriptparser.types.changers.Arithmetic; @@ -17,7 +18,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Objects; import java.util.TreeMap; import java.util.function.Function; import java.util.function.Supplier; @@ -27,8 +27,15 @@ */ public class SkriptRegistration extends io.github.syst3ms.skriptparser.registration.SkriptRegistration { - public SkriptRegistration(SkriptAddon registerer) { - super(registerer); + private final Skript skript; + + public SkriptRegistration(Skript registerer) { + super(registerer, new SkriptLogger(true)); + this.skript = registerer; + } + + public Skript getSkript() { + return this.skript; } @Override @@ -61,7 +68,8 @@ public class AssetStoreRegistrar, K extends String> { private final Class assetClass; private final String baseName; private final String pattern; - private Function toStringFunction = o -> Objects.toString(o, TypeManager.NULL_REPRESENTATION); + private Function toStringFunction; + private Function toVariableNameFunction; private final Function literalParser; @Nullable private Changer defaultChanger; @@ -83,7 +91,8 @@ public AssetStoreRegistrar(Class assetClass, DefaultAssetMap assetMap, assetMap.getAssetMap().forEach((key, value) -> this.assetStoreValues.put(key.toLowerCase(Locale.ROOT), value)); this.supplier = () -> assetStoreValues.values().stream().iterator(); this.literalParser = s -> this.assetStoreValues.get(s.toLowerCase(Locale.ROOT).replace(" ", "_")); - + this.toStringFunction = JsonAsset::getId; + this.toVariableNameFunction = c -> baseName + ":" + c.getId().toLowerCase(Locale.ROOT).replace(" ", "_"); } /** @@ -95,6 +104,11 @@ public AssetStoreRegistrar toStringFunction(Function to return this; } + public AssetStoreRegistrar toVariableNameFunction(Function toVariableNameFunction) { + this.toVariableNameFunction = toVariableNameFunction; + return this; + } + /** * @param defaultChanger a default {@link Changer} for this type * @return the registrar @@ -166,7 +180,8 @@ public AssetStoreRegistrar since(String since) { * Adds this type to the list of currently registered syntaxes */ public void register() { - AssetStoreType assetStoreType = new AssetStoreType<>(assetClass, baseName, pattern, literalParser, toStringFunction, + AssetStoreType assetStoreType = new AssetStoreType<>(assetClass, baseName, pattern, literalParser, + toStringFunction, toVariableNameFunction, defaultChanger, arithmetic, documentation, serializer, this.supplier); newTypes = true; types.add(assetStoreType); @@ -176,10 +191,11 @@ public void register() { public static class AssetStoreType, K extends String> extends Type { public AssetStoreType(Class c, String baseName, String pattern, Function literalParser, - Function toStringFunction, Changer defaultChanger, + Function toStringFunction, + Function toVariableNameFunction, Changer defaultChanger, Arithmetic arithmetic, Documentation documentation, TypeSerializer serializer, Supplier> supplier) { - super(c, baseName, pattern, literalParser, toStringFunction, defaultChanger, + super(c, baseName, pattern, literalParser, toStringFunction, toVariableNameFunction, defaultChanger, arithmetic, documentation, serializer, supplier); } } @@ -203,6 +219,7 @@ public class EnumRegistrar> { private final String pattern; private Function toStringFunction; + private Function toVariableNameFunction; private final Function literalParser; @Nullable private Changer defaultChanger; @@ -225,6 +242,7 @@ public EnumRegistrar(Class enumClass, String name, String pattern) { this.supplier = () -> this.values.values().iterator(); this.literalParser = s -> this.values.get(s.toLowerCase(Locale.ROOT).replace(" ", "_")); this.toStringFunction = e -> e.name().toLowerCase(Locale.ROOT); + this.toVariableNameFunction = e -> this.baseName + ":" + e.name().toLowerCase(Locale.ROOT).replace(" ", "_"); } @@ -237,6 +255,11 @@ public EnumRegistrar toStringFunction(Function toStringFun return this; } + public EnumRegistrar toVariableNameFunction(Function toVariableNameFunction) { + this.toVariableNameFunction = toVariableNameFunction; + return this; + } + /** * @param defaultChanger a default {@link Changer} for this type * @return the registrar @@ -313,7 +336,8 @@ public EnumRegistrar since(String since) { * Adds this type to the list of currently registered syntaxes */ public void register() { - EnumType enumType = new EnumType<>(this.enumClass, baseName, pattern, literalParser, toStringFunction, + EnumType enumType = new EnumType<>(this.enumClass, baseName, pattern, literalParser, + toStringFunction, toVariableNameFunction, defaultChanger, arithmetic, documentation, serializer, this.supplier); newTypes = true; types.add(enumType); @@ -322,10 +346,11 @@ public void register() { public static class EnumType> extends Type { public EnumType(Class c, String baseName, String pattern, Function literalParser, - Function toStringFunction, Changer defaultChanger, + Function toStringFunction, Function toVariableNameFunction, + Changer defaultChanger, Arithmetic arithmetic, Documentation documentation, TypeSerializer serializer, Supplier> supplier) { - super(c, baseName, pattern, literalParser, toStringFunction, defaultChanger, + super(c, baseName, pattern, literalParser, toStringFunction, toVariableNameFunction, defaultChanger, arithmetic, documentation, serializer, supplier); } } diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/variables/JsonVariableStorage.java b/src/main/java/com/github/skriptdev/skript/api/skript/variables/JsonVariableStorage.java index f3335856..c2703203 100644 --- a/src/main/java/com/github/skriptdev/skript/api/skript/variables/JsonVariableStorage.java +++ b/src/main/java/com/github/skriptdev/skript/api/skript/variables/JsonVariableStorage.java @@ -118,7 +118,7 @@ private void startFileWatcher() { } private void loadVariablesFromFile() { - Utils.log("Loading variables from file..."); + Utils.log("Loading variables from '%s'...", this.name); AtomicBoolean markForBackup = new AtomicBoolean(false); try { @@ -170,15 +170,15 @@ private void loadVariablesFromFile() { Utils.log(" - Loaded " + count.get() + " variables so far..."); } }); - Utils.log("Loaded %s variables from file!", count.get()); + Utils.log("Loaded %s variables from database '%s'!", count.get(), this.name); } if (markForBackup.get()) { - Utils.warn("Failed to load some variables from file. Creating backup..."); + Utils.warn("Failed to load some variables from database '%s'. Creating backup...", this.name); Files.copy(this.file.toPath(), this.file.toPath().resolveSibling(this.file.getName() + ".bak")); } } catch (IOException e) { - Utils.error("Failed to load variables from file", ErrorType.EXCEPTION); + Utils.error("Failed to load variables from database '%s'", this.name); throw new RuntimeException(e); } } diff --git a/src/main/java/com/github/skriptdev/skript/api/utils/Utils.java b/src/main/java/com/github/skriptdev/skript/api/utils/Utils.java index 1a402090..bbbd17f5 100644 --- a/src/main/java/com/github/skriptdev/skript/api/utils/Utils.java +++ b/src/main/java/com/github/skriptdev/skript/api/utils/Utils.java @@ -1,11 +1,13 @@ package com.github.skriptdev.skript.api.utils; -import com.github.skriptdev.skript.plugin.HySk; +import com.hypixel.hytale.logger.HytaleLogger; import com.hypixel.hytale.server.core.Message; +import com.hypixel.hytale.server.core.console.ConsoleSender; import com.hypixel.hytale.server.core.permissions.PermissionsModule; import com.hypixel.hytale.server.core.receiver.IMessageReceiver; import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.Universe; +import com.hypixel.hytale.server.core.util.MessageUtil; import fi.sulku.hytale.TinyMsg; import io.github.syst3ms.skriptparser.log.LogEntry; @@ -17,7 +19,20 @@ */ public class Utils { - static final Message CORE_PREFIX = TinyMsg.parse("[HySkript] "); + private static boolean DEBUG = false; + private static final Message CORE_PREFIX = TinyMsg.parse("[HySkript] "); + private static final HytaleLogger LOGGER = HytaleLogger.get(MessageUtil.toAnsiString( + TinyMsg.parse("HySkript|P")).toAnsi()); + + + public static HytaleLogger getLogger() { + return LOGGER; + } + + public static HytaleLogger getAddonLogger(String addonName) { + return HytaleLogger.get(MessageUtil.toAnsiString( + TinyMsg.parse("HySkript|" + addonName + "|A")).toAnsi()); + } /** * Send a message to a receiver. @@ -33,6 +48,13 @@ public static void sendMessage(IMessageReceiver receiver, String message, Object receiver.sendMessage(Message.raw(message)); } + public static void sendTinyMessage(IMessageReceiver receiver, String message, Object... args) { + if (args.length > 0) { + message = String.format(message, args); + } + receiver.sendMessage(TinyMsg.parse(message)); + } + public static void log(Level level, String message, Object... args) { log(null, level, message, args); } @@ -41,8 +63,8 @@ public static void log(IMessageReceiver receiver, Level level, String message, O if (args.length > 0) { message = String.format(message, args); } - if (receiver == null) { - HySk.getInstance().getLogger().at(level).log(message); + if (receiver == null || receiver instanceof ConsoleSender) { + LOGGER.at(level).log(message); } else { Color color = level == Level.SEVERE ? Color.RED : level == Level.WARNING ? Color.YELLOW : level == Level.FINE ? Color.PINK : Color.WHITE; @@ -64,7 +86,7 @@ public static void log(IMessageReceiver receiver, String message, Object... args public static void log(IMessageReceiver receiver, LogEntry logEntry) { String message = logEntry.getMessage(); switch (logEntry.getType()) { - case DEBUG -> log(receiver, Level.FINE, message); + case DEBUG -> debug(message); case INFO -> log(receiver, Level.INFO, message); case ERROR -> log(receiver, Level.SEVERE, message); case WARNING -> log(receiver, Level.WARNING, message); @@ -87,6 +109,33 @@ public static void warn(IMessageReceiver receiver, String message, Object... arg log(receiver, Level.WARNING, message, args); } + /** + * Set whether debug messages should print to the console. + * + * @param debug Whether to print debug messages + */ + public static void setDebug(boolean debug) { + DEBUG = debug; + debug("Debug mode is now enabled"); + } + + /** + * Send a debug message to the console. + * This will only happen if `debug` is enabled in config. + * + * @param message Message to send + * @param args Arguments for message formatting + */ + public static void debug(String message, Object... args) { + if (!DEBUG) return; + if (args.length > 0) { + message = String.format(message, args); + } + Message parse = TinyMsg.parse("" + message); + String ansi = MessageUtil.toAnsiString(parse).toAnsi(); + log(Level.INFO, ansi); + } + /** * Log a message to admin players who have the permission "skript.hyskript.admin.messages" * diff --git a/src/main/java/com/github/skriptdev/skript/plugin/Skript.java b/src/main/java/com/github/skriptdev/skript/plugin/Skript.java index 6b190307..e15bad3e 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/Skript.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/Skript.java @@ -4,6 +4,7 @@ import com.github.skriptdev.skript.api.skript.ScriptsLoader; import com.github.skriptdev.skript.api.skript.addon.AddonLoader; import com.github.skriptdev.skript.api.skript.command.ArgUtils; +import com.github.skriptdev.skript.api.skript.config.SkriptConfig; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.github.skriptdev.skript.api.skript.variables.JsonVariableStorage; import com.github.skriptdev.skript.api.utils.ReflectionUtils; @@ -11,8 +12,7 @@ import com.github.skriptdev.skript.plugin.command.EffectCommands; import com.github.skriptdev.skript.plugin.elements.ElementRegistration; import com.github.skriptdev.skript.plugin.elements.events.EventHandler; -import io.github.syst3ms.skriptparser.Parser; -import io.github.syst3ms.skriptparser.config.Config; +import com.hypixel.hytale.server.core.event.events.BootEvent; import io.github.syst3ms.skriptparser.config.Config.ConfigSection; import io.github.syst3ms.skriptparser.log.LogEntry; import io.github.syst3ms.skriptparser.log.SkriptLogger; @@ -30,7 +30,7 @@ public class Skript extends SkriptAddon { public static Skript INSTANCE; private final HySk hySk; - private final Config skriptConfig; + private final SkriptConfig skriptConfig; private final Path scriptsPath; private SkriptRegistration registration; private ElementRegistration elementRegistration; @@ -49,16 +49,10 @@ public class Skript extends SkriptAddon { Utils.log(" "); // LOAD CONFIG - Path skriptConfigPath = hySk.getDataDirectory().resolve("config.sk"); - SkriptLogger logger = new SkriptLogger(); - this.skriptConfig = new Config(skriptConfigPath, "/config.sk", logger); - logger.finalizeLogs(); - for (LogEntry logEntry : logger.close()) { - Utils.log(null, logEntry); - } + this.skriptConfig = new SkriptConfig(this); // SETUP SKRIPT - setup(); + setupSkript(); // ALL DONE Utils.log(" "); @@ -67,14 +61,25 @@ public class Skript extends SkriptAddon { Utils.log(" "); } - private void setup() { + private void setupSkript() { long start = System.currentTimeMillis(); - preSetup(); + + // INITIALIZE UTILITIES + Utils.debug("Initializing utilities..."); + ReflectionUtils.init(); + ArgUtils.init(); + + // SETUP REGISTRATION + Utils.debug("Setting up registration..."); this.registration = new SkriptRegistration(this); this.elementRegistration = new ElementRegistration(this.registration); + + // REGISTER ELEMENTS + Utils.debug("Registering elements..."); this.elementRegistration.registerElements(); // SETUP EFFECT COMMANDS + Utils.debug("Setting up effect commands..."); setupEffectCommands(); // FINISH SETUP @@ -86,6 +91,7 @@ private void setup() { this.addonLoader.loadAddonsFromFolder(); // SETUP ERROR HANDLER + Utils.debug("Setting up error handler..."); ErrorHandler.init(); // LOAD VARIABLES @@ -96,12 +102,11 @@ private void setup() { this.scriptsLoader.loadScripts(null, this.scriptsPath, false); // FINALIZE SCRIPT LOADING - Parser.getMainRegistration().getRegisterer().finishedLoading(); - } - - private void preSetup() { - ReflectionUtils.init(); - ArgUtils.init(); + this.hySk.getEventRegistry().register(BootEvent.class, event -> { + Utils.debug("Hytale finished booting, starting post-load triggers..."); + // Start any post-load triggers after Hytale finishes booting. + getAddons().forEach(SkriptAddon::finishedLoading); + }); } public void shutdown() { @@ -121,7 +126,7 @@ public void shutdown() { } private void setupEffectCommands() { - ConfigSection effectCommandSection = this.skriptConfig.getConfigSection("effect-commands"); + ConfigSection effectCommandSection = this.skriptConfig.getEffectCommands(); if (effectCommandSection != null) { if (effectCommandSection.getBoolean("enabled")) { EffectCommands.register(this, @@ -129,6 +134,8 @@ private void setupEffectCommands() { effectCommandSection.getBoolean("allow-ops"), effectCommandSection.getString("required-permission")); } + } else { + Utils.debug("Effect commands section is missing in config.sk"); } } @@ -136,12 +143,11 @@ private void loadVariables() { long start = System.currentTimeMillis(); Utils.log("Loading variables..."); Variables.registerStorage(JsonVariableStorage.class, "json-database"); - ConfigSection databases = this.skriptConfig.getConfigSection("databases"); + ConfigSection databases = this.skriptConfig.getDatabases(); if (databases == null) { - Utils.error("Databases section not found in config.sk"); return; } - SkriptLogger skriptLogger = new SkriptLogger(); + SkriptLogger skriptLogger = new SkriptLogger(true); Variables.load(skriptLogger, databases); skriptLogger.finalizeLogs(); for (LogEntry logEntry : skriptLogger.close()) { @@ -165,7 +171,7 @@ private void loadVariables() { * * @return The Skript configuration. */ - public @NotNull Config getSkriptConfig() { + public @NotNull SkriptConfig getSkriptConfig() { return this.skriptConfig; } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/command/EffectCommands.java b/src/main/java/com/github/skriptdev/skript/plugin/command/EffectCommands.java index 0bfe8b7a..5ecd25e0 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/command/EffectCommands.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/command/EffectCommands.java @@ -38,23 +38,26 @@ public static void register(Skript skript, String token, boolean allowOps, Strin // PERM CHECK PermissionsModule perm = PermissionsModule.get(); - if (!allowOps) { - PermissionProvider provider = perm.getFirstPermissionProvider(); - Set groupsForUser = perm.getGroupsForUser(sender.getUuid()); - if (groupsForUser.contains("OP")) { - boolean can = false; + PermissionProvider provider = perm.getFirstPermissionProvider(); + Set groupsForUser = perm.getGroupsForUser(sender.getUuid()); + + // If the player is an operator and allowOps is false, check their group/user permissions + if (!allowOps && groupsForUser.contains("OP")) { + boolean can = false; + // If the user explicitely has this permission, they can use effect commands + if (provider.getUserPermissions(sender.getUuid()).contains(permission)) { + can = true; + } else { // Check all groups for (String group : groupsForUser) { - // If the group has the explicit permission, they can use effect commands + // If the group explicitely has this permission, they can use effect commands if (provider.getGroupPermissions(group).contains(permission)) { can = true; break; } } - if (!can) return; - } else { - return; } + if (!can) return; } else if (!perm.hasPermission(sender.getUuid(), permission)) { return; } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/command/SkriptCommand.java b/src/main/java/com/github/skriptdev/skript/plugin/command/SkriptCommand.java index d6ffa182..39d417dd 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/command/SkriptCommand.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/command/SkriptCommand.java @@ -17,6 +17,7 @@ import com.hypixel.hytale.server.core.command.system.arguments.system.RequiredArg; import com.hypixel.hytale.server.core.command.system.arguments.types.ArgTypes; import com.hypixel.hytale.server.core.command.system.basecommands.AbstractCommandCollection; +import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.receiver.IMessageReceiver; import io.github.syst3ms.skriptparser.registration.SkriptAddon; import org.jetbrains.annotations.NotNull; @@ -170,9 +171,11 @@ protected CompletableFuture execute(@NotNull CommandContext commandContext } private void printInfo(IMessageReceiver sender) { - Utils.sendMessage(sender, "HySkript Version: %s", HySk.getInstance().getManifest().getVersion()); - Utils.sendMessage(sender, "Hytale Version: %s (%s)", ManifestUtil.getImplementationVersion(), ManifestUtil.getPatchline()); - Utils.sendMessage(sender, "Java Version: %s", System.getProperty("java.version")); + Utils.sendTinyMessage(sender, "HySkript Version: %s", + HySk.getInstance().getManifest().getVersion()); + Utils.sendTinyMessage(sender, "Hytale Version: %s (%s)", + ManifestUtil.getImplementationVersion(), ManifestUtil.getPatchline()); + Utils.sendTinyMessage(sender, "Java Version: %s", System.getProperty("java.version")); List addons = SkriptAddon.getAddons().stream() .filter(addon -> !addon.getAddonName().equalsIgnoreCase("skript-parser") @@ -180,15 +183,40 @@ private void printInfo(IMessageReceiver sender) { .toList(); if (!addons.isEmpty()) { - Utils.sendMessage(sender, "Loaded Addons: %s"); - addons.forEach(addon -> Utils.sendMessage(sender, " - %s", addon.getAddonName())); + Utils.sendTinyMessage(sender, "Loaded Addons (%s):", addons.size()); + addons.forEach(addon -> { + if (addon instanceof HySkriptAddon hySkriptAddon) { + Utils.sendTinyMessage(sender, " - %s:", hySkriptAddon.getAddonName()); + for (Message s : hySkriptAddon.getInfo()) { + sender.sendMessage(Message.raw(" ").insert(s)); + } + } else { + Utils.sendTinyMessage(sender, " - %s", addon.getAddonName()); + } + }); + } + + // Website + if (sender instanceof Player) { + Utils.sendTinyMessage(sender, "Website: HySkript on GitHub"); + } else { + Utils.sendTinyMessage(sender, "Website: https://github.com/SkriptDev/HySkript"); + } + + // Issue Tracker + if (sender instanceof Player) { + Utils.sendTinyMessage(sender, "Issues: GitHub Issue Tracker"); + } else { + Utils.sendTinyMessage(sender, "Issues: https://github.com/SkriptDev/HySkript/issues"); + } + + // Docs + if (sender instanceof Player) { + Utils.sendTinyMessage(sender, "Docs: SkriptHub Docs"); + } else { + Utils.sendTinyMessage(sender, "Docs: https://skripthub.net/hyskript/docs/"); } - Message link = Message.raw("https://github.com/SkriptDev/HySkript") - .link("https://github.com/SkriptDev/HySkript") - .color("#0CE8C3"); - Message website = Message.raw("Website: ").insert(link); - sender.sendMessage(website); } } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/command/ScriptCommand.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/command/ScriptCommand.java index 7f5c4026..ddfc0f9e 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/command/ScriptCommand.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/command/ScriptCommand.java @@ -113,10 +113,12 @@ public static void register(SkriptRegistration reg) { "- Description = The description of the argument, this is show in the command GUI (optional).", "", "**Entries**:", - "- `Description` = The description for your command that will show in the commands gui (optional).", - "- `Permission` = The permission required to execute the command (optional).", - "- `Aliases` = A list of aliases for the command (optional).", - "- `Trigger` = The code that will be executed when the command is executed (optional).") + "- `description` = The description for your command that will show in the commands gui (optional).", + "- `permission` = The permission required to execute the command (optional).", + "- `can-generate-permission` = Whether the command should generate a permission based on the command name " + + "(optional, default true).", + "- `aliases` = A list of aliases for the command (optional).", + "- `trigger` = The code that will be executed when the command is executed (optional).") .examples("command /kill:", "\tdescription: Kill all the players", "\ttrigger:", diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/command/ScriptSubCommand.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/command/ScriptSubCommand.java index 1d2d2475..8e6e8573 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/command/ScriptSubCommand.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/command/ScriptSubCommand.java @@ -7,6 +7,7 @@ import io.github.syst3ms.skriptparser.lang.Expression; import io.github.syst3ms.skriptparser.lang.Statement; import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.log.ErrorType; import io.github.syst3ms.skriptparser.log.SkriptLogger; import io.github.syst3ms.skriptparser.parsing.ParseContext; import io.github.syst3ms.skriptparser.parsing.ParserState; @@ -20,7 +21,8 @@ public class ScriptSubCommand extends CodeSection implements ScriptCommandParent public static void register(SkriptRegistration registration) { registration.newSection(ScriptSubCommand.class, "sub command <.+>") .name("Sub Command") - .description("Creates a sub command for a top level command or another sub command.") + .description("Creates a sub command for a top level command or another sub command.", + "Sub commands have the same entries/trigger as top level commands.") .since("1.0.0") .register(); } @@ -32,6 +34,12 @@ public static void register(SkriptRegistration registration) { @Override public boolean init(Expression @NotNull [] expressions, int matchedPattern, @NotNull ParseContext parseContext) { + for (Class currentSection : parseContext.getParserState().getCurrentContexts()) { + if (!ScriptCommand.ScriptCommandContext.class.isAssignableFrom(currentSection)) { + parseContext.getLogger().error("Sub commands can only be used within commands/sub commands.", ErrorType.STRUCTURE_ERROR); + return false; + } + } this.commandLine = parseContext.getMatches().getFirst().group(); this.commandBuilder = ScriptCommandBuilder.create(-1, parseContext.getLogger()); return this.commandBuilder.parseCommandLine(this.commandLine); diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/conditions/CondPlayerIsCrouching.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/conditions/CondPlayerIsCrouching.java index 8ba2218d..bf5e03e1 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/conditions/CondPlayerIsCrouching.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/conditions/CondPlayerIsCrouching.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.conditions; -import com.github.skriptdev.skript.api.hytale.EntityComponentUtils; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.entity.movement.MovementStatesComponent; @@ -37,7 +37,7 @@ public boolean init(Expression[] expressions, int matchedPattern, @NotNull Pa @Override public boolean check(@NotNull TriggerContext ctx) { return this.players.check(ctx, player -> { - MovementStatesComponent component = EntityComponentUtils.getMovementStatesComponent(player); + MovementStatesComponent component = EntityUtils.getMovementStatesComponent(player); if (component == null) return false; return component.getMovementStates().crouching; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffDropItem.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffDropItem.java index 0a391039..27fe5a18 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffDropItem.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffDropItem.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.effects.entity; -import com.github.skriptdev.skript.api.hytale.EntityComponentUtils; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.component.Store; import com.hypixel.hytale.math.vector.Location; @@ -108,12 +108,12 @@ protected void execute(@NotNull TriggerContext ctx) { if (world.isInThread()) { world.execute(() -> { for (ItemStack itemStack : itemStacks) { - EntityComponentUtils.dropItem(store, itemStack, location, velocity, pickupDelay); + EntityUtils.dropItem(store, itemStack, location, velocity, pickupDelay); } }); } else { for (ItemStack itemStack : itemStacks) { - EntityComponentUtils.dropItem(store, itemStack, location, velocity, pickupDelay); + EntityUtils.dropItem(store, itemStack, location, velocity, pickupDelay); } } } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffEntityEffect.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffEntityEffect.java index 68e4ad3b..f144ef38 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffEntityEffect.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffEntityEffect.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.effects.entity; -import com.github.skriptdev.skript.api.hytale.EntityComponentUtils; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Store; @@ -60,7 +60,7 @@ protected void execute(@NotNull TriggerContext ctx) { int index = EntityEffect.getAssetMap().getIndex(entityEffect.getId()); for (LivingEntity entity : this.entities.getArray(ctx)) { - EffectControllerComponent component = EntityComponentUtils.getComponent(entity, EffectControllerComponent.getComponentType()); + EffectControllerComponent component = EntityUtils.getComponent(entity, EffectControllerComponent.getComponentType()); if (component == null) continue; Ref reference = entity.getReference(); diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffBroadcast.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffBroadcast.java index a0e9cec7..9dccb3e1 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffBroadcast.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffBroadcast.java @@ -19,6 +19,7 @@ public static void register(SkriptRegistration registration) { .description("Broadcasts a message to all players in the server or in a specific world.") .examples("broadcast \"HELLO EVERYONE!!!\"", "broadcast \"Free Cheese At Spawn\" in world named \"default\"") + .since("1.0.0") .register(); } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffCancelEvent.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffCancelEvent.java index 3227ccf4..f2dae0a2 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffCancelEvent.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffCancelEvent.java @@ -14,7 +14,8 @@ public class EffCancelEvent extends Effect { public static void register(SkriptRegistration registration) { registration.newEffect(EffCancelEvent.class, "cancel event", "uncancel event") .name("Cancel Event") - .description("Cancels/uncancels the current event.") + .description("Cancels/uncancels the current event.", + "**Reminder**: This effect cannot be used after a delay.") .examples("on chat:", "\tcancel event") .since("1.0.0") @@ -25,6 +26,10 @@ public static void register(SkriptRegistration registration) { @Override public boolean init(Expression @NotNull [] expressions, int matchedPattern, ParseContext parseContext) { + if (parseContext.getParserState().isDelayed()) { + parseContext.getLogger().error("Cannot cancel an event after a delay.", ErrorType.SEMANTIC_ERROR); + return false; + } this.cancel = matchedPattern == 0; for (Class currentContext : parseContext.getParserState().getCurrentContexts()) { if (!CancellableContext.class.isAssignableFrom(currentContext)) { diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffDelay.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffDelay.java index 05a6dd0d..79fbee2e 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffDelay.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffDelay.java @@ -57,6 +57,7 @@ public static void register(SkriptRegistration registration) { @SuppressWarnings("unchecked") @Override public boolean init(Expression @NotNull [] expressions, int matchedPattern, @NotNull ParseContext parseContext) { + parseContext.getParserState().setDelayed(true); this.pattern = matchedPattern; this.isConditional = matchedPattern > 1; switch (matchedPattern) { diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffSendMessage.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffSendMessage.java index 78927a5c..e2e737e7 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffSendMessage.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffSendMessage.java @@ -2,8 +2,9 @@ import com.github.skriptdev.skript.api.skript.event.PlayerContext; import com.github.skriptdev.skript.api.utils.Utils; +import com.github.skriptdev.skript.plugin.elements.command.ScriptCommand.ScriptCommandContext; import com.hypixel.hytale.server.core.Message; -import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.console.ConsoleSender; import com.hypixel.hytale.server.core.receiver.IMessageReceiver; import io.github.syst3ms.skriptparser.lang.Effect; import io.github.syst3ms.skriptparser.lang.Expression; @@ -20,9 +21,14 @@ public static void register(SkriptRegistration registration) { "send [message[s]] %objects% [to %-messagereceivers%]") .name("Send Message") .description("Sends a message to a command sender such as a player or the console.", + "If a receiver is not specified:", + " - If run in a player event, the message will be sent to the player.", + " - If run in a command, the message will be sent to the command sender.", + " - Else the message will be sent to the console.", "See [Message Format](https://github.com/SkriptDev/HySkript/wiki/Tutorial-Message-Format) on the wiki" + "for info about formatting messages.") - .examples("send \"Welcome to the server\" to player") + .examples("send \"Welcome to the server\" to player", + "send formatted \"My script has loaded\"") .since("1.0.0") .register(); } @@ -47,45 +53,35 @@ protected void execute(@NotNull TriggerContext ctx) { if (this.senders != null) { for (IMessageReceiver commandSender : this.senders.getArray(ctx)) { - for (Object value : messages) { - if (value instanceof String string) { - Utils.sendMessage(commandSender, string); - } else if (value instanceof Message message) { - commandSender.sendMessage(message); - } else { - Utils.sendMessage(commandSender, TypeManager.toString(new Object[]{value})); - } - } + sendMessage(commandSender, messages); } } else { if (ctx instanceof PlayerContext playerContext) { - Player commandSender = playerContext.getPlayer(); - for (Object value : messages) { - if (value instanceof String string) { - Utils.sendMessage(commandSender, string); - } else if (value instanceof Message message) { - commandSender.sendMessage(message); - } else { - Utils.sendMessage(commandSender, TypeManager.toString(new Object[]{value})); - } - } + sendMessage(playerContext.getPlayer(), messages); + } else if (ctx instanceof ScriptCommandContext commandContext) { + sendMessage(commandContext.getSender(), messages); } else { - for (Object value : messages) { - if (value instanceof String s) { - Utils.log(s); - } else if (value instanceof Message message) { - Utils.log(message.getRawText()); - } else { - Utils.log(TypeManager.toString(new Object[]{value})); - } - } + sendMessage(ConsoleSender.INSTANCE, messages); + } + } + } + + private void sendMessage(IMessageReceiver commandSender, Object[] objects) { + for (Object value : objects) { + if (value instanceof String string) { + Utils.sendMessage(commandSender, string); + } else if (value instanceof Message message) { + commandSender.sendMessage(message); + } else { + Utils.sendMessage(commandSender, TypeManager.toString(new Object[]{value})); } } } @Override public String toString(@NotNull TriggerContext ctx, boolean debug) { - return "send message[s] " + this.messages.toString(ctx, debug); + String to = this.senders != null ? " to " + this.senders.toString(ctx, debug) : ""; + return "send message[s] " + this.messages.toString(ctx, debug) + to; } } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffConnect.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffConnect.java index 751bf838..3254cf8a 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffConnect.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffConnect.java @@ -20,6 +20,7 @@ public static void register(SkriptRegistration reg) { "See [PLAYER REFERRAL](https://support.hytale.com/hc/en-us/articles/45326769420827-Hytale-Server-" + "Manual#multiserver-architecture) for more info.") .examples("connect all players to \"https://someserver.net\"") + .since("1.0.0") .register(); } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDiscoverZone.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDiscoverZone.java index 4cf03fee..bc42748b 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDiscoverZone.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDiscoverZone.java @@ -35,7 +35,7 @@ public static void register(SkriptRegistration reg) { reg.addSingleContextValue(DiscoverZoneContext.class, String.class, "zone-name", DiscoverZoneContext::getZoneName); - reg.addSingleContextValue(DiscoverZoneContext.class, boolean.class, + reg.addSingleContextValue(DiscoverZoneContext.class, Boolean.class, "displaying", DiscoverZoneContext::isDisplaying); reg.addSingleContextValue(DiscoverZoneContext.class, String.class, "region-name", DiscoverZoneContext::getRegionName); diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprTargetBlockOfPlayer.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprTargetBlockOfPlayer.java index 657f2abb..305d997e 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprTargetBlockOfPlayer.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprTargetBlockOfPlayer.java @@ -1,7 +1,9 @@ package com.github.skriptdev.skript.plugin.elements.expressions.block; import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.skript.config.SkriptConfig; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.github.skriptdev.skript.api.utils.Utils; import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Store; import com.hypixel.hytale.math.vector.Vector3i; @@ -18,11 +20,23 @@ public class ExprTargetBlockOfPlayer implements Expression { + private static int MAX_DISTANCE = 160; // Default from config + public static void register(SkriptRegistration reg) { + SkriptConfig skriptConfig = reg.getSkript().getSkriptConfig(); + int anInt = skriptConfig.getMaxTargetBlockDistance(); + if (anInt > 0) { + MAX_DISTANCE = anInt; + } else { + Utils.debug("'max-target-block-distance' from config.sk is not set or invalid, using default value: " + MAX_DISTANCE); + } + reg.newExpression(ExprTargetBlockOfPlayer.class, Block.class, true, "target block of %player%") .name("Target Block of Player") - .description("Returns the block the player is looking at.") + .description("Returns the block the player is looking at.", + "The default max distance is 160 blocks.", + "You can change this in config.sk under 'max-target-block-distance'.") .examples("set {_block} to target block of player") .since("1.0.0") .register(); @@ -49,8 +63,7 @@ public Block[] getValues(@NotNull TriggerContext ctx) { Store store = world.getEntityStore().getStore(); - // TODO configurable maxDistance - Vector3i targetBlock = TargetUtil.getTargetBlock(ref, 50, store); + Vector3i targetBlock = TargetUtil.getTargetBlock(ref, MAX_DISTANCE, store); if (targetBlock == null) return null; return new Block[]{new Block(world, targetBlock)}; } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityHealth.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityHealth.java index c7f332ce..805dcc70 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityHealth.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityHealth.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.entity; -import com.github.skriptdev.skript.api.hytale.EntityComponentUtils; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.server.core.entity.LivingEntity; import com.hypixel.hytale.server.core.modules.entitystats.EntityStatMap; @@ -45,7 +45,7 @@ public boolean init(Expression @NotNull [] expressions, int matchedPattern, P @Override public @Nullable Number getProperty(@NotNull LivingEntity entity) { - EntityStatMap entityStatMap = EntityComponentUtils.getEntityStatMap(entity); + EntityStatMap entityStatMap = EntityUtils.getEntityStatMap(entity); if (entityStatMap == null) return null; EntityStatValue health = entityStatMap.get(HEALTH_STAT_INDEX); if (health == null) return null; @@ -74,7 +74,7 @@ public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, Runnable healthRunnable = () -> { - EntityStatMap statMap = EntityComponentUtils.getEntityStatMap(entity); + EntityStatMap statMap = EntityUtils.getEntityStatMap(entity); if (statMap == null) return; if (changeMode == ChangeMode.RESET) { diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityStat.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityStat.java index f144732b..24740e47 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityStat.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityStat.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.entity; -import com.github.skriptdev.skript.api.hytale.EntityComponentUtils; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.server.core.entity.LivingEntity; import com.hypixel.hytale.server.core.modules.entitystats.EntityStatMap; @@ -58,7 +58,7 @@ public Number[] getValues(@NotNull TriggerContext ctx) { List values = new ArrayList<>(); for (LivingEntity livingEntity : this.entities.getArray(ctx)) { - EntityStatMap entityStatMap = EntityComponentUtils.getEntityStatMap(livingEntity); + EntityStatMap entityStatMap = EntityUtils.getEntityStatMap(livingEntity); if (entityStatMap == null) continue; EntityStatValue entityStatValue = entityStatMap.get(statIndex); @@ -88,7 +88,7 @@ public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, newValue = 0f; } for (LivingEntity entity : this.entities.getArray(ctx)) { - EntityStatMap statMap = EntityComponentUtils.getEntityStatMap(entity); + EntityStatMap statMap = EntityUtils.getEntityStatMap(entity); if (statMap == null) continue; if (changeMode == ChangeMode.RESET) { diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityVelocity.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityVelocity.java index 2aee899f..005c7ea6 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityVelocity.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityVelocity.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.entity; -import com.github.skriptdev.skript.api.hytale.EntityComponentUtils; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.math.vector.Vector3d; import com.hypixel.hytale.protocol.ChangeVelocityType; @@ -43,7 +43,7 @@ public Vector3d[] getValues(@NotNull TriggerContext ctx) { Vector3d[] velocities = new Vector3d[entityArray.length]; for (int i = 0; i < entityArray.length; i++) { - Velocity component = EntityComponentUtils.getComponent(entityArray[i], Velocity.getComponentType()); + Velocity component = EntityUtils.getComponent(entityArray[i], Velocity.getComponentType()); if (component == null) continue; velocities[i] = component.getVelocity(); } @@ -67,7 +67,7 @@ public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, } for (Entity entity : this.entities.getArray(ctx)) { - Velocity component = EntityComponentUtils.getComponent(entity, Velocity.getComponentType()); + Velocity component = EntityUtils.getComponent(entity, Velocity.getComponentType()); if (component == null) continue; switch (changeMode) { diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprName.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprName.java index ae6dae16..89dd195c 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprName.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprName.java @@ -1,38 +1,78 @@ package com.github.skriptdev.skript.plugin.elements.expressions.entity; -import com.hypixel.hytale.protocol.GameMode; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.hypixel.hytale.server.core.entity.Entity; import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.world.World; +import io.github.syst3ms.skriptparser.lang.Expression; +import io.github.syst3ms.skriptparser.lang.TriggerContext; import io.github.syst3ms.skriptparser.lang.properties.PropertyExpression; +import io.github.syst3ms.skriptparser.parsing.ParseContext; import io.github.syst3ms.skriptparser.registration.SkriptRegistration; +import io.github.syst3ms.skriptparser.types.changers.ChangeMode; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Optional; + public class ExprName extends PropertyExpression { public static void register(SkriptRegistration registration) { - registration.newPropertyExpression(ExprName.class, String.class, "name[s]", "object") + registration.newPropertyExpression(ExprName.class, String.class, + "[:display] name[s]", "entities/players/playerrefs/worlds") .name("Name of Object") - .description("Returns the name of an object.", - "Currently supports players, entities, and worlds.") + .description("Gets the name of an object.", + "Currently supports players, entities, and worlds.", + "Display name refers to the nameplate over an entity/player's head.", + "Display name of Entity/Player can be set. PlayerRef/World do not support setting.") .examples("set {_name} to name of player", - "set {_w} to name of world of player") + "set {_w} to name of world of player", + "set display name of target entity of player to \"Mr Sheep\"") .since("1.0.0") .register(); } - @SuppressWarnings("removal") // #getLegacyDisplayName TODO (find a better solution?) + private boolean display; + + @Override + public boolean init(Expression @NotNull [] expressions, int matchedPattern, ParseContext parseContext) { + this.display = parseContext.hasMark("display"); + return super.init(expressions, matchedPattern, parseContext); + } + @Override public @Nullable String getProperty(Object object) { return switch (object) { case PlayerRef playerRef -> playerRef.getUsername(); - case Player player -> player.getDisplayName(); - case Entity entity -> entity.getLegacyDisplayName(); + case Player player -> this.display ? EntityUtils.getName(player) : player.getDisplayName(); + case Entity entity -> EntityUtils.getName(entity); case World world -> world.getName(); - case GameMode gameMode -> gameMode.name(); default -> null; }; } + @Override + public Optional[]> acceptsChange(@NotNull ChangeMode mode) { + if (this.display && (mode == ChangeMode.SET || mode == ChangeMode.DELETE)) + return Optional.of(new Class[]{String.class}); + return Optional.empty(); + } + + @SuppressWarnings("ConstantValue") + @Override + public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, Object @NotNull [] changeWith) { + String name = null; + + if (changeWith != null && changeWith.length > 0 && changeWith[0] instanceof String s) { + name = s; + } + + for (Object o : getOwner().getArray(ctx)) { + if (o instanceof Entity entity) { + EntityUtils.setNameplateName(entity, name); + } + } + } + } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entityeffect/ExprActiveEntityEffects.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entityeffect/ExprActiveEntityEffects.java index 84f3a249..86fcfada 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entityeffect/ExprActiveEntityEffects.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entityeffect/ExprActiveEntityEffects.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.entityeffect; -import com.github.skriptdev.skript.api.hytale.EntityComponentUtils; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Store; @@ -48,7 +48,7 @@ public ActiveEntityEffect[] getValues(@NotNull TriggerContext ctx) { List effects = new ArrayList<>(); for (LivingEntity entity : this.entities.getArray(ctx)) { - EffectControllerComponent component = EntityComponentUtils.getComponent(entity, EffectControllerComponent.getComponentType()); + EffectControllerComponent component = EntityUtils.getComponent(entity, EffectControllerComponent.getComponentType()); if (component == null) continue; component.getActiveEffects().forEach(effects::add); @@ -83,7 +83,7 @@ public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, if (reference == null) continue; Store store = reference.getStore(); - EffectControllerComponent component = EntityComponentUtils.getComponent(livingEntity, + EffectControllerComponent component = EntityUtils.getComponent(livingEntity, EffectControllerComponent.getComponentType()); if (component == null) continue; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprUUID.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprUUID.java index b45a8bc7..00c59ddb 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprUUID.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprUUID.java @@ -1,5 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.other; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.hypixel.hytale.server.core.entity.Entity; import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.world.World; @@ -13,7 +14,8 @@ public class ExprUUID extends PropertyExpression { public static void register(SkriptRegistration registration) { - registration.newPropertyExpression(ExprUUID.class, UUID.class, "uuid", "objects") + registration.newPropertyExpression(ExprUUID.class, UUID.class, + "uuid", "players/playerrefs/entities/worlds") .name("UUID of Object") .description("Get the UUID of a player, player ref, entity, or world.") .examples("set {_uuid} to uuid of {_player}") @@ -21,12 +23,11 @@ public static void register(SkriptRegistration registration) { .register(); } - @SuppressWarnings("removal") // Entity#getUuid TODO (what else would you use?) @Override public @Nullable UUID getProperty(@NotNull Object owner) { return switch (owner) { case PlayerRef playerRef -> playerRef.getUuid(); - case Entity entity -> entity.getUuid(); + case Entity entity -> EntityUtils.getUUID(entity); case World world -> world.getWorldConfig().getUuid(); default -> null; }; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprAllPlayers.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprAllPlayers.java index 6bafd41e..60c40613 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprAllPlayers.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprAllPlayers.java @@ -23,6 +23,7 @@ public static void register(SkriptRegistration registration) { "loop all players in world of player:", "loop all players:", "kill all players") + .since("1.0.0") .register(); } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprPlayerPermissionGroup.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprPlayerPermissionGroup.java index c3b5b083..59b49df2 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprPlayerPermissionGroup.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprPlayerPermissionGroup.java @@ -1,5 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.player; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.permissions.PermissionsModule; @@ -39,7 +40,6 @@ public boolean init(Expression[] expressions, int matchedPattern, @NotNull Pa return true; } - @SuppressWarnings("removal") @Override public String[] getValues(@NotNull TriggerContext ctx) { List groups = new ArrayList<>(); @@ -49,7 +49,7 @@ public String[] getValues(@NotNull TriggerContext ctx) { if (o instanceof UUID u) { groups.addAll(provider.getGroupsForUser(u)); } else if (o instanceof Player player) { - UUID uuid = player.getUuid(); + UUID uuid = EntityUtils.getUUID(player); if (uuid == null) continue; groups.addAll(provider.getGroupsForUser(uuid)); } else if (o instanceof PlayerRef ref) { @@ -66,7 +66,7 @@ public Optional[]> acceptsChange(@NotNull ChangeMode mode) { return Optional.empty(); } - @SuppressWarnings({"ConstantValue", "removal"}) + @SuppressWarnings({"ConstantValue"}) @Override public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, Object @NotNull [] changeWith) { if (changeWith == null) return; @@ -80,7 +80,7 @@ public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, } else if (permissable instanceof PlayerRef ref) { permChange(changeMode, provider, ref.getUuid(), permissions); } else if (permissable instanceof Player player) { - UUID uuid = player.getUuid(); + UUID uuid = EntityUtils.getUUID(player); if (uuid == null) continue; permChange(changeMode, provider, uuid, permissions); } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprPlayerPermissions.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprPlayerPermissions.java index a33cb35e..a2afb7a7 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprPlayerPermissions.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprPlayerPermissions.java @@ -1,5 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.player; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.permissions.PermissionsModule; @@ -44,7 +45,6 @@ public boolean init(Expression[] expressions, int matchedPattern, @NotNull Pa return true; } - @SuppressWarnings("removal") @Override public String[] getValues(@NotNull TriggerContext ctx) { List permissions = new ArrayList<>(); @@ -52,7 +52,7 @@ public String[] getValues(@NotNull TriggerContext ctx) { PermissionProvider provider = PermissionsModule.get().getFirstPermissionProvider(); for (Object o : this.permissables.getArray(ctx)) { if (o instanceof Player player) { - UUID uuid = player.getUuid(); + UUID uuid = EntityUtils.getUUID(player); if (uuid == null) continue; permissions.addAll(provider.getUserPermissions(uuid)); } else if (o instanceof PlayerRef playerRef) { @@ -73,7 +73,7 @@ public Optional[]> acceptsChange(@NotNull ChangeMode mode) { return Optional.empty(); } - @SuppressWarnings({"ConstantValue", "removal"}) + @SuppressWarnings({"ConstantValue"}) @Override public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, Object @NotNull [] changeWith) { if (changeWith == null) return; @@ -84,16 +84,16 @@ public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, } PermissionProvider provider = PermissionsModule.get().getFirstPermissionProvider(); - for (Object permissable : this.permissables.getArray(ctx)) { - if (permissable instanceof Player player) { - UUID uuid = player.getUuid(); + for (Object permissible : this.permissables.getArray(ctx)) { + if (permissible instanceof Player player) { + UUID uuid = EntityUtils.getUUID(player); if (uuid == null) continue; permChange(changeMode, provider, uuid, permissions); - } else if (permissable instanceof PlayerRef playerRef) { + } else if (permissible instanceof PlayerRef playerRef) { permChange(changeMode, provider, playerRef.getUuid(), permissions); - } else if (permissable instanceof UUID uuid) { + } else if (permissible instanceof UUID uuid) { permChange(changeMode, provider, uuid, permissions); - } else if (permissable instanceof String s) { + } else if (permissible instanceof String s) { permChange(changeMode, provider, s, permissions); } } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecDropItem.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecDropItem.java index eb688517..0d48388c 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecDropItem.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecDropItem.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.sections; -import com.github.skriptdev.skript.api.hytale.EntityComponentUtils; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.component.Store; import com.hypixel.hytale.math.vector.Location; @@ -135,7 +135,7 @@ public Optional walk(@NotNull TriggerContext ctx) { setNext(null); Runnable dropRunnable = () -> { - Pair pair = EntityComponentUtils.dropItem(store, itemStack, location, velocity, pickupDelay); + Pair pair = EntityUtils.dropItem(store, itemStack, location, velocity, pickupDelay); ItemComponentContext itemContext = new ItemComponentContext(pair.getFirst(), pair.getSecond()); // Copy variables from the previous context into our section context diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecExecuteInWorld.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecExecuteInWorld.java index f4ac1f79..01202dfb 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecExecuteInWorld.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecExecuteInWorld.java @@ -30,6 +30,7 @@ public static void register(SkriptRegistration registration) { @Override public boolean init(Expression[] expressions, int matchedPattern, @NotNull ParseContext parseContext) { this.world = (Expression) expressions[0]; + parseContext.getParserState().setDelayed(true); return true; } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/DefaultConverters.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/DefaultConverters.java index 9551473b..72438265 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/DefaultConverters.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/DefaultConverters.java @@ -1,9 +1,10 @@ package com.github.skriptdev.skript.plugin.elements.types; -import com.github.skriptdev.skript.api.hytale.EntityComponentUtils; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.hypixel.hytale.math.vector.Location; import com.hypixel.hytale.math.vector.Vector3d; import com.hypixel.hytale.math.vector.Vector3f; +import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType; import com.hypixel.hytale.server.core.asset.type.item.config.Item; import com.hypixel.hytale.server.core.entity.Entity; @@ -11,6 +12,7 @@ import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent; import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.world.World; +import com.hypixel.hytale.server.core.util.MessageUtil; import io.github.syst3ms.skriptparser.types.conversions.Converters; import java.util.Optional; @@ -20,6 +22,7 @@ public class DefaultConverters { public static void register() { entity(); inventory(); + other(); } @SuppressWarnings("removal") @@ -33,7 +36,7 @@ private static void entity() { World world = entity.getWorld(); if (world == null) return Optional.empty(); - TransformComponent component = EntityComponentUtils.getComponent(entity, TransformComponent.getComponentType()); + TransformComponent component = EntityUtils.getComponent(entity, TransformComponent.getComponentType()); if (component == null) return Optional.empty(); Vector3d pos = component.getPosition(); @@ -47,7 +50,7 @@ private static void entity() { World world = entity.getWorld(); if (world == null) return Optional.empty(); - TransformComponent component = EntityComponentUtils.getComponent(entity, TransformComponent.getComponentType()); + TransformComponent component = EntityUtils.getComponent(entity, TransformComponent.getComponentType()); if (component == null) return Optional.empty(); Vector3d pos = component.getPosition(); @@ -77,5 +80,9 @@ private static void inventory() { }); } + private static void other() { + Converters.registerConverter(Message.class, String.class, (message) -> + Optional.of(MessageUtil.toAnsiString(message).toAnsi())); + } } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesBlock.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesBlock.java index 921ee231..628efd61 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesBlock.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesBlock.java @@ -12,6 +12,7 @@ static void register(SkriptRegistration reg) { .description("Represents a block in a world.") .since("1.0.0") .toStringFunction(Block::toTypeString) + .toVariableNameFunction(Block::toVariableNameString) .register(); reg.newEnumType(InteractionType.class, "interactiontype", "interactiontype@s") .name("Interaction Type") diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesCustom.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesCustom.java index 63a43a56..0906c0ad 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesCustom.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesCustom.java @@ -12,6 +12,7 @@ static void register(SkriptRegistration reg) { .usage(Direction.getUsageString()) .literalParser(Direction::parse) .toStringFunction(Direction::getName) + .toVariableNameFunction(Direction::getVariableName) .since("1.0.0") .register(); } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesEntity.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesEntity.java index 997400cc..bc8b2635 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesEntity.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesEntity.java @@ -1,5 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.types; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.github.skriptdev.skript.api.skript.registration.NPCRegistry; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.component.Ref; @@ -17,7 +18,6 @@ public class TypesEntity { - @SuppressWarnings("removal") // LivingEntity::getLegacyDisplayName static void register(SkriptRegistration reg) { reg.newType(ActiveEntityEffect.class, "activeentityeffect", "activeEntityEffect@s") .name("Active Entity Effect") @@ -26,7 +26,6 @@ static void register(SkriptRegistration reg) { .toStringFunction(ActiveEntityEffect::toString) .register(); reg.newType(Entity.class, "entity", "entit@y@ies") - .toStringFunction(Entity::toString) // TODO get its name or something .name("Entity") .description("Represents any Entity in the game, including Players and NPCs.") .since("1.0.0") @@ -50,18 +49,22 @@ public void change(Entity @NotNull [] toChange, Object @NotNull [] changeWith, @ } } }) + .toStringFunction(EntityUtils::getName) + .toVariableNameFunction(EntityUtils::getVariableName) .register(); reg.newType(LivingEntity.class, "livingentity", "livingEntit@y@ies") .name("Living Entity") .description("Represents any living entity in the game, including players and mobs.") .since("1.0.0") - .toStringFunction(LivingEntity::getLegacyDisplayName) + .toStringFunction(EntityUtils::getName) + .toVariableNameFunction(EntityUtils::getVariableName) .register(); reg.newType(NPCEntity.class, "npcentity", "npcEntit@y@ies") .name("NPC Entity") .description("Represents an NPC entity in the game.") .since("1.0.0") .toStringFunction(NPCRegistry::stringify) + .toVariableNameFunction(EntityUtils::getVariableName) .register(); reg.newType(NPCRegistry.NPCRole.class, "npcrole", "npcrole@s") .name("NPC Role") @@ -70,6 +73,7 @@ public void change(Entity @NotNull [] toChange, Object @NotNull [] changeWith, @ .usage(NPCRegistry.getTypeUsage()) .since("1.0.0") .toStringFunction(NPCRegistry.NPCRole::name) + .toVariableNameFunction(r -> "npc_role:" + r.name().toLowerCase()) .supplier(NPCRegistry::iterator) .literalParser(NPCRegistry::parse) .register(); diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesItem.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesItem.java index bfc5aca1..1d87078c 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesItem.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesItem.java @@ -16,6 +16,8 @@ import org.bson.BsonString; import org.jetbrains.annotations.NotNull; +import java.util.Locale; + public class TypesItem { static void register(SkriptRegistration reg) { @@ -72,6 +74,11 @@ public ItemContainer deserialize(@NotNull Gson gson, @NotNull JsonElement elemen String quantity = itemStack.getQuantity() == 1 ? "" : itemStack.getQuantity() + " of "; return "itemstack of " + quantity + itemStack.getItem().getId(); }) + .toVariableNameFunction(itemStack -> { + int quantity = itemStack.getQuantity(); + String id = itemStack.getItem().getId().toLowerCase(Locale.ROOT); + return "itemstack:" + quantity + ":" + id; + }) .serializer(new TypeSerializer<>() { @Override public JsonElement serialize(@NotNull Gson gson, @NotNull ItemStack value) { diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesPlayer.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesPlayer.java index 7efb63b1..a87ec9db 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesPlayer.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesPlayer.java @@ -1,10 +1,13 @@ package com.github.skriptdev.skript.plugin.elements.types; +import com.github.skriptdev.skript.api.hytale.EntityUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.protocol.GameMode; import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.universe.PlayerRef; +import java.util.UUID; + public class TypesPlayer { public static void register(SkriptRegistration reg) { @@ -19,6 +22,11 @@ public static void register(SkriptRegistration reg) { .description("Represents a player in the game.") .since("1.0.0") .toStringFunction(Player::getDisplayName) + .toVariableNameFunction(player -> { + UUID uuid = EntityUtils.getUUID(player); + assert uuid != null; // A player's UUID should never be null + return uuid.toString(); + }) .register(); reg.newType(PlayerRef.class, "playerref", "playerRef@s") .name("Player Ref") diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesServer.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesServer.java index d3a1489e..a9c04c78 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesServer.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesServer.java @@ -17,6 +17,7 @@ import com.hypixel.hytale.server.core.command.system.arguments.types.ArgumentType; import com.hypixel.hytale.server.core.modules.entity.damage.Damage; import com.hypixel.hytale.server.core.receiver.IMessageReceiver; +import com.hypixel.hytale.server.core.util.MessageUtil; import io.github.syst3ms.skriptparser.types.changers.TypeSerializer; import org.bson.BsonDocument; import org.bson.BsonString; @@ -70,6 +71,7 @@ public Message deserialize(@NotNull Gson gson, @NotNull JsonElement element) { return Message.CODEC.decode(decode, new ExtraInfo()); } }) + .toStringFunction(m -> MessageUtil.toAnsiString(m).toAnsi()) .register(); registration.newEnumType(NotificationStyle.class, "notificationstyle", "notificationStyle@s") .name("Notification Style") @@ -179,6 +181,7 @@ public Location deserialize(@NotNull Gson gson, @NotNull JsonElement element) { return new Location(world, position, rotation); } }) + .toStringFunction(Location::toString) .since("1.0.0") .register(); } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesWorld.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesWorld.java index 2da4b6e8..e804c154 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesWorld.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesWorld.java @@ -17,6 +17,8 @@ static void register(SkriptRegistration reg) { .since("1.0.0") .toStringFunction(worldChunk -> "chunk (x=" + worldChunk.getX() + ",z=" + worldChunk.getZ() + ") in world '" + worldChunk.getWorld().getName() + "'") + .toVariableNameFunction(worldChunk -> "chunk:" + worldChunk.getWorld().getName() + + ":" + worldChunk.getX() + ":" + worldChunk.getZ()) .register(); reg.newType(RelativeDoublePosition.class, "relativeposition", "relativePosition@s") .name("Relative Position") @@ -38,6 +40,7 @@ static void register(SkriptRegistration reg) { .description("Represents a world in the game.") .since("1.0.0") .toStringFunction(World::getName) + .toVariableNameFunction(w -> "world:" + w.getName()) .register(); reg.newType(Zone.class, "zone", "zone@s") .name("Zone") diff --git a/src/main/resources/config.sk b/src/main/resources/config.sk index c6fb6722..6b001519 100644 --- a/src/main/resources/config.sk +++ b/src/main/resources/config.sk @@ -1,8 +1,23 @@ # HySkript Config +hyskript-version: $pluginVersion +# Do not change this value manually. +# This is automatically updated when you update HySkript. +# This is used to update the config if it's outdated. + debug: false # Whether or not to enable debug mode (maybe print more verbose logs to console). +max-target-block-distance: 160 +# The maximum distance from a Player to a block to be considered a target block. +# Default 160 = 5 chunks +# Increasing this amount could cause performance issues, so test carefully. + +commands-generate-permissions: true +# Hytale by default generates permissions for all commands. +# If you want to disable this, set this to false. +# You can also disable it per command in the command entries. + # Effect commands allow you to execute effects in chat. effect-commands: enabled: true @@ -12,7 +27,7 @@ effect-commands: # Whether or not ops can use effect commands. # If false, they will require the permission specified below in 'required-permission'. - required-permission: hyskript.effect-commands + required-permission: skript.hyskript.effect-commands # The permission required to use effect commands (if allow-ops is false). token: !