From c09fd3d30f1c4611da10fdc7560d7b8d3526386f Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 4 May 2024 22:30:05 +0200 Subject: [PATCH 01/24] Update to Loom and Legacy-Looming 1.6 --- build.gradle | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 66226bc16..705017056 100644 --- a/build.gradle +++ b/build.gradle @@ -3,8 +3,8 @@ plugins { id "eclipse" id "idea" id "maven-publish" - id "fabric-loom" version "1.5.4" apply false - id "legacy-looming" version "1.5.3" apply false + id "fabric-loom" version "1.6.2" apply false + id "legacy-looming" version "1.6.3" apply false id "com.diffplug.spotless" version "6.20.0" id "org.ajoberstar.grgit" version "3.1.1" id "me.modmuss50.mod-publish-plugin" version "0.4.5" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1af9e0930..b82aa23a4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 944f0fb3e8be903c3be7a40cc14607c4fb53096b Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 4 May 2024 22:32:28 +0200 Subject: [PATCH 02/24] Add 1.6.4 submodule --- legacyfabric-api/1.6.4/build.gradle | 0 legacyfabric-api/1.6.4/gradle.properties | 2 + .../1.6.4/src/main/resources/fabric.mod.json | 43 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 legacyfabric-api/1.6.4/build.gradle create mode 100644 legacyfabric-api/1.6.4/gradle.properties create mode 100644 legacyfabric-api/1.6.4/src/main/resources/fabric.mod.json diff --git a/legacyfabric-api/1.6.4/build.gradle b/legacyfabric-api/1.6.4/build.gradle new file mode 100644 index 000000000..e69de29bb diff --git a/legacyfabric-api/1.6.4/gradle.properties b/legacyfabric-api/1.6.4/gradle.properties new file mode 100644 index 000000000..bff6c84c0 --- /dev/null +++ b/legacyfabric-api/1.6.4/gradle.properties @@ -0,0 +1,2 @@ +minVersionIncluded=1.6.4 +maxVersionIncluded=1.6.4 diff --git a/legacyfabric-api/1.6.4/src/main/resources/fabric.mod.json b/legacyfabric-api/1.6.4/src/main/resources/fabric.mod.json new file mode 100644 index 000000000..676b475e1 --- /dev/null +++ b/legacyfabric-api/1.6.4/src/main/resources/fabric.mod.json @@ -0,0 +1,43 @@ +{ + "schemaVersion": 1, + "id": "legacy-fabric-api", + "name": "Legacy Fabric API", + "version": "${version}", + "environment": "*", + "license": "Apache-2.0", + "icon": "assets/legacy-fabric-api/icon.png", + "contact": { + "homepage": "https://legacyfabric.net/", + "issues": "https://github.com/Legacy-Fabric/fabric/issues", + "sources": "https://github.com/Legacy-Fabric/fabric" + }, + "authors": [ + { + "name": "Legacy Fabric", + "contact": { + "homepage": "https://legacyfabric.net/", + "discord": "https://legacyfabric.net/discord", + "sources": "https://github.com/Legacy-Fabric/fabric", + "issues": "https://github.com/Legacy-Fabric/fabric/issues" + } + }, + { + "name": "FabricMC", + "contact": { + "homepage": "https://fabricmc.net", + "discord": "https://discord.gg/v6v4pMv", + "sources": "https://github.com/FabricMC/fabric", + "issues": "https://github.com/FabricMC/fabric/issues" + } + } + ], + "description": "Core API module providing key hooks and inter-compatibility features for Minecraft 1.7.10-1.12.2.", + "depends": { + "minecraft": "${minecraft_version}" + }, + "custom": { + "modmenu": { + "badges": [ "library" ] + } + } +} From e66630a0b8c640d1be5abc547b9da77cf84766d0 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 4 May 2024 22:33:13 +0200 Subject: [PATCH 03/24] Fix json translation files not being parsed correctly in some versions --- .../loader/client/TranslationStorageMixin.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/legacy-fabric-resource-loader-v1/common/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/TranslationStorageMixin.java b/legacy-fabric-resource-loader-v1/common/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/TranslationStorageMixin.java index 33682ac59..632aeff0e 100644 --- a/legacy-fabric-resource-loader-v1/common/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/TranslationStorageMixin.java +++ b/legacy-fabric-resource-loader-v1/common/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/TranslationStorageMixin.java @@ -19,7 +19,6 @@ import java.io.IOException; import java.io.InputStream; -import java.io.StringReader; import java.util.List; import java.util.Locale; import java.util.Map; @@ -27,10 +26,9 @@ import com.google.common.base.Splitter; import com.google.common.collect.Iterables; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import org.apache.commons.io.Charsets; import org.apache.commons.io.IOUtils; import org.jetbrains.annotations.NotNull; @@ -38,6 +36,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -63,9 +62,11 @@ public abstract class TranslationStorageMixin { @Shadow Map translations; + @Unique private static final boolean isUpperCase = VersionUtils.matches("<1.11"); - private static final Gson GSON = new GsonBuilder().create(); + @Unique + private static final JsonParser JSON_PARSER = new JsonParser(); @Inject(method = "load(Lnet/minecraft/resource/ResourceManager;Ljava/util/List;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resource/language/TranslationStorage;setRightToLeft()V")) private void loadLangFileFromOtherVersion(ResourceManager resourceManager, List languages, CallbackInfo ci) { @@ -115,8 +116,7 @@ private void load(InputStream stream) throws IOException { if (lines.get(0).startsWith("{")) { // Load as json String content = String.join("\n", lines); - JsonObject object = GSON.fromJson(new StringReader(content), JsonObject.class); - + JsonObject object = JSON_PARSER.parse(content).getAsJsonObject(); recursiveLoadTranslations("", object); } else { // Load as properties/lang for (String string : lines) { From 97155667167238a68d9a6dc92c0a88e38823953f Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 4 May 2024 22:34:39 +0200 Subject: [PATCH 04/24] Add resource-loader support for 1.6.4 --- .../1.6.4/build.gradle | 0 .../1.6.4/gradle.properties | 2 + .../ClientResourceReloadListenerMixins.java | 94 ++++++++++++++++++ .../client/DefaultResourcePackMixin.java | 75 ++++++++++++++ .../loader/client/MinecraftClientMixin.java | 70 +++++++++++++ .../ReloadableResourceManagerImplMixin.java | 45 +++++++++ .../resources/assets/legacy-fabric/icon.png | Bin 0 -> 1579 bytes .../1.6.4/src/main/resources/fabric.mod.json | 38 +++++++ ...gacy-fabric-resource-loader-v1.mixins.json | 14 +++ .../loader/client/ResourceReloadTest.java | 51 ++++++++++ .../src/testmod/resources/fabric.mod.json | 14 +++ .../1.7.10/gradle.properties | 2 +- 12 files changed, 404 insertions(+), 1 deletion(-) create mode 100644 legacy-fabric-resource-loader-v1/1.6.4/build.gradle create mode 100644 legacy-fabric-resource-loader-v1/1.6.4/gradle.properties create mode 100644 legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/ClientResourceReloadListenerMixins.java create mode 100644 legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/DefaultResourcePackMixin.java create mode 100644 legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/MinecraftClientMixin.java create mode 100644 legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/ReloadableResourceManagerImplMixin.java create mode 100644 legacy-fabric-resource-loader-v1/1.6.4/src/main/resources/assets/legacy-fabric/icon.png create mode 100644 legacy-fabric-resource-loader-v1/1.6.4/src/main/resources/fabric.mod.json create mode 100644 legacy-fabric-resource-loader-v1/1.6.4/src/main/resources/legacy-fabric-resource-loader-v1.mixins.json create mode 100644 legacy-fabric-resource-loader-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/resource/loader/client/ResourceReloadTest.java create mode 100644 legacy-fabric-resource-loader-v1/1.6.4/src/testmod/resources/fabric.mod.json diff --git a/legacy-fabric-resource-loader-v1/1.6.4/build.gradle b/legacy-fabric-resource-loader-v1/1.6.4/build.gradle new file mode 100644 index 000000000..e69de29bb diff --git a/legacy-fabric-resource-loader-v1/1.6.4/gradle.properties b/legacy-fabric-resource-loader-v1/1.6.4/gradle.properties new file mode 100644 index 000000000..bff6c84c0 --- /dev/null +++ b/legacy-fabric-resource-loader-v1/1.6.4/gradle.properties @@ -0,0 +1,2 @@ +minVersionIncluded=1.6.4 +maxVersionIncluded=1.6.4 diff --git a/legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/ClientResourceReloadListenerMixins.java b/legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/ClientResourceReloadListenerMixins.java new file mode 100644 index 000000000..4ddde0965 --- /dev/null +++ b/legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/ClientResourceReloadListenerMixins.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.resource.loader.client; + +import java.util.Collection; +import java.util.Collections; +import java.util.Locale; + +import org.spongepowered.asm.mixin.Mixin; + +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.render.GameRenderer; +import net.minecraft.client.render.WorldRenderer; +import net.minecraft.client.render.item.ItemRenderer; +import net.minecraft.client.resource.language.LanguageManager; +import net.minecraft.client.sound.SoundSystem; +import net.minecraft.client.texture.TextureManager; +import net.minecraft.resource.FoliageColorResourceReloadListener; +import net.minecraft.resource.GrassColorResourceReloadListener; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.MappingResolver; + +import net.legacyfabric.fabric.api.resource.IdentifiableResourceReloadListener; +import net.legacyfabric.fabric.api.resource.ResourceReloadListenerKeys; +import net.legacyfabric.fabric.api.util.Identifier; + +@Mixin({ + SoundSystem.class, GameRenderer.class, LanguageManager.class, GrassColorResourceReloadListener.class, FoliageColorResourceReloadListener.class, TextureManager.class, + WorldRenderer.class, ItemRenderer.class, TextRenderer.class +}) +@Environment(EnvType.CLIENT) +public abstract class ClientResourceReloadListenerMixins implements IdentifiableResourceReloadListener { + private Collection fabric_idDeps; + private Identifier fabric_id; + + @SuppressWarnings("ConstantConditions") + @Override + public Collection getFabricDependencies() { + if (this.fabric_idDeps == null) { + Object self = this; + + if (self instanceof WorldRenderer) { + this.fabric_idDeps = Collections.singletonList(ResourceReloadListenerKeys.TEXTURES); + } else if (self instanceof ItemRenderer) { + this.fabric_idDeps = Collections.singletonList(ResourceReloadListenerKeys.MODELS); + } else { + this.fabric_idDeps = Collections.emptyList(); + } + } + + return this.fabric_idDeps; + } + + @SuppressWarnings("ConstantConditions") + @Override + public Identifier getFabricId() { + if (this.fabric_id == null) { + Object self = this; + + if (self instanceof SoundSystem) { + this.fabric_id = ResourceReloadListenerKeys.SOUNDS; + } else if (self instanceof TextRenderer) { + this.fabric_id = ResourceReloadListenerKeys.FONTS; + } else if (self instanceof LanguageManager) { + this.fabric_id = ResourceReloadListenerKeys.LANGUAGES; + } else if (self instanceof TextureManager) { + this.fabric_id = ResourceReloadListenerKeys.TEXTURES; + } else { + MappingResolver resolver = FabricLoader.getInstance().getMappingResolver(); + this.fabric_id = new Identifier("minecraft", "private/" + resolver.mapClassName("intermediary", self.getClass().getName()).toLowerCase(Locale.ROOT)); + } + } + + return this.fabric_id; + } +} diff --git a/legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/DefaultResourcePackMixin.java b/legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/DefaultResourcePackMixin.java new file mode 100644 index 000000000..4b37056fc --- /dev/null +++ b/legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/DefaultResourcePackMixin.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.resource.loader.client; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Enumeration; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.resource.DefaultResourcePack; +import net.minecraft.util.Identifier; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +@Mixin(DefaultResourcePack.class) +public class DefaultResourcePackMixin { + @Inject(method = "openClassLoader", at = @At("HEAD"), cancellable = true) + protected void onFindInputStream(Identifier identifier, CallbackInfoReturnable callback) { + // if (DefaultResourcePack.resourcePath != null) { + // Fall through to Vanilla logic, they have a special case here. + // return; + // } + + String path = "assets/" + identifier.getNamespace() + "/" + identifier.getPath(); + URL found = null; + + try { + Enumeration candidates = DefaultResourcePack.class.getClassLoader().getResources(path); + + // Get the last element + while (candidates.hasMoreElements()) { + found = candidates.nextElement(); + } + + if (found == null) { + // Mimics vanilla behavior + + callback.setReturnValue(null); + return; + } + } catch (IOException var6) { + // Default path + } + + try { + if (found != null) { + callback.setReturnValue(found.openStream()); + } + } catch (Exception e) { + // Default path + } + } +} diff --git a/legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/MinecraftClientMixin.java b/legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/MinecraftClientMixin.java new file mode 100644 index 000000000..c05d9ccc2 --- /dev/null +++ b/legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/MinecraftClientMixin.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.resource.loader.client; + +import java.util.ArrayList; +import java.util.List; + +import com.google.common.collect.Lists; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.resource.DefaultResourcePack; +import net.minecraft.resource.ResourcePack; + +import net.legacyfabric.fabric.impl.resource.loader.ModResourcePackUtil; + +@Mixin(MinecraftClient.class) +public class MinecraftClientMixin { + private void fabric_modifyResourcePackList(List list) { + List oldList = Lists.newArrayList(list); + list.clear(); + + boolean appended = false; + + for (ResourcePack pack : oldList) { + list.add(pack); + + boolean isDefaultResources = pack instanceof DefaultResourcePack; + + if (isDefaultResources) { + ModResourcePackUtil.appendModResourcePacks(list); + appended = true; + } + } + + if (!appended) { + StringBuilder builder = new StringBuilder("Fabric could not find resource pack injection location!"); + + for (ResourcePack rp : oldList) { + builder.append("\n - ").append(rp.getName()).append(" (").append(rp.getClass().getName()).append(")"); + } + + throw new RuntimeException(builder.toString()); + } + } + + @Inject(method = "reloadResources", at = @At(value = "INVOKE", target = "Lnet/minecraft/resource/ReloadableResourceManager;reload(Ljava/util/List;)V", ordinal = 0), locals = LocalCapture.CAPTURE_FAILHARD) + public void reloadResources(CallbackInfo ci, ArrayList list) { + fabric_modifyResourcePackList(list); + } +} diff --git a/legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/ReloadableResourceManagerImplMixin.java b/legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/ReloadableResourceManagerImplMixin.java new file mode 100644 index 000000000..5a88eb98a --- /dev/null +++ b/legacy-fabric-resource-loader-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/resource/loader/client/ReloadableResourceManagerImplMixin.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.resource.loader.client; + +import java.util.List; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.resource.ReloadableResourceManagerImpl; +import net.minecraft.resource.ResourcePack; +import net.minecraft.resource.ResourceReloadListener; + +import net.legacyfabric.fabric.impl.resource.loader.ResourceManagerHelperImpl; + +@Mixin(ReloadableResourceManagerImpl.class) +public class ReloadableResourceManagerImplMixin { + @Shadow + @Final + private List listeners; + + @Inject(method = "reload", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/logging/LogManager;info(Ljava/lang/String;)V")) + public void onReload(List resourcePacks, CallbackInfo ci) { + ResourceManagerHelperImpl.getInstance().sort(this.listeners); + } +} diff --git a/legacy-fabric-resource-loader-v1/1.6.4/src/main/resources/assets/legacy-fabric/icon.png b/legacy-fabric-resource-loader-v1/1.6.4/src/main/resources/assets/legacy-fabric/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2931efbf610873c0084debb8690902b0103d27fe GIT binary patch literal 1579 zcmbVMTWB0r7@iGm)TAXsYw<=rnU=;v=W=GRbL=!tc4Brl6GO7t2vVJ$IlDV#XU;e? z+r2ymsZdMQqAyaFLLUo;RumtE8Z@?uf_*4nP^4;o6fOFoSkN+o1$K?f2nE9_*b5G-l)AV)k5Qhb^- zU{V4ZnTKgnmXdpcB*Kg!W(1hvM2N&RO30x1u~eI9meGQGe@_?PDQq%q1CiV$8~M7 z?MQ_mOdqCh^a65Sv|ntwSXjV5se1;VK1|Kr8G7TQoQL&*ctt{L{fClG}xPK5k^yK3%T69N6J=>3jBqc zDNvZsrJ-yOXI^^mWf1cmY^XST)CVzIGjvEPENowmy}ax zvJ8_(Cf#+H-dBlH53`_u-~6BVAMz|(g?jCVdBWNZ(+A}(pFV7>S3QgPiQcMaflkIC z-3Ti|VT~{au*vq0ts9O&m$p&Gl=L6+q6_m$IcVq}o~+Pl{g>1esQp4%wp~|*zk1n` zZ7T6Toc4`y88s}riCP|ZXrJ?FLz@^KTcyqLjey zu95Yz%F&S{<0~f)Iomek?+hQ%MhCu%T^zsg>C_L`1`Br`xNY&))k9yTQb$JC>)w_f zpU(^tu^Q)y%W~lVz`jz;_ jF?g&s@Y=Qe&c#kW|JbvqK0Y=Rw)4XDoVqsk_>;c_`@;F@ literal 0 HcmV?d00001 diff --git a/legacy-fabric-resource-loader-v1/1.6.4/src/main/resources/fabric.mod.json b/legacy-fabric-resource-loader-v1/1.6.4/src/main/resources/fabric.mod.json new file mode 100644 index 000000000..f70352482 --- /dev/null +++ b/legacy-fabric-resource-loader-v1/1.6.4/src/main/resources/fabric.mod.json @@ -0,0 +1,38 @@ +{ + "schemaVersion": 1, + "id": "legacy-fabric-resource-loader-v1", + "name": "Legacy Fabric Resource Loader (V1)", + "version": "${version}", + "environment": "*", + "license": "Apache-2.0", + "icon": "assets/legacy-fabric/icon.png", + "contact": { + "homepage": "https://legacyfabric.net/", + "irc": "irc://irc.esper.net:6667/legacyfabric", + "issues": "https://github.com/Legacy-Fabric/fabric/issues", + "sources": "https://github.com/Legacy-Fabric/fabric" + }, + "authors": [ + "FabricMC" + ], + "depends": { + "fabricloader": ">=0.4.0", + "minecraft": "${minecraft_version}" + }, + "description": "Asset loading", + "mixins": [ + "legacy-fabric-resource-loader-v1.mixins.json" + ], + "custom": { + "modmenu": { + "badges": [ "library" ], + "parent": { + "id": "legacy-fabric-api", + "name": "Legacy Fabric API", + "badges": [ "library" ], + "description": "Core API module providing key hooks and inter-compatibility features for Minecraft 1.7.10-1.12.2.", + "icon": "assets/legacy-fabric/icon.png" + } + } + } +} diff --git a/legacy-fabric-resource-loader-v1/1.6.4/src/main/resources/legacy-fabric-resource-loader-v1.mixins.json b/legacy-fabric-resource-loader-v1/1.6.4/src/main/resources/legacy-fabric-resource-loader-v1.mixins.json new file mode 100644 index 000000000..7b3aa4675 --- /dev/null +++ b/legacy-fabric-resource-loader-v1/1.6.4/src/main/resources/legacy-fabric-resource-loader-v1.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "package": "net.legacyfabric.fabric.mixin.resource.loader", + "compatibilityLevel": "JAVA_8", + "client": [ + "client.ClientResourceReloadListenerMixins", + "client.DefaultResourcePackMixin", + "client.MinecraftClientMixin", + "client.ReloadableResourceManagerImplMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/legacy-fabric-resource-loader-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/resource/loader/client/ResourceReloadTest.java b/legacy-fabric-resource-loader-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/resource/loader/client/ResourceReloadTest.java new file mode 100644 index 000000000..99ab573c7 --- /dev/null +++ b/legacy-fabric-resource-loader-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/resource/loader/client/ResourceReloadTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.test.resource.loader.client; + +import java.util.Arrays; + +import net.minecraft.resource.ResourceManager; + +import net.fabricmc.api.ClientModInitializer; + +import net.legacyfabric.fabric.api.logger.v1.Logger; +import net.legacyfabric.fabric.api.resource.IdentifiableResourceReloadListener; +import net.legacyfabric.fabric.api.resource.ResourceManagerHelper; +import net.legacyfabric.fabric.api.util.Identifier; +import net.legacyfabric.fabric.impl.logger.LoggerImpl; + +public class ResourceReloadTest implements ClientModInitializer { + private static final Logger LOGGER = Logger.get(LoggerImpl.API, "Test", "ResourceReload"); + + @Override + public void onInitializeClient() { + Identifier id = new Identifier("legacy-fabric-api", "test_reload"); + ResourceManagerHelper.getInstance().registerReloadListener(new IdentifiableResourceReloadListener() { + @Override + public Identifier getFabricId() { + return id; + } + + @Override + public void reload(ResourceManager resourceManager) { + LOGGER.info("Resources and reloading"); + LOGGER.info("Namespaces are %s", Arrays.toString(resourceManager.getAllNamespaces().toArray())); + } + }); + } +} diff --git a/legacy-fabric-resource-loader-v1/1.6.4/src/testmod/resources/fabric.mod.json b/legacy-fabric-resource-loader-v1/1.6.4/src/testmod/resources/fabric.mod.json new file mode 100644 index 000000000..5f42c7640 --- /dev/null +++ b/legacy-fabric-resource-loader-v1/1.6.4/src/testmod/resources/fabric.mod.json @@ -0,0 +1,14 @@ +{ + "schemaVersion": 1, + "id": "legacy-fabric-resource-loader-v1-testmod", + "description": "Tests for resource loading", + "version": "1.0.0", + "entrypoints": { + "client": [ + "net.legacyfabric.fabric.test.resource.loader.client.ResourceReloadTest" + ] + }, + "depends": { + "minecraft": "${minecraft_version}" + } +} diff --git a/legacy-fabric-resource-loader-v1/1.7.10/gradle.properties b/legacy-fabric-resource-loader-v1/1.7.10/gradle.properties index c6dcd9541..af031afbf 100644 --- a/legacy-fabric-resource-loader-v1/1.7.10/gradle.properties +++ b/legacy-fabric-resource-loader-v1/1.7.10/gradle.properties @@ -1,2 +1,2 @@ -minVersionIncluded=1.3 +minVersionIncluded=1.7.10 maxVersionIncluded=1.7.10 From e1fd2a8f815437487b3f1bcede6bb0bd21e5c0ad Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 4 May 2024 22:35:01 +0200 Subject: [PATCH 05/24] Fix version requirement being wrong or missing for some modules --- .../common/src/main/resources/fabric.mod.json | 3 ++- legacy-fabric-command-api-v2/1.7.10/gradle.properties | 2 +- legacy-fabric-item-groups-v1/1.8.9/gradle.properties | 2 +- legacy-fabric-item-groups-v1/common/gradle.properties | 2 +- legacy-fabric-keybindings-api-v1/1.7.10/gradle.properties | 2 +- .../1.7.10/src/testmod/resources/fabric.mod.json | 4 +++- legacy-fabric-lifecycle-events-v1/1.7.10/gradle.properties | 2 +- legacy-fabric-lifecycle-events-v1/common/gradle.properties | 2 +- 8 files changed, 11 insertions(+), 8 deletions(-) diff --git a/legacy-fabric-command-api-v1/common/src/main/resources/fabric.mod.json b/legacy-fabric-command-api-v1/common/src/main/resources/fabric.mod.json index 5611e7bde..f16165af2 100644 --- a/legacy-fabric-command-api-v1/common/src/main/resources/fabric.mod.json +++ b/legacy-fabric-command-api-v1/common/src/main/resources/fabric.mod.json @@ -22,7 +22,8 @@ ], "description": "Adds command-related hooks.", "depends": { - "minecraft": "${minecraft_version}" + "minecraft": "${minecraft_version}", + "legacy-fabric-lifecycle-events-v1-common": "*" }, "custom": { "modmenu": { diff --git a/legacy-fabric-command-api-v2/1.7.10/gradle.properties b/legacy-fabric-command-api-v2/1.7.10/gradle.properties index c6dcd9541..af031afbf 100644 --- a/legacy-fabric-command-api-v2/1.7.10/gradle.properties +++ b/legacy-fabric-command-api-v2/1.7.10/gradle.properties @@ -1,2 +1,2 @@ -minVersionIncluded=1.3 +minVersionIncluded=1.7.10 maxVersionIncluded=1.7.10 diff --git a/legacy-fabric-item-groups-v1/1.8.9/gradle.properties b/legacy-fabric-item-groups-v1/1.8.9/gradle.properties index 7a09d76fd..3b74ec5e2 100644 --- a/legacy-fabric-item-groups-v1/1.8.9/gradle.properties +++ b/legacy-fabric-item-groups-v1/1.8.9/gradle.properties @@ -1,2 +1,2 @@ -minVersionIncluded=1.3 +minVersionIncluded=1.7.10 maxVersionIncluded=1.10.2 diff --git a/legacy-fabric-item-groups-v1/common/gradle.properties b/legacy-fabric-item-groups-v1/common/gradle.properties index d523a75a0..503076051 100644 --- a/legacy-fabric-item-groups-v1/common/gradle.properties +++ b/legacy-fabric-item-groups-v1/common/gradle.properties @@ -1,2 +1,2 @@ -minVersionIncluded=1.3 +minVersionIncluded=1.7.10 maxVersionIncluded=1.12.2 diff --git a/legacy-fabric-keybindings-api-v1/1.7.10/gradle.properties b/legacy-fabric-keybindings-api-v1/1.7.10/gradle.properties index c6dcd9541..af031afbf 100644 --- a/legacy-fabric-keybindings-api-v1/1.7.10/gradle.properties +++ b/legacy-fabric-keybindings-api-v1/1.7.10/gradle.properties @@ -1,2 +1,2 @@ -minVersionIncluded=1.3 +minVersionIncluded=1.7.10 maxVersionIncluded=1.7.10 diff --git a/legacy-fabric-keybindings-api-v1/1.7.10/src/testmod/resources/fabric.mod.json b/legacy-fabric-keybindings-api-v1/1.7.10/src/testmod/resources/fabric.mod.json index b9c55e26f..0033bc2ec 100644 --- a/legacy-fabric-keybindings-api-v1/1.7.10/src/testmod/resources/fabric.mod.json +++ b/legacy-fabric-keybindings-api-v1/1.7.10/src/testmod/resources/fabric.mod.json @@ -9,6 +9,8 @@ ] }, "depends": { - "minecraft": "${minecraft_version}" + "minecraft": "${minecraft_version}", + "legacy-fabric-keybinding-api-v1": "*", + "legacy-fabric-lifecycle-events-v1-common": "*" } } diff --git a/legacy-fabric-lifecycle-events-v1/1.7.10/gradle.properties b/legacy-fabric-lifecycle-events-v1/1.7.10/gradle.properties index c6dcd9541..af031afbf 100644 --- a/legacy-fabric-lifecycle-events-v1/1.7.10/gradle.properties +++ b/legacy-fabric-lifecycle-events-v1/1.7.10/gradle.properties @@ -1,2 +1,2 @@ -minVersionIncluded=1.3 +minVersionIncluded=1.7.10 maxVersionIncluded=1.7.10 diff --git a/legacy-fabric-lifecycle-events-v1/common/gradle.properties b/legacy-fabric-lifecycle-events-v1/common/gradle.properties index 13b94f3a1..1bd1b1914 100644 --- a/legacy-fabric-lifecycle-events-v1/common/gradle.properties +++ b/legacy-fabric-lifecycle-events-v1/common/gradle.properties @@ -1,2 +1,2 @@ -minVersionIncluded=1.3 +minVersionIncluded=1.7.10 maxVersionIncluded=1.13.2 From 9d7f0213b76675043bb6b3f40dde319695721261 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 4 May 2024 22:37:37 +0200 Subject: [PATCH 06/24] Fix tested modules table in readme --- README.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index acfde5ab1..c39fd9898 100644 --- a/README.md +++ b/README.md @@ -14,20 +14,20 @@ For support, consider joining the [Legacy Fabric discord server](https://legacyf ? = Not sure if it was tested or working correctly\ ❌ = Not working at all, likely crashing -| | 1.7.10 | 1.8 | 1.8.9 | 1.9.4 | 1.10.2 | 1.11.2 | 1.12.2 | 1.13.2 | -|----------------------|--------|-----|-------|-------|--------|--------|--------|--------| -| api-base | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| command-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| command-api-v2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| crash-report-info-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| entity-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| gamerule-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ? | -| item-groups-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| keybindings-api-v1 | ⚠ #132 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| lifecycle-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| logger-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| networking-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| permissions-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| registry-sync-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| rendering-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| resource-loader-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| | 1.6.4 | 1.7.10 | 1.8 | 1.8.9 | 1.9.4 | 1.10.2 | 1.11.2 | 1.12.2 | 1.13.2 | +|----------------------|-------|--------|-----|-------|-------|--------|--------|--------|--------| +| api-base | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| command-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| command-api-v2 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| crash-report-info-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| entity-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| gamerule-api-v1 | ? | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ? | +| item-groups-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| keybindings-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| lifecycle-events-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| logger-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| networking-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| permissions-api-v1 | ? | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| registry-sync-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| rendering-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| resource-loader-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | From a3186b00d8c242a322c002307c42f2fceb19222b Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 4 May 2024 23:19:55 +0200 Subject: [PATCH 07/24] Port lifecycle module to 1.6.4 --- README.md | 2 +- .../versioned/MinecraftClientMixin.java | 39 +++++++++++ .../versioned/MinecraftServerMixin.java | 20 ++++++ .../versioned/ServerChunkProviderMixin.java | 50 ++++++++++++++ ...acy-fabric-lifecycle-events-v1.mixins.json | 6 +- .../1.6.4/build.gradle | 0 .../1.6.4/gradle.properties | 2 + .../versioned/ClientChunkProviderMixin.java | 49 ++++++++++++++ .../versioned/MinecraftClientMixin.java | 39 +++++++++++ .../versioned/MinecraftServerMixin.java | 62 ++++++++++++++++++ .../versioned/ServerChunkProviderMixin.java | 48 ++++++++++++++ .../resources/assets/legacy-fabric/icon.png | Bin 0 -> 1579 bytes .../1.6.4/src/main/resources/fabric.mod.json | 37 +++++++++++ ...acy-fabric-lifecycle-events-v1.mixins.json | 16 +++++ .../client/ClientLifecycleEventsTest.java | 38 +++++++++++ .../src/testmod/resources/fabric.mod.json | 14 ++++ .../versioned/MinecraftClientMixin.java | 39 +++++++++++ .../versioned/MinecraftServerMixin.java | 13 ++++ .../versioned/ServerChunkProviderMixin.java | 48 ++++++++++++++ ...acy-fabric-lifecycle-events-v1.mixins.json | 6 +- .../versioned/MinecraftClientMixin.java | 39 +++++++++++ .../versioned/MinecraftServerMixin.java | 20 ++++++ .../versioned/ServerChunkProviderMixin.java | 48 ++++++++++++++ ...acy-fabric-lifecycle-events-v1.mixins.json | 6 +- .../common/gradle.properties | 2 +- .../event/lifecycle/MinecraftServerMixin.java | 11 ---- .../lifecycle/ServerChunkProviderMixin.java | 22 ------- .../client/MinecraftClientMixin.java | 5 -- 28 files changed, 635 insertions(+), 46 deletions(-) create mode 100644 legacy-fabric-lifecycle-events-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java create mode 100644 legacy-fabric-lifecycle-events-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java create mode 100644 legacy-fabric-lifecycle-events-v1/1.6.4/build.gradle create mode 100644 legacy-fabric-lifecycle-events-v1/1.6.4/gradle.properties create mode 100644 legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/ClientChunkProviderMixin.java create mode 100644 legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java create mode 100644 legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java create mode 100644 legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java create mode 100644 legacy-fabric-lifecycle-events-v1/1.6.4/src/main/resources/assets/legacy-fabric/icon.png create mode 100644 legacy-fabric-lifecycle-events-v1/1.6.4/src/main/resources/fabric.mod.json create mode 100644 legacy-fabric-lifecycle-events-v1/1.6.4/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json create mode 100644 legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/lifecycle/client/ClientLifecycleEventsTest.java create mode 100644 legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/resources/fabric.mod.json create mode 100644 legacy-fabric-lifecycle-events-v1/1.7.10/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java create mode 100644 legacy-fabric-lifecycle-events-v1/1.7.10/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java create mode 100644 legacy-fabric-lifecycle-events-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java create mode 100644 legacy-fabric-lifecycle-events-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java diff --git a/README.md b/README.md index c39fd9898..5ce9f2955 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ For support, consider joining the [Legacy Fabric discord server](https://legacyf | gamerule-api-v1 | ? | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ? | | item-groups-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | keybindings-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| lifecycle-events-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| lifecycle-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | logger-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | networking-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | permissions-api-v1 | ? | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | diff --git a/legacy-fabric-lifecycle-events-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java b/legacy-fabric-lifecycle-events-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java new file mode 100644 index 000000000..11dd84134 --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.event.lifecycle.client.versioned; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.MinecraftClient; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import net.legacyfabric.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; + +@Environment(EnvType.CLIENT) +@Mixin(MinecraftClient.class) +public class MinecraftClientMixin { + @Inject(at = @At(value = "INVOKE", target = "Lorg/apache/logging/log4j/Logger;info(Ljava/lang/String;)V", shift = At.Shift.AFTER, remap = false), method = "stop") + private void api$onStopping(CallbackInfo ci) { + ClientLifecycleEvents.CLIENT_STOPPING.invoker().onClientStopping((MinecraftClient) (Object) this); + } +} diff --git a/legacy-fabric-lifecycle-events-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java b/legacy-fabric-lifecycle-events-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java index af6bc7fe5..cc904578f 100644 --- a/legacy-fabric-lifecycle-events-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java +++ b/legacy-fabric-lifecycle-events-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java @@ -21,11 +21,14 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Slice; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import net.minecraft.server.MinecraftServer; import net.minecraft.server.world.ServerWorld; +import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerWorldEvents; @Mixin(MinecraftServer.class) @@ -33,10 +36,27 @@ public abstract class MinecraftServerMixin { @Shadow public ServerWorld[] worlds; + @Inject(at = @At("HEAD"), method = "saveWorlds") + public void api$serverWorldUnload(boolean silent, CallbackInfo ci) { + for (ServerWorld world : this.worlds) { + ServerWorldEvents.UNLOAD.invoker().onWorldUnload((MinecraftServer) (Object) this, world); + } + } + @Inject(at = @At(value = "TAIL"), method = "prepareWorlds") public void serverWorldLoad(CallbackInfo ci) { for (ServerWorld world : this.worlds) { ServerWorldEvents.LOAD.invoker().onWorldLoad((MinecraftServer) (Object) this, world); } } + + @Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/server/MinecraftServer;getTimeMillis()J"), method = "run", slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;setServerMeta(Lnet/minecraft/server/ServerMetadata;)V"))) + public void api$startServerTick(CallbackInfo ci) { + ServerTickEvents.START_SERVER_TICK.invoker().onStartTick((MinecraftServer) (Object) this); + } + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;setServerMeta(Lnet/minecraft/server/ServerMetadata;)V", shift = At.Shift.AFTER), method = "run") + public void api$afterServerStart(CallbackInfo ci) { + ServerLifecycleEvents.SERVER_STARTED.invoker().onServerStarted((MinecraftServer) (Object) this); + } } diff --git a/legacy-fabric-lifecycle-events-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java b/legacy-fabric-lifecycle-events-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java new file mode 100644 index 000000000..c55f346f7 --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.event.lifecycle.versioned; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import net.minecraft.server.world.ServerWorld; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ServerChunkProvider; + +import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerChunkEvents; + +@Mixin(ServerChunkProvider.class) +public class ServerChunkProviderMixin { + @Final + @Shadow + private ServerWorld world; + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/ChunkStorage;writeChunk(Lnet/minecraft/world/World;Lnet/minecraft/world/chunk/Chunk;)V"), method = "saveChunk") + public void api$chunkUnload(Chunk chunk, CallbackInfo ci) { + ServerChunkEvents.CHUNK_UNLOAD.invoker().onChunkUnload(this.world, chunk); + } + + @Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/chunk/ChunkStorage;loadChunk(Lnet/minecraft/world/World;II)Lnet/minecraft/world/chunk/Chunk;"), method = "loadChunk", locals = LocalCapture.CAPTURE_FAILEXCEPTION) + public void api$chunkLoad(int x, int z, CallbackInfoReturnable cir, Chunk chunk) { + ServerChunkEvents.CHUNK_LOAD.invoker().onChunkLoad(this.world, chunk); + } +} diff --git a/legacy-fabric-lifecycle-events-v1/1.12.2/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json b/legacy-fabric-lifecycle-events-v1/1.12.2/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json index 252c7673a..381cfac59 100644 --- a/legacy-fabric-lifecycle-events-v1/1.12.2/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json +++ b/legacy-fabric-lifecycle-events-v1/1.12.2/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json @@ -3,10 +3,12 @@ "package": "net.legacyfabric.fabric.mixin.event.lifecycle", "compatibilityLevel": "JAVA_8", "mixins": [ - "versioned.MinecraftServerMixin" + "versioned.MinecraftServerMixin", + "versioned.ServerChunkProviderMixin" ], "client": [ - "client.versioned.ClientChunkProviderMixin" + "client.versioned.ClientChunkProviderMixin", + "client.versioned.MinecraftClientMixin" ], "injectors": { "defaultRequire": 1 diff --git a/legacy-fabric-lifecycle-events-v1/1.6.4/build.gradle b/legacy-fabric-lifecycle-events-v1/1.6.4/build.gradle new file mode 100644 index 000000000..e69de29bb diff --git a/legacy-fabric-lifecycle-events-v1/1.6.4/gradle.properties b/legacy-fabric-lifecycle-events-v1/1.6.4/gradle.properties new file mode 100644 index 000000000..72b74abca --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.6.4/gradle.properties @@ -0,0 +1,2 @@ +minVersionIncluded=1.3 +maxVersionIncluded=1.6.4 diff --git a/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/ClientChunkProviderMixin.java b/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/ClientChunkProviderMixin.java new file mode 100644 index 000000000..c9ec3a52d --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/ClientChunkProviderMixin.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.event.lifecycle.client.versioned; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.world.ClientWorld; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ClientChunkProvider; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import net.legacyfabric.fabric.api.client.event.lifecycle.v1.ClientChunkEvents; + +@Environment(EnvType.CLIENT) +@Mixin(ClientChunkProvider.class) +public abstract class ClientChunkProviderMixin { + @Shadow + private World world; + + @Shadow + public abstract Chunk getChunk(int i, int j); + + @Inject(at = @At("RETURN"), method = "unloadChunk") + public void api$chunkUnload(int i, int j, CallbackInfo ci) { + ClientChunkEvents.CHUNK_UNLOAD.invoker().onChunkUnload((ClientWorld) this.world, this.getChunk(i, j)); + } +} diff --git a/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java b/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java new file mode 100644 index 000000000..143f0ed62 --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.event.lifecycle.client.versioned; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.MinecraftClient; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import net.legacyfabric.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; + +@Environment(EnvType.CLIENT) +@Mixin(MinecraftClient.class) +public class MinecraftClientMixin { + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/util/logging/LogManager;info(Ljava/lang/String;)V", shift = At.Shift.AFTER), method = "stop") + private void api$onStopping(CallbackInfo ci) { + ClientLifecycleEvents.CLIENT_STOPPING.invoker().onClientStopping((MinecraftClient) (Object) this); + } +} diff --git a/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java b/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java new file mode 100644 index 000000000..7c0d32b3d --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.event.lifecycle.versioned; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Slice; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.world.ServerWorld; + +import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerTickEvents; +import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerWorldEvents; + +@Mixin(MinecraftServer.class) +public abstract class MinecraftServerMixin { + @Shadow + public ServerWorld[] worlds; + + @Inject(at = @At("HEAD"), method = "saveWorlds") + public void api$serverWorldUnload(boolean silent, CallbackInfo ci) { + for (ServerWorld world : this.worlds) { + ServerWorldEvents.UNLOAD.invoker().onWorldUnload((MinecraftServer) (Object) this, world); + } + } + + @Inject(at = @At(value = "TAIL"), method = "method_2980") + public void api$serverWorldLoad(CallbackInfo ci) { + for (ServerWorld world : this.worlds) { + ServerWorldEvents.LOAD.invoker().onWorldLoad((MinecraftServer) (Object) this, world); + } + } + + @Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/server/MinecraftServer;getTimeMillis()J"), method = "run", slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/server/MinecraftServer;running:Z"))) + public void api$startServerTick(CallbackInfo ci) { + ServerTickEvents.START_SERVER_TICK.invoker().onStartTick((MinecraftServer) (Object) this); + } + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getTimeMillis()J", ordinal = 0, shift = At.Shift.AFTER), method = "run") + public void api$afterServerStart(CallbackInfo ci) { + ServerLifecycleEvents.SERVER_STARTED.invoker().onServerStarted((MinecraftServer) (Object) this); + } +} diff --git a/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java b/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java new file mode 100644 index 000000000..72cd96ffd --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.event.lifecycle.versioned; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import net.minecraft.server.world.ServerWorld; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ServerChunkProvider; + +import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerChunkEvents; + +@Mixin(ServerChunkProvider.class) +public class ServerChunkProviderMixin { + @Shadow + private ServerWorld world; + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/ChunkStorage;writeChunk(Lnet/minecraft/world/World;Lnet/minecraft/world/chunk/Chunk;)V"), method = "method_2128") + public void api$chunkUnload(Chunk chunk, CallbackInfo ci) { + ServerChunkEvents.CHUNK_UNLOAD.invoker().onChunkUnload(this.world, chunk); + } + + @Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/chunk/ChunkStorage;loadChunk(Lnet/minecraft/world/World;II)Lnet/minecraft/world/chunk/Chunk;"), method = "method_2129", locals = LocalCapture.CAPTURE_FAILEXCEPTION) + public void api$chunkLoad(int x, int z, CallbackInfoReturnable cir, Chunk chunk) { + ServerChunkEvents.CHUNK_LOAD.invoker().onChunkLoad(this.world, chunk); + } +} diff --git a/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/resources/assets/legacy-fabric/icon.png b/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/resources/assets/legacy-fabric/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2931efbf610873c0084debb8690902b0103d27fe GIT binary patch literal 1579 zcmbVMTWB0r7@iGm)TAXsYw<=rnU=;v=W=GRbL=!tc4Brl6GO7t2vVJ$IlDV#XU;e? z+r2ymsZdMQqAyaFLLUo;RumtE8Z@?uf_*4nP^4;o6fOFoSkN+o1$K?f2nE9_*b5G-l)AV)k5Qhb^- zU{V4ZnTKgnmXdpcB*Kg!W(1hvM2N&RO30x1u~eI9meGQGe@_?PDQq%q1CiV$8~M7 z?MQ_mOdqCh^a65Sv|ntwSXjV5se1;VK1|Kr8G7TQoQL&*ctt{L{fClG}xPK5k^yK3%T69N6J=>3jBqc zDNvZsrJ-yOXI^^mWf1cmY^XST)CVzIGjvEPENowmy}ax zvJ8_(Cf#+H-dBlH53`_u-~6BVAMz|(g?jCVdBWNZ(+A}(pFV7>S3QgPiQcMaflkIC z-3Ti|VT~{au*vq0ts9O&m$p&Gl=L6+q6_m$IcVq}o~+Pl{g>1esQp4%wp~|*zk1n` zZ7T6Toc4`y88s}riCP|ZXrJ?FLz@^KTcyqLjey zu95Yz%F&S{<0~f)Iomek?+hQ%MhCu%T^zsg>C_L`1`Br`xNY&))k9yTQb$JC>)w_f zpU(^tu^Q)y%W~lVz`jz;_ jF?g&s@Y=Qe&c#kW|JbvqK0Y=Rw)4XDoVqsk_>;c_`@;F@ literal 0 HcmV?d00001 diff --git a/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/resources/fabric.mod.json b/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/resources/fabric.mod.json new file mode 100644 index 000000000..f8b664e41 --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/resources/fabric.mod.json @@ -0,0 +1,37 @@ +{ + "schemaVersion": 1, + "id": "legacy-fabric-lifecycle-events-v1", + "name": "Legacy Fabric Lifecycle Events (V1)", + "version": "${version}", + "environment": "*", + "license": "Apache-2.0", + "icon": "assets/legacy-fabric/icon.png", + "contact": { + "homepage": "https://legacy-fabric.github.io/", + "issues": "https://github.com/Legacy-Fabric/fabric/issues", + "sources": "https://github.com/Legacy-Fabric/fabric" + }, + "authors": [ + "Legacy-Fabric", + "FabricMC" + ], + "mixins": [ + "legacy-fabric-lifecycle-events-v1.mixins.json" + ], + "description": "Events for the game's lifecycle.", + "depends": { + "minecraft": "${minecraft_version}" + }, + "custom": { + "modmenu": { + "badges": [ "library" ], + "parent": { + "id": "legacy-fabric-api", + "name": "Legacy Fabric API", + "badges": [ "library" ], + "description": "Core API module providing key hooks and inter-compatibility features for Minecraft 1.7.10-1.12.2.", + "icon": "assets/legacy-fabric/icon.png" + } + } + } +} diff --git a/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json b/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json new file mode 100644 index 000000000..381cfac59 --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.6.4/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json @@ -0,0 +1,16 @@ +{ + "required": true, + "package": "net.legacyfabric.fabric.mixin.event.lifecycle", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "versioned.MinecraftServerMixin", + "versioned.ServerChunkProviderMixin" + ], + "client": [ + "client.versioned.ClientChunkProviderMixin", + "client.versioned.MinecraftClientMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/lifecycle/client/ClientLifecycleEventsTest.java b/legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/lifecycle/client/ClientLifecycleEventsTest.java new file mode 100644 index 000000000..bf1b8088e --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/lifecycle/client/ClientLifecycleEventsTest.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.test.lifecycle.client; + +import net.fabricmc.api.ClientModInitializer; + +import net.legacyfabric.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; +import net.legacyfabric.fabric.api.logger.v1.Logger; +import net.legacyfabric.fabric.impl.logger.LoggerImpl; + +public class ClientLifecycleEventsTest implements ClientModInitializer { + private static final Logger LOGGER = Logger.get(LoggerImpl.API, "Test", "ClientLifecycleEvents"); + + @Override + public void onInitializeClient() { + ClientLifecycleEvents.CLIENT_STARTED.register(client -> { + LOGGER.info("Client started"); + }); + ClientLifecycleEvents.CLIENT_STOPPING.register(client -> { + LOGGER.info("Client stopping"); + }); + } +} diff --git a/legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/resources/fabric.mod.json b/legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/resources/fabric.mod.json new file mode 100644 index 000000000..e53297411 --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/resources/fabric.mod.json @@ -0,0 +1,14 @@ +{ + "schemaVersion": 1, + "id": "legacy-fabric-lifecycle-events-v1-testmod-1-8-9", + "description": "Tests for lifecycle events", + "version": "1.0.0", + "entrypoints": { + "client": [ + "net.legacyfabric.fabric.test.lifecycle.client.ClientLifecycleEventsTest" + ] + }, + "depends": { + "minecraft": "${minecraft_version}" + } +} diff --git a/legacy-fabric-lifecycle-events-v1/1.7.10/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java b/legacy-fabric-lifecycle-events-v1/1.7.10/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java new file mode 100644 index 000000000..11dd84134 --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.7.10/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.event.lifecycle.client.versioned; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.MinecraftClient; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import net.legacyfabric.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; + +@Environment(EnvType.CLIENT) +@Mixin(MinecraftClient.class) +public class MinecraftClientMixin { + @Inject(at = @At(value = "INVOKE", target = "Lorg/apache/logging/log4j/Logger;info(Ljava/lang/String;)V", shift = At.Shift.AFTER, remap = false), method = "stop") + private void api$onStopping(CallbackInfo ci) { + ClientLifecycleEvents.CLIENT_STOPPING.invoker().onClientStopping((MinecraftClient) (Object) this); + } +} diff --git a/legacy-fabric-lifecycle-events-v1/1.7.10/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java b/legacy-fabric-lifecycle-events-v1/1.7.10/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java index 415358a2f..fb9e12c5b 100644 --- a/legacy-fabric-lifecycle-events-v1/1.7.10/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java +++ b/legacy-fabric-lifecycle-events-v1/1.7.10/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java @@ -21,11 +21,14 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Slice; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import net.minecraft.server.MinecraftServer; import net.minecraft.server.world.ServerWorld; +import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerWorldEvents; @Mixin(MinecraftServer.class) @@ -46,4 +49,14 @@ public abstract class MinecraftServerMixin { ServerWorldEvents.LOAD.invoker().onWorldLoad((MinecraftServer) (Object) this, world); } } + + @Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/server/MinecraftServer;getTimeMillis()J"), method = "run", slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;setServerMeta(Lnet/minecraft/server/ServerMetadata;)V"))) + public void api$startServerTick(CallbackInfo ci) { + ServerTickEvents.START_SERVER_TICK.invoker().onStartTick((MinecraftServer) (Object) this); + } + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;setServerMeta(Lnet/minecraft/server/ServerMetadata;)V", shift = At.Shift.AFTER), method = "run") + public void api$afterServerStart(CallbackInfo ci) { + ServerLifecycleEvents.SERVER_STARTED.invoker().onServerStarted((MinecraftServer) (Object) this); + } } diff --git a/legacy-fabric-lifecycle-events-v1/1.7.10/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java b/legacy-fabric-lifecycle-events-v1/1.7.10/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java new file mode 100644 index 000000000..f4aee8f97 --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.7.10/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.event.lifecycle.versioned; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import net.minecraft.server.world.ServerWorld; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ServerChunkProvider; + +import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerChunkEvents; + +@Mixin(ServerChunkProvider.class) +public class ServerChunkProviderMixin { + @Shadow + private ServerWorld world; + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/ChunkStorage;writeChunk(Lnet/minecraft/world/World;Lnet/minecraft/world/chunk/Chunk;)V"), method = "saveChunk") + public void api$chunkUnload(Chunk chunk, CallbackInfo ci) { + ServerChunkEvents.CHUNK_UNLOAD.invoker().onChunkUnload(this.world, chunk); + } + + @Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/chunk/ChunkStorage;loadChunk(Lnet/minecraft/world/World;II)Lnet/minecraft/world/chunk/Chunk;"), method = "loadChunk", locals = LocalCapture.CAPTURE_FAILEXCEPTION) + public void api$chunkLoad(int x, int z, CallbackInfoReturnable cir, Chunk chunk) { + ServerChunkEvents.CHUNK_LOAD.invoker().onChunkLoad(this.world, chunk); + } +} diff --git a/legacy-fabric-lifecycle-events-v1/1.7.10/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json b/legacy-fabric-lifecycle-events-v1/1.7.10/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json index 252c7673a..381cfac59 100644 --- a/legacy-fabric-lifecycle-events-v1/1.7.10/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json +++ b/legacy-fabric-lifecycle-events-v1/1.7.10/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json @@ -3,10 +3,12 @@ "package": "net.legacyfabric.fabric.mixin.event.lifecycle", "compatibilityLevel": "JAVA_8", "mixins": [ - "versioned.MinecraftServerMixin" + "versioned.MinecraftServerMixin", + "versioned.ServerChunkProviderMixin" ], "client": [ - "client.versioned.ClientChunkProviderMixin" + "client.versioned.ClientChunkProviderMixin", + "client.versioned.MinecraftClientMixin" ], "injectors": { "defaultRequire": 1 diff --git a/legacy-fabric-lifecycle-events-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java b/legacy-fabric-lifecycle-events-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java new file mode 100644 index 000000000..11dd84134 --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/versioned/MinecraftClientMixin.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.event.lifecycle.client.versioned; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.MinecraftClient; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import net.legacyfabric.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; + +@Environment(EnvType.CLIENT) +@Mixin(MinecraftClient.class) +public class MinecraftClientMixin { + @Inject(at = @At(value = "INVOKE", target = "Lorg/apache/logging/log4j/Logger;info(Ljava/lang/String;)V", shift = At.Shift.AFTER, remap = false), method = "stop") + private void api$onStopping(CallbackInfo ci) { + ClientLifecycleEvents.CLIENT_STOPPING.invoker().onClientStopping((MinecraftClient) (Object) this); + } +} diff --git a/legacy-fabric-lifecycle-events-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java b/legacy-fabric-lifecycle-events-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java index 5ef61aeaa..d42aa62b8 100644 --- a/legacy-fabric-lifecycle-events-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java +++ b/legacy-fabric-lifecycle-events-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/MinecraftServerMixin.java @@ -21,11 +21,14 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Slice; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import net.minecraft.server.MinecraftServer; import net.minecraft.server.world.ServerWorld; +import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerWorldEvents; @Mixin(MinecraftServer.class) @@ -33,10 +36,27 @@ public abstract class MinecraftServerMixin { @Shadow public ServerWorld[] worlds; + @Inject(at = @At("HEAD"), method = "saveWorlds") + public void api$serverWorldUnload(boolean silent, CallbackInfo ci) { + for (ServerWorld world : this.worlds) { + ServerWorldEvents.UNLOAD.invoker().onWorldUnload((MinecraftServer) (Object) this, world); + } + } + @Inject(at = @At(value = "TAIL"), method = "method_2980") public void serverWorldLoad(CallbackInfo ci) { for (ServerWorld world : this.worlds) { ServerWorldEvents.LOAD.invoker().onWorldLoad((MinecraftServer) (Object) this, world); } } + + @Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/server/MinecraftServer;getTimeMillis()J"), method = "run", slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;setServerMeta(Lnet/minecraft/server/ServerMetadata;)V"))) + public void api$startServerTick(CallbackInfo ci) { + ServerTickEvents.START_SERVER_TICK.invoker().onStartTick((MinecraftServer) (Object) this); + } + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;setServerMeta(Lnet/minecraft/server/ServerMetadata;)V", shift = At.Shift.AFTER), method = "run") + public void api$afterServerStart(CallbackInfo ci) { + ServerLifecycleEvents.SERVER_STARTED.invoker().onServerStarted((MinecraftServer) (Object) this); + } } diff --git a/legacy-fabric-lifecycle-events-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java b/legacy-fabric-lifecycle-events-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java new file mode 100644 index 000000000..f4aee8f97 --- /dev/null +++ b/legacy-fabric-lifecycle-events-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/versioned/ServerChunkProviderMixin.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.event.lifecycle.versioned; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import net.minecraft.server.world.ServerWorld; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ServerChunkProvider; + +import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerChunkEvents; + +@Mixin(ServerChunkProvider.class) +public class ServerChunkProviderMixin { + @Shadow + private ServerWorld world; + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/ChunkStorage;writeChunk(Lnet/minecraft/world/World;Lnet/minecraft/world/chunk/Chunk;)V"), method = "saveChunk") + public void api$chunkUnload(Chunk chunk, CallbackInfo ci) { + ServerChunkEvents.CHUNK_UNLOAD.invoker().onChunkUnload(this.world, chunk); + } + + @Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/chunk/ChunkStorage;loadChunk(Lnet/minecraft/world/World;II)Lnet/minecraft/world/chunk/Chunk;"), method = "loadChunk", locals = LocalCapture.CAPTURE_FAILEXCEPTION) + public void api$chunkLoad(int x, int z, CallbackInfoReturnable cir, Chunk chunk) { + ServerChunkEvents.CHUNK_LOAD.invoker().onChunkLoad(this.world, chunk); + } +} diff --git a/legacy-fabric-lifecycle-events-v1/1.8.9/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json b/legacy-fabric-lifecycle-events-v1/1.8.9/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json index 252c7673a..381cfac59 100644 --- a/legacy-fabric-lifecycle-events-v1/1.8.9/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json +++ b/legacy-fabric-lifecycle-events-v1/1.8.9/src/main/resources/legacy-fabric-lifecycle-events-v1.mixins.json @@ -3,10 +3,12 @@ "package": "net.legacyfabric.fabric.mixin.event.lifecycle", "compatibilityLevel": "JAVA_8", "mixins": [ - "versioned.MinecraftServerMixin" + "versioned.MinecraftServerMixin", + "versioned.ServerChunkProviderMixin" ], "client": [ - "client.versioned.ClientChunkProviderMixin" + "client.versioned.ClientChunkProviderMixin", + "client.versioned.MinecraftClientMixin" ], "injectors": { "defaultRequire": 1 diff --git a/legacy-fabric-lifecycle-events-v1/common/gradle.properties b/legacy-fabric-lifecycle-events-v1/common/gradle.properties index 1bd1b1914..13b94f3a1 100644 --- a/legacy-fabric-lifecycle-events-v1/common/gradle.properties +++ b/legacy-fabric-lifecycle-events-v1/common/gradle.properties @@ -1,2 +1,2 @@ -minVersionIncluded=1.7.10 +minVersionIncluded=1.3 maxVersionIncluded=1.13.2 diff --git a/legacy-fabric-lifecycle-events-v1/common/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/MinecraftServerMixin.java b/legacy-fabric-lifecycle-events-v1/common/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/MinecraftServerMixin.java index 1e31a6037..c7681e9fe 100644 --- a/legacy-fabric-lifecycle-events-v1/common/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/MinecraftServerMixin.java +++ b/legacy-fabric-lifecycle-events-v1/common/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/MinecraftServerMixin.java @@ -22,7 +22,6 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Slice; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import net.minecraft.server.MinecraftServer; @@ -37,11 +36,6 @@ public class MinecraftServerMixin { @Shadow public ServerWorld[] worlds; - @Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/server/MinecraftServer;getTimeMillis()J"), method = "run", slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;setServerMeta(Lnet/minecraft/server/ServerMetadata;)V"))) - public void api$startServerTick(CallbackInfo ci) { - ServerTickEvents.START_SERVER_TICK.invoker().onStartTick((MinecraftServer) (Object) this); - } - @Inject(at = @At(value = "INVOKE", target = "Ljava/lang/Thread;sleep(J)V", remap = false), method = "run") public void api$endServerTick(CallbackInfo ci) { ServerTickEvents.END_SERVER_TICK.invoker().onEndTick((MinecraftServer) (Object) this); @@ -62,11 +56,6 @@ public class MinecraftServerMixin { ServerLifecycleEvents.SERVER_STARTING.invoker().onServerStarting((MinecraftServer) (Object) this); } - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;setServerMeta(Lnet/minecraft/server/ServerMetadata;)V", shift = At.Shift.AFTER), method = "run") - public void api$afterServerStart(CallbackInfo ci) { - ServerLifecycleEvents.SERVER_STARTED.invoker().onServerStarted((MinecraftServer) (Object) this); - } - @Inject(at = @At("HEAD"), method = "saveWorlds") public void api$serverWorldUnload(boolean silent, CallbackInfo ci) { for (ServerWorld world : this.worlds) { diff --git a/legacy-fabric-lifecycle-events-v1/common/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/ServerChunkProviderMixin.java b/legacy-fabric-lifecycle-events-v1/common/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/ServerChunkProviderMixin.java index 5af0f7edb..6000e7798 100644 --- a/legacy-fabric-lifecycle-events-v1/common/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/ServerChunkProviderMixin.java +++ b/legacy-fabric-lifecycle-events-v1/common/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/ServerChunkProviderMixin.java @@ -18,31 +18,9 @@ package net.legacyfabric.fabric.mixin.event.lifecycle; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.ServerChunkProvider; -import net.legacyfabric.fabric.api.event.lifecycle.v1.ServerChunkEvents; - @Mixin(ServerChunkProvider.class) public class ServerChunkProviderMixin { - @Shadow - private ServerWorld world; - - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/ChunkStorage;writeChunk(Lnet/minecraft/world/World;Lnet/minecraft/world/chunk/Chunk;)V"), method = "saveChunk") - public void api$chunkUnload(Chunk chunk, CallbackInfo ci) { - ServerChunkEvents.CHUNK_UNLOAD.invoker().onChunkUnload(this.world, chunk); - } - - @Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/chunk/ChunkStorage;loadChunk(Lnet/minecraft/world/World;II)Lnet/minecraft/world/chunk/Chunk;"), method = "loadChunk", locals = LocalCapture.CAPTURE_FAILEXCEPTION) - public void api$chunkLoad(int x, int z, CallbackInfoReturnable cir, Chunk chunk) { - ServerChunkEvents.CHUNK_LOAD.invoker().onChunkLoad(this.world, chunk); - } } diff --git a/legacy-fabric-lifecycle-events-v1/common/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/MinecraftClientMixin.java b/legacy-fabric-lifecycle-events-v1/common/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/MinecraftClientMixin.java index e408880b2..d4c63004f 100644 --- a/legacy-fabric-lifecycle-events-v1/common/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/MinecraftClientMixin.java +++ b/legacy-fabric-lifecycle-events-v1/common/src/main/java/net/legacyfabric/fabric/mixin/event/lifecycle/client/MinecraftClientMixin.java @@ -43,11 +43,6 @@ public class MinecraftClientMixin { ClientTickEvents.END_CLIENT_TICK.invoker().onEndTick((MinecraftClient) (Object) this); } - @Inject(at = @At(value = "INVOKE", target = "Lorg/apache/logging/log4j/Logger;info(Ljava/lang/String;)V", shift = At.Shift.AFTER, remap = false), method = "stop") - private void api$onStopping(CallbackInfo ci) { - ClientLifecycleEvents.CLIENT_STOPPING.invoker().onClientStopping((MinecraftClient) (Object) this); - } - @Inject(at = @At(value = "RETURN"), method = "initializeGame") private void api$onStart(CallbackInfo ci) { ClientLifecycleEvents.CLIENT_STARTED.invoker().onClientStarted((MinecraftClient) (Object) this); From 028d1a0ace821342eaa1e76c4c047888f989f34b Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 4 May 2024 23:20:17 +0200 Subject: [PATCH 08/24] Port keybindings module to 1.6.4 --- README.md | 2 +- .../1.6.4/build.gradle | 0 .../1.6.4/gradle.properties | 2 + .../1.6.4/src/main/resources/fabric.mod.json | 35 +++++++++++++++++ .../client/keybinding/KeybindingTest.java | 39 +++++++++++++++++++ .../src/testmod/resources/fabric.mod.json | 16 ++++++++ 6 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 legacy-fabric-keybindings-api-v1/1.6.4/build.gradle create mode 100644 legacy-fabric-keybindings-api-v1/1.6.4/gradle.properties create mode 100644 legacy-fabric-keybindings-api-v1/1.6.4/src/main/resources/fabric.mod.json create mode 100644 legacy-fabric-keybindings-api-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/client/keybinding/KeybindingTest.java create mode 100644 legacy-fabric-keybindings-api-v1/1.6.4/src/testmod/resources/fabric.mod.json diff --git a/README.md b/README.md index 5ce9f2955..2bbeaea60 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ For support, consider joining the [Legacy Fabric discord server](https://legacyf | entity-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | gamerule-api-v1 | ? | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ? | | item-groups-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| keybindings-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| keybindings-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | lifecycle-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | logger-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | networking-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | diff --git a/legacy-fabric-keybindings-api-v1/1.6.4/build.gradle b/legacy-fabric-keybindings-api-v1/1.6.4/build.gradle new file mode 100644 index 000000000..e69de29bb diff --git a/legacy-fabric-keybindings-api-v1/1.6.4/gradle.properties b/legacy-fabric-keybindings-api-v1/1.6.4/gradle.properties new file mode 100644 index 000000000..bff6c84c0 --- /dev/null +++ b/legacy-fabric-keybindings-api-v1/1.6.4/gradle.properties @@ -0,0 +1,2 @@ +minVersionIncluded=1.6.4 +maxVersionIncluded=1.6.4 diff --git a/legacy-fabric-keybindings-api-v1/1.6.4/src/main/resources/fabric.mod.json b/legacy-fabric-keybindings-api-v1/1.6.4/src/main/resources/fabric.mod.json new file mode 100644 index 000000000..17813b87b --- /dev/null +++ b/legacy-fabric-keybindings-api-v1/1.6.4/src/main/resources/fabric.mod.json @@ -0,0 +1,35 @@ +{ + "schemaVersion": 1, + "id": "legacy-fabric-keybinding-api-v1", + "name": "Legacy Fabric Keybinding API (V1)", + "version": "${version}", + "environment": "client", + "license": "Apache-2.0", + "icon": "assets/legacy-fabric-api/icon.png", + "contact": { + "homepage": "https://legacyfabric.net/", + "issues": "https://github.com/Legacy-Fabric/fabric/issues", + "sources": "https://github.com/Legacy-Fabric/fabric" + }, + "authors": [ + "Legacy Fabric", + "FabricMC" + ], + "depends": { + "minecraft": "${minecraft_version}" + }, + "mixins": [], + "description": "Hooks that help adding keybindings", + "custom": { + "modmenu": { + "badges": [ "library" ], + "parent": { + "id": "legacy-fabric-api", + "name": "Legacy Fabric API", + "badges": [ "library" ], + "description": "Core API module providing key hooks and inter-compatibility features for Minecraft 1.7.10-1.12.2.", + "icon": "assets/legacy-fabric-api/icon.png" + } + } + } +} diff --git a/legacy-fabric-keybindings-api-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/client/keybinding/KeybindingTest.java b/legacy-fabric-keybindings-api-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/client/keybinding/KeybindingTest.java new file mode 100644 index 000000000..bcb65a476 --- /dev/null +++ b/legacy-fabric-keybindings-api-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/client/keybinding/KeybindingTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.test.client.keybinding; + +import org.lwjgl.input.Keyboard; + +import net.minecraft.client.option.KeyBinding; + +import net.fabricmc.api.ClientModInitializer; + +import net.legacyfabric.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.legacyfabric.fabric.api.client.keybinding.v1.KeyBindingHelper; + +public class KeybindingTest implements ClientModInitializer { + @Override + public void onInitializeClient() { + KeyBinding keyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding("api.keybinding.testTranslationKey", Keyboard.KEY_F)); + ClientTickEvents.END_CLIENT_TICK.register(client -> { + if (keyBinding.wasPressed()) { + System.out.printf("The key %s was pressed%n", Keyboard.getKeyName(keyBinding.code)); + } + }); + } +} diff --git a/legacy-fabric-keybindings-api-v1/1.6.4/src/testmod/resources/fabric.mod.json b/legacy-fabric-keybindings-api-v1/1.6.4/src/testmod/resources/fabric.mod.json new file mode 100644 index 000000000..0033bc2ec --- /dev/null +++ b/legacy-fabric-keybindings-api-v1/1.6.4/src/testmod/resources/fabric.mod.json @@ -0,0 +1,16 @@ +{ + "schemaVersion": 1, + "id": "legacy-fabric-keybinding-api-v1-testmod", + "description": "Tests for keybindings", + "version": "1.0.0", + "entrypoints": { + "client": [ + "net.legacyfabric.fabric.test.client.keybinding.KeybindingTest" + ] + }, + "depends": { + "minecraft": "${minecraft_version}", + "legacy-fabric-keybinding-api-v1": "*", + "legacy-fabric-lifecycle-events-v1-common": "*" + } +} From a4b7195787f6a94c9d337ae00455e12b7e2faf12 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 4 May 2024 23:54:28 +0200 Subject: [PATCH 09/24] Add testmod to command api v1 --- README.md | 2 +- .../fabric/test/command/CommandV1Test.java | 32 +++++++++ .../test/command/ModMetadataCommandV1.java | 70 +++++++++++++++++++ .../src/testmod/resources/fabric.mod.json | 14 ++++ 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 legacy-fabric-command-api-v1/common/src/testmod/java/net/legacyfabric/fabric/test/command/CommandV1Test.java create mode 100644 legacy-fabric-command-api-v1/common/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommandV1.java create mode 100644 legacy-fabric-command-api-v1/common/src/testmod/resources/fabric.mod.json diff --git a/README.md b/README.md index 2bbeaea60..7e3b8691e 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ For support, consider joining the [Legacy Fabric discord server](https://legacyf | | 1.6.4 | 1.7.10 | 1.8 | 1.8.9 | 1.9.4 | 1.10.2 | 1.11.2 | 1.12.2 | 1.13.2 | |----------------------|-------|--------|-----|-------|-------|--------|--------|--------|--------| | api-base | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| command-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| command-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | command-api-v2 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | crash-report-info-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | entity-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | diff --git a/legacy-fabric-command-api-v1/common/src/testmod/java/net/legacyfabric/fabric/test/command/CommandV1Test.java b/legacy-fabric-command-api-v1/common/src/testmod/java/net/legacyfabric/fabric/test/command/CommandV1Test.java new file mode 100644 index 000000000..390a8a7ab --- /dev/null +++ b/legacy-fabric-command-api-v1/common/src/testmod/java/net/legacyfabric/fabric/test/command/CommandV1Test.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.test.command; + +import net.fabricmc.api.ModInitializer; + +import net.legacyfabric.fabric.api.logger.v1.Logger; +import net.legacyfabric.fabric.api.registry.CommandRegistry; + +public class CommandV1Test implements ModInitializer { + public static final Logger LOGGER = Logger.get("LegacyFabricAPI", "Test", "CommandV1Test"); + + @Override + public void onInitialize() { + CommandRegistry.INSTANCE.register(new ModMetadataCommandV1()); + } +} diff --git a/legacy-fabric-command-api-v1/common/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommandV1.java b/legacy-fabric-command-api-v1/common/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommandV1.java new file mode 100644 index 000000000..afcf17ff1 --- /dev/null +++ b/legacy-fabric-command-api-v1/common/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommandV1.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.test.command; + +import net.minecraft.command.AbstractCommand; +import net.minecraft.command.CommandException; +import net.minecraft.command.CommandSource; + +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.metadata.ContactInformation; + +public class ModMetadataCommandV1 extends AbstractCommand { + @Override + public String getCommandName() { + return "modmetadatav1"; + } + + @Override + public String getUsageTranslationKey(CommandSource source) { + return "modmetadatav1"; + } + + @Override + public void execute(CommandSource source, String[] args) throws CommandException { + if (args.length > 0) { + FabricLoader.getInstance().getModContainer(args[0]).ifPresent(container -> { + StringBuilder builder = new StringBuilder(); + builder.append("Mod Name: ".concat(container.getMetadata().getName()).concat("\n")); + builder.append("Description: ".concat(container.getMetadata().getDescription()).concat("\n")); + ContactInformation contact = container.getMetadata().getContact(); + + if (contact.get("issues").isPresent()) { + StringBuilder issueText = new StringBuilder(""); + issueText.append("Issues: "); + StringBuilder issueUrl = new StringBuilder(contact.get("issues").get()); + issueText.append(issueUrl); + issueText.append("\n"); + builder.append(issueText); + } + + if (contact.get("sources").isPresent()) { + StringBuilder sourcesText = new StringBuilder(""); + sourcesText.append("Sources: "); + StringBuilder sourcesUrl = new StringBuilder(contact.get("sources").get()); + sourcesText.append(sourcesUrl); + sourcesText.append("\n"); + builder.append(sourcesText); + } + + builder.append("Metadata Type: ".concat(container.getMetadata().getType()).concat("\n")); + CommandV1Test.LOGGER.info(builder.toString()); + }); + } + } +} diff --git a/legacy-fabric-command-api-v1/common/src/testmod/resources/fabric.mod.json b/legacy-fabric-command-api-v1/common/src/testmod/resources/fabric.mod.json new file mode 100644 index 000000000..7af4a7f70 --- /dev/null +++ b/legacy-fabric-command-api-v1/common/src/testmod/resources/fabric.mod.json @@ -0,0 +1,14 @@ +{ + "schemaVersion": 1, + "id": "legacy-fabric-command-api-v1-testmod", + "description": "Tests for api features", + "version": "1.0.0", + "entrypoints": { + "main": [ + "net.legacyfabric.fabric.test.command.CommandV1Test" + ] + }, + "depends": { + "minecraft": "${minecraft_version}" + } +} From 9fd9e561121c4301957df127eaf9dd40c2f000be Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 4 May 2024 23:54:41 +0200 Subject: [PATCH 10/24] fix some test mod modid --- .../1.12.2/src/testmod/resources/fabric.mod.json | 2 +- .../1.6.4/src/testmod/resources/fabric.mod.json | 2 +- .../1.7.10/src/testmod/resources/fabric.mod.json | 2 +- .../1.8.9/src/testmod/resources/fabric.mod.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/legacy-fabric-lifecycle-events-v1/1.12.2/src/testmod/resources/fabric.mod.json b/legacy-fabric-lifecycle-events-v1/1.12.2/src/testmod/resources/fabric.mod.json index e53297411..36a567c30 100644 --- a/legacy-fabric-lifecycle-events-v1/1.12.2/src/testmod/resources/fabric.mod.json +++ b/legacy-fabric-lifecycle-events-v1/1.12.2/src/testmod/resources/fabric.mod.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "id": "legacy-fabric-lifecycle-events-v1-testmod-1-8-9", + "id": "legacy-fabric-lifecycle-events-v1-testmod-versioned", "description": "Tests for lifecycle events", "version": "1.0.0", "entrypoints": { diff --git a/legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/resources/fabric.mod.json b/legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/resources/fabric.mod.json index e53297411..36a567c30 100644 --- a/legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/resources/fabric.mod.json +++ b/legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/resources/fabric.mod.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "id": "legacy-fabric-lifecycle-events-v1-testmod-1-8-9", + "id": "legacy-fabric-lifecycle-events-v1-testmod-versioned", "description": "Tests for lifecycle events", "version": "1.0.0", "entrypoints": { diff --git a/legacy-fabric-lifecycle-events-v1/1.7.10/src/testmod/resources/fabric.mod.json b/legacy-fabric-lifecycle-events-v1/1.7.10/src/testmod/resources/fabric.mod.json index e53297411..36a567c30 100644 --- a/legacy-fabric-lifecycle-events-v1/1.7.10/src/testmod/resources/fabric.mod.json +++ b/legacy-fabric-lifecycle-events-v1/1.7.10/src/testmod/resources/fabric.mod.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "id": "legacy-fabric-lifecycle-events-v1-testmod-1-8-9", + "id": "legacy-fabric-lifecycle-events-v1-testmod-versioned", "description": "Tests for lifecycle events", "version": "1.0.0", "entrypoints": { diff --git a/legacy-fabric-lifecycle-events-v1/1.8.9/src/testmod/resources/fabric.mod.json b/legacy-fabric-lifecycle-events-v1/1.8.9/src/testmod/resources/fabric.mod.json index e53297411..36a567c30 100644 --- a/legacy-fabric-lifecycle-events-v1/1.8.9/src/testmod/resources/fabric.mod.json +++ b/legacy-fabric-lifecycle-events-v1/1.8.9/src/testmod/resources/fabric.mod.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "id": "legacy-fabric-lifecycle-events-v1-testmod-1-8-9", + "id": "legacy-fabric-lifecycle-events-v1-testmod-versioned", "description": "Tests for lifecycle events", "version": "1.0.0", "entrypoints": { From 16d50f3e19e45df45fd1a4da824af7e6e0815569 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sun, 5 May 2024 14:18:26 +0200 Subject: [PATCH 11/24] Port permission api module to 1.6.4 --- .../1.6.4/build.gradle | 0 .../1.6.4/gradle.properties | 2 + .../impl/permission/PermissionImpl.java | 62 ++++++++++++++++++ .../permission/CommandBlockExecutorMixin.java | 32 +++++++++ .../legacy-fabric-permissions-api-v1/icon.png | Bin 0 -> 1579 bytes .../1.6.4/src/main/resources/fabric.mod.json | 43 ++++++++++++ ...gacy-fabric-permissions-api-v1.mixins.json | 11 ++++ .../1.8.9/gradle.properties | 2 +- .../impl/permission/PermissionImpl.java | 62 ++++++++++++++++++ .../1.8.9/src/main/resources/fabric.mod.json | 5 ++ ...gacy-fabric-permissions-api-v1.mixins.json | 3 - .../permission/v1/PermissionsApiHolder.java | 37 ++--------- .../fabric/mixin/permission/ConsoleMixin.java | 0 .../fabric/mixin/permission/EntityMixin.java | 0 .../permission/ServerPlayerEntityMixin.java | 0 .../common/src/main/resources/fabric.mod.json | 4 +- ...bric-permissions-api-v1-common.mixins.json | 13 ++++ 17 files changed, 239 insertions(+), 37 deletions(-) create mode 100644 legacy-fabric-permissions-api-v1/1.6.4/build.gradle create mode 100644 legacy-fabric-permissions-api-v1/1.6.4/gradle.properties create mode 100644 legacy-fabric-permissions-api-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java create mode 100644 legacy-fabric-permissions-api-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/permission/CommandBlockExecutorMixin.java create mode 100644 legacy-fabric-permissions-api-v1/1.6.4/src/main/resources/assets/legacy-fabric-permissions-api-v1/icon.png create mode 100644 legacy-fabric-permissions-api-v1/1.6.4/src/main/resources/fabric.mod.json create mode 100644 legacy-fabric-permissions-api-v1/1.6.4/src/main/resources/legacy-fabric-permissions-api-v1.mixins.json create mode 100644 legacy-fabric-permissions-api-v1/1.8.9/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java rename legacy-fabric-permissions-api-v1/{1.8.9 => common}/src/main/java/net/legacyfabric/fabric/mixin/permission/ConsoleMixin.java (100%) rename legacy-fabric-permissions-api-v1/{1.8.9 => common}/src/main/java/net/legacyfabric/fabric/mixin/permission/EntityMixin.java (100%) rename legacy-fabric-permissions-api-v1/{1.8.9 => common}/src/main/java/net/legacyfabric/fabric/mixin/permission/ServerPlayerEntityMixin.java (100%) create mode 100644 legacy-fabric-permissions-api-v1/common/src/main/resources/legacy-fabric-permissions-api-v1-common.mixins.json diff --git a/legacy-fabric-permissions-api-v1/1.6.4/build.gradle b/legacy-fabric-permissions-api-v1/1.6.4/build.gradle new file mode 100644 index 000000000..e69de29bb diff --git a/legacy-fabric-permissions-api-v1/1.6.4/gradle.properties b/legacy-fabric-permissions-api-v1/1.6.4/gradle.properties new file mode 100644 index 000000000..72b74abca --- /dev/null +++ b/legacy-fabric-permissions-api-v1/1.6.4/gradle.properties @@ -0,0 +1,2 @@ +minVersionIncluded=1.3 +maxVersionIncluded=1.6.4 diff --git a/legacy-fabric-permissions-api-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java b/legacy-fabric-permissions-api-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java new file mode 100644 index 000000000..13e91de82 --- /dev/null +++ b/legacy-fabric-permissions-api-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.permission; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.server.MinecraftServer; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.ModInitializer; +import net.fabricmc.loader.api.FabricLoader; + +import net.legacyfabric.fabric.api.permission.v1.PermissionsApiHolder; +import net.legacyfabric.fabric.api.permission.v1.PlayerPermissionsApi; + +public class PermissionImpl implements ModInitializer { + @Override + public void onInitialize() { + PermissionsApiHolder.setFallbackPlayerPermissionsApi(FallbackPlayerPermissionsApi.INSTANCE); + } + + private enum FallbackPlayerPermissionsApi implements PlayerPermissionsApi { + INSTANCE; + + @Override + public String getId() { + return "legacy-fabric-fallback-permissions-api"; + } + + @Override + public boolean hasPermission(ServerPlayerEntity player, String perm) { + return getServer().getPlayerManager().canCheat(player.getUsername()); + } + } + + protected static MinecraftServer getServer() { + try { + return MinecraftServer.getServer(); + } catch (NoSuchMethodError e) { + if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) { + return MinecraftClient.getInstance().getServer(); + } else { + return (MinecraftServer) FabricLoader.getInstance().getGameInstance(); + } + } + } +} diff --git a/legacy-fabric-permissions-api-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/permission/CommandBlockExecutorMixin.java b/legacy-fabric-permissions-api-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/permission/CommandBlockExecutorMixin.java new file mode 100644 index 000000000..c492b5cbd --- /dev/null +++ b/legacy-fabric-permissions-api-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/permission/CommandBlockExecutorMixin.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.permission; + +import org.spongepowered.asm.mixin.Mixin; + +import net.minecraft.block.entity.CommandBlockBlockEntity; + +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +@Mixin(CommandBlockBlockEntity.class) +public abstract class CommandBlockExecutorMixin implements PermissibleCommandSource { + @Override + public boolean hasPermission(String perm) { + return true; + } +} diff --git a/legacy-fabric-permissions-api-v1/1.6.4/src/main/resources/assets/legacy-fabric-permissions-api-v1/icon.png b/legacy-fabric-permissions-api-v1/1.6.4/src/main/resources/assets/legacy-fabric-permissions-api-v1/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2931efbf610873c0084debb8690902b0103d27fe GIT binary patch literal 1579 zcmbVMTWB0r7@iGm)TAXsYw<=rnU=;v=W=GRbL=!tc4Brl6GO7t2vVJ$IlDV#XU;e? z+r2ymsZdMQqAyaFLLUo;RumtE8Z@?uf_*4nP^4;o6fOFoSkN+o1$K?f2nE9_*b5G-l)AV)k5Qhb^- zU{V4ZnTKgnmXdpcB*Kg!W(1hvM2N&RO30x1u~eI9meGQGe@_?PDQq%q1CiV$8~M7 z?MQ_mOdqCh^a65Sv|ntwSXjV5se1;VK1|Kr8G7TQoQL&*ctt{L{fClG}xPK5k^yK3%T69N6J=>3jBqc zDNvZsrJ-yOXI^^mWf1cmY^XST)CVzIGjvEPENowmy}ax zvJ8_(Cf#+H-dBlH53`_u-~6BVAMz|(g?jCVdBWNZ(+A}(pFV7>S3QgPiQcMaflkIC z-3Ti|VT~{au*vq0ts9O&m$p&Gl=L6+q6_m$IcVq}o~+Pl{g>1esQp4%wp~|*zk1n` zZ7T6Toc4`y88s}riCP|ZXrJ?FLz@^KTcyqLjey zu95Yz%F&S{<0~f)Iomek?+hQ%MhCu%T^zsg>C_L`1`Br`xNY&))k9yTQb$JC>)w_f zpU(^tu^Q)y%W~lVz`jz;_ jF?g&s@Y=Qe&c#kW|JbvqK0Y=Rw)4XDoVqsk_>;c_`@;F@ literal 0 HcmV?d00001 diff --git a/legacy-fabric-permissions-api-v1/1.6.4/src/main/resources/fabric.mod.json b/legacy-fabric-permissions-api-v1/1.6.4/src/main/resources/fabric.mod.json new file mode 100644 index 000000000..7a960c2e7 --- /dev/null +++ b/legacy-fabric-permissions-api-v1/1.6.4/src/main/resources/fabric.mod.json @@ -0,0 +1,43 @@ +{ + "schemaVersion": 1, + "id": "legacy-fabric-permissions-api-v1", + "name": "Legacy Fabric Permissions API (v2)", + "version": "${version}", + "environment": "*", + "license": "Apache-2.0", + "icon": "assets/legacy-fabric-permissions-api-v1/icon.png", + "contact": { + "homepage": "https://legacy-fabric.github.io/", + "irc": "irc://irc.esper.net:6667/legacyfabric", + "issues": "https://github.com/Legacy-Fabric/fabric/issues", + "sources": "https://github.com/Legacy-Fabric/fabric" + }, + "authors": [ + "FabricMC" + ], + "entrypoints": { + "main": [ + "net.legacyfabric.fabric.impl.permission.PermissionImpl" + ] + }, + "depends": { + "fabricloader": ">=0.4.0", + "minecraft": "${minecraft_version}" + }, + "description": "Simple permission api", + "mixins": [ + "legacy-fabric-permissions-api-v1.mixins.json" + ], + "custom": { + "modmenu": { + "badges": [ "library" ], + "parent": { + "id": "legacy-fabric-api", + "name": "Legacy Fabric API", + "badges": [ "library" ], + "description": "Core API module providing key hooks and inter-compatibility features for Minecraft 1.7.10-1.12.2.", + "icon": "assets/legacy-fabric-permissions-api-v1/icon.png" + } + } + } +} diff --git a/legacy-fabric-permissions-api-v1/1.6.4/src/main/resources/legacy-fabric-permissions-api-v1.mixins.json b/legacy-fabric-permissions-api-v1/1.6.4/src/main/resources/legacy-fabric-permissions-api-v1.mixins.json new file mode 100644 index 000000000..c02686873 --- /dev/null +++ b/legacy-fabric-permissions-api-v1/1.6.4/src/main/resources/legacy-fabric-permissions-api-v1.mixins.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "net.legacyfabric.fabric.mixin.permission", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "CommandBlockExecutorMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/legacy-fabric-permissions-api-v1/1.8.9/gradle.properties b/legacy-fabric-permissions-api-v1/1.8.9/gradle.properties index d523a75a0..503076051 100644 --- a/legacy-fabric-permissions-api-v1/1.8.9/gradle.properties +++ b/legacy-fabric-permissions-api-v1/1.8.9/gradle.properties @@ -1,2 +1,2 @@ -minVersionIncluded=1.3 +minVersionIncluded=1.7.10 maxVersionIncluded=1.12.2 diff --git a/legacy-fabric-permissions-api-v1/1.8.9/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java b/legacy-fabric-permissions-api-v1/1.8.9/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java new file mode 100644 index 000000000..6d1861698 --- /dev/null +++ b/legacy-fabric-permissions-api-v1/1.8.9/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.permission; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.server.MinecraftServer; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.ModInitializer; +import net.fabricmc.loader.api.FabricLoader; + +import net.legacyfabric.fabric.api.permission.v1.PermissionsApiHolder; +import net.legacyfabric.fabric.api.permission.v1.PlayerPermissionsApi; + +public class PermissionImpl implements ModInitializer { + @Override + public void onInitialize() { + PermissionsApiHolder.setFallbackPlayerPermissionsApi(FallbackPlayerPermissionsApi.INSTANCE); + } + + private enum FallbackPlayerPermissionsApi implements PlayerPermissionsApi { + INSTANCE; + + @Override + public String getId() { + return "legacy-fabric-fallback-permissions-api"; + } + + @Override + public boolean hasPermission(ServerPlayerEntity player, String perm) { + return getServer().getPlayerManager().isOperator(player.getGameProfile()); + } + } + + protected static MinecraftServer getServer() { + try { + return MinecraftServer.getServer(); + } catch (NoSuchMethodError e) { + if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) { + return MinecraftClient.getInstance().getServer(); + } else { + return (MinecraftServer) FabricLoader.getInstance().getGameInstance(); + } + } + } +} diff --git a/legacy-fabric-permissions-api-v1/1.8.9/src/main/resources/fabric.mod.json b/legacy-fabric-permissions-api-v1/1.8.9/src/main/resources/fabric.mod.json index 919f98876..7a960c2e7 100644 --- a/legacy-fabric-permissions-api-v1/1.8.9/src/main/resources/fabric.mod.json +++ b/legacy-fabric-permissions-api-v1/1.8.9/src/main/resources/fabric.mod.json @@ -15,6 +15,11 @@ "authors": [ "FabricMC" ], + "entrypoints": { + "main": [ + "net.legacyfabric.fabric.impl.permission.PermissionImpl" + ] + }, "depends": { "fabricloader": ">=0.4.0", "minecraft": "${minecraft_version}" diff --git a/legacy-fabric-permissions-api-v1/1.8.9/src/main/resources/legacy-fabric-permissions-api-v1.mixins.json b/legacy-fabric-permissions-api-v1/1.8.9/src/main/resources/legacy-fabric-permissions-api-v1.mixins.json index 8f85c2ebd..f01ad87f9 100644 --- a/legacy-fabric-permissions-api-v1/1.8.9/src/main/resources/legacy-fabric-permissions-api-v1.mixins.json +++ b/legacy-fabric-permissions-api-v1/1.8.9/src/main/resources/legacy-fabric-permissions-api-v1.mixins.json @@ -5,10 +5,7 @@ "mixins": [ "CommandBlockExecutorMixin", "CommandStats_1Mixin", - "ConsoleMixin", - "EntityMixin", "ExecuteCommand_1Mixin", - "ServerPlayerEntityMixin", "SignBlockEntity_1Mixin", "SignBlockEntity_2Mixin" ], diff --git a/legacy-fabric-permissions-api-v1/common/src/main/java/net/legacyfabric/fabric/api/permission/v1/PermissionsApiHolder.java b/legacy-fabric-permissions-api-v1/common/src/main/java/net/legacyfabric/fabric/api/permission/v1/PermissionsApiHolder.java index 46b3821bd..98a1cbc54 100644 --- a/legacy-fabric-permissions-api-v1/common/src/main/java/net/legacyfabric/fabric/api/permission/v1/PermissionsApiHolder.java +++ b/legacy-fabric-permissions-api-v1/common/src/main/java/net/legacyfabric/fabric/api/permission/v1/PermissionsApiHolder.java @@ -19,13 +19,6 @@ import org.jetbrains.annotations.ApiStatus; -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.server.MinecraftServer; - -import net.fabricmc.api.EnvType; -import net.fabricmc.loader.api.FabricLoader; - import net.legacyfabric.fabric.api.logger.v1.Logger; import net.legacyfabric.fabric.impl.logger.LoggerImpl; @@ -37,6 +30,7 @@ public class PermissionsApiHolder { private static final Logger LOGGER = Logger.get(LoggerImpl.API, "PermissionApiHolder"); private static PlayerPermissionsApi PLAYER_PERMISSIONS_API = null; + private static PlayerPermissionsApi FALLBACK_PLAYER_PERMISSIONS_API = null; public static boolean setPlayerPermissionsApi(PlayerPermissionsApi api) { if (PLAYER_PERMISSIONS_API == null) { @@ -49,32 +43,11 @@ public static boolean setPlayerPermissionsApi(PlayerPermissionsApi api) { } public static PlayerPermissionsApi getPlayerPermissionsApi() { - return PLAYER_PERMISSIONS_API != null ? PLAYER_PERMISSIONS_API : FallbackPlayerPermissionsApi.INSTANCE; + return PLAYER_PERMISSIONS_API != null ? PLAYER_PERMISSIONS_API : FALLBACK_PLAYER_PERMISSIONS_API; } - private enum FallbackPlayerPermissionsApi implements PlayerPermissionsApi { - INSTANCE; - - @Override - public String getId() { - return "legacy-fabric-fallback-permissions-api"; - } - - @Override - public boolean hasPermission(ServerPlayerEntity player, String perm) { - return getServer().getPlayerManager().isOperator(player.getGameProfile()); - } - } - - protected static MinecraftServer getServer() { - try { - return MinecraftServer.getServer(); - } catch (NoSuchMethodError e) { - if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) { - return MinecraftClient.getInstance().getServer(); - } else { - return (MinecraftServer) FabricLoader.getInstance().getGameInstance(); - } - } + @ApiStatus.Internal + public static void setFallbackPlayerPermissionsApi(PlayerPermissionsApi api) { + FALLBACK_PLAYER_PERMISSIONS_API = api; } } diff --git a/legacy-fabric-permissions-api-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/permission/ConsoleMixin.java b/legacy-fabric-permissions-api-v1/common/src/main/java/net/legacyfabric/fabric/mixin/permission/ConsoleMixin.java similarity index 100% rename from legacy-fabric-permissions-api-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/permission/ConsoleMixin.java rename to legacy-fabric-permissions-api-v1/common/src/main/java/net/legacyfabric/fabric/mixin/permission/ConsoleMixin.java diff --git a/legacy-fabric-permissions-api-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/permission/EntityMixin.java b/legacy-fabric-permissions-api-v1/common/src/main/java/net/legacyfabric/fabric/mixin/permission/EntityMixin.java similarity index 100% rename from legacy-fabric-permissions-api-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/permission/EntityMixin.java rename to legacy-fabric-permissions-api-v1/common/src/main/java/net/legacyfabric/fabric/mixin/permission/EntityMixin.java diff --git a/legacy-fabric-permissions-api-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/permission/ServerPlayerEntityMixin.java b/legacy-fabric-permissions-api-v1/common/src/main/java/net/legacyfabric/fabric/mixin/permission/ServerPlayerEntityMixin.java similarity index 100% rename from legacy-fabric-permissions-api-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/permission/ServerPlayerEntityMixin.java rename to legacy-fabric-permissions-api-v1/common/src/main/java/net/legacyfabric/fabric/mixin/permission/ServerPlayerEntityMixin.java diff --git a/legacy-fabric-permissions-api-v1/common/src/main/resources/fabric.mod.json b/legacy-fabric-permissions-api-v1/common/src/main/resources/fabric.mod.json index ebf36e9a6..af01052bc 100644 --- a/legacy-fabric-permissions-api-v1/common/src/main/resources/fabric.mod.json +++ b/legacy-fabric-permissions-api-v1/common/src/main/resources/fabric.mod.json @@ -20,7 +20,9 @@ "minecraft": "${minecraft_version}" }, "description": "Simple permission api", - "mixins": [], + "mixins": [ + "legacy-fabric-permissions-api-v1-common.mixins.json" + ], "custom": { "modmenu": { "badges": [ "library" ], diff --git a/legacy-fabric-permissions-api-v1/common/src/main/resources/legacy-fabric-permissions-api-v1-common.mixins.json b/legacy-fabric-permissions-api-v1/common/src/main/resources/legacy-fabric-permissions-api-v1-common.mixins.json new file mode 100644 index 000000000..a982b0f48 --- /dev/null +++ b/legacy-fabric-permissions-api-v1/common/src/main/resources/legacy-fabric-permissions-api-v1-common.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "package": "net.legacyfabric.fabric.mixin.permission", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "ConsoleMixin", + "EntityMixin", + "ServerPlayerEntityMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} From da5a3a94d9c2b9a03dfcc1e429e7592ef4c9019d Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sun, 5 May 2024 14:20:08 +0200 Subject: [PATCH 12/24] Barebone port of command api v2 (sponge) to 1.6.4 --- README.md | 34 +- .../1.6.4/build.gradle | 0 .../1.6.4/gradle.properties | 2 + .../api/command/v2/CommandRegistrar.java | 42 + .../fabric/api/command/v2/Selector.java | 109 ++ .../fabric/api/command/v2/StringType.java | 36 + .../v2/lib/sponge/CommandCallable.java | 120 +++ .../v2/lib/sponge/CommandException.java | 84 ++ .../command/v2/lib/sponge/CommandManager.java | 139 +++ .../command/v2/lib/sponge/CommandMapping.java | 56 ++ .../lib/sponge/CommandMessageFormatting.java | 54 + .../lib/sponge/CommandNotFoundException.java | 61 ++ .../sponge/CommandPermissionException.java | 54 + .../command/v2/lib/sponge/CommandResult.java | 271 +++++ .../lib/sponge/ImmutableCommandMapping.java | 109 ++ .../sponge/InvocationCommandException.java | 38 + .../v2/lib/sponge/TextMessageException.java | 90 ++ .../sponge/args/ArgumentParseException.java | 150 +++ .../args/ChildCommandElementExecutor.java | 276 +++++ .../v2/lib/sponge/args/CommandArgs.java | 339 +++++++ .../v2/lib/sponge/args/CommandContext.java | 328 ++++++ .../v2/lib/sponge/args/CommandElement.java | 123 +++ .../v2/lib/sponge/args/CommandFlags.java | 543 ++++++++++ .../v2/lib/sponge/args/GenericArguments.java | 949 ++++++++++++++++++ .../v2/lib/sponge/args/KeyElement.java | 40 + .../args/PatternMatchingCommandElement.java | 142 +++ .../sponge/args/SelectorCommandElement.java | 65 ++ .../sponge/args/parsing/InputTokenizer.java | 73 ++ .../args/parsing/QuotedStringTokenizer.java | 164 +++ .../args/parsing/RawStringInputTokenizer.java | 33 + .../v2/lib/sponge/args/parsing/SingleArg.java | 100 ++ .../parsing/SpaceSplitInputTokenizer.java | 57 ++ .../sponge/args/parsing/TokenizerState.java | 66 ++ .../lib/sponge/dispatcher/Disambiguator.java | 40 + .../v2/lib/sponge/dispatcher/Dispatcher.java | 115 +++ .../sponge/dispatcher/SimpleDispatcher.java | 459 +++++++++ .../v2/lib/sponge/spec/CommandExecutor.java | 41 + .../v2/lib/sponge/spec/CommandSpec.java | 491 +++++++++ .../impl/command/CommandManagerImpl.java | 258 +++++ .../fabric/impl/command/CommandWrapper.java | 123 +++ .../fabric/impl/command/ImplInit.java | 46 + .../fabric/impl/command/InternalObjects.java | 28 + .../lib/sponge/args/AllOfCommandElement.java | 83 ++ .../lib/sponge/args/BigDecimalElement.java | 47 + .../lib/sponge/args/BigIntegerElement.java | 47 + .../sponge/args/ChoicesCommandElement.java | 90 ++ .../lib/sponge/args/DateTimeElement.java | 94 ++ .../lib/sponge/args/DurationElement.java | 66 ++ .../lib/sponge/args/EntityCommandElement.java | 164 +++ .../lib/sponge/args/EnumValueElement.java | 60 ++ .../args/FilteredSuggestionsElement.java | 53 + .../args/FirstParsingCommandElement.java | 101 ++ .../command/lib/sponge/args/IpElement.java | 57 ++ .../sponge/args/LiteralCommandElement.java | 85 ++ .../sponge/args/MarkTrueCommandElement.java | 50 + .../lib/sponge/args/ModCommandElement.java | 48 + .../lib/sponge/args/NumericElement.java | 63 ++ .../sponge/args/OnlyOneCommandElement.java | 65 ++ .../sponge/args/OptionalCommandElement.java | 94 ++ .../sponge/args/PermissionCommandElement.java | 92 ++ .../lib/sponge/args/PlayerCommandElement.java | 92 ++ .../RemainingJoinedStringsCommandElement.java | 62 ++ .../sponge/args/RepeatedCommandElement.java | 73 ++ .../sponge/args/SequenceCommandElement.java | 125 +++ .../lib/sponge/args/StringCommandElement.java | 45 + .../lib/sponge/args/StringElement.java | 36 + .../command/lib/sponge/args/UrlElement.java | 58 ++ .../command/lib/sponge/args/UuidElement.java | 45 + .../lib/sponge/args/Vec3dCommandElement.java | 133 +++ .../sponge/args/WithSuggestionsElement.java | 61 ++ .../mixin/command/ChatMessageAccessor.java | 29 + .../mixin/command/MinecraftServerMixin.java | 36 + .../icon.png | Bin 0 -> 1579 bytes .../1.6.4/src/main/resources/fabric.mod.json | 46 + ...y-fabric-sponge-command-api-v2.mixins.json | 12 + .../test/command/ModMetadataCommand.java | 74 ++ .../test/command/SpongeCommandTest.java | 31 + .../src/testmod/resources/fabric.mod.json | 14 + 78 files changed, 8662 insertions(+), 17 deletions(-) create mode 100644 legacy-fabric-command-api-v2/1.6.4/build.gradle create mode 100644 legacy-fabric-command-api-v2/1.6.4/gradle.properties create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/CommandRegistrar.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/Selector.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/StringType.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandCallable.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandException.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandManager.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMapping.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMessageFormatting.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandNotFoundException.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandPermissionException.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandResult.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/ImmutableCommandMapping.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/InvocationCommandException.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/TextMessageException.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ArgumentParseException.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ChildCommandElementExecutor.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandArgs.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandContext.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandFlags.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/GenericArguments.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/KeyElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/PatternMatchingCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/SelectorCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/InputTokenizer.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/QuotedStringTokenizer.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/RawStringInputTokenizer.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SingleArg.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SpaceSplitInputTokenizer.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/TokenizerState.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Disambiguator.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Dispatcher.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/SimpleDispatcher.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandExecutor.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandSpec.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandManagerImpl.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandWrapper.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/ImplInit.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/InternalObjects.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/AllOfCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigDecimalElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigIntegerElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ChoicesCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DateTimeElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DurationElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EntityCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EnumValueElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FilteredSuggestionsElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FirstParsingCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/IpElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/LiteralCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/MarkTrueCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ModCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/NumericElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OnlyOneCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OptionalCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PermissionCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PlayerCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RemainingJoinedStringsCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RepeatedCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/SequenceCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UrlElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UuidElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/Vec3dCommandElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/WithSuggestionsElement.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/ChatMessageAccessor.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/MinecraftServerMixin.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/resources/assets/legacy-fabric-sponge-command-api-v2/icon.png create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/resources/fabric.mod.json create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/resources/legacy-fabric-sponge-command-api-v2.mixins.json create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommand.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/SpongeCommandTest.java create mode 100644 legacy-fabric-command-api-v2/1.6.4/src/testmod/resources/fabric.mod.json diff --git a/README.md b/README.md index 7e3b8691e..84a0f0be5 100644 --- a/README.md +++ b/README.md @@ -14,20 +14,20 @@ For support, consider joining the [Legacy Fabric discord server](https://legacyf ? = Not sure if it was tested or working correctly\ ❌ = Not working at all, likely crashing -| | 1.6.4 | 1.7.10 | 1.8 | 1.8.9 | 1.9.4 | 1.10.2 | 1.11.2 | 1.12.2 | 1.13.2 | -|----------------------|-------|--------|-----|-------|-------|--------|--------|--------|--------| -| api-base | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| command-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| command-api-v2 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| crash-report-info-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| entity-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| gamerule-api-v1 | ? | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ? | -| item-groups-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| keybindings-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| lifecycle-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| logger-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| networking-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| permissions-api-v1 | ? | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| registry-sync-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| rendering-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| resource-loader-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| | 1.6.4 | 1.7.10 | 1.8 | 1.8.9 | 1.9.4 | 1.10.2 | 1.11.2 | 1.12.2 | 1.13.2 | +|----------------------|------------------------------------|--------|-----|-------|-------|--------|--------|--------|--------| +| api-base | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| command-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| command-api-v2 | ⚠
Text formatting need rework | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| crash-report-info-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| entity-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| gamerule-api-v1 | ? | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ? | +| item-groups-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| keybindings-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| lifecycle-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| logger-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| networking-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| permissions-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| registry-sync-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| rendering-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| resource-loader-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | diff --git a/legacy-fabric-command-api-v2/1.6.4/build.gradle b/legacy-fabric-command-api-v2/1.6.4/build.gradle new file mode 100644 index 000000000..e69de29bb diff --git a/legacy-fabric-command-api-v2/1.6.4/gradle.properties b/legacy-fabric-command-api-v2/1.6.4/gradle.properties new file mode 100644 index 000000000..bff6c84c0 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/gradle.properties @@ -0,0 +1,2 @@ +minVersionIncluded=1.6.4 +maxVersionIncluded=1.6.4 diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/CommandRegistrar.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/CommandRegistrar.java new file mode 100644 index 000000000..c81a2e7d7 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/CommandRegistrar.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandManager; +import net.legacyfabric.fabric.api.event.Event; +import net.legacyfabric.fabric.api.event.EventFactory; + +/** + * An entrypoint and event for registering commands to the {@link CommandManager}. + */ +@FunctionalInterface +public interface CommandRegistrar { + Event EVENT = EventFactory.createArrayBacked(CommandRegistrar.class, listeners -> (manager, dedicated) -> { + for (CommandRegistrar registrar : listeners) { + registrar.register(manager, dedicated); + } + }); + + /** + * Register your commands here. + * + * @param manager The command manager + * @param dedicated Whether the mod is running on a dedicated server + */ + void register(CommandManager manager, boolean dedicated); +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/Selector.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/Selector.java new file mode 100644 index 000000000..d17d16814 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/Selector.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Sets; + +import net.minecraft.command.CommandSource; +import net.minecraft.entity.Entity; +import net.minecraft.server.MinecraftServer; + +public enum Selector { + ALL_ENTITIES('e') { + @Override + public Set resolve(CommandSource sender) { + return Sets.newHashSet(sender.getWorld().entities); + } + }, + ALL_PLAYERS('a') { + @Override + public Set resolve(CommandSource sender) { + return (Set) sender.getWorld().playerEntities.stream().map(e -> (Entity) e).collect(Collectors.toSet()); + } + }, + NEAREST_PLAYER('p') { + @Override + public Set resolve(CommandSource sender) { + return Sets.newHashSet(sender.getWorld().getClosestPlayer(sender.method_4086().x, sender.method_4086().y, sender.method_4086().z, 50.0D)); + } + }, + RANDOM_PLAYER('r') { + @Override + public Set resolve(CommandSource sender) { + try { + return Sets.newHashSet((Entity) MinecraftServer.getServer().getPlayerManager().players.stream().findAny().orElseThrow(NullPointerException::new)); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + }, + EXECUTING_ENTITY('s') { + @Override + public Set resolve(CommandSource sender) { + //TODO @s didn't exist this early in the game's development, and there seems to be no code to handle it, so maybe this'll work? + return Sets.newHashSet(sender.getWorld().getPlayerByName(sender.getUsername())); + } + }; + + private final char key; + private static final Map MAP; + + Selector(char key) { + this.key = key; + } + + public char getKey() { + return this.key; + } + + public abstract Set resolve(CommandSource sender); + + public static List complete(String s) { + if (s.startsWith("@") && s.length() == 2) { + return Arrays.stream(values()).map(Selector::getKey).map(String::valueOf).distinct().collect(Collectors.toList()); + } + + return ImmutableList.of(); + } + + public static Selector parse(String value) { + if (MAP.containsKey(value)) { + return MAP.get(value); + } + + throw new IllegalArgumentException("Unknown selector"); + } + + static { + ImmutableMap.Builder builder = ImmutableMap.builder(); + + for (Selector s : values()) { + builder.put("@" + s.getKey(), s); + } + + MAP = builder.build(); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/StringType.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/StringType.java new file mode 100644 index 000000000..f294fb603 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/StringType.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2; + +/** + * Specifies a method to parse {@link String}s in a command. + */ +public enum StringType { + SINGLE_WORD(false), + GREEDY_PHRASE(true); + + private final boolean all; + + StringType(boolean all) { + this.all = all; + } + + public boolean isAll() { + return this.all; + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandCallable.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandCallable.java new file mode 100644 index 000000000..fbcffdb4a --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandCallable.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge; + +import java.util.List; +import java.util.Optional; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; +import net.minecraft.world.World; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.spec.CommandSpec; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; +import net.legacyfabric.fabric.api.util.Location; + +/** + * A low-level interface for commands that can be executed. For almost all use + * cases, higher-level tools should be used instead, like {@link CommandSpec}. + * + *

Implementations are not required to implement a sane + * {@link Object#equals(Object)} but really should.

+ */ +public interface CommandCallable { + /** + * Execute the command based on input arguments. + * + *

The implementing class must perform the necessary permission + * checks.

+ * + * @param source The caller of the command + * @param arguments The raw arguments for this command + * @return The result of a command being processed + * @throws CommandException Thrown on a command error + */ + CommandResult process(PermissibleCommandSource source, String arguments) throws CommandException; + + /** + * Gets a list of suggestions based on input. + * + *

If a suggestion is chosen by the user, it will replace the last + * word.

+ * + * @param source The command source + * @param arguments The arguments entered up to this point + * @param targetPosition The position the source is looking at when + * performing tab completion + * @return A list of suggestions + * @throws CommandException Thrown if there was a parsing error + */ + List getSuggestions(PermissibleCommandSource source, String arguments, @Nullable Location targetPosition) throws CommandException; + + /** + * Test whether this command can probably be executed by the given source. + * + *

If implementations are unsure if the command can be executed by + * the source, {@code true} should be returned. Return values of this method + * may be used to determine whether this command is listed in command + * listings.

+ * + * @param source The caller of the command + * @return Whether permission is (probably) granted + */ + boolean testPermission(PermissibleCommandSource source); + + /** + * Gets a short one-line description of this command. + * + *

The help system may display the description in the command list.

+ * + * @param source The source of the help request + * @return A description + */ + Optional getShortDescription(PermissibleCommandSource source); + + /** + * Gets a longer formatted help message about this command. + * + *

It is recommended to use the default text color and style. Sections + * with text actions (e.g. hyperlinks) should be underlined.

+ * + *

Multi-line messages can be created by separating the lines with + * {@code \n}.

+ * + *

The help system may display this message when a source requests + * detailed information about a command.

+ * + * @param source The source of the help request + * @return A help text + */ + Optional getHelp(PermissibleCommandSource source); + + /** + * Gets the usage string of this command. + * + *

A usage string may look like + * {@code [-w <world>] <var1> <var2>}.

+ * + *

The string must not contain the command alias.

+ * + * @param source The source of the help request + * @return A usage string + */ + ChatMessage getUsage(PermissibleCommandSource source); +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandException.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandException.java new file mode 100644 index 000000000..44190ca1f --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandException.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge; + +import net.minecraft.text.ChatMessage; + +/** + * Thrown when an executed command raises an error or when execution of + * the command failed. + */ +public class CommandException extends TextMessageException { + private static final long serialVersionUID = 4626722485860074825L; + + private final boolean includeUsage; + + /** + * Constructs a new {@link CommandException} with the given message. + * + * @param message The detail message + */ + public CommandException(ChatMessage message) { + this(message, false); + } + + /** + * Constructs a new {@link CommandException} with the given message and + * the given cause. + * + * @param message The detail message + * @param cause The cause + */ + public CommandException(ChatMessage message, Throwable cause) { + this(message, cause, false); + } + + /** + * Constructs a new {@link CommandException} with the given message. + * + * @param message The detail message + * @param includeUsage Whether to include usage in the exception + */ + public CommandException(ChatMessage message, boolean includeUsage) { + super(message); + this.includeUsage = includeUsage; + } + + /** + * Constructs a new {@link CommandException} with the given message and + * the given cause. + * + * @param message The detail message + * @param cause The cause + * @param includeUsage Whether to include the usage in the exception + */ + public CommandException(ChatMessage message, Throwable cause, boolean includeUsage) { + super(message, cause); + this.includeUsage = includeUsage; + } + + /** + * Gets whether the exception should include usage in + * the presentation of the exception/stack-trace. + * + * @return Whether to include usage in the exception + */ + public boolean shouldIncludeUsage() { + return this.includeUsage; + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandManager.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandManager.java new file mode 100644 index 000000000..8004c9a72 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandManager.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge; + +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.world.World; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher.Dispatcher; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; +import net.legacyfabric.fabric.api.util.Location; + +/** + * A command dispatcher watches for commands (such as those said in chat) + * and dispatches them to the correct command handler. + */ +public interface CommandManager extends Dispatcher { + /** + * Register a given command using the given list of aliases. + * + *

If there is a conflict with one of the aliases (i.e. that alias + * is already assigned to another command), then the alias will be skipped. + * It is possible for there to be no alias to be available out of + * the provided list of aliases, which would mean that the command would not + * be assigned to any aliases.

+ * + *

The first non-conflicted alias becomes the "primary alias."

+ * + * @param callable The command + * @param alias An array of aliases + * @return The registered command mapping, unless no aliases could be + * registered + */ + Optional register(CommandCallable callable, String... alias); + + /** + * Register a given command using the given list of aliases. + * + *

If there is a conflict with one of the aliases (i.e. that alias + * is already assigned to another command), then the alias will be skipped. + * It is possible for there to be no alias to be available out of + * the provided list of aliases, which would mean that the command would + * not be assigned to any aliases.

+ * + *

The first non-conflicted alias becomes the "primary alias."

+ * + * @param callable The command + * @param aliases A list of aliases + * @return The registered command mapping, unless no aliases could be + * registered + * @throws IllegalArgumentException Thrown if {@code plugin} is not a + * plugin instance + */ + Optional register(CommandCallable callable, List aliases); + + /** + * Register a given command using a given list of aliases. + * + *

The provided callback function will be called with a list of aliases + * that are not taken (from the list of aliases that were requested) and + * it should return a list of aliases to actually register. Aliases may be + * removed, and if no aliases remain, then the command will not be + * registered. It may be possible that no aliases are available, and thus + * the callback would receive an empty list. New aliases should not be added + * to the list in the callback as this may cause + * {@link IllegalArgumentException} to be thrown.

+ * + *

The first non-conflicted alias becomes the "primary alias."

+ * + * @param callable The command + * @param aliases A list of aliases + * @param callback The callback + * @return The registered command mapping, unless no aliases could be + * registered + * @throws IllegalArgumentException Thrown if new conflicting aliases are + * added in the callback + */ + Optional register(CommandCallable callable, List aliases, Function, List> callback); + + /** + * Remove a command identified by the given mapping. + * + * @param mapping The mapping + * @return The previous mapping associated with the alias, if one was found + */ + Optional removeMapping(CommandMapping mapping); + + /** + * Gets the number of registered aliases. + * + * @return The number of aliases + */ + int size(); + + /** + * Execute the command based on input arguments. + * + *

The implementing class must perform the necessary permission + * checks.

+ * + * @param source The caller of the command + * @param arguments The raw arguments for this command + * @return The result of a command being processed + */ + @Override + CommandResult process(PermissibleCommandSource source, String arguments); + + /** + * Gets a list of suggestions based on input. + * + *

If a suggestion is chosen by the user, it will replace the last + * word.

+ * + * @param source The command source + * @param arguments The arguments entered up to this point + * @return A list of suggestions + */ + @Override + List getSuggestions(PermissibleCommandSource source, String arguments, @Nullable Location targetPosition); +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMapping.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMapping.java new file mode 100644 index 000000000..500a26515 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMapping.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge; + +import java.util.Set; + +/** + * Provides information about a mapping between a command and its aliases. + * + *

Implementations are not required to implement a sane + * {@link Object#equals(Object)} but may choose to do so.

+ */ +public interface CommandMapping { + /** + * Gets the primary alias. + * + * @return The primary alias + */ + String getPrimaryAlias(); + + /** + * Gets an immutable list of all aliases. + * + *

The returned list must contain at least one entry, of which one must + * be the one returned by {@link #getPrimaryAlias()}.

+ * + *

There may be several versions of the same alias with different + * casing, although generally implementations should ignore the casing + * of aliases.

+ * + * @return A set of aliases + */ + Set getAllAliases(); + + /** + * Gets the callable. + * + * @return The callable + */ + CommandCallable getCallable(); +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMessageFormatting.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMessageFormatting.java new file mode 100644 index 000000000..e172fe9a7 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMessageFormatting.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge; + +import net.minecraft.text.ChatMessage; +import net.minecraft.util.Formatting; + +public class CommandMessageFormatting { + private CommandMessageFormatting() { + } + + public static final ChatMessage PIPE_TEXT = ChatMessage.createTextMessage("|"); + public static final ChatMessage SPACE_TEXT = ChatMessage.createTextMessage(" "); + public static final ChatMessage STAR_TEXT = ChatMessage.createTextMessage("*"); + public static final ChatMessage LT_TEXT = ChatMessage.createTextMessage("<"); + public static final ChatMessage GT_TEXT = ChatMessage.createTextMessage(">"); + public static final ChatMessage ELLIPSIS_TEXT = ChatMessage.createTextMessage("…"); + + /** + * Format text to be output as an error directly to a sender. Not necessary + * when creating an exception to be thrown + * + * @param error The error message + * @return The formatted error message. + */ + public static ChatMessage error(ChatMessage error) { + return error.setColor(Formatting.RED); + } + + /** + * Format text to be output as a debug message directly to a sender. + * + * @param debug The debug message + * @return The formatted debug message. + */ + public static ChatMessage debug(ChatMessage debug) { + return debug.setColor(Formatting.GRAY); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandNotFoundException.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandNotFoundException.java new file mode 100644 index 000000000..fdf65e9b7 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandNotFoundException.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge; + +import com.google.common.base.Preconditions; + +import net.minecraft.text.ChatMessage; + +/** + * This exception is thrown when a sender tries to execute a command that does + * not exist. + */ +public class CommandNotFoundException extends CommandException { + private static final long serialVersionUID = -7714518367616848051L; + + private final String command; + + /** + * Create an exception with the default message. + * + * @param command The command that was queried for + */ + public CommandNotFoundException(String command) { + this(ChatMessage.createTextMessage("No such command"), command); + } + + /** + * Create an exception with a custom message. + * + * @param message The message + * @param command The command that was queried for + */ + public CommandNotFoundException(ChatMessage message, String command) { + super(message); + this.command = Preconditions.checkNotNull(command, "command"); + } + + /** + * Returns the command that was queried for. + * + * @return The command + */ + public String getCommand() { + return this.command; + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandPermissionException.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandPermissionException.java new file mode 100644 index 000000000..7b6ea274b --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandPermissionException.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge; + +import net.minecraft.text.ChatMessage; + +/** + * This exception is thrown when a subject does not have permission to execute + * a command. + */ +public class CommandPermissionException extends CommandException { + private static final long serialVersionUID = -6057386975881181213L; + + /** + * Create an exception with the default message. + */ + public CommandPermissionException() { + this(ChatMessage.createTextMessage("You do not have permission to use this command!")); + } + + /** + * Create a permissions exception with a custom message. + * + * @param message The message + */ + public CommandPermissionException(ChatMessage message) { + super(message); + } + + /** + * Create a permissions exception with a custom message and cause. + * + * @param message the message + * @param cause the cause + */ + public CommandPermissionException(ChatMessage message, Throwable cause) { + super(message, cause); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandResult.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandResult.java new file mode 100644 index 000000000..3637eb2c9 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandResult.java @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge; + +import java.util.Optional; + +import org.jetbrains.annotations.Nullable; + +/** + * Represents the result of a command in Sponge. + */ +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class CommandResult { + private static final CommandResult EMPTY = builder().build(); + private static final CommandResult SUCCESS = builder().successCount(1).build(); + private final Optional successCount; + private final Optional affectedBlocks; + private final Optional affectedEntities; + private final Optional affectedItems; + private final Optional queryResult; + + /** + * Returns a {@link Builder}. + * + * @return A new command result builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Returns a new {@link CommandResult} indicating that a command was + * processed. + * + * @return The command result + */ + public static CommandResult empty() { + return EMPTY; + } + + /** + * Returns a result indicating the command was processed with a single + * success. + * + * @return The result + */ + public static CommandResult success() { + return SUCCESS; + } + + /** + * Returns a result indicating the command was processed with a single + * success. + * + * @param count The success count + * @return The result + */ + public static CommandResult successCount(int count) { + return builder().successCount(count).build(); + } + + /** + * Returns a result indicating the command was processed with an + * amount of affected blocks. + * + * @param count The amount of blocks affected + * @return The result + */ + public static CommandResult affectedBlocks(int count) { + return builder().affectedBlocks(count).build(); + } + + /** + * Returns a result indicating the command was processed with an + * amount of affected entities. + * + * @param count The amount of entities affected + * @return The result + */ + public static CommandResult affectedEntities(int count) { + return builder().affectedEntities(count).build(); + } + + /** + * Returns a result indicating the command was processed with an + * amount of affected items. + * + * @param count The amount of items affected + * @return The result + */ + public static CommandResult affectedItems(int count) { + return builder().affectedItems(count).build(); + } + + /** + * Returns a result indicating the command was processed with an + * amount of queries. + * + * @param count The amount of queries + * @return The result + */ + public static CommandResult queryResult(int count) { + return builder().queryResult(count).build(); + } + + /** + * Constructs a new command result. + * + * @param successCount The success count + * @param affectedBlocks The number of affected blocks + * @param affectedEntities The number of affected entities + * @param affectedItems The number of affected items + * @param queryResult The query result + */ + CommandResult(@Nullable Integer successCount, @Nullable Integer affectedBlocks, @Nullable Integer affectedEntities, @Nullable Integer affectedItems, @Nullable Integer queryResult) { + this.successCount = Optional.ofNullable(successCount); + this.affectedBlocks = Optional.ofNullable(affectedBlocks); + this.affectedEntities = Optional.ofNullable(affectedEntities); + this.affectedItems = Optional.ofNullable(affectedItems); + this.queryResult = Optional.ofNullable(queryResult); + } + + /** + * Gets the success count of the command. + * + * @return The success count of the command + */ + public Optional getSuccessCount() { + return this.successCount; + } + + /** + * Gets the number of blocks affected by the command. + * + * @return The number of blocks affected by the command, if such a count + * exists + */ + public Optional getAffectedBlocks() { + return this.affectedBlocks; + } + + /** + * Gets the number of entities affected by the command. + * + * @return The number of entities affected by the command, if such a count + * exists + */ + public Optional getAffectedEntities() { + return this.affectedEntities; + } + + /** + * Gets the number of items affected by the command. + * + * @return The number of items affected by the command, if such a count + * exists + */ + public Optional getAffectedItems() { + return this.affectedItems; + } + + /** + * Gets the query result of the command, e.g. the time of the day, + * an amount of money or a player's amount of XP. + * + * @return The query result of the command, if one exists + */ + public Optional getQueryResult() { + return this.queryResult; + } + + /** + * A builder for {@link CommandResult}s. + */ + public static class Builder { + @Nullable + private Integer successCount; + @Nullable + private Integer affectedBlocks; + @Nullable + private Integer affectedEntities; + @Nullable + private Integer affectedItems; + @Nullable + private Integer queryResult; + + Builder() { + } + + /** + * Sets if the command has been processed. + * + * @param successCount If the command has been processed + * @return This builder, for chaining + */ + public Builder successCount(@Nullable Integer successCount) { + this.successCount = successCount; + return this; + } + + /** + * Sets the amount of blocks affected by the command. + * + * @param affectedBlocks The amount of blocks affected by the command + * @return This builder, for chaining + */ + public Builder affectedBlocks(@Nullable Integer affectedBlocks) { + this.affectedBlocks = affectedBlocks; + return this; + } + + /** + * Sets the amount of entities affected by the command. + * + * @param affectedEntities The amount of entities affected by the + * command + * @return This builder, for chaining + */ + public Builder affectedEntities(@Nullable Integer affectedEntities) { + this.affectedEntities = affectedEntities; + return this; + } + + /** + * Sets the amount of items affected by the command. + * + * @param affectedItems The amount of items affected by the command + * @return This builder, for chaining + */ + public Builder affectedItems(@Nullable Integer affectedItems) { + this.affectedItems = affectedItems; + return this; + } + + /** + * Sets the query result of the command, e.g. the time of the day, + * an amount of money or a player's amount of XP. + * + * @param queryResult The query result of the command + * @return This builder, for chaining + */ + public Builder queryResult(@Nullable Integer queryResult) { + this.queryResult = queryResult; + return this; + } + + /** + * Builds the {@link CommandResult}. + * + * @return A CommandResult with the specified settings + */ + public CommandResult build() { + return new CommandResult(this.successCount, this.affectedBlocks, this.affectedEntities, this.affectedItems, this.queryResult); + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/ImmutableCommandMapping.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/ImmutableCommandMapping.java new file mode 100644 index 000000000..a02b51051 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/ImmutableCommandMapping.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; + +/** + * An immutable command mapping instance that returns the same objects that + * this instance is constructed with. + */ +public final class ImmutableCommandMapping implements CommandMapping { + private final String primary; + private final Set aliases; + private final CommandCallable callable; + + /** + * Create a new instance. + * + * @param callable The command callable + * @param primary The primary alias + * @param alias A list of all aliases + * @throws IllegalArgumentException Thrown if aliases are duplicated + */ + public ImmutableCommandMapping(CommandCallable callable, String primary, String... alias) { + this(callable, primary, Arrays.asList(Preconditions.checkNotNull(alias, "alias"))); + } + + /** + * Create a new instance. + * + * @param callable The command callable + * @param primary The primary alias + * @param aliases A collection of all aliases + * @throws IllegalArgumentException Thrown if aliases are duplicated + */ + public ImmutableCommandMapping(CommandCallable callable, String primary, Collection aliases) { + Preconditions.checkNotNull(primary, "primary"); + Preconditions.checkNotNull(aliases, "aliases"); + this.primary = primary; + this.aliases = new HashSet<>(aliases); + this.aliases.add(primary); + this.callable = Preconditions.checkNotNull(callable, "callable"); + } + + @Override + public String getPrimaryAlias() { + return this.primary; + } + + @Override + public Set getAllAliases() { + return ImmutableSet.copyOf(this.aliases); + } + + @Override + public CommandCallable getCallable() { + return this.callable; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null || this.getClass() != o.getClass()) { + return false; + } + + ImmutableCommandMapping that = (ImmutableCommandMapping) o; + return this.primary.equals(that.primary) && this.aliases.equals(that.aliases) && this.callable.equals(that.callable); + } + + @Override + public int hashCode() { + return Objects.hash(this.primary, this.aliases, this.callable); + } + + @Override + public String toString() { + return "ImmutableCommandMapping{" + + "primary='" + this.primary + '\'' + + ", aliases=" + this.aliases + + ", spec=" + this.callable + + '}'; + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/InvocationCommandException.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/InvocationCommandException.java new file mode 100644 index 000000000..91ce6bf70 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/InvocationCommandException.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge; + +import net.minecraft.text.ChatMessage; + +/** + * Thrown when invocation of a command fails, wrapping the exception that + * is thrown. + */ +public class InvocationCommandException extends CommandException { + private static final long serialVersionUID = 2123904283741023948L; + + /** + * Constructs a new exception with the given message and the given cause. + * + * @param message The detail message + * @param cause The cause + */ + public InvocationCommandException(ChatMessage message, Throwable cause) { + super(message, cause); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/TextMessageException.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/TextMessageException.java new file mode 100644 index 000000000..9005c0cab --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/TextMessageException.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge; + +import net.minecraft.text.ChatMessage; + +/** + * A subclass of Exception that contains a rich message that is an instance of + * {@link Text} rather than a String. This allows formatted and localized + * exception messages. + */ +public class TextMessageException extends Exception { + private static final long serialVersionUID = -5281221645176698853L; + + private final ChatMessage message; + + /** + * Constructs a new {@link TextMessageException}. + */ + public TextMessageException() { + this.message = null; + } + + /** + * Constructs a new {@link TextMessageException} with the given message. + * + * @param message The detail message + */ + public TextMessageException(ChatMessage message) { + this.message = message; + } + + /** + * Constructs a new {@link TextMessageException} with the given message and + * cause. + * + * @param message The detail message + * @param throwable The cause + */ + public TextMessageException(ChatMessage message, Throwable throwable) { + super(throwable); + this.message = message; + } + + /** + * Constructs a new {@link TextMessageException} with the given cause. + * + * @param throwable The cause + */ + public TextMessageException(Throwable throwable) { + super(throwable); + this.message = null; + } + + @Override + public String getMessage() { + ChatMessage message = this.getText(); + return message == null ? null : message.toString(); + } + + /** + * Returns the text message for this exception, or null if nothing is + * present. + * + * @return The text for this message + */ + public ChatMessage getText() { + return this.message; + } + + @Override + public String getLocalizedMessage() { + return this.getMessage(); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ArgumentParseException.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ArgumentParseException.java new file mode 100644 index 000000000..4ce87f733 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ArgumentParseException.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; + +import com.google.common.base.Strings; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; + +/** + * Exception thrown when an error occurs while parsing arguments. + */ +public class ArgumentParseException extends CommandException { + private static final long serialVersionUID = -8555316116315990226L; + + private final String source; + private final int position; + + /** + * Return a new {@link ArgumentParseException} with the given message, source and position. + * + * @param message The message to use for this exception + * @param source The source string being parsed + * @param position The current position in the source string + */ + public ArgumentParseException(ChatMessage message, String source, int position) { + super(message, true); + this.source = source; + this.position = position; + } + + /** + * Return a new {@link ArgumentParseException} with the given message, cause, source and position. + * + * @param message The message to use for this exception + * @param cause The cause for this exception + * @param source The source string being parsed + * @param position The current position in the source string + */ + public ArgumentParseException(ChatMessage message, Throwable cause, String source, int position) { + super(message, cause, true); + this.source = source; + this.position = position; + } + + @Override + public ChatMessage getText() { + ChatMessage superText = super.getText(); + + if (this.source == null || this.source.isEmpty()) { + return super.getText(); + } else if (superText == null) { + return ChatMessage.createTextMessage(this.getAnnotatedPosition()); + } else { + return ChatMessage.createTextMessage(superText.toString() + "\n" + this.getAnnotatedPosition()); + } + } + + private ChatMessage getSuperText() { + return super.getText(); + } + + /** + * Return a string pointing to the position of the arguments when this + * exception occurs. + * + * @return The appropriate position string + */ + public String getAnnotatedPosition() { + String source = this.source; + int position = this.position; + + if (source.length() > 80) { + if (position >= 37) { + int startPos = position - 37; + int endPos = Math.min(source.length(), position + 37); + + if (endPos < source.length()) { + source = "..." + source.substring(startPos, endPos) + "..."; + } else { + source = "..." + source.substring(startPos, endPos); + } + + position -= 40; + } else { + source = source.substring(0, 77) + "..."; + } + } + + return source + "\n" + Strings.repeat(" ", position) + "^"; + } + + /** + * Gets the position of the last fetched argument in the provided source + * string. + * + * @return The source string to get position for + */ + public int getPosition() { + return this.position; + } + + /** + * Returns the source string arguments are being parsed from. + * + * @return The source string + */ + public String getSourceString() { + return this.source; + } + + /** + * An {@link ArgumentParseException} where the usage is already specified. + */ + public static class WithUsage extends ArgumentParseException { + private static final long serialVersionUID = -786214501012293475L; + + private final ChatMessage usage; + + public WithUsage(ArgumentParseException wrapped, ChatMessage usage) { + super(wrapped.getSuperText(), wrapped.getCause(), wrapped.getSourceString(), wrapped.getPosition()); + this.usage = usage; + } + + /** + * Gets the usage associated with this exception. + * + * @return The usage + */ + public ChatMessage getUsage() { + return this.usage; + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ChildCommandElementExecutor.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ChildCommandElementExecutor.java new file mode 100644 index 000000000..10e4f57aa --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ChildCommandElementExecutor.java @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; + +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; +import java.util.stream.Collectors; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.google.common.collect.Multimaps; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; +import net.minecraft.world.World; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandCallable; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMapping; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandResult; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher.SimpleDispatcher; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.spec.CommandExecutor; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.spec.CommandSpec; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; +import net.legacyfabric.fabric.api.util.Location; + +public class ChildCommandElementExecutor extends CommandElement implements CommandExecutor { + private static final AtomicInteger COUNTER = new AtomicInteger(); + private static final CommandElement NONE = GenericArguments.none(); + + @Nullable + private final CommandExecutor fallbackExecutor; + @Nullable + private final CommandElement fallbackElements; + private final SimpleDispatcher dispatcher = new SimpleDispatcher(SimpleDispatcher.FIRST_DISAMBIGUATOR); + private final boolean fallbackOnFail; + + /** + * Create a new combined argument element and executor to handle the + * parsing and execution of child commands. + * + * @param fallbackExecutor The executor to execute if the child command + * has been marked optional (Generally when this is wrapped in a + * {@link GenericArguments#optional(CommandElement)} + * @param fallbackElements The alternate {@link CommandElement}s that should + * be parsed if a child element fails to be parsed + * @param fallbackOnFail If true, then if a child command cannot parse the + * elements, the exception is discarded and the parent command attempts + * to parse the elements. If false, a child command will not pass + * control back to the parent, displaying its own exception message + */ + public ChildCommandElementExecutor(@Nullable CommandExecutor fallbackExecutor, @Nullable CommandElement fallbackElements, boolean fallbackOnFail) { + super(ChatMessage.createTextMessage("child" + COUNTER.getAndIncrement())); + this.fallbackExecutor = fallbackExecutor; + this.fallbackElements = NONE == fallbackElements ? null : fallbackElements; + this.fallbackOnFail = fallbackOnFail; + } + + /** + * Register a child command for a given set of aliases. + * + * @param callable The command to register + * @param aliases The aliases to register it as + * @return The child command's mapping, if present + */ + public Optional register(CommandCallable callable, List aliases) { + return this.dispatcher.register(callable, aliases); + } + + /** + * Register a child command for a given set of aliases. + * + * @param callable The command to register + * @param aliases The aliases to register it as + * @return The child command's mapping, if present + */ + public Optional register(CommandCallable callable, String... aliases) { + return this.dispatcher.register(callable, aliases); + } + + @Override + public List complete(final PermissibleCommandSource src, CommandArgs args, CommandContext context) { + List completions = Lists.newArrayList(); + + if (this.fallbackElements != null) { + CommandArgs.Snapshot state = args.getSnapshot(); + completions.addAll(this.fallbackElements.complete(src, args, context)); + args.applySnapshot(state); + } + + final Optional commandComponent = args.nextIfPresent(); + + if (!commandComponent.isPresent()) { + return ImmutableList.copyOf(this.filterCommands(src)); + } + + if (args.hasNext()) { + Optional child = this.dispatcher.get(commandComponent.get(), src); + + if (!child.isPresent()) { + return ImmutableList.of(); + } + + if (child.get().getCallable() instanceof CommandSpec) { + return ((CommandSpec) child.get().getCallable()).complete(src, args, context); + } + + args.nextIfPresent(); + final String arguments = args.getRaw().substring(args.getRawPosition()); + + while (args.hasNext()) { + args.nextIfPresent(); + } + + try { + return child.get() + .getCallable() + .getSuggestions(src, arguments, context.>getOne(CommandContext.TARGET_BLOCK_ARG).orElse(null)); + } catch (CommandException e) { + ChatMessage eText = e.getText(); + + if (eText != null) { + src.method_5505(CommandMessageFormatting.error(eText)); + } + + return ImmutableList.of(); + } + } + + completions.addAll(this.filterCommands(src).stream() + .filter(((input) -> { + String test = commandComponent.get(); + return input.toLowerCase().startsWith(test.toLowerCase()); + })) + .collect(Collectors.toList())); + return completions; + } + + private Set filterCommands(final PermissibleCommandSource src) { + return Multimaps.filterValues( + this.dispatcher.getAll(), + (input) -> + input != null && input.getCallable().testPermission(src) + ).keys().elementSet(); + } + + @Override + public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { + if (this.fallbackExecutor != null && !args.hasNext()) { + if (this.fallbackElements != null) { + // there might be optionals to take account of that would parse this successfully. + this.fallbackElements.parse(source, args, context); + } + + return; // execute the fallback regardless in this scenario. + } + + CommandArgs.Snapshot state = args.getSnapshot(); + final String key = args.next(); + Optional optionalCommandMapping = this.dispatcher.get(key, source).map(Function.identity()); + + if (optionalCommandMapping.isPresent()) { + final CommandMapping mapping = optionalCommandMapping.get(); + + try { + if ((mapping.getCallable() instanceof CommandSpec)) { + CommandSpec spec = ((CommandSpec) mapping.getCallable()); + spec.populateContext(source, args, context); + } else { + if (args.hasNext()) { + args.next(); + context.putArg(this.getUntranslatedKey() + "_args", args.getRaw().substring(args.getRawPosition())); + } + + while (args.hasNext()) { + args.next(); + } + } + + // Success, add to context now so that we don't execute the wrong executor in the first place. + context.putArg(this.getUntranslatedKey(), mapping); + } catch (ArgumentParseException ex) { + // If we get here, fallback to the elements, if they exist. + args.applySnapshot(state); + + if (this.fallbackOnFail && this.fallbackElements != null) { + this.fallbackElements.parse(source, args, context); + return; + } + + // Get the usage + args.next(); + + if (ex instanceof ArgumentParseException.WithUsage) { + // This indicates a previous child failed, so we just prepend our child + throw new ArgumentParseException.WithUsage(ex, ChatMessage.createTextMessage(key + " " + ((ArgumentParseException.WithUsage) ex).getUsage())); + } + + throw new ArgumentParseException.WithUsage(ex, ChatMessage.createTextMessage(key + " " + mapping.getCallable().getUsage(source))); + } + } else { + // Not a child, so let's continue with the fallback. + if (this.fallbackExecutor != null && this.fallbackElements != null) { + args.applySnapshot(state); + this.fallbackElements.parse(source, args, context); + } else { + // If we have no elements to parse, then we throw this error - this is the only element + // so specifying it implicitly means we have a child command to execute. + throw args.createError(ChatMessage.createTextMessage(String.format("Input command %s was not a valid subcommand!", key))); + } + } + } + + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + return null; + } + + @Override + public CommandResult execute(PermissibleCommandSource src, CommandContext args) throws CommandException { + CommandMapping mapping = args.getOne(this.getUntranslatedKey()).orElse(null); + + if (mapping == null) { + if (this.fallbackExecutor == null) { + throw new CommandException(ChatMessage.createTextMessage(String.format("Invalid subcommand state -- no more than one mapping may be provided for child arg %s", this.getKey()))); + } + + return this.fallbackExecutor.execute(src, args); + } + + if (mapping.getCallable() instanceof CommandSpec) { + CommandSpec spec = ((CommandSpec) mapping.getCallable()); + spec.checkPermission(src); + return spec.getExecutor().execute(src, args); + } + + final String arguments = args.getOne(this.getUntranslatedKey() + "_args").orElse(""); + return mapping.getCallable().process(src, arguments); + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource src) { + ChatMessage usage = this.dispatcher.getUsage(src); + + if (this.fallbackElements == null) { + return usage; + } + + ChatMessage elementUsage = this.fallbackElements.getUsage(src); + + if (elementUsage.toString().isEmpty()) { + return usage; + } + + return ChatMessage.createTextMessage("").addUsing(usage).addUsing(CommandMessageFormatting.PIPE_TEXT).addUsing(elementUsage); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandArgs.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandArgs.java new file mode 100644 index 000000000..4179f942c --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandArgs.java @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +import com.google.common.collect.ImmutableList; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing.SingleArg; + +/** + * Holder for command arguments. + */ +public final class CommandArgs { + private final String rawInput; + private final List args; + private int index = -1; + + /** + * Create a new CommandArgs instance with the given raw input and arguments. + * + * @param rawInput Raw input + * @param args Arguments extracted from the raw input + */ + public CommandArgs(String rawInput, List args) { + this.rawInput = rawInput; + this.args = new ArrayList<>(args); + } + + /** + * Return whether more arguments remain to be read. + * + * @return Whether more arguments remain + */ + public boolean hasNext() { + return this.index + 1 < this.args.size(); + } + + /** + * Returns true if: + * + *
    + *
  • The next element returned by {@link #next()} is the last
  • + *
  • {@link #hasNext()} is false
  • + *
+ * Else returns false. + * + * @return True if a completion can occur + */ + public boolean canComplete() { + return this.index + 2 >= this.args.size(); + } + + /** + * Try to read the next argument without advancing the current index. + * + * @return The next argument + * @throws ArgumentParseException if not enough arguments are present + */ + public String peek() throws ArgumentParseException { + if (!this.hasNext()) { + throw this.createError(ChatMessage.createTextMessage("Not enough arguments")); + } + + return this.args.get(this.index + 1).getValue(); + } + + /** + * Try to read the next argument, advancing the current index if successful. + * + * @return The next argument + * @throws ArgumentParseException if not enough arguments are present + */ + public String next() throws ArgumentParseException { + if (!this.hasNext()) { + throw this.createError(ChatMessage.createTextMessage("Not enough arguments!")); + } + + return this.args.get(++this.index).getValue(); + } + + /** + * Try to read the next argument, advancing the current index if successful + * or returning an absent optional if not. + * + * @return The optional next argument. + */ + public Optional nextIfPresent() { + return this.hasNext() ? Optional.of(this.args.get(++this.index).getValue()) : Optional.empty(); + } + + /** + * Create a parse exception with the provided message which has the position + * of the last parsed argument attached. The returned exception must be + * thrown at the target + * + * @param message The message for the exception + * @return the newly created, but unthrown exception + */ + public ArgumentParseException createError(ChatMessage message) { + return new ArgumentParseException(message, this.rawInput, this.index < 0 ? 0 : this.args.get(this.index).getStartIdx()); + } + + /** + * Gets a list of all arguments as a string. The returned list is immutable. + * + * @return all arguments + */ + public List getAll() { + return Collections.unmodifiableList(this.args.stream().map(SingleArg::getValue).collect(Collectors.toList())); + } + + List getArgs() { + return this.args; + } + + /** + * Return this arguments object's current state. Can be used to reset with + * the {@link #setState(Object)} method. + * + * @return The current state + * @deprecated Use {@link #getSnapshot()} and + * {@link #applySnapshot(Snapshot)} instead + */ + @Deprecated + public Object getState() { + return this.getSnapshot(); + } + + /** + * Restore the arguments object's state to a state previously used. + * + * @param state the previous state + * @deprecated Use {@link #getSnapshot()} and + * {@link #applySnapshot(Snapshot)} instead + */ + @Deprecated + public void setState(Object state) { + if (!(state instanceof Snapshot)) { + throw new IllegalArgumentException("Provided state was not of appropriate format returned by getState!"); + } + + this.applySnapshot((Snapshot) state, false); // keep parity with before + } + + /** + * Return the raw string used to provide input to this arguments object. + * + * @return The raw input + */ + public String getRaw() { + return this.rawInput; + } + + /** + * Get an arg at the specified position. + * + * @param index index of the element to return + */ + public String get(int index) { + return this.args.get(index).getValue(); + } + + /** + * Insert an arg as the next arg to be returned by {@link #next()}. + * + * @param value The argument to insert + */ + public void insertArg(String value) { + int index = this.index < 0 ? 0 : this.args.get(this.index).getEndIdx(); + this.args.add(this.index + 1, new SingleArg(value, index, index)); + } + + /** + * Remove the arguments parsed between startState and endState. + * + * @param startState The starting state + * @param endState The ending state + * @deprecated Use with {@link #getSnapshot()} instead of + * {@link #getState()} with {@link #removeArgs(Snapshot, Snapshot)} + */ + @Deprecated + public void removeArgs(Object startState, Object endState) { + if (!(startState instanceof Integer) || !(endState instanceof Integer)) { + throw new IllegalArgumentException("One of the states provided was not of the correct type!"); + } + + this.removeArgs((int) startState, (int) endState); + } + + /** + * Remove the arguments parsed between two snapshots. + * + * @param startSnapshot The starting state + * @param endSnapshot The ending state + */ + public void removeArgs(Snapshot startSnapshot, Snapshot endSnapshot) { + this.removeArgs(startSnapshot.index, endSnapshot.index); + } + + private void removeArgs(int startIdx, int endIdx) { + if (this.index >= startIdx) { + if (this.index < endIdx) { + this.index = startIdx - 1; + } else { + this.index -= (endIdx - startIdx) + 1; + } + } + + for (int i = startIdx; i <= endIdx; ++i) { + this.args.remove(startIdx); + } + } + + /** + * Returns the number of arguments. + * + * @return the number of arguments + */ + public int size() { + return this.args.size(); + } + + /** + * Go back to the previous argument. + */ + void previous() { + if (this.index > -1) { + --this.index; + } + } + + /** + * Gets the current position in raw input. + * + * @return the raw position + */ + public int getRawPosition() { + return this.index < 0 ? 0 : this.args.get(this.index).getStartIdx(); + } + + /** + * Gets a snapshot of the data inside this context to allow it to be + * restored later. + * + * @return The {@link Snapshot} containing the current state of the + * {@link CommandArgs} + */ + public Snapshot getSnapshot() { + return new Snapshot(this.index, this.args); + } + + /** + * Resets a {@link CommandArgs} to a previous state using a previously + * created {@link Snapshot}. + * + * @param snapshot The {@link Snapshot} to restore this context + * with + */ + public void applySnapshot(Snapshot snapshot) { + this.applySnapshot(snapshot, true); + } + + /** + * Resets a {@link CommandArgs} to a previous state using a previously + * created {@link Snapshot}. + * + *

If resetArgs is set to false, this snapshot will not reset the + * argument list to its previous state, only the index.

+ * + * @param snapshot The {@link Snapshot} to restore this context + * with + * @param resetArgs Whether to restore the argument list + */ + public void applySnapshot(Snapshot snapshot, boolean resetArgs) { + this.index = snapshot.index; + + if (resetArgs) { + this.args.clear(); + this.args.addAll(snapshot.args); + } + } + + /** + * A snapshot of a {@link CommandArgs}. This object does not contain any + * public API methods, a snapshot should be considered a black box. + */ + public final class Snapshot { + final int index; + final ImmutableList args; + + Snapshot(int index, List args) { + this.index = index; + this.args = ImmutableList.copyOf(args); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null || this.getClass() != o.getClass()) { + return false; + } + + Snapshot snapshot = (Snapshot) o; + return this.index == snapshot.index + && Objects.equals(this.args, snapshot.args); + } + + @Override + public int hashCode() { + return Objects.hash(this.index, this.args); + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandContext.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandContext.java new file mode 100644 index 000000000..b40b46a40 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandContext.java @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; + +import java.util.Collection; +import java.util.Collections; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.Set; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; +import net.legacyfabric.fabric.api.util.Location; +import net.legacyfabric.fabric.mixin.command.ChatMessageAccessor; + +/** + * Context that a command is executed in. + * This object stores parsed arguments from other commands + */ +public final class CommandContext { + /** + * The argument key for a target block position that may be present + * during tab completion, of type {@link Location Location<World>}. + */ + public static final String TARGET_BLOCK_ARG = "targetblock-pos048658"; // Random junk afterwards so we don't accidentally conflict with other args + + /** + * The argument key to indicate that a tab completion is taking place. + */ + public static final String TAB_COMPLETION = "tab-complete-50456"; // Random junk afterwards so we don't accidentally conflict with other args + + private final Multimap parsedArgs; + private final Set definedFlags; + + /** + * Create a new empty CommandContext. + */ + public CommandContext() { + this.parsedArgs = ArrayListMultimap.create(); + this.definedFlags = Sets.newHashSet(); + } + + /** + * Gets all values for the given argument. May return an empty list if no + * values are present. + * + * @param key The key to get values for + * @param the type of value to get + * @return the collection of all values + */ + @SuppressWarnings("unchecked") + public Collection getAll(String key) { + return Collections.unmodifiableCollection((Collection) this.parsedArgs.get(key)); + } + + /** + * Gets all values for the given argument. May return an empty list if no + * values are present. + * + * @param key The key to get values for + * @param the type of value to get + * @return the collection of all values + */ + public Collection getAll(ChatMessage key) { + return this.getAll(CommandContext.textToArgKey(key)); + } + + /** + * Gets the value for the given key if the key has only one value. + * + *

An empty {@link Optional} indicates that there are either zero or more + * than one values for the given key. Use {@link #hasAny(Text)} to verify + * which.

+ * + * @param key the key to get + * @param the expected type of the argument + * @return the argument + */ + @SuppressWarnings("unchecked") + public Optional getOne(String key) { + Collection values = this.parsedArgs.get(key); + + if (values.size() != 1) { + return Optional.empty(); + } + + return Optional.ofNullable((T) values.iterator().next()); + } + + /** + * Gets the value for the given key if the key has only one value. + * + *

An empty {@link Optional} indicates that there are either zero or more + * than one values for the given key. Use {@link #hasAny(Text)} to verify + * which.

+ * + * @param key the key to get + * @param the expected type of the argument + * @return the argument + */ + public Optional getOne(ChatMessage key) { + return this.getOne(CommandContext.textToArgKey(key)); + } + + /** + * Gets the value for the given key if the key has only one value, throws an + * exception otherwise. + * + * @param key the key to get + * @param the expected type of the argument + * @return the argument + * @throws NoSuchElementException if there is no element with the + * associated key + * @throws IllegalArgumentException if there are more than one element + * associated with the key (thus, the argument is illegal in this + * context) + * @throws ClassCastException if the element type is not what is expected + * by the caller + */ + @SuppressWarnings("unchecked") + public T requireOne(String key) throws NoSuchElementException, IllegalArgumentException, ClassCastException { + Collection values = this.parsedArgs.get(key); + + if (values.size() == 1) { + return (T) values.iterator().next(); + } else if (values.isEmpty()) { + throw new NoSuchElementException(); + } + + throw new IllegalArgumentException(); + } + + /** + * Gets the value for the given key if the key has only one value, throws an + * exception otherwise. + * + * @param key the key to get + * @param the expected type of the argument + * @return the argument + * @throws NoSuchElementException if there is no element with the + * associated key + * @throws IllegalArgumentException if there are more than one element + * associated with the key (thus, the argument is illegal in this + * context) + * @throws ClassCastException if the element type is not what is expected + */ + public T requireOne(ChatMessage key) + throws NoSuchElementException, IllegalArgumentException, ClassCastException { + return this.requireOne(CommandContext.textToArgKey(key)); + } + + /** + * Insert an argument into this context. + * + * @param key the key to store the arg under + * @param value the value for this argument + */ + public void putArg(String key, Object value) { + Preconditions.checkNotNull(value, "value"); + this.parsedArgs.put(key, value); + } + + /** + * Insert an argument into this context. + * + * @param key the key to store the arg under + * @param value the value for this argument + */ + public void putArg(ChatMessage key, Object value) { + this.putArg(CommandContext.textToArgKey(key), value); + } + + /** + * Defines the flag as being present when parsing this context. + * + * @param key the key for the flag defined + */ + public void addFlag(String key) { + this.definedFlags.add(key); + } + + /** + * Defines the flag as being present when parsing this context. + * + * @param key the key for the flag defined + */ + public void addFlag(ChatMessage key) { + this.addFlag(CommandContext.textToArgKey(key)); + } + + /** + * Perform a permissions check, throwing an exception if the required + * permissions are not present. + * + * @param commander the source to check against + * @param permission The permission to check + * @throws CommandException if the source does not have permission + */ + public void checkPermission(PermissibleCommandSource commander, String permission) throws CommandException { + if (!commander.hasPermission(permission)) { + throw new CommandException(ChatMessage.createTextMessage("You do not have permission to use this command!")); + } + } + + /** + * Returns whether this context has any value for the given argument key. + * + * @param key The key to look up + * @return whether there are any values present + */ + public boolean hasAny(String key) { + return this.parsedArgs.containsKey(key); + } + + /** + * Returns whether this context has any value for the given argument key. + * + * @param key The key to look up + * @return whether there are any values present + */ + public boolean hasAny(ChatMessage key) { + return this.hasAny(CommandContext.textToArgKey(key)); + } + + /** + * Returns whether the given flag has been defined in this context. + * + * @param key The key to look up + * @return whether the flag is defined + */ + public boolean hasFlag(String key) { + return this.definedFlags.contains(key); + } + + /** + * Returns whether the given flag has been defined in this context. + * + * @param key The key to look up + * @return whether the flag is defined + */ + public boolean hasFlag(ChatMessage key) { + return this.hasFlag(CommandContext.textToArgKey(key)); + } + + /** + * Gets a snapshot of the data inside this context to allow it to be + * restored later. + * + *

This is only guaranteed to create a shallow copy of the + * backing store. If any value is mutable, any changes to that value + * will be reflected in this snapshot. It is therefore not recommended + * that you keep this snapshot around for longer than is necessary.

+ * + * @return The {@link Snapshot} containing the current state of the + * {@link CommandContext} + */ + public Snapshot createSnapshot() { + return new Snapshot(this.parsedArgs, this.definedFlags); + } + + /** + * Resets a {@link CommandContext} to a previous state using a previously + * created {@link Snapshot}. + * + * @param snapshot The {@link Snapshot} to restore this context with + */ + public void applySnapshot(Snapshot snapshot) { + this.parsedArgs.clear(); + this.parsedArgs.putAll(snapshot.args); + this.definedFlags.clear(); + this.definedFlags.addAll(snapshot.flags); + } + + /** + * A snapshot of a {@link CommandContext}. This object does not contain any + * public API methods, a snapshot should be considered a black box. + */ + public static final class Snapshot { + final Multimap args; + final Set flags; + + Snapshot(Multimap args, Set flags) { + this.args = ArrayListMultimap.create(args); + this.flags = Sets.newHashSet(flags); + } + } + + /** + * Converts a {@link Text} into a String key. + * + * @param key the text to be converted into a string key + * @return the string key. if {@code key} is a {@link TranslatableText}, the translation key. + */ + public static String textToArgKey(@Nullable ChatMessage key) { + if (key == null) { + return null; + } + + if (((ChatMessageAccessor) key).getTranslationKey() != null) { // Use translation key + return ((ChatMessageAccessor) key).getTranslationKey(); + } + + return key.toString(); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandElement.java new file mode 100644 index 000000000..502c1506d --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandElement.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; + +import java.util.List; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +/** + * Represents a command argument element. + */ +public abstract class CommandElement { + @Nullable + private final ChatMessage key; + + protected CommandElement(@Nullable ChatMessage key) { + this.key = key; + } + + /** + * Return the key to be used for this object. + * + * @return the user-facing representation of the key + */ + @Nullable + public ChatMessage getKey() { + return this.key; + } + + /** + * Return the plain key, to be used when looking up this command element in + * a {@link CommandContext}. If the key is a {@link TranslatableText}, this + * is the translation's id. Otherwise, this is the result of + * {@link Text#asString()} ()} ()}. + * + * @return the raw key + */ + @Nullable + public String getUntranslatedKey() { + return CommandContext.textToArgKey(this.key); + } + + /** + * Attempt to extract a value for this element from the given arguments and + * put it in the given context. This method normally delegates to + * {@link #parseValue(PermissibleCommandSource, CommandArgs)} for getting the values. + * This method is expected to have no side-effects for the source, meaning + * that executing it will not change the state of the {@link PermissibleCommandSource} + * in any way. + * + * @param source The source to parse for + * @param args The args to extract from + * @param context The context to supply to + * @throws ArgumentParseException if unable to extract a value + */ + public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { + Object val = this.parseValue(source, args); + String key = this.getUntranslatedKey(); + + if (key != null && val != null) { + if (val instanceof Iterable) { + for (Object ent : ((Iterable) val)) { + context.putArg(key, ent); + } + } else { + context.putArg(key, val); + } + } + } + + /** + * Attempt to extract a value for this element from the given arguments. + * This method is expected to have no side-effects for the source, meaning + * that executing it will not change the state of the {@link PermissibleCommandSource} + * in any way. + * + * @param source The source to parse for + * @param args the arguments + * @return The extracted value + * @throws ArgumentParseException if unable to extract a value + */ + @Nullable + public abstract Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException; + + /** + * Fetch completions for command arguments. + * + * @param src The source requesting tab completions + * @param args The arguments currently provided + * @param context The context to store state in + * @return Any relevant completions + */ + public abstract List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context); + + /** + * Return a usage message for this specific argument. + * + * @param src The source requesting usage + * @return The formatted usage + */ + public ChatMessage getUsage(PermissibleCommandSource src) { + return this.getKey() == null ? ChatMessage.createTextMessage("") : ChatMessage.createTextMessage("<" + this.getKey() + ">"); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandFlags.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandFlags.java new file mode 100644 index 000000000..cab7d8638 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandFlags.java @@ -0,0 +1,543 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import com.google.common.collect.ImmutableList; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public final class CommandFlags extends CommandElement { + @Nullable + private final CommandElement childElement; + private final Map, CommandElement> usageFlags; + private final Map shortFlags; + private final Map longFlags; + private final UnknownFlagBehavior unknownShortFlagBehavior; + private final UnknownFlagBehavior unknownLongFlagBehavior; + private final boolean anchorFlags; + + protected CommandFlags(@Nullable CommandElement childElement, Map, CommandElement> usageFlags, Map shortFlags, Map longFlags, UnknownFlagBehavior unknownShortFlagBehavior, UnknownFlagBehavior unknownLongFlagBehavior, boolean anchorFlags) { + super(null); + this.childElement = childElement; + this.usageFlags = usageFlags; + this.shortFlags = shortFlags; + this.longFlags = longFlags; + this.unknownShortFlagBehavior = unknownShortFlagBehavior; + this.unknownLongFlagBehavior = unknownLongFlagBehavior; + this.anchorFlags = anchorFlags; + } + + @Override + public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { + CommandArgs.Snapshot state = args.getSnapshot(); + + while (args.hasNext()) { + String arg = args.next(); + + if (arg.startsWith("-")) { + CommandArgs.Snapshot start = args.getSnapshot(); + boolean remove; + + if (arg.startsWith("--")) { // Long flag + remove = this.parseLongFlag(source, arg.substring(2), args, context); + } else { + remove = this.parseShortFlags(source, arg.substring(1), args, context); + } + + if (remove) { + args.removeArgs(start, args.getSnapshot()); + } + } else if (this.anchorFlags) { + break; + } + } + + // We removed the arguments so we don't parse them as they have already been parsed as flags, + // so don't restore them here! + args.applySnapshot(state, false); + + if (this.childElement != null) { + this.childElement.parse(source, args, context); + } + } + + private boolean parseLongFlag(PermissibleCommandSource source, String longFlag, CommandArgs args, CommandContext context) throws ArgumentParseException { + String[] flagSplit = longFlag.split("=", 2); + String flag = flagSplit[0].toLowerCase(); + CommandElement element = this.longFlags.get(flag); + + if (element == null) { + switch (this.unknownLongFlagBehavior) { + case ERROR: + throw args.createError(ChatMessage.createTextMessage(String.format("Unknown long flag %s specified", flagSplit[0]))); + case ACCEPT_NONVALUE: + context.addFlag(flag); + context.putArg(flag, flagSplit.length == 2 ? flagSplit[1] : true); + return true; + case ACCEPT_VALUE: + context.addFlag(flag); + context.putArg(flag, flagSplit.length == 2 ? flagSplit[1] : args.next()); + return true; + case IGNORE: + return false; + default: + throw new Error("New UnknownFlagBehavior added without corresponding case clauses"); + } + } else if (flagSplit.length == 2) { + args.insertArg(flagSplit[1]); + } + + element.parse(source, args, context); + return true; + } + + private boolean parseShortFlags(PermissibleCommandSource source, String shortFlags, CommandArgs args, CommandContext context) throws ArgumentParseException { + for (int i = 0; i < shortFlags.length(); i++) { + String shortFlag = shortFlags.substring(i, i + 1); + CommandElement element = this.shortFlags.get(shortFlag); + + if (element == null) { + switch (this.unknownShortFlagBehavior) { + case IGNORE: + if (i == 0) { + return false; + } + + throw args.createError(ChatMessage.createTextMessage(String.format("Unknown short flag %s specified", shortFlag))); + case ERROR: + throw args.createError(ChatMessage.createTextMessage(String.format("Unknown short flag %s specified", shortFlag))); + case ACCEPT_NONVALUE: + context.addFlag(shortFlag); + context.putArg(shortFlag, true); + break; + case ACCEPT_VALUE: + context.addFlag(shortFlag); + context.putArg(shortFlag, args.next()); + break; + default: + throw new Error("New UnknownFlagBehavior added without corresponding case clauses"); + } + } else { + element.parse(source, args, context); + } + } + + return true; + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource src) { + final List builder = new ArrayList<>(); + + for (Map.Entry, CommandElement> arg : this.usageFlags.entrySet()) { + builder.add("["); + + for (Iterator it = arg.getKey().iterator(); it.hasNext(); ) { + String flag = it.next(); + builder.add(flag.length() > 1 ? "--" : "-"); + builder.add(flag); + + if (it.hasNext()) { + builder.add("|"); + } + } + + ChatMessage usage = arg.getValue().getUsage(src); + + if (!usage.toString().trim().isEmpty()) { + builder.add(" "); + builder.add(usage); + } + + builder.add("]"); + builder.add(" "); + } + + if (this.childElement != null) { + builder.add(this.childElement.getUsage(src)); + } + + return ChatMessage.createTextMessage(Arrays.stream(builder.toArray()).map(Object::toString).collect(Collectors.joining())); + } + + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + return null; + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + CommandArgs.Snapshot state = args.getSnapshot(); + + while (args.hasNext()) { + String next = args.nextIfPresent().get(); + + if (next.startsWith("-")) { + CommandArgs.Snapshot start = args.getSnapshot(); + List ret; + + if (next.startsWith("--")) { + ret = this.tabCompleteLongFlag(next.substring(2), src, args, context); + } else { + ret = this.tabCompleteShortFlags(next.substring(1), src, args, context); + } + + if (ret != null) { + return ret; + } + + args.removeArgs(start, args.getSnapshot()); + } else if (this.anchorFlags) { + break; + } + } + + // the modifications are intentional + args.applySnapshot(state, false); + + // Prevent tab completion gobbling up an argument if the value parsed. + if (!args.hasNext() && !args.getRaw().matches("\\s+$")) { + return ImmutableList.of(); + } + + return this.childElement != null ? this.childElement.complete(src, args, context) : ImmutableList.of(); + } + + @Nullable + private List tabCompleteLongFlag(String longFlag, PermissibleCommandSource src, CommandArgs args, CommandContext context) { + String[] flagSplit = longFlag.split("=", 2); + boolean isSplitFlag = flagSplit.length == 2; + CommandElement element = this.longFlags.get(flagSplit[0].toLowerCase()); + + if (element == null || !isSplitFlag && !args.hasNext()) { + return this.longFlags.keySet().stream() + .filter((input) -> input.startsWith(flagSplit[0])) + .map(f -> "--" + f) + .collect(Collectors.toList()); + } else if (isSplitFlag) { + args.insertArg(flagSplit[1]); + } + + CommandArgs.Snapshot state = args.getSnapshot(); + List completion; + + try { + element.parse(src, args, context); + + if (args.getSnapshot().equals(state)) { + // Not iterated, but succeeded. Check completions to account for optionals + completion = element.complete(src, args, context); + } else { + args.previous(); + String res = args.peek(); + completion = element.complete(src, args, context); + + if (!completion.contains(res)) { + completion = ImmutableList.builder().addAll(completion).add(res).build(); + } + } + } catch (ArgumentParseException ex) { + args.applySnapshot(state); + completion = element.complete(src, args, context); + } + + if (completion.isEmpty()) { + if (isSplitFlag) { + return ImmutableList.of(); // so we don't overwrite the flag + } + + return null; + } + + if (isSplitFlag) { + return completion.stream().map(x -> "--" + flagSplit[0] + "=" + x).collect(Collectors.toList()); + } + + return completion; + } + + @Nullable + private List tabCompleteShortFlags(String shortFlags, PermissibleCommandSource src, CommandArgs args, CommandContext context) { + for (int i = 0; i < shortFlags.length(); i++) { + CommandElement element = this.shortFlags.get(shortFlags.substring(i, i + 1)); + + if (element == null) { + if (i == 0 && this.unknownShortFlagBehavior == UnknownFlagBehavior.ACCEPT_VALUE) { + args.nextIfPresent(); + return null; + } + } else { + CommandArgs.Snapshot start = args.getSnapshot(); + + try { + element.parse(src, args, context); + + // if the iterator hasn't moved, then just try to complete, no point going backwards. + if (args.getSnapshot().equals(start)) { + return element.complete(src, args, context); + } + + // if we managed to parse this, then go back to get the completions for it. + args.previous(); + String currentText = args.peek(); + + // ensure this is returned as a valid option + List elements = element.complete(src, args, context); + + if (!elements.contains(currentText)) { + return ImmutableList.builder().add(args.peek()).addAll(element.complete(src, args, context)).build(); + } else { + return elements; + } + } catch (ArgumentParseException ex) { + args.applySnapshot(start); + return element.complete(src, args, context); + } + } + } + + return null; + } + + /** + * Indicates to the flag parser how it should treat an argument that looks + * like a flag that it does not recognise. + */ + public enum UnknownFlagBehavior { + /** + * Throw an {@link ArgumentParseException} when an unknown flag is + * encountered. + */ + ERROR, + /** + * Mark the flag as a non-value flag. + */ + ACCEPT_NONVALUE, + + /** + * Mark the flag as a string-valued flag. + */ + ACCEPT_VALUE, + /** + * Act as if the unknown flag is an ordinary argument, allowing the + * parsers specified in {@link Builder#buildWith(CommandElement)} to + * attempt to parse the element instead. + */ + IGNORE, + } + + public static class Builder { + private final Map, CommandElement> usageFlags = new HashMap<>(); + private final Map shortFlags = new HashMap<>(); + private final Map longFlags = new HashMap<>(); + private UnknownFlagBehavior unknownLongFlagBehavior = UnknownFlagBehavior.ERROR; + private UnknownFlagBehavior unknownShortFlagBehavior = UnknownFlagBehavior.ERROR; + private boolean anchorFlags = false; + + Builder() { + } + + private Builder flag(Function func, String... specs) { + final List availableFlags = new ArrayList<>(specs.length); + CommandElement el = null; + + for (String spec : specs) { + if (spec.startsWith("-")) { + final String flagKey = spec.substring(1); + + if (el == null) { + el = func.apply(flagKey); + } + + availableFlags.add(flagKey); + this.longFlags.put(flagKey.toLowerCase(), el); + } else { + for (int i = 0; i < spec.length(); ++i) { + final String flagKey = spec.substring(i, i + 1); + + if (el == null) { + el = func.apply(flagKey); + } + + availableFlags.add(flagKey); + this.shortFlags.put(flagKey, el); + } + } + } + + this.usageFlags.put(availableFlags, el); + return this; + } + + /** + * Allow a flag with any of the provided specifications that has no + * value. This flag will be exposed in a {@link CommandContext} under + * the key equivalent to the first flag in the specification array. + * The specifications are handled as so for each element in the + * {@code specs} array: + *
    + *
  • If the element starts with -, the remainder of the element + * is interpreted as a long flag (so, "-flag" means "--flag" will + * be matched in an argument string)
  • + *
  • Otherwise, each code point of the element is interpreted + * as a short flag (meaning "flag" will cause "-f", "-l", "-a" and + * "-g" to be matched in an argument string, storing "true" under + * the key "f".)
  • + *
+ * + * @param specs The flag specifications + * @return this + */ + public Builder flag(String... specs) { + return this.flag(input -> new FlagElement(ChatMessage.createTextMessage(input), null), specs); + } + + /** + * Allow a flag with any of the provided specifications that has no + * value but requires the source to have a specific permission to + * specify the command. + * + * @param flagPermission The required permission + * @param specs The flag specifications + * @return this + * @see #flag(String...) for details on the format + */ + public Builder permissionFlag(final String flagPermission, String... specs) { + return this.flag(input -> GenericArguments.requiringPermission(new FlagElement(ChatMessage.createTextMessage(input), null), flagPermission), specs); + } + + /** + * Allow a flag with any of the provided specifications, with the given + * command element. The flag may be present multiple times, and may + * therefore have multiple values. + * + * @param value The command element used to parse any occurrences + * @param specs The flag specifications + * @return this + * @see #flag(String...) for information on how the flag specifications + * are parsed + */ + public Builder valueFlag(CommandElement value, String... specs) { + return this.flag(input -> new FlagElement(ChatMessage.createTextMessage(input), value), specs); + } + + /** + * Sets how long flags that are not registered should be handled when + * encountered. + * + * @param behavior The behavior to use + * @return this + */ + public Builder setUnknownLongFlagBehavior(UnknownFlagBehavior behavior) { + this.unknownLongFlagBehavior = behavior; + return this; + } + + /** + * Sets how long flags that are not registered should be handled when + * encountered. + * + *

If a command that supports flags accepts negative numbers (or + * arguments that may begin with a dash), setting this to + * {@link UnknownFlagBehavior#IGNORE} will cause these elements to + * be ignored by the flag parser and will be parsed by the command's + * non-flag elements instead.

+ * + * @param behavior The behavior to use + * @return this + */ + public Builder setUnknownShortFlagBehavior(UnknownFlagBehavior behavior) { + this.unknownShortFlagBehavior = behavior; + return this; + } + + /** + * Whether flags should be anchored to the beginning of the text (so + * flags will only be picked up if they are at the beginning of the + * input). + * + * @param anchorFlags Whether flags are anchored + * @return this + */ + public Builder setAnchorFlags(boolean anchorFlags) { + this.anchorFlags = anchorFlags; + return this; + } + + /** + * Build a flag command element using the given command element to + * handle all non-flag arguments. + * + *

If you wish to add multiple elements here, wrap them in + * {@link GenericArguments#seq(CommandElement...)}

+ * + * @param wrapped The wrapped command element + * @return the new command element + */ + public CommandElement buildWith(CommandElement wrapped) { + return new CommandFlags(wrapped, this.usageFlags, this.shortFlags, this.longFlags, this.unknownShortFlagBehavior, this.unknownLongFlagBehavior, this.anchorFlags); + } + } + + private static class FlagElement extends CommandElement { + @Nullable + private final CommandElement valueElement; + + private FlagElement(ChatMessage key, @Nullable CommandElement valueElement) { + super(key); + this.valueElement = valueElement; + } + + @Override + public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { + String key = this.getUntranslatedKey(); + + if (this.valueElement != null) { + this.valueElement.parse(source, args, context); + } else { + context.putArg(key, true); + } + + context.addFlag(key); + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + return null; //unused + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + return this.valueElement != null ? this.valueElement.complete(src, args, context) : Collections.emptyList(); + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/GenericArguments.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/GenericArguments.java new file mode 100644 index 000000000..b370fa9dc --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/GenericArguments.java @@ -0,0 +1,949 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.InetAddress; +import java.net.URL; +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.Collection; +import java.util.Map; +import java.util.UUID; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.text.ChatMessage; +import net.minecraft.util.math.Vec3d; + +import net.fabricmc.loader.api.ModContainer; + +import net.legacyfabric.fabric.api.command.v2.StringType; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; +import net.legacyfabric.fabric.api.util.TriState; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.AllOfCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.BigDecimalElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.BigIntegerElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.ChoicesCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.DateTimeElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.DurationElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.EntityCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.EnumValueElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.FilteredSuggestionsElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.FirstParsingCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.IpElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.LiteralCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.MarkTrueCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.ModCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.NumericElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.OnlyOneCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.OptionalCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.PermissionCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.PlayerCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.RemainingJoinedStringsCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.RepeatedCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.SequenceCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.StringCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.StringElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.UrlElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.UuidElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.Vec3dCommandElement; +import net.legacyfabric.fabric.impl.command.lib.sponge.args.WithSuggestionsElement; + +/** + * Class containing factory methods for common command elements. + */ +@SuppressWarnings({"UnstableApiUsage"}) +public class GenericArguments { + private static final CommandElement NONE = new SequenceCommandElement(ImmutableList.of()); + + private GenericArguments() { + } + + /** + * Expects no arguments, returns no values. + * + * @return An expectation of no arguments + */ + public static CommandElement none() { + return NONE; + } + + /** + * Expects no arguments. Adds 'true' to the context when parsed. + * + *

This will return only one value.

+ * + * @param key the key to store 'true' under + * @return the argument + */ + public static CommandElement markTrue(ChatMessage key) { + return new MarkTrueCommandElement(key); + } + + /** + * Expect an argument to represent online players, or if nothing matches + * and the source is a {@link PlayerEntity}, give the player. If nothing matches + * and the source is not a player, throw an exception. + * + *

Gives values of type {@link PlayerEntity}.

+ * + *

This argument accepts the following inputs:

+ * + *
    + *
  • A player's name
  • + *
  • A regex that matches the beginning of one or more player's names + *
  • + *
  • A selector
  • + *
+ * + *

This may return multiple players. If you must only return one, wrap + * this element in an {@link #onlyOne(CommandElement)} call.

+ * + * @param key The key to store under + * @return the argument + */ + public static CommandElement playerOrSource(ChatMessage key) { + return new PlayerCommandElement(key, true); + } + + /** + * Expect an argument to represent online players. Returns values of type + * {@link PlayerEntity}. + * + *

This argument accepts the following inputs:

+ * + *
    + *
  • A player's name
  • + *
  • A regex that matches the beginning of one or more player's names + *
  • + *
  • A selector
  • + *
+ * + *

This may return multiple players. If you must only return one, wrap + * this element in an {@link #onlyOne(CommandElement)} call.

+ * + * @param key The key to store under + * @return the argument + */ + public static CommandElement player(ChatMessage key) { + return new PlayerCommandElement(key, false); + } + + /** + * Expect an argument to represent a {@link Vec3d}. + * + *

This will return one value.

+ * + * @param key The key to store under + * @return the argument + */ + public static CommandElement vec3d(ChatMessage key) { + return new Vec3dCommandElement(key); + } + + /** + * Expect an argument to represent a {@link ModContainer}'s id. + * + *

This argument accepts the following inputs:

+ * + *
    + *
  • The specified {@link ModContainer}'s id
  • + *
  • A regex that matches the beginning of one or more plugin id
  • + *
+ * + *

This may return multiple {@link ModContainer}s. If you must only + * return one, wrap this element in an {@link #onlyOne(CommandElement)} + * call.

+ * + * @param key The key to store under + * @return the argument + */ + public static CommandElement mod(ChatMessage key) { + return new ModCommandElement(key); + } + + /** + * Gets a builder to create a command element that parses flags. + * + *

There should only be ONE of these in a command element sequence if you + * wish to use flags. A {@link CommandFlags.Builder} can handle multiple + * flags that have different behaviors. Using multiple builders in the same + * sequence may cause unexpected behavior.

+ * + *

Any command elements that are not associated with flags should be + * placed into the {@link CommandFlags.Builder#buildWith(CommandElement)} + * parameter, allowing the flags to be used throughout the argument string. + *

+ * + * @return the newly created builder + */ + public static CommandFlags.Builder flags() { + return new CommandFlags.Builder(); + } + + /** + * Consumes a series of arguments. Usage is the elements concatenated + * + * @param elements The series of arguments to expect + * @return the element to match the input + */ + public static CommandElement seq(CommandElement... elements) { + return new SequenceCommandElement(ImmutableList.copyOf(elements)); + } + + /** + * Return an argument that allows selecting from a limited set of values. + * + *

If there are 5 or fewer choices available, the choices will be shown + * in the command usage. Otherwise, the usage will only display only the + * key.

+ * + *

Choices are case sensitive. If you do not require + * case sensitivity, see {@link #choicesInsensitive(Text, Map)}.

+ * + *

To override this behavior, see + * {@link #choices(Text, Map, boolean, boolean)}.

+ * + *

When parsing, only one choice may be selected, returning its + * associated value.

+ * + * @param key The key to store the resulting value under + * @param choices The choices users can choose from + * @return the element to match the input + */ + public static CommandElement choices(ChatMessage key, Map choices) { + return choices(key, choices, choices.size() <= ChoicesCommandElement.CUTOFF, true); + } + + /** + * Return an argument that allows selecting from a limited set of values. + * + *

If there are 5 or fewer choices available, the choices will be shown + * in the command usage. Otherwise, the usage will only display only the + * key.

+ * + *

Choices are not case sensitive. If you require + * case sensitivity, see {@link #choices(Text, Map)}

+ * + *

To override this behavior, see + * {@link #choices(Text, Map, boolean, boolean)}.

+ * + *

When parsing, only one choice may be selected, returning its + * associated value.

+ * + * @param key The key to store the resulting value under + * @param choices The choices users can choose from + * @return the element to match the input + */ + public static CommandElement choicesInsensitive(ChatMessage key, Map choices) { + return choices(key, choices, choices.size() <= ChoicesCommandElement.CUTOFF, false); + } + + /** + * Return an argument that allows selecting from a limited set of values. + * + *

Unless {@code choicesInUsage} is true, general command usage will only + * display the provided key.

+ * + *

Choices are case sensitive. If you do not require + * case sensitivity, see {@link #choices(Text, Map, boolean, boolean)}

+ * + *

When parsing, only one choice may be selected, returning its + * associated value.

+ * + * @param key The key to store the resulting value under + * @param choices The choices users can choose from + * @param choicesInUsage Whether to display the available choices, or simply + * the provided key, as part of usage + * @return the element to match the input + */ + public static CommandElement choices(ChatMessage key, Map choices, boolean choicesInUsage) { + return choices(key, choices, choicesInUsage, true); + } + + /** + * Return an argument that allows selecting from a limited set of values. + * + *

Unless {@code choicesInUsage} is true, general command usage will only + * display the provided key.

+ * + *

When parsing, only one choice may be selected, returning its + * associated value.

+ * + * @param key The key to store the resulting value under + * @param choices The choices users can choose from + * @param choicesInUsage Whether to display the available choices, or simply + * the provided key, as part of usage + * @param caseSensitive Whether the matches should be case sensitive + * @return the element to match the input + */ + public static CommandElement choices(ChatMessage key, Map choices, boolean choicesInUsage, boolean caseSensitive) { + if (!caseSensitive) { + Map choicesMap = choices.entrySet().stream().collect(Collectors.toMap(x -> x.getKey().toLowerCase(), Map.Entry::getValue)); + return choices(key, choicesMap::keySet, selection -> choicesMap.get(selection.toLowerCase()), choicesInUsage); + } + + Map immChoices = ImmutableMap.copyOf(choices); + return choices(key, immChoices::keySet, immChoices::get, choicesInUsage); + } + + /** + * Return an argument that allows selecting from a limited set of values. + * + *

If there are 5 or fewer choices available, the choices will be shown + * in the command usage. Otherwise, the usage will only display only the + * key.

+ * + *

To override this behavior, see {@link #choices(Text, Map, boolean)}. + *

+ * + *

Only one choice may be selected, returning its associated value.

+ * + * @param key The key to store the resulting value under + * @param keys The function that will supply available keys + * @param values The function that maps an element of {@code key} to a value + * and any other key to {@code null} + * @return the element to match the input + */ + public static CommandElement choices(ChatMessage key, Supplier> keys, Function values) { + return new ChoicesCommandElement(key, keys, values, TriState.DEFAULT); + } + + /** + * Return an argument that allows selecting from a limited set of values. + * Unless {@code choicesInUsage} is true, general command usage will only + * display the provided key. + * + *

Only one choice may be selected, returning its associated value.

+ * + * @param key The key to store the resulting value under + * @param keys The function that will supply available keys + * @param values The function that maps an element of {@code key} to a value + * and any other key to {@code null} + * @param choicesInUsage Whether to display the available choices, or simply + * the provided key, as part of usage + * @return the element to match the input + */ + public static CommandElement choices(ChatMessage key, Supplier> keys, Function values, boolean choicesInUsage) { + return new ChoicesCommandElement(key, keys, values, choicesInUsage ? TriState.TRUE : TriState.FALSE); + } + + /** + * Returns a command element that matches the first of the provided elements + * that parses tab completion matches from all options. + * + * @param elements The elements to check against + * @return The command element matching the first passing of the elements + * provided + */ + public static CommandElement firstParsing(CommandElement... elements) { + return new FirstParsingCommandElement(ImmutableList.copyOf(elements)); + } + + /** + * Make the provided command element optional. + * + *

This means the command element is not required. However, if the + * element is provided with invalid format and there are no more args + * specified, any errors will still be passed on.

+ * + * @param element The element to optionally require + * @return the element to match the input + */ + public static CommandElement optional(CommandElement element) { + return new OptionalCommandElement(element, null, false); + } + + /** + * Make the provided command element optional. + * + *

This means the command element is not required. However, if the + * element is provided with invalid format and there are no more args + * specified, any errors will still be passed on. If the given element's key + * and {@code value} are not null and this element is not provided the + * element's key will be set to the given value.

+ * + * @param element The element to optionally require + * @param value The default value to set + * @return the element to match the input + */ + public static CommandElement optional(CommandElement element, Object value) { + return new OptionalCommandElement(element, value, false); + } + + /** + * Make the provided command element optional + * This means the command element is not required. + * If the argument is provided but of invalid format, it will be skipped. + * + * @param element The element to optionally require + * @return the element to match the input + */ + public static CommandElement optionalWeak(CommandElement element) { + return new OptionalCommandElement(element, null, true); + } + + /** + *

Make the provided command element optional.

+ * + *

This means the command element is not required.

+ * + *
    + *
  • If the argument is provided but of invalid format, it will be + * skipped.
  • + *
  • If the given element's key and {@code value} are not null and + * this element is not provided the element's key will be set to the + * given value.
  • + *
+ * + * @param element The element to optionally require + * @param value The default value to set + * @return the element to match the input + */ + public static CommandElement optionalWeak(CommandElement element, Object value) { + return new OptionalCommandElement(element, value, true); + } + + /** + * Require a given command element to be provided a certain number of times. + * + *

Command values will be stored under their provided keys in the + * CommandContext.

+ * + * @param element The element to repeat + * @param times The number of times to repeat the element. + * @return the element to match the input + */ + public static CommandElement repeated(CommandElement element, int times) { + return new RepeatedCommandElement(element, times); + } + + /** + * Require all remaining args to match as many instances of + * {@link CommandElement} as will fit. Command element values will be stored + * under their provided keys in the CommandContext. + * + * @param element The element to repeat + * @return the element to match the input + */ + public static CommandElement allOf(CommandElement element) { + return new AllOfCommandElement(element); + } + + // -- Argument types for basic java types + + /** + * Require an argument to be a string. Any provided argument will fit in + * under this argument. + * + *

Gives values of type {@link String}. This will return only one value. + *

+ * + * @param key The key to store the parsed argument under + * @return the element to match the input + */ + public static CommandElement string(ChatMessage key) { + return new StringElement(key); + } + + /** + * Require an argument to be an integer (base 10). + * + *

Gives values of type {@link Integer}. This will return only one value. + *

+ * + * @param key The key to store the parsed argument under + * @return the element to match the input + */ + public static CommandElement integer(ChatMessage key) { + return new NumericElement<>(key, Integer::parseInt, Integer::parseInt, input -> ChatMessage.createTextMessage(String.format("Expected an integer, but input '%s' was not", input))); + } + + /** + * Require an argument to be a long (base 10). + * + *

Gives values of type {@link Long}. This will return only one value. + *

+ * + * @param key The key to store the parsed argument under + * @return the element to match the input + */ + public static CommandElement longNum(ChatMessage key) { + return new NumericElement<>(key, Long::parseLong, Long::parseLong, input -> ChatMessage.createTextMessage(String.format("Expected a long, but input '%s' was not", input))); + } + + /** + * Require an argument to be an double-precision floating point number. + * + *

Gives values of type {@link Double}. This will return only one value. + *

+ * + * @param key The key to store the parsed argument under + * @return the element to match the input + */ + public static CommandElement doubleNum(ChatMessage key) { + return new NumericElement<>(key, Double::parseDouble, null, input -> ChatMessage.createTextMessage(String.format("Expected a number, but input '%s' was not", input))); + } + + private static final Map BOOLEAN_CHOICES = ImmutableMap.builder() + .put("true", true) + .put("t", true) + .put("y", true) + .put("yes", true) + .put("verymuchso", true) + .put("1", true) + .put("false", false) + .put("f", false) + .put("n", false) + .put("no", false) + .put("notatall", false) + .put("0", false) + .build(); + + /** + * Require an argument to be a boolean. + * + *

The recognized true values are:

+ * + *
    + *
  • true
  • + *
  • t
  • + *
  • yes
  • + *
  • y
  • + *
  • verymuchso
  • + *
+ * + * + *

The recognized false values are:

+ * + *
    + *
  • false
  • + *
  • f
  • + *
  • no
  • + *
  • n
  • + *
  • notatall
  • + *
+ * + *

Gives values of type {@link Boolean}. This will return only one value. + *

+ * + * @param key The key to store the parsed argument under + * @return the element to match the input + */ + public static CommandElement bool(ChatMessage key) { + return GenericArguments.choices(key, BOOLEAN_CHOICES); + } + + /** + * Require the argument to be a key under the provided enum. + * + *

Gives values of type T. This will return only one value.

+ * + * @param key The key to store the matched enum value under + * @param type The enum class to get enum constants from + * @param The type of enum + * @return the element to match the input + */ + public static > CommandElement enumValue(ChatMessage key, Class type) { + return new EnumValueElement<>(key, type); + } + + /** + * Require one or more strings, which are combined into a single, + * space-separated string. + * + *

Gives values of type {@link String}. This will return only one value. + *

+ * + * @param key The key to store the parsed argument under + * @return the element to match the input + */ + public static CommandElement remainingJoinedStrings(ChatMessage key) { + return new RemainingJoinedStringsCommandElement(key, false); + } + + /** + * Require one or more strings, without any processing, which are combined + * into a single, space-separated string. + * + *

Gives values of type {@link String}. This will return only one value. + *

+ * + * @param key The key to store the parsed argument under + * @return the element to match the input + */ + public static CommandElement remainingRawJoinedStrings(ChatMessage key) { + return new RemainingJoinedStringsCommandElement(key, true); + } + + /** + * Expect a literal sequence of arguments. This element matches the input + * against a predefined array of arguments expected to be present, + * case-insensitively. + * + *

This will return only one value.

+ * + * @param key The key to add to the context. Will be set to a value of true + * if this element matches + * @param expectedArgs The sequence of arguments expected + * @return the appropriate command element + */ + public static CommandElement literal(ChatMessage key, String... expectedArgs) { + return new LiteralCommandElement(key, ImmutableList.copyOf(expectedArgs), true); + } + + /** + * Expect a literal sequence of arguments. This element matches the input + * against a predefined array of arguments expected to be present, + * case-insensitively. + * + *

This will return only one value.

+ * + * @param key The key to store this argument as + * @param putValue The value to put at key if this argument matches. May be + * null + * @param expectedArgs The sequence of arguments expected + * @return the appropriate command element + */ + public static CommandElement literal(ChatMessage key, @Nullable Object putValue, String... expectedArgs) { + return new LiteralCommandElement(key, ImmutableList.copyOf(expectedArgs), putValue); + } + + /** + * Restricts the given command element to only insert one value into the + * context at the provided key. + * + *

If more than one value is returned by an element, or the target key + * already contains a value, this will throw an + * {@link ArgumentParseException}

+ * + * @param element The element to restrict + * @return the restricted element + */ + public static CommandElement onlyOne(CommandElement element) { + return new OnlyOneCommandElement(element); + } + + /** + * Checks a permission for a given command argument to be used. + * + *

If the element attempts to parse an argument and the user does not + * have the permission, an {@link ArgumentParseException} will be thrown.

+ * + * @param element The element to wrap + * @param permission The permission to check + * @return the element + */ + public static CommandElement requiringPermission(CommandElement element, String permission) { + return new PermissionCommandElement(element, permission, false); + } + + /** + * Checks a permission for a given command argument to be used. + * + *

If the element attempts to parse an argument and the user does not + * have the permission, the element will be skipped over.

+ * + *

If the invoking {@link PermissibleCommandSource} has permission to use the + * element, but the wrapped element fails to parse, an exception will + * be reported in the normal way. If you require this element to be + * truly optional, wrap this element in either + * {@link #optional(CommandElement)} or + * {@link #optionalWeak(CommandElement)}, as required.

+ * + * @param element The element to wrap + * @param permission The permission to check + * @return the element + */ + public static CommandElement requiringPermissionWeak(CommandElement element, String permission) { + return new PermissionCommandElement(element, permission, true); + } + + /** + * Expect an argument to represent an {@link Entity}. + * + *

This argument accepts the following inputs:

+ * + *
    + *
  • A player's name
  • + *
  • An entity's {@link UUID}
  • + *
  • A regex that matches the beginning of one or more player's names + * or entities UUIDs. + *
  • + *
  • A selector
  • + *
+ * + * @param key The key to store under + * @return the argument + */ + public static CommandElement entity(ChatMessage key) { + return new EntityCommandElement(key, false, false, null); + } + + /** + * Expect an argument to represent an {@link Entity} of the specified type. + * + *

This argument accepts the following inputs:

+ * + *
    + *
  • A player's name (if appropriate)
  • + *
  • An entity's {@link UUID}
  • + *
  • A regex that matches the beginning of one or more player's names + * or entities UUIDs. + *
  • + *
  • A selector
  • + *
+ * + * @param key The key to store under + * @param clazz The type which the entity must subclass + * @return the argument + */ + public static CommandElement entity(ChatMessage key, Class clazz) { + return new EntityCommandElement(key, false, false, clazz); + } + + /** + * Expect an argument to represent an {@link Entity} of the specified type, + * or if the argument is not present and the {@link PermissibleCommandSource} is + * looking at an applicable entity, return that entity. + * + *

This argument accepts the following inputs:

+ * + *
    + *
  • A player's name (if appropriate)
  • + *
  • An entity's {@link UUID}
  • + *
  • A regex that matches the beginning of one or more player's names + * or entities UUIDs. + *
  • + *
  • A selector
  • + *
+ * + * @param key The key to store under + * @param clazz The type which the entity must subclass + * @return the argument + */ + public static CommandElement entityOrTarget(ChatMessage key, Class clazz) { + return new EntityCommandElement(key, false, true, clazz); + } + + /** + * Expect an argument to represent a {@link URL}. + * + *

This will return only one value.

+ * + * @param key The key to store under + * @return the argument + */ + public static CommandElement url(ChatMessage key) { + return new UrlElement(key); + } + + /** + * Expect an argument to return an IP address, in the form of an + * {@link InetAddress}. + * + *

This will return only one value.

+ * + * @param key The key to store under + * @return the argument + */ + public static CommandElement ip(ChatMessage key) { + return new IpElement(key); + } + + /** + * Expect an argument to return a {@link BigDecimal}. + * + * @param key The key to store under + * @return the argument + */ + public static CommandElement bigDecimal(ChatMessage key) { + return new BigDecimalElement(key); + } + + /** + * Expect an argument to return a {@link BigInteger}. + * + *

This will return only one value.

+ * + * @param key The key to store under + * @return the argument + */ + public static CommandElement bigInteger(ChatMessage key) { + return new BigIntegerElement(key); + } + + /** + * Expect an argument to be a {@link UUID}. + * + *

This will return only one value.

+ * + * @param key The key to store under + * @return the argument + */ + public static CommandElement uuid(ChatMessage key) { + return new UuidElement(key); + } + + /** + * Expect an argument to be a {@link String}. + * + *

This will return only one value.

+ * + * @param key The key to store under + * @param type The type of parsing to be followed + * @return the argument + */ + public static CommandElement string(ChatMessage key, StringType type) { + return new StringCommandElement(key, type); + } + + /** + * Expect an argument to be a date-time, in the form of a + * {@link LocalDateTime}. If no date is specified, {@link LocalDate#now()} + * is used; if no time is specified, {@link LocalTime#MIDNIGHT} is used. + * + *

Date-times are expected in the ISO-8601 format.

+ * + *

This will return only one value.

+ * + * @param key The key to store under + * @return the argument + * @see ISO-8601 + */ + public static CommandElement dateTime(ChatMessage key) { + return new DateTimeElement(key, false); + } + + /** + * Expect an argument to be a date-time, in the form of a + * {@link LocalDateTime}. If no date is specified, {@link LocalDate#now()} + * is used; if no time is specified, {@link LocalTime#MIDNIGHT} is used. + * + *

If no argument at all is specified, defaults to + * {@link LocalDateTime#now()}.

+ * + *

Date-times are expected in the ISO-8601 format.

+ * + *

This will return only one value.

+ * + * @param key The key to store under + * @return the argument + */ + public static CommandElement dateTimeOrNow(ChatMessage key) { + return new DateTimeElement(key, true); + } + + /** + * Expect an argument to be a {@link Duration}. + * + *

Durations are expected in the following format: {@code #D#H#M#S}. + * This is not case sensitive.

+ * + *

This will return only one value.

+ * + * @param key The key to store under + * @return the argument + */ + public static CommandElement duration(ChatMessage key) { + return new DurationElement(key); + } + + /** + * Uses a custom set of suggestions for an argument. The provided + * suggestions will replace the regular ones. + * + * @param argument The element to replace the suggestions of + * @param suggestions The suggestions to use + * @return the argument + */ + public static CommandElement withSuggestions(CommandElement argument, Iterable suggestions) { + return withSuggestions(argument, suggestions, true); + } + + /** + * Uses a custom set of suggestions for an argument. The provided + * suggestions will replace the regular ones. + * + *

If {@code requireBegin} is false, then the already typed argument + * will not be used to filter the provided suggestions.

+ * + * @param argument The element to replace the suggestions of + * @param suggestions The suggestions to use + * @param requireBegin Whether or not to require the current argument to + * begin provided arguments + * @return the argument + */ + public static CommandElement withSuggestions(CommandElement argument, Iterable suggestions, boolean requireBegin) { + return withSuggestions(argument, (s) -> suggestions, requireBegin); + } + + /** + * Uses a custom set of suggestions for an argument. The provided + * suggestions will replace the regular ones. + * + * @param argument The element to replace the suggestions of + * @param suggestions A function to return the suggestions to use + * @return the argument + */ + public static CommandElement withSuggestions(CommandElement argument, Function> suggestions) { + return withSuggestions(argument, suggestions, true); + } + + /** + * Uses a custom set of suggestions for an argument. The provided + * suggestions will replace the regular ones. + * + *

If {@code requireBegin} is false, then the already typed argument + * will not be used to filter the provided suggestions.

+ * + * @param argument The element to replace the suggestions of + * @param suggestions A function to return the suggestions to use + * @param requireBegin Whether or not to require the current argument to + * begin provided arguments + * @return the argument + */ + public static CommandElement withSuggestions(CommandElement argument, Function> suggestions, boolean requireBegin) { + return new WithSuggestionsElement(argument, suggestions, requireBegin); + } + + /** + * Filters an argument's suggestions. A suggestion will only be used if it + * matches the predicate. + * + * @param argument The element to filter the suggestions of + * @param predicate The predicate to test suggestions against + * @return the argument + */ + public static CommandElement withConstrainedSuggestions(CommandElement argument, Predicate predicate) { + return new FilteredSuggestionsElement(argument, predicate); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/KeyElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/KeyElement.java new file mode 100644 index 000000000..f70b70e01 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/KeyElement.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; + +import java.util.Collections; +import java.util.List; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +/** + * Parent class that specifies elements as having no tab completions. + * Useful for inputs with a very large domain, like strings and integers. + */ +public abstract class KeyElement extends CommandElement { + protected KeyElement(ChatMessage key) { + super(key); + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + return Collections.emptyList(); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/PatternMatchingCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/PatternMatchingCommandElement.java new file mode 100644 index 000000000..57c638d55 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/PatternMatchingCommandElement.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +/** + * Abstract command element that matches values based on a regex pattern. + */ +public abstract class PatternMatchingCommandElement extends CommandElement { + private static final ChatMessage nullKeyArg = ChatMessage.createTextMessage("argument"); + final boolean useRegex; + + /** + * @param yesIWantRegex Specify if you want to allow regex for users of + * the command element. Note that this will open up for DoS attacks. + */ + protected PatternMatchingCommandElement(@Nullable ChatMessage key, boolean yesIWantRegex) { + super(key); + this.useRegex = yesIWantRegex; + } + + protected PatternMatchingCommandElement(@Nullable ChatMessage key) { + this(key, false); + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + Iterable choices = this.getChoices(source); + Iterable ret; + String arg = args.next(); + + // Check to see if we have an exact match first + Optional exactMatch = this.getExactMatch(choices, arg); + + if (exactMatch.isPresent()) { + // Return this as a collection as this can get transformed by the subclass. + return Collections.singleton(exactMatch.get()); + } + + if (this.useRegex) { + Pattern pattern = this.getFormattedPattern(arg); + ret = StreamSupport.stream(choices.spliterator(), false).filter(element -> pattern.matcher(element).find()).collect(Collectors.toList()).stream().map(this::getValue).collect(Collectors.toList()); + } else { + Iterable startsWith = StreamSupport.stream(choices.spliterator(), false).filter(element -> element.regionMatches(true, 0, arg, 0, arg.length())).collect(Collectors.toList()); + ret = StreamSupport.stream(startsWith.spliterator(), false).map(this::getValue).collect(Collectors.toList()); + } + + if (!ret.iterator().hasNext()) { + throw args.createError(ChatMessage.createTextMessage(String.format("No values matching pattern '%s' present for %s!", arg, this.getKey() == null + ? nullKeyArg : this.getKey()))); + } + + return ret; + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + Iterable choices = this.getChoices(src); + final Optional nextArg = args.nextIfPresent(); + + if (nextArg.isPresent()) { + if (this.useRegex) { + choices = StreamSupport.stream(choices.spliterator(), false).filter(input -> this.getFormattedPattern(nextArg.get()).matcher(input).find()).collect(Collectors.toList()); + } else { + String arg = nextArg.get(); + choices = StreamSupport.stream(choices.spliterator(), false).filter(input -> input.regionMatches(true, 0, arg, 0, arg.length())).collect(Collectors.toList()); + } + } + + return ImmutableList.copyOf(choices); + } + + Pattern getFormattedPattern(String input) { + if (!input.startsWith("^")) { // Anchor matches to the beginning -- this lets us use find() + input = "^" + input; + } + + return Pattern.compile(input, Pattern.CASE_INSENSITIVE); + } + + /** + * Tests a string against a set of valid choices to see if it is a + * case-insensitive match. + * + * @param choices The choices available to match against + * @param potentialChoice The potential choice + * @return If matched, an {@link Optional} containing the matched value + */ + protected Optional getExactMatch(final Iterable choices, final String potentialChoice) { + return Optional.ofNullable(Iterables.tryFind(choices, potentialChoice::equalsIgnoreCase).orNull()).map(this::getValue); + } + + /** + * Gets the available choices for this command source. + * + * @param source The source requesting choices + * @return the possible choices + */ + protected abstract Iterable getChoices(PermissibleCommandSource source); + + /** + * Gets the value for a given choice. For any result in + * {@link #getChoices(PermissibleCommandSource)}, this must return a non-null value. + * Otherwise, an {@link IllegalArgumentException} may be throw. + * + * @param choice The specified choice + * @return the choice's value + * @throws IllegalArgumentException if the input string is not any return + * value of {@link #getChoices(PermissibleCommandSource)} + */ + protected abstract Object getValue(String choice) throws IllegalArgumentException; +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/SelectorCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/SelectorCommandElement.java new file mode 100644 index 000000000..09610c43e --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/SelectorCommandElement.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; + +import java.util.List; +import java.util.Optional; + +import com.google.common.collect.ImmutableList; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.Selector; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public abstract class SelectorCommandElement extends PatternMatchingCommandElement { + protected SelectorCommandElement(@Nullable ChatMessage key) { + super(key); + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + String arg = args.peek(); + + if (arg.startsWith("@")) { // Possibly a selector + try { + return Selector.parse(args.next()).resolve(source); + } catch (IllegalArgumentException ex) { + throw args.createError(ChatMessage.createTextMessage(ex.getMessage())); + } + } + + return super.parseValue(source, args); + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + CommandArgs.Snapshot state = args.getSnapshot(); + final Optional nextArg = args.nextIfPresent(); + args.applySnapshot(state); + List choices = nextArg.isPresent() ? Selector.complete(nextArg.get()) : ImmutableList.of(); + + if (choices.isEmpty()) { + choices = super.complete(src, args, context); + } + + return choices; + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/InputTokenizer.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/InputTokenizer.java new file mode 100644 index 000000000..837cc4d9c --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/InputTokenizer.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing; + +import java.util.List; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; + +public interface InputTokenizer { + /** + * Use an input string tokenizer that supports quoted arguments and + * character escapes. + * + *

Forcing lenient to true makes the following apply:

+ * + *
    + *
  • Unclosed quotations are treated as a single string from the + * opening quotation to the end of the arguments rather than throwing + * an exception
  • + *
+ * + * @param forceLenient Whether the tokenizer is forced into lenient mode + * @return the appropriate tokenizer + */ + static InputTokenizer quotedStrings(boolean forceLenient) { + return new QuotedStringTokenizer(true, forceLenient, false); + } + + /** + * Returns an input tokenizer that takes input strings and splits them by + * space. + * + * @return The appropriate tokenizer + */ + static InputTokenizer spaceSplitString() { + return SpaceSplitInputTokenizer.INSTANCE; + } + + /** + * Returns an input tokenizer that returns the input string as a single + * argument. + * + * @return The appropriate tokenizer + */ + static InputTokenizer rawInput() { + return RawStringInputTokenizer.INSTANCE; + } + + /** + * Take the input string and split it as appropriate into argument tokens. + * + * @param arguments The provided arguments + * @param lenient Whether to parse leniently + * @return The tokenized strings. Empty list if error occurs + * @throws ArgumentParseException if an invalid input is provided + */ + List tokenize(String arguments, boolean lenient) throws ArgumentParseException; +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/QuotedStringTokenizer.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/QuotedStringTokenizer.java new file mode 100644 index 000000000..106d51cdf --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/QuotedStringTokenizer.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; + +/** + * Parser for converting a quoted string into a list of arguments. + * + *

Grammar is roughly (yeah, this is not really a proper grammar but it gives + * you an idea of what's happening:

+ * + *
 WHITESPACE = Character.isWhiteSpace(codePoint)
+ * CHAR := (all unicode)
+ * ESCAPE := '\' CHAR
+ * QUOTE = ' | "
+ * UNQUOTED_ARG := (CHAR | ESCAPE)+ WHITESPACE
+ * QUOTED_ARG := QUOTE (CHAR | ESCAPE)+ QUOTE
+ * ARGS := ((UNQUOTED_ARG | QUOTED_ARG) WHITESPACE+)+
+ */ +class QuotedStringTokenizer implements InputTokenizer { + private static final int CHAR_BACKSLASH = '\\'; + private static final int CHAR_SINGLE_QUOTE = '\''; + private static final int CHAR_DOUBLE_QUOTE = '"'; + private final boolean handleQuotedStrings; + private final boolean forceLenient; + private final boolean trimTrailingSpace; + + QuotedStringTokenizer(boolean handleQuotedStrings, boolean forceLenient, boolean trimTrailingSpace) { + this.handleQuotedStrings = handleQuotedStrings; + this.forceLenient = forceLenient; + this.trimTrailingSpace = trimTrailingSpace; + } + + @Override + public List tokenize(String arguments, boolean lenient) throws ArgumentParseException { + if (arguments.length() == 0) { + return Collections.emptyList(); + } + + final TokenizerState state = new TokenizerState(arguments, lenient); + List returnedArgs = new ArrayList<>(arguments.length() / 4); + + if (this.trimTrailingSpace) { + this.skipWhiteSpace(state); + } + + while (state.hasMore()) { + if (!this.trimTrailingSpace) { + this.skipWhiteSpace(state); + } + + int startIdx = state.getIndex() + 1; + String arg = this.nextArg(state); + returnedArgs.add(new SingleArg(arg, startIdx, state.getIndex())); + + if (this.trimTrailingSpace) { + this.skipWhiteSpace(state); + } + } + + return returnedArgs; + } + + // Parsing methods + + private void skipWhiteSpace(TokenizerState state) throws ArgumentParseException { + if (!state.hasMore()) { + return; + } + + while (state.hasMore() && Character.isWhitespace(state.peek())) { + state.next(); + } + } + + private String nextArg(TokenizerState state) throws ArgumentParseException { + StringBuilder argBuilder = new StringBuilder(); + + if (state.hasMore()) { + int codePoint = state.peek(); + + if (this.handleQuotedStrings && (codePoint == CHAR_DOUBLE_QUOTE || codePoint == CHAR_SINGLE_QUOTE)) { + // quoted string + this.parseQuotedString(state, codePoint, argBuilder); + } else { + this.parseUnquotedString(state, argBuilder); + } + } + + return argBuilder.toString(); + } + + private void parseQuotedString(TokenizerState state, int startQuotation, StringBuilder builder) throws ArgumentParseException { + // Consume the start quotation character + int nextCodePoint = state.next(); + + if (nextCodePoint != startQuotation) { + throw state.createException(ChatMessage.createTextMessage(String.format("Actual next character '%c' did not match expected quotation character '%c'", + nextCodePoint, startQuotation))); + } + + while (true) { + if (!state.hasMore()) { + if (state.isLenient() || this.forceLenient) { + return; + } + + throw state.createException(ChatMessage.createTextMessage("Unterminated quoted string found")); + } + + nextCodePoint = state.peek(); + + if (nextCodePoint == startQuotation) { + state.next(); + return; + } else if (nextCodePoint == CHAR_BACKSLASH) { + this.parseEscape(state, builder); + } else { + builder.appendCodePoint(state.next()); + } + } + } + + private void parseUnquotedString(TokenizerState state, StringBuilder builder) throws ArgumentParseException { + while (state.hasMore()) { + int nextCodePoint = state.peek(); + + if (Character.isWhitespace(nextCodePoint)) { + return; + } else if (nextCodePoint == CHAR_BACKSLASH) { + this.parseEscape(state, builder); + } else { + builder.appendCodePoint(state.next()); + } + } + } + + private void parseEscape(TokenizerState state, StringBuilder builder) throws ArgumentParseException { + state.next(); // Consume \ + builder.appendCodePoint(state.next()); // TODO: Unicode character escapes (\u00A7 type thing)? + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/RawStringInputTokenizer.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/RawStringInputTokenizer.java new file mode 100644 index 000000000..7e9ca53f9 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/RawStringInputTokenizer.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing; + +import java.util.Collections; +import java.util.List; + +class RawStringInputTokenizer implements InputTokenizer { + static final RawStringInputTokenizer INSTANCE = new RawStringInputTokenizer(); + + private RawStringInputTokenizer() { + } + + @Override + public List tokenize(String arguments, boolean lenient) { + return Collections.singletonList(new SingleArg(arguments, 0, arguments.length())); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SingleArg.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SingleArg.java new file mode 100644 index 000000000..bf8b5bbf2 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SingleArg.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing; + +import com.google.common.base.Objects; + +/** + * This represents a single argument with its start and end indexes + * in the associated raw input string. + */ +public class SingleArg { + private final String value; + private final int startIdx; + private final int endIdx; + + /** + * Create a new argument. + * + * @param value The argument string + * @param startIdx The starting index of {@code value} in an input string + * @param endIdx The ending index of {@code value} in an input string + */ + public SingleArg(String value, int startIdx, int endIdx) { + this.value = value; + this.startIdx = startIdx; + this.endIdx = endIdx; + } + + /** + * Gets the string used. + * + * @return The string used + */ + public String getValue() { + return this.value; + } + + /** + * Gets the starting index. + * + * @return The starting index + */ + public int getStartIdx() { + return this.startIdx; + } + + /** + * Gets the ending index. + * + * @return The ending index + */ + public int getEndIdx() { + return this.endIdx; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof SingleArg)) { + return false; + } + + SingleArg singleArg = (SingleArg) o; + return this.startIdx == singleArg.startIdx + && this.endIdx == singleArg.endIdx + && Objects.equal(this.value, singleArg.value); + } + + @Override + public int hashCode() { + return Objects.hashCode(this.value, this.startIdx, this.endIdx); + } + + @Override + public String toString() { + return Objects.toStringHelper(this) + .add("value", this.value) + .add("startIdx", this.startIdx) + .add("endIdx", this.endIdx) + .toString(); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SpaceSplitInputTokenizer.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SpaceSplitInputTokenizer.java new file mode 100644 index 000000000..b8e0e16dd --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SpaceSplitInputTokenizer.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +import com.google.common.collect.ImmutableList; + +class SpaceSplitInputTokenizer implements InputTokenizer { + public static final SpaceSplitInputTokenizer INSTANCE = new SpaceSplitInputTokenizer(); + private static final Pattern SPACE_REGEX = Pattern.compile("^[ ]*$"); + + private SpaceSplitInputTokenizer() { + } + + @Override + public List tokenize(String arguments, boolean lenient) { + if (SPACE_REGEX.matcher(arguments).matches()) { + return ImmutableList.of(); + } + + List ret = new ArrayList<>(); + int lastIndex = 0; + int spaceIndex; + + while ((spaceIndex = arguments.indexOf(" ")) != -1) { + if (spaceIndex != 0) { + ret.add(new SingleArg(arguments.substring(0, spaceIndex), lastIndex, lastIndex + spaceIndex)); + arguments = arguments.substring(spaceIndex); + } else { + arguments = arguments.substring(1); + } + + lastIndex += spaceIndex + 1; + } + + ret.add(new SingleArg(arguments, lastIndex, lastIndex + arguments.length())); + return ret; + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/TokenizerState.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/TokenizerState.java new file mode 100644 index 000000000..8a83c351b --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/TokenizerState.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; + +class TokenizerState { + private final boolean lenient; + private final String buffer; + private int index = -1; + + TokenizerState(String buffer, boolean lenient) { + this.buffer = buffer; + this.lenient = lenient; + } + + // Utility methods + public boolean hasMore() { + return this.index + 1 < this.buffer.length(); + } + + public int peek() throws ArgumentParseException { + if (!this.hasMore()) { + throw this.createException(ChatMessage.createTextMessage("Buffer overrun while parsing args")); + } + + return this.buffer.codePointAt(this.index + 1); + } + + public int next() throws ArgumentParseException { + if (!this.hasMore()) { + throw this.createException(ChatMessage.createTextMessage("Buffer overrun while parsing args")); + } + + return this.buffer.codePointAt(++this.index); + } + + public ArgumentParseException createException(ChatMessage message) { + return new ArgumentParseException(message, this.buffer, this.index); + } + + public boolean isLenient() { + return this.lenient; + } + + public int getIndex() { + return this.index; + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Disambiguator.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Disambiguator.java new file mode 100644 index 000000000..f82134407 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Disambiguator.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher; + +import java.util.List; +import java.util.Optional; + +import org.jetbrains.annotations.Nullable; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMapping; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +@FunctionalInterface +public interface Disambiguator { + /** + * Disambiguate an alias in cases where there are multiple command mappings + * registered for a given alias. + * + * @param source The PermissibleCommandSource executing the command, if any + * @param aliasUsed The alias input by the user + * @param availableOptions The commands registered to this alias + * @return The specific command to use + */ + Optional disambiguate(@Nullable PermissibleCommandSource source, String aliasUsed, List availableOptions); +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Dispatcher.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Dispatcher.java new file mode 100644 index 000000000..40cb5346c --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Dispatcher.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher; + +import java.util.Optional; +import java.util.Set; + +import com.google.common.collect.Multimap; +import org.jetbrains.annotations.Nullable; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandCallable; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMapping; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +/** + * Executes a command based on user input. + */ +public interface Dispatcher extends CommandCallable { + /** + * Gets a list of commands. Each command, regardless of how many aliases it + * may have, will only appear once in the returned set. + * + *

The returned collection cannot be modified.

+ * + * @return A list of registrations + */ + Set getCommands(); + + /** + * Gets a list of primary aliases. + * + *

The returned collection cannot be modified.

+ * + * @return A list of aliases + */ + Set getPrimaryAliases(); + + /** + * Gets a list of all the command aliases, which includes the primary alias. + * + *

A command may have more than one alias assigned to it. The returned + * collection cannot be modified.

+ * + * @return A list of aliases + */ + Set getAliases(); + + /** + * Gets the {@link CommandMapping} associated with an alias. Returns null if + * no command is named by the given alias. + * + * @param alias The alias + * @return The command mapping, if available + */ + Optional get(String alias); + + /** + * Gets the {@link CommandMapping} associated with an alias in the context + * of a given {@link PermissibleCommandSource}. Returns null if no command is named by + * the given alias. + * + * @param alias The alias to look up + * @param source The source this alias is being looked up for + * @return The command mapping, if available + */ + Optional get(String alias, @Nullable PermissibleCommandSource source); + + /** + * Gets all the {@link CommandMapping}s associated with an alias. + * + * @param alias The alias + * @return The command mappings associated with the alias + */ + Set getAll(String alias); + + /** + * Gets all commands currently registered with this dispatcher. The returned + * value is immutable. + * + * @return a multimap from alias to mapping of every registered command + */ + Multimap getAll(); + + /** + * Returns whether the dispatcher contains a registered command for the + * given alias. + * + * @param alias The alias + * @return True if a registered command exists + */ + boolean containsAlias(String alias); + + /** + * Returns whether the dispatcher contains the given mapping. + * + * @param mapping The mapping + * @return True if a mapping exists + */ + boolean containsMapping(CommandMapping mapping); +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/SimpleDispatcher.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/SimpleDispatcher.java new file mode 100644 index 000000000..9017acc49 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/SimpleDispatcher.java @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; +import net.minecraft.util.Formatting; +import net.minecraft.world.World; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandCallable; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMapping; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandNotFoundException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandResult; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.ImmutableCommandMapping; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.InvocationCommandException; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; +import net.legacyfabric.fabric.api.util.Location; + +/** + * A simple implementation of a {@link Dispatcher}. + */ +public final class SimpleDispatcher implements Dispatcher { + /** + * This is a disambiguator function that returns the first matching command. + */ + public static final Disambiguator FIRST_DISAMBIGUATOR = (source, aliasUsed, availableOptions) -> { + for (CommandMapping mapping : availableOptions) { + if (mapping.getPrimaryAlias().toLowerCase().equals(aliasUsed.toLowerCase())) { + return Optional.of(mapping); + } + } + + return Optional.of(availableOptions.get(0)); + }; + + private final Disambiguator disambiguatorFunc; + private final ListMultimap commands = ArrayListMultimap.create(); + + /** + * Creates a basic new dispatcher. + */ + public SimpleDispatcher() { + this(FIRST_DISAMBIGUATOR); + } + + /** + * Creates a new dispatcher with a specific disambiguator. + * + * @param disambiguatorFunc Function that returns the preferred command if + * multiple exist for a given alias + */ + public SimpleDispatcher(Disambiguator disambiguatorFunc) { + this.disambiguatorFunc = disambiguatorFunc; + } + + /** + * Register a given command using the given list of aliases. + * + *

If there is a conflict with one of the aliases (i.e. that alias + * is already assigned to another command), then the alias will be skipped. + * It is possible for there to be no alias to be available out of + * the provided list of aliases, which would mean that the command would not + * be assigned to any aliases.

+ * + *

The first non-conflicted alias becomes the "primary alias."

+ * + * @param callable The command + * @param alias An array of aliases + * @return The registered command mapping, unless no aliases could be + * registered + */ + public Optional register(CommandCallable callable, String... alias) { + Preconditions.checkNotNull(alias, "alias"); + return this.register(callable, Arrays.asList(alias)); + } + + /** + * Register a given command using the given list of aliases. + * + *

If there is a conflict with one of the aliases (i.e. that alias + * is already assigned to another command), then the alias will be skipped. + * It is possible for there to be no alias to be available out of + * the provided list of aliases, which would mean that the command would not + * be assigned to any aliases.

+ * + *

The first non-conflicted alias becomes the "primary alias."

+ * + * @param callable The command + * @param aliases A list of aliases + * @return The registered command mapping, unless no aliases could be + * registered + */ + public Optional register(CommandCallable callable, List aliases) { + return this.register(callable, aliases, Function.identity()); + } + + /** + * Register a given command using a given list of aliases. + * + *

The provided callback function will be called with a list of aliases + * that are not taken (from the list of aliases that were requested) and + * it should return a list of aliases to actually register. Aliases may be + * removed, and if no aliases remain, then the command will not be + * registered. It may be possible that no aliases are available, and thus + * the callback would receive an empty list. New aliases should not be added + * to the list in the callback as this may cause + * {@link IllegalArgumentException} to be thrown.

+ * + *

The first non-conflicted alias becomes the "primary alias."

+ * + * @param callable The command + * @param aliases A list of aliases + * @param callback The callback + * @return The registered command mapping, unless no aliases could + * be registered + */ + public synchronized Optional register(CommandCallable callable, List aliases, Function, List> callback) { + Preconditions.checkNotNull(aliases, "aliases"); + Preconditions.checkNotNull(callable, "callable"); + Preconditions.checkNotNull(callback, "callback"); + + // Invoke the callback with the commands that /can/ be registered + aliases = ImmutableList.copyOf(callback.apply(aliases)); + + if (aliases.isEmpty()) { + return Optional.empty(); + } + + String primary = aliases.get(0); + List secondary = aliases.subList(1, aliases.size()); + CommandMapping mapping = new ImmutableCommandMapping(callable, primary, secondary); + + for (String alias : aliases) { + this.commands.put(alias.toLowerCase(), mapping); + } + + return Optional.of(mapping); + } + + /** + * Remove a mapping identified by the given alias. + * + * @param alias The alias + * @return The previous mapping associated with the alias, if one was found + */ + public synchronized Collection remove(String alias) { + return this.commands.removeAll(alias.toLowerCase()); + } + + /** + * Remove all mappings identified by the given aliases. + * + * @param aliases A collection of aliases + * @return Whether any were found + */ + public synchronized boolean removeAll(Collection aliases) { + Preconditions.checkNotNull(aliases, "aliases"); + + boolean found = false; + + for (Object alias : aliases) { + if (!this.commands.removeAll(alias.toString().toLowerCase()).isEmpty()) { + found = true; + } + } + + return found; + } + + /** + * Remove a command identified by the given mapping. + * + * @param mapping The mapping + * @return The previous mapping associated with the alias, if one was found + */ + public synchronized Optional removeMapping(CommandMapping mapping) { + Preconditions.checkNotNull(mapping, "mapping"); + + CommandMapping found = null; + + Iterator it = this.commands.values().iterator(); + + while (it.hasNext()) { + CommandMapping current = it.next(); + + if (current.equals(mapping)) { + it.remove(); + found = current; + } + } + + return Optional.ofNullable(found); + } + + /** + * Remove all mappings contained with the given collection. + * + * @param mappings The collection + * @return Whether the at least one command was removed + */ + public synchronized boolean removeMappings(Collection mappings) { + Preconditions.checkNotNull(mappings, "mappings"); + boolean found = false; + Iterator it = this.commands.values().iterator(); + + while (it.hasNext()) { + if (mappings.contains(it.next())) { + it.remove(); + found = true; + } + } + + return found; + } + + @Override + public synchronized Set getCommands() { + return ImmutableSet.copyOf(this.commands.values()); + } + + @Override + public synchronized Set getPrimaryAliases() { + Set aliases = new HashSet<>(); + + for (CommandMapping mapping : this.commands.values()) { + aliases.add(mapping.getPrimaryAlias()); + } + + return Collections.unmodifiableSet(aliases); + } + + @Override + public synchronized Set getAliases() { + Set aliases = new HashSet<>(); + + for (CommandMapping mapping : this.commands.values()) { + aliases.addAll(mapping.getAllAliases()); + } + + return Collections.unmodifiableSet(aliases); + } + + @Override + public Optional get(String alias) { + return this.get(alias, null); + } + + @Override + public synchronized Optional get(String alias, @Nullable PermissibleCommandSource source) { + List results = this.commands.get(alias.toLowerCase()); + Optional result = Optional.empty(); + + if (results.size() == 1) { + result = Optional.of(results.get(0)); + } else if (results.size() > 1) { + result = this.disambiguatorFunc.disambiguate(source, alias, results); + } + + if (source != null) { + result = result.filter(m -> m.getCallable().testPermission(source)); + } + + return result; + } + + @Override + public synchronized boolean containsAlias(String alias) { + return this.commands.containsKey(alias.toLowerCase()); + } + + @Override + public boolean containsMapping(CommandMapping mapping) { + Preconditions.checkNotNull(mapping, "mapping"); + + for (CommandMapping test : this.commands.values()) { + if (mapping.equals(test)) { + return true; + } + } + + return false; + } + + @Override + public CommandResult process(PermissibleCommandSource source, String commandLine) throws CommandException { + final String[] argSplit = commandLine.split(" ", 2); + Optional cmdOptional = this.get(argSplit[0], source); + + if (!cmdOptional.isPresent()) { + throw new CommandNotFoundException(ChatMessage.createTranslateMessage("commands.generic.notFound"), argSplit[0]); + } + + final String arguments = argSplit.length > 1 ? argSplit[1] : ""; + CommandMapping mapping = cmdOptional.get(); + final CommandCallable spec = mapping.getCallable(); + + try { + return spec.process(source, arguments); + } catch (CommandNotFoundException e) { + throw new CommandException(ChatMessage.createTextMessage("No such child command: " + e.getCommand())); + } catch (RuntimeException e) { + throw new InvocationCommandException(ChatMessage.createTextMessage("An unexpected error happened executing the command"), e); + } + } + + @Override + public List getSuggestions(PermissibleCommandSource src, final String arguments, @Nullable Location targetPosition) throws CommandException { + final String[] argSplit = arguments.split(" ", 2); + Optional cmdOptional = this.get(argSplit[0], src); + + if (argSplit.length == 1) { + return Collections.unmodifiableList(new ArrayList<>(this.filterCommands(src, argSplit[0]))); + } else if (!cmdOptional.isPresent()) { + return ImmutableList.of(); + } + + return cmdOptional.get().getCallable().getSuggestions(src, argSplit[1], targetPosition); + } + + @Override + public boolean testPermission(PermissibleCommandSource source) { + for (CommandMapping mapping : this.commands.values()) { + if (mapping.getCallable().testPermission(source)) { + return true; + } + } + + return false; + } + + @Override + public Optional getShortDescription(PermissibleCommandSource source) { + return Optional.empty(); + } + + @Override + public Optional getHelp(PermissibleCommandSource source) { + if (this.commands.isEmpty()) { + return Optional.empty(); + } + + ChatMessage build = ChatMessage.createTextMessage("Available commands:\n"); + + for (Iterator it = this.filterCommands(source).iterator(); it.hasNext(); ) { + final Optional mappingOpt = this.get(it.next(), source); + + if (!mappingOpt.isPresent()) { + continue; + } + + CommandMapping mapping = mappingOpt.get(); + final Optional description = mapping.getCallable().getShortDescription(source); + ChatMessage text = ChatMessage.createTextMessage(mapping.getPrimaryAlias()); + build.addUsing( + text.setColor(Formatting.GREEN).setUnderlined(true) + ).addUsing(CommandMessageFormatting.SPACE_TEXT) + .addUsing(description.orElse(mapping.getCallable().getUsage(source))); + + if (it.hasNext()) { + build.addText("\n"); + } + } + + return Optional.of(ChatMessage.createTextMessage(build.toString())); + } + + private Set filterCommands(final PermissibleCommandSource src) { + return Multimaps.filterValues(this.commands, input -> input.getCallable().testPermission(src)).keys().elementSet(); + } + + // Filter out commands by String first + private Set filterCommands(final PermissibleCommandSource src, String start) { + Multimap map = Multimaps.filterKeys(this.commands, + input -> input != null && input.toLowerCase().startsWith(start.toLowerCase())); + return Multimaps.filterValues(map, input -> input.getCallable().testPermission(src)).keys().elementSet(); + } + + /** + * Gets the number of registered aliases. + * + * @return The number of aliases + */ + public synchronized int size() { + return this.commands.size(); + } + + @Override + public ChatMessage getUsage(final PermissibleCommandSource source) { + final StringBuilder build = new StringBuilder(); + Iterable filteredCommands = this.filterCommands(source).stream() + .filter(input -> { + if (input == null) { + return false; + } + + final Optional ret = this.get(input, source); + return ret.isPresent() && ret.get().getPrimaryAlias().equals(input); + }) + .collect(Collectors.toList()); + + for (Iterator it = filteredCommands.iterator(); it.hasNext(); ) { + build.append(it.next()); + + if (it.hasNext()) { + build.append(CommandMessageFormatting.PIPE_TEXT); + } + } + + return ChatMessage.createTextMessage(build.toString()); + } + + @Override + public synchronized Set getAll(String alias) { + return ImmutableSet.copyOf(this.commands.get(alias)); + } + + @Override + public Multimap getAll() { + return ImmutableMultimap.copyOf(this.commands); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandExecutor.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandExecutor.java new file mode 100644 index 000000000..56d09b002 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandExecutor.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.spec; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandResult; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +/** + * Interface containing the method directing how a certain command will + * be executed. + */ +@FunctionalInterface +public interface CommandExecutor { + /** + * Callback for the execution of a command. + * + * @param src The commander who is executing this command + * @param args The parsed command arguments for this command + * @return the result of executing this command + * @throws CommandException If a user-facing error occurs while + * executing this command + */ + CommandResult execute(PermissibleCommandSource src, CommandContext args) throws CommandException; +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandSpec.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandSpec.java new file mode 100644 index 000000000..0ab9a3d0e --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandSpec.java @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.api.command.v2.lib.sponge.spec; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import com.google.common.base.Objects; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; +import net.minecraft.world.World; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandCallable; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandPermissionException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandResult; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ChildCommandElementExecutor; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.GenericArguments; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing.InputTokenizer; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; +import net.legacyfabric.fabric.api.util.Location; + +/** + * Specification for how command arguments should be parsed. + */ +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public final class CommandSpec implements CommandCallable { + private final CommandElement args; + private final CommandExecutor executor; + private final Optional description; + private final Optional extendedDescription; + @Nullable + private final String permission; + private final InputTokenizer argumentParser; + + CommandSpec(CommandElement args, CommandExecutor executor, @Nullable ChatMessage description, @Nullable ChatMessage extendedDescription, + @Nullable String permission, InputTokenizer parser) { + this.args = args; + this.executor = executor; + this.permission = permission; + this.description = Optional.ofNullable(description); + this.extendedDescription = Optional.ofNullable(extendedDescription); + this.argumentParser = parser; + } + + /** + * Return a new builder for a CommandSpec. + * + * @return a new builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Builder for command specs. + */ + public static final class Builder { + private static final CommandElement DEFAULT_ARG = GenericArguments.none(); + private CommandElement args = DEFAULT_ARG; + @Nullable + private ChatMessage description; + @Nullable + private ChatMessage extendedDescription; + @Nullable + private String permission; + @Nullable + private CommandExecutor executor; + @Nullable + private Map, CommandCallable> childCommandMap; + private boolean childCommandFallback = true; + private InputTokenizer argumentParser = InputTokenizer.quotedStrings(false); + + Builder() { + } + + /** + * Sets the permission that will be checked before using this command. + * + * @param permission The permission to check + * @return this + */ + public Builder permission(String permission) { + this.permission = permission; + return this; + } + + /** + * Sets the callback that will handle this command's execution. + * + * @param executor The executor that will be called with this command's + * parsed arguments + * @return this + */ + public Builder executor(CommandExecutor executor) { + Preconditions.checkNotNull(executor, "executor"); + this.executor = executor; + return this; + } + + /** + * Adds more child arguments for this command. + * If an executor or arguments are set, they are used as fallbacks. + * + * @param children The children to use + * @return this + */ + public Builder children(Map, ? extends CommandCallable> children) { + Preconditions.checkNotNull(children, "children"); + + if (this.childCommandMap == null) { + this.childCommandMap = new HashMap<>(); + } + + this.childCommandMap.putAll(children); + return this; + } + + /** + * Add a single child command to this command. + * + * @param child The child to add + * @param aliases Aliases to make the child available under. First + * one is primary and is the only one guaranteed to be listed in + * usage outputs. + * @return this + */ + public Builder child(CommandCallable child, String... aliases) { + if (this.childCommandMap == null) { + this.childCommandMap = new HashMap<>(); + } + + this.childCommandMap.put(ImmutableList.copyOf(aliases), child); + return this; + } + + /** + * Add a single child command to this command. + * + * @param child The child to add. + * @param aliases Aliases to make the child available under. First + * one is primary and is the only one guaranteed to be listed in + * usage outputs. + * @return this + */ + public Builder child(CommandCallable child, Collection aliases) { + if (this.childCommandMap == null) { + this.childCommandMap = new HashMap<>(); + } + + this.childCommandMap.put(ImmutableList.copyOf(aliases), child); + return this; + } + + /** + * A short, one-line description of this command's purpose. + * + * @param description The description to set + * @return this + */ + public Builder description(@Nullable ChatMessage description) { + this.description = description; + return this; + } + + /** + * Sets an extended description to use in longer help listings for this + * command. Will be appended to the short description and the command's + * usage. + * + * @param extendedDescription The description to set + * @return this + */ + public Builder extendedDescription(@Nullable ChatMessage extendedDescription) { + this.extendedDescription = extendedDescription; + return this; + } + + /** + * If a child command is selected but fails to parse arguments passed to + * it, the following determines the behavior. + * + *
    + *
  • If this is set to false, this command (the + * parent) will not attempt to parse the command, and will send back + * the error from the child.
  • + *
  • If this is set to true, the error from the + * child will simply be discarded, and the parent command will + * execute.
  • + *
+ * + *

The default for this is true, which emulates the + * behavior from previous API revisions.

+ * + * @param childCommandFallback Whether to fallback on argument parse + * failure + * @return this + */ + public Builder childArgumentParseExceptionFallback(boolean childCommandFallback) { + this.childCommandFallback = childCommandFallback; + return this; + } + + /** + * Sets the argument specification for this command. Generally, for a + * multi-argument command the {@link GenericArguments#seq(CommandElement...)} + * method is used to parse a sequence of args. + * + * @param args The arguments object to use + * @return this + * @see GenericArguments + */ + public Builder arguments(CommandElement args) { + Preconditions.checkNotNull(args, "args"); + this.args = GenericArguments.seq(args); + return this; + } + + /** + * Sets the argument specification for this command. This method accepts + * a sequence of arguments. This is equivalent to calling {@code + * arguments(seq(args))}. + * + * @param args The arguments object to use + * @return this + * @see GenericArguments + */ + public Builder arguments(CommandElement... args) { + Preconditions.checkNotNull(args, "args"); + this.args = GenericArguments.seq(args); + return this; + } + + /** + * Sets the input tokenizer to be used to convert input from a string + * into a list of argument tokens. + * + * @param parser The parser to use + * @return this + * @see InputTokenizer for common input parser implementations + */ + public Builder inputTokenizer(InputTokenizer parser) { + Preconditions.checkNotNull(parser, "parser"); + this.argumentParser = parser; + return this; + } + + /** + * Create a new {@link CommandSpec} based on the data provided in this + * builder. + * + * @return the new spec + */ + public CommandSpec build() { + if (this.childCommandMap == null || this.childCommandMap.isEmpty()) { + Preconditions.checkNotNull(this.executor, "An executor is required"); + } else if (this.executor == null) { + ChildCommandElementExecutor childCommandElementExecutor = + this.registerInDispatcher(new ChildCommandElementExecutor(null, null, false)); + if (this.args == DEFAULT_ARG) { + this.arguments(childCommandElementExecutor); + } else { + this.arguments(this.args, childCommandElementExecutor); + } + } else { + this.arguments(this.registerInDispatcher(new ChildCommandElementExecutor(this.executor, this.args, this.childCommandFallback))); + } + + return new CommandSpec(this.args, this.executor, this.description, this.extendedDescription, this.permission, + this.argumentParser); + } + + @SuppressWarnings({"ConstantConditions"}) + private ChildCommandElementExecutor registerInDispatcher(ChildCommandElementExecutor childDispatcher) { + for (Map.Entry, ? extends CommandCallable> spec : this.childCommandMap.entrySet()) { + childDispatcher.register(spec.getValue(), spec.getKey()); + } + + this.executor(childDispatcher); + return childDispatcher; + } + } + + /** + * Check the relevant permission for this command with the provided source, + * throwing an exception if the source does not have permission to use + * the command. + * + * @param source The source to check + * @throws CommandException if the source does not have permission + */ + public void checkPermission(PermissibleCommandSource source) throws CommandException { + Preconditions.checkNotNull(source, "source"); + + if (!this.testPermission(source)) { + throw new CommandPermissionException(); + } + } + + /** + * Process this command with existing arguments and context objects. + * + * @param source The source to populate the context with + * @param args The arguments to process with + * @param context The context to put data in + * @throws ArgumentParseException if an invalid argument is provided + */ + public void populateContext(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { + this.args.parse(source, args, context); + + if (args.hasNext()) { + args.next(); + throw args.createError(ChatMessage.createTextMessage("Too many arguments!")); + } + } + + /** + * Return tab completion results using the existing parsed arguments and + * context. Primarily useful when including a subcommand in an existing + * specification. + * + * @param source The source to parse arguments for + * @param args The arguments object + * @param context The context object + * @return possible completions, or an empty list if none + */ + public List complete(PermissibleCommandSource source, CommandArgs args, CommandContext context) { + Preconditions.checkNotNull(source, "source"); + List ret = this.args.complete(source, args, context); + return ret == null ? ImmutableList.of() : ImmutableList.copyOf(ret); + } + + /** + * Gets the active executor for this command. Generally not a good idea to + * call this directly, unless you are handling arg parsing specially + * + * @return The active executor for this command + */ + public CommandExecutor getExecutor() { + return this.executor; + } + + /** + * Gets the active input tokenizer used for this command. + * + * @return This command's input tokenizer + */ + public InputTokenizer getInputTokenizer() { + return this.argumentParser; + } + + @Override + public CommandResult process(PermissibleCommandSource source, String arguments) throws CommandException { + this.checkPermission(source); + final CommandArgs args = new CommandArgs(arguments, this.getInputTokenizer().tokenize(arguments, false)); + final CommandContext context = new CommandContext(); + this.populateContext(source, args, context); + return this.getExecutor().execute(source, context); + } + + @Override + public List getSuggestions(PermissibleCommandSource source, String arguments, @Nullable Location targetPos) throws CommandException { + CommandArgs args = new CommandArgs(arguments, this.getInputTokenizer().tokenize(arguments, true)); + CommandContext ctx = new CommandContext(); + + if (targetPos != null) { + ctx.putArg(CommandContext.TARGET_BLOCK_ARG, targetPos); + } + + ctx.putArg(CommandContext.TAB_COMPLETION, true); + return this.complete(source, args, ctx); + } + + @Override + public boolean testPermission(PermissibleCommandSource source) { + return source.hasPermission(this.permission); + } + + /** + * Gets a short, one-line description used with this command if any is + * present. + * + * @return the short description. + */ + @Override + public Optional getShortDescription(PermissibleCommandSource source) { + return this.description; + } + + /** + * Gets the extended description used with this command if any is present. + * + * @param source The source to get the description for + * @return the extended description. + */ + public Optional getExtendedDescription(PermissibleCommandSource source) { + return this.extendedDescription; + } + + /** + * Gets the usage for this command appropriate for the provided command + * source. + * + * @param source The source + * @return the usage for the source + */ + @Override + public ChatMessage getUsage(PermissibleCommandSource source) { + Preconditions.checkNotNull(source, "source"); + return this.args.getUsage(source); + } + + /** + * Return a longer description for this command. This description is + * composed of at least all present of the short description, the usage + * statement, and the extended description + * + * @param source The source to get the extended description for + * @return the extended description + */ + @Override + public Optional getHelp(PermissibleCommandSource source) { + Preconditions.checkNotNull(source, "source"); + StringBuilder builder = new StringBuilder(); + this.getShortDescription(source).ifPresent((a) -> builder.append(a.toString()).append("\n")); + builder.append(this.getUsage(source)); + this.getExtendedDescription(source).ifPresent((a) -> builder.append(a.toString()).append("\n")); + return Optional.of(ChatMessage.createTextMessage(builder.toString())); + } + + @Override + public boolean equals(@Nullable Object o) { + if (this == o) { + return true; + } + + if (o == null || this.getClass() != o.getClass()) { + return false; + } + + CommandSpec that = (CommandSpec) o; + return Objects.equal(this.args, that.args) + && Objects.equal(this.executor, that.executor) + && Objects.equal(this.description, that.description) + && Objects.equal(this.extendedDescription, that.extendedDescription) + && Objects.equal(this.permission, that.permission) + && Objects.equal(this.argumentParser, that.argumentParser); + } + + @Override + public int hashCode() { + return Objects.hashCode(this.args, this.executor, this.description, this.extendedDescription, this.permission, this.argumentParser); + } + + @Override + public String toString() { + return Objects.toStringHelper(this) + .add("args", this.args) + .add("executor", this.executor) + .add("description", this.description) + .add("extendedDescription", this.extendedDescription) + .add("permission", this.permission) + .add("argumentParser", this.argumentParser) + .toString(); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandManagerImpl.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandManagerImpl.java new file mode 100644 index 000000000..ad14b1452 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandManagerImpl.java @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; + +import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; +import net.minecraft.world.World; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandCallable; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandManager; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMapping; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandPermissionException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandResult; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.InvocationCommandException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher.Disambiguator; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher.SimpleDispatcher; +import net.legacyfabric.fabric.api.logger.v1.Logger; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; +import net.legacyfabric.fabric.api.util.Location; +import net.legacyfabric.fabric.impl.logger.LoggerImpl; + +public class CommandManagerImpl implements CommandManager { + private static final Logger LOGGER = Logger.get(LoggerImpl.API, "Command Manager"); + private final Object lock = new Object(); + private final SimpleDispatcher dispatcher; + private final List mappings = Lists.newArrayList(); + + public CommandManagerImpl(Disambiguator disambiguator) { + this.dispatcher = new SimpleDispatcher(disambiguator); + } + + @Override + public Optional register(CommandCallable callable, String... alias) { + return this.register(callable, Arrays.asList(alias)); + } + + @Override + public Optional register(CommandCallable callable, List aliases) { + return this.register(callable, aliases, Function.identity()); + } + + @Override + public Optional register(CommandCallable callable, List aliases, Function, List> callback) { + synchronized (this.lock) { + return this.dispatcher.register(callable, aliases, callback).map(mapping -> { + this.mappings.add(mapping); + return mapping; + }); + } + } + + @Override + public Optional removeMapping(CommandMapping mapping) { + synchronized (this.lock) { + return this.dispatcher.removeMapping(mapping).map(commandMapping -> { + this.mappings.remove(commandMapping); + return commandMapping; + }); + } + } + + @Override + public int size() { + synchronized (this.lock) { + return this.dispatcher.size(); + } + } + + @Override + public CommandResult process(PermissibleCommandSource source, String command) { + final String[] argSplit = command.split(" ", 2); + + try { + try { + this.dispatcher.process(source, command); + } catch (InvocationCommandException e) { + if (e.getCause() != null) { + throw e.getCause(); + } + } catch (CommandPermissionException e) { + if (e.getText() != null) { + source.method_5505(CommandMessageFormatting.error(e.getText())); + } + } catch (CommandException e) { + ChatMessage text = e.getText(); + + if (text != null) { + source.method_5505(CommandMessageFormatting.error(text)); + } + + if (e.shouldIncludeUsage()) { + Optional mapping = this.dispatcher.get(argSplit[0], source); + + if (mapping.isPresent()) { + ChatMessage usage; + + if (e instanceof ArgumentParseException.WithUsage) { + usage = ((ArgumentParseException.WithUsage) e).getUsage(); + } else { + usage = mapping.get().getCallable().getUsage(source); + } + + source.method_5505(CommandMessageFormatting.error(ChatMessage.createTextMessage(String.format("Usage: /%s %s", argSplit[0], usage)))); + } + } + } + } catch (Throwable t) { + LOGGER.error("An unexpected error happened executing a command"); + t.printStackTrace(); + + if (t instanceof Error) { + throw (Error) t; + } + + ChatMessage message = CommandMessageFormatting.error(ChatMessage.createTextMessage("An unexpected error happened executing the command")); + // message.setStyle(message.getStyle().setHoverEvent(new HoverEvent(HoverEventAction.SHOW_TEXT, new LiteralText("Stacktrace: \n" + Arrays.stream(t.getStackTrace()).map(StackTraceElement::toString).collect(Collectors.joining("\n")))))); + source.method_5505(message); + } + + return CommandResult.empty(); + } + + @Override + public List getSuggestions(PermissibleCommandSource source, String arguments, @Nullable Location targetPosition) { + try { + final String[] argSplit = arguments.split(" ", 2); + return Lists.newArrayList(this.dispatcher.getSuggestions(source, arguments, targetPosition)); + } catch (CommandException e) { + source.method_5505(CommandMessageFormatting.error(ChatMessage.createTextMessage(String.format("Error getting suggestions: %s", e.getText().toString())))); + return Collections.emptyList(); + } catch (Exception e) { + throw new RuntimeException(String.format("Error occured while tab completing '%s'", arguments), e); + } + } + + @Override + public boolean testPermission(PermissibleCommandSource source) { + synchronized (this.lock) { + return this.dispatcher.testPermission(source); + } + } + + @Override + public Optional getShortDescription(PermissibleCommandSource source) { + synchronized (this.lock) { + return this.dispatcher.getShortDescription(source); + } + } + + @Override + public Optional getHelp(PermissibleCommandSource source) { + synchronized (this.lock) { + return this.dispatcher.getHelp(source); + } + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource source) { + synchronized (this.lock) { + return this.dispatcher.getUsage(source); + } + } + + @Override + public Set getCommands() { + synchronized (this.lock) { + return this.dispatcher.getCommands(); + } + } + + @Override + public Set getPrimaryAliases() { + synchronized (this.lock) { + return this.dispatcher.getPrimaryAliases(); + } + } + + @Override + public Set getAliases() { + synchronized (this.lock) { + return this.dispatcher.getAliases(); + } + } + + @Override + public Optional get(String alias) { + synchronized (this.lock) { + return this.dispatcher.get(alias); + } + } + + @Override + public Optional get(String alias, @Nullable PermissibleCommandSource source) { + synchronized (this.lock) { + return this.dispatcher.get(alias, source); + } + } + + @Override + public Set getAll(String alias) { + synchronized (this.lock) { + return this.dispatcher.getAll(alias); + } + } + + protected List getMappings() { + return this.mappings; + } + + @Override + public Multimap getAll() { + synchronized (this.lock) { + return this.dispatcher.getAll(); + } + } + + @Override + public boolean containsAlias(String alias) { + synchronized (this.lock) { + return this.dispatcher.containsAlias(alias); + } + } + + @Override + public boolean containsMapping(CommandMapping mapping) { + synchronized (this.lock) { + return this.dispatcher.containsMapping(mapping); + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandWrapper.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandWrapper.java new file mode 100644 index 000000000..26fd98ea3 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandWrapper.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import org.jetbrains.annotations.NotNull; + +import net.minecraft.command.AbstractCommand; +import net.minecraft.command.CommandSource; +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMapping; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandPermissionException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.InvocationCommandException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; +import net.legacyfabric.fabric.api.util.Location; + +public class CommandWrapper extends AbstractCommand { + private final CommandMapping mapping; + + public CommandWrapper(CommandMapping mapping) { + this.mapping = mapping; + } + + @Override + public String getCommandName() { + return this.mapping.getPrimaryAlias(); + } + + @Override + public List getAliases() { + return new ArrayList<>(this.mapping.getAllAliases()); + } + + @Override + public String getUsageTranslationKey(CommandSource source) { + return this.mapping.getCallable().getHelp((PermissibleCommandSource) source).map(ChatMessage::toJson).orElse(""); + } + + @Override + public void execute(CommandSource source, String[] args) { + try { + try { + this.mapping.getCallable().process((PermissibleCommandSource) source, String.join(" ", args)); + } catch (InvocationCommandException e) { + if (e.getCause() != null) { + throw e.getCause(); + } + } catch (CommandPermissionException e) { + if (e.getText() != null) { + source.method_5505(CommandMessageFormatting.error(e.getText())); + } + } catch (CommandException e) { + ChatMessage text = e.getText(); + + if (text != null) { + source.method_5505(CommandMessageFormatting.error(text)); + } + + if (e.shouldIncludeUsage()) { + ChatMessage usage; + + if (e instanceof ArgumentParseException.WithUsage) { + usage = ((ArgumentParseException.WithUsage) e).getUsage(); + } else { + usage = this.mapping.getCallable().getUsage((PermissibleCommandSource) source); + } + + source.method_5505(CommandMessageFormatting.error(ChatMessage.createTextMessage(String.format("Usage: /%s %s", this.getCommandName(), usage)))); + } + } + } catch (Throwable t) { + // Minecraft handles these exceptions for us + throw new RuntimeException(t); + } + } + + @Override + public boolean isAccessible(CommandSource source) { + return this.mapping.getCallable().testPermission((PermissibleCommandSource) source); + } + + @Override + public List method_3276(CommandSource source, String[] args) { + try { + return this.mapping.getCallable().getSuggestions((PermissibleCommandSource) source, Arrays.stream(args).collect(Collectors.joining(" ")), new Location<>(source.getWorld(), source.method_4086())); + } catch (CommandException e) { + source.method_5505(CommandMessageFormatting.error(ChatMessage.createTextMessage(String.format("Error getting suggestions: %s", e.getText().toString())))); + return Collections.emptyList(); + } catch (Exception e) { + throw new RuntimeException(String.format("Error occurred while providing auto complete hints for '%s'", String.join(" ", args)), e); + } + } + + //TODO: Autogenerated stub, make this actually work. + @Override + public int compareTo(@NotNull Object o) { + return 0; + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/ImplInit.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/ImplInit.java new file mode 100644 index 000000000..8858416fe --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/ImplInit.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.api.DedicatedServerModInitializer; + +import net.legacyfabric.fabric.api.command.v2.CommandRegistrar; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandManager; +import net.legacyfabric.fabric.api.registry.CommandRegistry; + +public class ImplInit implements DedicatedServerModInitializer, ClientModInitializer, CommandRegistrar { + @Override + public void register(CommandManager manager, boolean dedicated) { + CommandRegistrar.EVENT.invoker().register(manager, dedicated); + InternalObjects.getCommandManager().getCommands().forEach(mapping -> { + CommandWrapper wrapper = new CommandWrapper(mapping); + CommandRegistry.INSTANCE.register(wrapper); + }); + } + + @Override + public void onInitializeClient() { + this.register(InternalObjects.getCommandManager(), false); + } + + @Override + public void onInitializeServer() { + this.register(InternalObjects.getCommandManager(), true); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/InternalObjects.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/InternalObjects.java new file mode 100644 index 000000000..aa590d8c4 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/InternalObjects.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher.SimpleDispatcher; + +public class InternalObjects { + private static final CommandManagerImpl COMMAND_MANAGER = new CommandManagerImpl(SimpleDispatcher.FIRST_DISAMBIGUATOR); + + public static CommandManagerImpl getCommandManager() { + return COMMAND_MANAGER; + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/AllOfCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/AllOfCommandElement.java new file mode 100644 index 000000000..6f90c2996 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/AllOfCommandElement.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.Collections; +import java.util.List; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class AllOfCommandElement extends CommandElement { + private final CommandElement element; + + public AllOfCommandElement(CommandElement element) { + super(null); + this.element = element; + } + + @Override + public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { + while (args.hasNext()) { + this.element.parse(source, args, context); + } + } + + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + return null; + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + CommandArgs.Snapshot startState = null; + + try { + while (args.hasNext()) { + startState = args.getSnapshot(); + this.element.parse(src, args, context); + } + } catch (ArgumentParseException e) { + // ignored + } + + // The final element, if an exception was not thrown, might have more completions available to it. + // Therefore, we reapply the last snapshot and complete from it. + if (startState != null) { + args.applySnapshot(startState); + } + + if (args.canComplete()) { + return this.element.complete(src, args, context); + } + + // If we have more elements, do not complete. + return Collections.emptyList(); + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource context) { + return ChatMessage.createTextMessage(this.element.getUsage(context).toString() + CommandMessageFormatting.STAR_TEXT.toString()); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigDecimalElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigDecimalElement.java new file mode 100644 index 000000000..85fcfe1c3 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigDecimalElement.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.math.BigDecimal; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class BigDecimalElement extends KeyElement { + public BigDecimalElement(ChatMessage key) { + super(key); + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + String next = args.next(); + + try { + return new BigDecimal(next); + } catch (NumberFormatException ex) { + throw args.createError(ChatMessage.createTextMessage("Expected a number, but input " + next + " was not")); + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigIntegerElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigIntegerElement.java new file mode 100644 index 000000000..44f3208ea --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigIntegerElement.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.math.BigInteger; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class BigIntegerElement extends KeyElement { + public BigIntegerElement(ChatMessage key) { + super(key); + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + String integerString = args.next(); + + try { + return new BigInteger(integerString); + } catch (NumberFormatException ex) { + throw args.createError(ChatMessage.createTextMessage("Expected an integer, but input " + integerString + " was not")); + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ChoicesCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ChoicesCommandElement.java new file mode 100644 index 000000000..347d62295 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ChoicesCommandElement.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; +import net.legacyfabric.fabric.api.util.TriState; + +public class ChoicesCommandElement extends CommandElement { + public static final int CUTOFF = 5; + private final Supplier> keySupplier; + private final Function valueSupplier; + private final TriState choicesInUsage; + + public ChoicesCommandElement(ChatMessage key, Supplier> keySupplier, Function valueSupplier, TriState choicesInUsage) { + super(key); + this.keySupplier = keySupplier; + this.valueSupplier = valueSupplier; + this.choicesInUsage = choicesInUsage; + } + + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + Object value = this.valueSupplier.apply(args.next()); + + if (value == null) { + throw args.createError(ChatMessage.createTextMessage(String.format("Argument was not a valid choice. Valid choices: %s", this.keySupplier.get().toString()))); + } + + return value; + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + final String prefix = args.nextIfPresent().orElse(""); + return Collections.unmodifiableList(this.keySupplier.get().stream().filter((input) -> input.startsWith(prefix)).collect(Collectors.toList())); + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource commander) { + Collection keys = this.keySupplier.get(); + + if (this.choicesInUsage == TriState.TRUE || (this.choicesInUsage == TriState.DEFAULT && keys.size() <= CUTOFF)) { + final ChatMessage build = ChatMessage.createTextMessage(""); + build.addUsing(CommandMessageFormatting.LT_TEXT); + + for (Iterator it = keys.iterator(); it.hasNext(); ) { + build.addUsing(ChatMessage.createTextMessage(it.next())); + + if (it.hasNext()) { + build.addUsing(CommandMessageFormatting.PIPE_TEXT); + } + } + + build.addUsing(CommandMessageFormatting.GT_TEXT); + return ChatMessage.createTextMessage(build.toString()); + } + + return super.getUsage(commander); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DateTimeElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DateTimeElement.java new file mode 100644 index 000000000..a7169d94c --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DateTimeElement.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeParseException; +import java.util.List; + +import com.google.common.collect.ImmutableList; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class DateTimeElement extends CommandElement { + private final boolean returnNow; + + public DateTimeElement(ChatMessage key, boolean returnNow) { + super(key); + this.returnNow = returnNow; + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + if (!args.hasNext() && this.returnNow) { + return LocalDateTime.now(); + } + + CommandArgs.Snapshot state = args.getSnapshot(); + String date = args.next(); + + try { + return LocalDateTime.parse(date); + } catch (DateTimeParseException ex) { + try { + return LocalDateTime.of(LocalDate.now(), LocalTime.parse(date)); + } catch (DateTimeParseException ex2) { + try { + return LocalDateTime.of(LocalDate.parse(date), LocalTime.MIDNIGHT); + } catch (DateTimeParseException ex3) { + if (this.returnNow) { + args.applySnapshot(state); + return LocalDateTime.now(); + } + + throw args.createError(ChatMessage.createTextMessage("Invalid date-time!")); + } + } + } + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + String date = LocalDateTime.now().withNano(0).toString(); + + if (date.startsWith(args.nextIfPresent().orElse(""))) { + return ImmutableList.of(date); + } else { + return ImmutableList.of(); + } + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource src) { + if (!this.returnNow) { + return super.getUsage(src); + } else { + return ChatMessage.createTextMessage("[" + this.getKey().toString() + "]"); + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DurationElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DurationElement.java new file mode 100644 index 000000000..45557f8f6 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DurationElement.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.time.Duration; +import java.time.format.DateTimeParseException; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class DurationElement extends KeyElement { + public DurationElement(ChatMessage key) { + super(key); + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + String s = args.next().toUpperCase(); + + if (!s.contains("T")) { + if (s.contains("D")) { + if (s.contains("H") || s.contains("M") || s.contains("S")) { + s = s.replace("D", "DT"); + } + } else { + if (s.startsWith("P")) { + s = "PT" + s.substring(1); + } else { + s = "T" + s; + } + } + } + + if (!s.startsWith("P")) { + s = "P" + s; + } + + try { + return Duration.parse(s); + } catch (DateTimeParseException ex) { + throw args.createError(ChatMessage.createTextMessage("Invalid duration!")); + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EntityCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EntityCommandElement.java new file mode 100644 index 000000000..24d71ad11 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EntityCommandElement.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +import com.google.common.collect.Sets; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.MinecraftServer; +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.SelectorCommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class EntityCommandElement extends SelectorCommandElement { + private final boolean returnTarget; + private final boolean returnSource; + @Nullable + private final Class clazz; + + public EntityCommandElement(ChatMessage key, boolean returnSource, boolean returnTarget, @Nullable Class clazz) { + super(key); + this.returnSource = returnSource; + this.returnTarget = returnTarget; + this.clazz = clazz; + } + + @SuppressWarnings("unchecked") + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + if (!args.hasNext()) { + if (this.returnSource) { + return this.tryReturnSource(source, args, true); + } + + if (this.returnTarget) { + return this.tryReturnTarget(source, args); + } + } + + CommandArgs.Snapshot state = args.getSnapshot(); + + try { + Iterable entities = (Iterable) super.parseValue(source, args); + + for (Entity entity : entities) { + if (!this.checkEntity(entity)) { + ChatMessage name = ChatMessage.createTextMessage(this.clazz == null ? "null" : this.clazz.getSimpleName()); + throw args.createError(ChatMessage.createTextMessage("The entity is not of the required type! (").addUsing(name).addText(")")); + } + } + + return entities; + } catch (ArgumentParseException ex) { + if (this.returnSource) { + args.applySnapshot(state); + return this.tryReturnSource(source, args, true); + } + + throw ex; + } + } + + @Override + protected Iterable getChoices(PermissibleCommandSource source) { + Set worldEntities = (Set) Arrays.stream(MinecraftServer.getServer().worlds).flatMap(world -> world.entities.stream()) + .filter(o -> this.checkEntity((Entity) o)) + .map(entity -> ((Entity) entity).getUuid().toString()).collect(Collectors.toSet()); + Collection players = Sets.newHashSet(MinecraftServer.getServer().getPlayerManager().players); + + if (!players.isEmpty() && this.checkEntity(players.iterator().next())) { + final Set setToReturn = Sets.newHashSet(worldEntities); // to ensure mutability + players.forEach(x -> setToReturn.add(x.getTranslationKey())); + return setToReturn; + } + + return worldEntities; + } + + @Override + protected Object getValue(String choice) throws IllegalArgumentException { + UUID uuid; + + try { + uuid = UUID.fromString(choice); + } catch (IllegalArgumentException ignored) { + // Player could be a name + return Optional.ofNullable(MinecraftServer.getServer().getPlayerManager().getPlayer(choice)).orElseThrow(() -> new IllegalArgumentException("Input value " + choice + " does not represent a valid entity")); + } + + boolean found = false; + Optional ret = Optional.ofNullable((Entity) MinecraftServer.getServer().getWorld().entities.stream() + .filter(o -> ((Entity) o).getUuid().equals(uuid)).findFirst().orElse(null)); + + if (ret.isPresent()) { + Entity entity = ret.get(); + + if (this.checkEntity(entity)) { + return entity; + } + + found = true; + } + + if (found) { + throw new IllegalArgumentException("Input value " + choice + " was not an entity of the required type!"); + } + + throw new IllegalArgumentException("Input value " + choice + " was not an entity"); + } + + private Entity tryReturnSource(PermissibleCommandSource source, CommandArgs args, boolean check) throws ArgumentParseException { + if (source instanceof Entity && (!check || this.checkEntity((Entity) source))) { + return (Entity) source; + } + + throw args.createError(ChatMessage.createTextMessage("No entities matched and source was not an entity!")); + } + + // TODO + private Entity tryReturnTarget(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + Entity entity = this.tryReturnSource(source, args, false); + throw args.createError(ChatMessage.createTextMessage("No entities matched and source was not looking at a valid entity!")); + // return entity.getWorld().getIntersectingEntities(entity, 10).stream().filter(e -> !e.getEntity().equals(entity)).map(EntityUniverse.EntityHit::getEntity).filter(this::checkEntity).findFirst().orElseThrow(() -> args.createError(new LiteralText("No entities matched and source was not looking at a valid entity!"))); + } + + private boolean checkEntity(Entity entity) { + if (this.clazz == null) { + return true; + } else { + return this.clazz.isAssignableFrom(entity.getClass()); + } + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource src) { + return src instanceof Entity && (this.returnSource || this.returnTarget) ? ChatMessage.createTextMessage("[" + this.getKey().toString() + "]") : super.getUsage(src); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EnumValueElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EnumValueElement.java new file mode 100644 index 000000000..8056677a7 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EnumValueElement.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.PatternMatchingCommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class EnumValueElement> extends PatternMatchingCommandElement { + private final Class type; + private final Map values; + + public EnumValueElement(ChatMessage key, Class type) { + super(key); + this.type = type; + this.values = Arrays.stream(type.getEnumConstants()) + .collect(Collectors.toMap(value -> value.name().toLowerCase(), + Function.identity(), (value, value2) -> { + throw new UnsupportedOperationException(type.getCanonicalName() + " contains more than one enum constant " + "with the same name, only differing by capitalization, which is unsupported."); + } + )); + } + + @Override + protected Iterable getChoices(PermissibleCommandSource source) { + return this.values.keySet(); + } + + @Override + protected Object getValue(String choice) throws IllegalArgumentException { + T value = this.values.get(choice.toLowerCase()); + + if (value == null) { + throw new IllegalArgumentException("No enum constant " + this.type.getCanonicalName() + "." + choice); + } + + return value; + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FilteredSuggestionsElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FilteredSuggestionsElement.java new file mode 100644 index 000000000..11cc5ba78 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FilteredSuggestionsElement.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.Collections; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import org.jetbrains.annotations.Nullable; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class FilteredSuggestionsElement extends CommandElement { + private final CommandElement wrapped; + private final Predicate predicate; + + public FilteredSuggestionsElement(CommandElement wrapped, Predicate predicate) { + super(wrapped.getKey()); + this.wrapped = wrapped; + this.predicate = predicate; + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + return this.wrapped.parseValue(source, args); + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + return Collections.unmodifiableList(this.wrapped.complete(src, args, context).stream().filter(this.predicate).collect(Collectors.toList())); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FirstParsingCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FirstParsingCommandElement.java new file mode 100644 index 000000000..4032395fa --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FirstParsingCommandElement.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class FirstParsingCommandElement extends CommandElement { + private final List elements; + + public FirstParsingCommandElement(List elements) { + super(null); + this.elements = elements; + } + + @Override + public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { + ArgumentParseException lastException = null; + + for (CommandElement element : this.elements) { + CommandArgs.Snapshot startState = args.getSnapshot(); + CommandContext.Snapshot contextSnapshot = context.createSnapshot(); + + try { + element.parse(source, args, context); + return; + } catch (ArgumentParseException ex) { + lastException = ex; + args.applySnapshot(startState); + context.applySnapshot(contextSnapshot); + } + } + + if (lastException != null) { + throw lastException; + } + } + + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + return null; + } + + @Override + public List complete(final PermissibleCommandSource src, final CommandArgs args, final CommandContext context) { + return Lists.newLinkedList(Iterables.concat(this.elements.stream().map(element -> { + if (element == null) { + return ImmutableList.of(); + } else { + CommandArgs.Snapshot snapshot = args.getSnapshot(); + List ret = element.complete(src, args, context); + args.applySnapshot(snapshot); + return ret; + } + }).collect(Collectors.toSet()))); + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource commander) { + final ChatMessage ret = ChatMessage.createTextMessage(""); + + for (Iterator it = this.elements.iterator(); it.hasNext(); ) { + ret.addUsing(it.next().getUsage(commander)); + + if (it.hasNext()) { + ret.addUsing(CommandMessageFormatting.PIPE_TEXT); + } + } + + return ChatMessage.createTextMessage(ret.toString()); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/IpElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/IpElement.java new file mode 100644 index 000000000..2ff15bd71 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/IpElement.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Objects; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class IpElement extends KeyElement { + private final PlayerCommandElement possiblePlayer; + + public IpElement(ChatMessage key) { + super(key); + this.possiblePlayer = new PlayerCommandElement(key, false); + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + String s = args.next(); + + try { + return InetAddress.getByName(s); + } catch (UnknownHostException e) { + try { + return ((ServerPlayerEntity) Objects.requireNonNull(this.possiblePlayer.parseValue(source, args))).getIp(); + } catch (ArgumentParseException ex) { + throw args.createError(ChatMessage.createTextMessage("Invalid IP address!")); + } + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/LiteralCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/LiteralCommandElement.java new file mode 100644 index 000000000..60d48b4ef --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/LiteralCommandElement.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.List; +import java.util.Optional; + +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableList; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class LiteralCommandElement extends CommandElement { + private final List expectedArgs; + @Nullable + private final Object putValue; + + public LiteralCommandElement(@Nullable ChatMessage key, List expectedArgs, @Nullable Object putValue) { + super(key); + this.expectedArgs = ImmutableList.copyOf(expectedArgs); + this.putValue = putValue; + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + for (String arg : this.expectedArgs) { + String current; + + if (!(current = args.next()).equalsIgnoreCase(arg)) { + throw args.createError(ChatMessage.createTextMessage(String.format("Argument %s did not match expected next argument %s", current, arg))); + } + } + + return this.putValue; + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + for (String arg : this.expectedArgs) { + final Optional next = args.nextIfPresent(); + + if (!next.isPresent()) { + break; + } else if (args.hasNext()) { + if (!next.get().equalsIgnoreCase(arg)) { + break; + } + } else { + if (arg.toLowerCase().startsWith(next.get().toLowerCase())) { // Case-insensitive compare + return ImmutableList.of(arg); // TODO: Possibly complete all remaining args? Does that even work + } + } + } + + return ImmutableList.of(); + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource src) { + return ChatMessage.createTextMessage(Joiner.on(' ').join(this.expectedArgs)); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/MarkTrueCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/MarkTrueCommandElement.java new file mode 100644 index 000000000..4cd1d0276 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/MarkTrueCommandElement.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.Collections; +import java.util.List; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class MarkTrueCommandElement extends CommandElement { + public MarkTrueCommandElement(ChatMessage key) { + super(key); + } + + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + return true; + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + return Collections.emptyList(); + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource src) { + return ChatMessage.createTextMessage(""); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ModCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ModCommandElement.java new file mode 100644 index 000000000..fe89e8e4d --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ModCommandElement.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.Optional; +import java.util.stream.Collectors; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.PatternMatchingCommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class ModCommandElement extends PatternMatchingCommandElement { + public ModCommandElement(@Nullable ChatMessage key) { + super(key); + } + + @Override + protected Iterable getChoices(PermissibleCommandSource source) { + return FabricLoader.getInstance().getAllMods().stream().map(container -> container.getMetadata().getId()).collect(Collectors.toSet()); + } + + @Override + protected Object getValue(String choice) throws IllegalArgumentException { + Optional plugin = FabricLoader.getInstance().getModContainer(choice); + return plugin.orElseThrow(() -> new IllegalArgumentException("Mod " + choice + " was not found")); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/NumericElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/NumericElement.java new file mode 100644 index 000000000..f767d5c57 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/NumericElement.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.function.BiFunction; +import java.util.function.Function; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class NumericElement extends KeyElement { + private final Function parseFunc; + @Nullable + private final BiFunction parseRadixFunction; + private final Function errorSupplier; + + public NumericElement(ChatMessage key, Function parseFunc, @Nullable BiFunction parseRadixFunction, Function errorSupplier) { + super(key); + this.parseFunc = parseFunc; + this.parseRadixFunction = parseRadixFunction; + this.errorSupplier = errorSupplier; + } + + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + final String input = args.next(); + + try { + if (this.parseRadixFunction != null) { + if (input.startsWith("0x")) { + return this.parseRadixFunction.apply(input.substring(2), 16); + } else if (input.startsWith("0b")) { + return this.parseRadixFunction.apply(input.substring(2), 2); + } + } + + return this.parseFunc.apply(input); + } catch (NumberFormatException ex) { + throw args.createError(this.errorSupplier.apply(input)); + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OnlyOneCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OnlyOneCommandElement.java new file mode 100644 index 000000000..1473dc4e4 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OnlyOneCommandElement.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.List; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class OnlyOneCommandElement extends CommandElement { + private final CommandElement element; + + public OnlyOneCommandElement(CommandElement element) { + super(element.getKey()); + this.element = element; + } + + @Override + public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { + this.element.parse(source, args, context); + + if (context.getAll(this.element.getUntranslatedKey()).size() > 1) { + ChatMessage key = this.element.getKey(); + throw args.createError(ChatMessage.createTextMessage(String.format("Argument %s may have only one value!", key != null ? key : "unknown"))); + } + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource src) { + return this.element.getUsage(src); + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + return this.element.parseValue(source, args); + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + return this.element.complete(src, args, context); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OptionalCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OptionalCommandElement.java new file mode 100644 index 000000000..b02c1bf0d --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OptionalCommandElement.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.List; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class OptionalCommandElement extends CommandElement { + private final CommandElement element; + @Nullable + private final Object value; + private final boolean considerInvalidFormatEmpty; + + public OptionalCommandElement(CommandElement element, @Nullable Object value, boolean considerInvalidFormatEmpty) { + super(null); + this.element = element; + this.value = value; + this.considerInvalidFormatEmpty = considerInvalidFormatEmpty; + } + + @Override + public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { + if (!args.hasNext()) { + ChatMessage key = this.element.getKey(); + + if (key != null && this.value != null) { + context.putArg(key.toString(), this.value); + } + + return; + } + + CommandArgs.Snapshot startState = args.getSnapshot(); + + try { + this.element.parse(source, args, context); + } catch (ArgumentParseException ex) { + if (this.considerInvalidFormatEmpty || args.hasNext()) { // If there are more args, suppress. Otherwise, throw the error + args.applySnapshot(startState); + + if (this.element.getKey() != null && this.value != null) { + context.putArg(this.element.getUntranslatedKey(), this.value); + } + } else { + throw ex; + } + } + } + + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + return args.hasNext() ? null : this.element.parseValue(source, args); + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + return this.element.complete(src, args, context); + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource src) { + final ChatMessage containingUsage = this.element.getUsage(src); + + if (containingUsage.toString().isEmpty()) { + return ChatMessage.createTextMessage(""); + } + + return ChatMessage.createTextMessage("[" + this.element.getUsage(src) + "]"); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PermissionCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PermissionCommandElement.java new file mode 100644 index 000000000..8c1bb112d --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PermissionCommandElement.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.List; + +import com.google.common.collect.ImmutableList; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class PermissionCommandElement extends CommandElement { + private final CommandElement element; + private final String permission; + private final boolean isOptional; + + public PermissionCommandElement(CommandElement element, String permission, boolean isOptional) { + super(element.getKey()); + this.element = element; + this.permission = permission; + this.isOptional = isOptional; + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + if (this.checkPermission(source, args)) { + return this.element.parseValue(source, args); + } + + return null; + } + + private boolean checkPermission(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + boolean hasPermission = source.hasPermission(this.permission); + + if (!hasPermission && !this.isOptional) { + ChatMessage key = this.getKey(); + throw args.createError(ChatMessage.createTextMessage(String.format("You do not have permission to use the %s argument", key != null ? key : "unknown"))); + } + + return hasPermission; + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + boolean flag = /*src.hasPermission(this.permission)*/ true; + + if (!flag) { + return ImmutableList.of(); + } + + return this.element.complete(src, args, context); + } + + @Override + public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { + if (this.checkPermission(source, args)) { + this.element.parse(source, args, context); + } + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource src) { + if (this.isOptional && !src.hasPermission(this.permission)) { + return ChatMessage.createTextMessage(""); + } + + return this.element.getUsage(src); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PlayerCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PlayerCommandElement.java new file mode 100644 index 000000000..09012256b --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PlayerCommandElement.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.MinecraftServer; +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.SelectorCommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class PlayerCommandElement extends SelectorCommandElement { + private final boolean returnSource; + + public PlayerCommandElement(ChatMessage key, boolean returnSource) { + super(key); + this.returnSource = returnSource; + } + + @SuppressWarnings("unchecked") + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + if (!args.hasNext() && this.returnSource) { + return this.tryReturnSource(source, args); + } + + CommandArgs.Snapshot state = args.getSnapshot(); + + try { + return StreamSupport.stream(((Iterable) super.parseValue(source, args)).spliterator(), false).filter(e -> e instanceof PlayerEntity).collect(Collectors.toList()); + } catch (ArgumentParseException ex) { + if (this.returnSource) { + args.applySnapshot(state); + return this.tryReturnSource(source, args); + } + + throw ex; + } + } + + @Override + protected Iterable getChoices(PermissibleCommandSource source) { + return (Iterable) MinecraftServer.getServer().getPlayerManager().players.stream().map(player -> ((PlayerEntity) player).getUsername()).collect(Collectors.toSet()); + } + + @Override + protected Object getValue(String choice) throws IllegalArgumentException { + Optional ret = MinecraftServer.getServer().getPlayerManager().players.stream().findFirst().map(Function.identity()); + + if (!ret.isPresent()) { + throw new IllegalArgumentException("Input value " + choice + " was not a player"); + } + + return ret.get(); + } + + private PlayerEntity tryReturnSource(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + if (source instanceof PlayerEntity) { + return ((PlayerEntity) source); + } else { + throw args.createError(ChatMessage.createTextMessage("No players matched and source was not a player!")); + } + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource src) { + return src != null && this.returnSource ? ChatMessage.createTextMessage("[" + super.getUsage(src) + "]") : super.getUsage(src); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RemainingJoinedStringsCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RemainingJoinedStringsCommandElement.java new file mode 100644 index 000000000..b6ad018a1 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RemainingJoinedStringsCommandElement.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class RemainingJoinedStringsCommandElement extends KeyElement { + private final boolean raw; + + public RemainingJoinedStringsCommandElement(ChatMessage key, boolean raw) { + super(key); + this.raw = raw; + } + + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + if (this.raw) { + args.next(); + String ret = args.getRaw().substring(args.getRawPosition()); + + while (args.hasNext()) { // Consume remaining args + args.next(); + } + + return ret; + } + + final StringBuilder ret = new StringBuilder(args.next()); + + while (args.hasNext()) { + ret.append(' ').append(args.next()); + } + + return ret.toString(); + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource src) { + return ChatMessage.createTextMessage("").addText(CommandMessageFormatting.LT_TEXT.toString()).addUsing(this.getKey()).addUsing(CommandMessageFormatting.ELLIPSIS_TEXT).addUsing(CommandMessageFormatting.GT_TEXT); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RepeatedCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RepeatedCommandElement.java new file mode 100644 index 000000000..2cd715f55 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RepeatedCommandElement.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.Collections; +import java.util.List; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class RepeatedCommandElement extends CommandElement { + private final CommandElement element; + private final int times; + + public RepeatedCommandElement(CommandElement element, int times) { + super(null); + this.element = element; + this.times = times; + } + + @Override + public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { + for (int i = 0; i < this.times; ++i) { + this.element.parse(source, args, context); + } + } + + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + return null; + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + for (int i = 0; i < this.times; ++i) { + CommandArgs.Snapshot startState = args.getSnapshot(); + + try { + this.element.parse(src, args, context); + } catch (ArgumentParseException e) { + args.applySnapshot(startState); + return this.element.complete(src, args, context); + } + } + + return Collections.emptyList(); + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource src) { + return ChatMessage.createTextMessage(this.times + '*' + this.element.getUsage(src).toString()); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/SequenceCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/SequenceCommandElement.java new file mode 100644 index 000000000..c0b1e2d14 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/SequenceCommandElement.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class SequenceCommandElement extends CommandElement { + private final List elements; + + public SequenceCommandElement(List elements) { + super(null); + this.elements = elements; + } + + @Override + public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { + for (CommandElement element : this.elements) { + element.parse(source, args, context); + } + } + + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + return null; + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + Set completions = Sets.newHashSet(); + + for (CommandElement element : this.elements) { + CommandArgs.Snapshot state = args.getSnapshot(); + CommandContext.Snapshot contextSnapshot = context.createSnapshot(); + + try { + element.parse(src, args, context); + + // If we get here, the parse occurred successfully. + // However, if nothing was consumed, then we should consider + // what could have been. + CommandContext.Snapshot afterSnapshot = context.createSnapshot(); + + if (state.equals(args.getSnapshot())) { + context.applySnapshot(contextSnapshot); + completions.addAll(element.complete(src, args, context)); + args.applySnapshot(state); + context.applySnapshot(afterSnapshot); + } else if (args.hasNext()) { + completions.clear(); + } else { + // What we might also have - we have no args left to parse so + // while the parse itself was successful, there could be other + // valid entries to add... + context.applySnapshot(contextSnapshot); + args.applySnapshot(state); + completions.addAll(element.complete(src, args, context)); + + if (!(element instanceof OptionalCommandElement)) { + break; + } + + // The last element was optional, so we go back to before this + // element would have been parsed, and assume it never existed... + context.applySnapshot(contextSnapshot); + args.applySnapshot(state); + } + } catch (ArgumentParseException ignored) { + args.applySnapshot(state); + context.applySnapshot(contextSnapshot); + completions.addAll(element.complete(src, args, context)); + break; + } + } + + return Lists.newArrayList(completions); + } + + @Override + public ChatMessage getUsage(PermissibleCommandSource commander) { + final ChatMessage build = ChatMessage.createTextMessage(""); + + for (Iterator it = this.elements.iterator(); it.hasNext(); ) { + ChatMessage usage = it.next().getUsage(commander); + + if (!usage.toString().isEmpty()) { + build.addUsing(usage); + + if (it.hasNext()) { + build.addUsing(CommandMessageFormatting.SPACE_TEXT); + } + } + } + + return ChatMessage.createTextMessage(build.toString()); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringCommandElement.java new file mode 100644 index 000000000..398215c95 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringCommandElement.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.StringType; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class StringCommandElement extends KeyElement { + private final StringType stringType; + private final RemainingJoinedStringsCommandElement joinedElement; + + public StringCommandElement(ChatMessage key, StringType type) { + super(key); + this.stringType = type; + this.joinedElement = type.isAll() ? new RemainingJoinedStringsCommandElement(key, false) : null; + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + return this.stringType.isAll() ? (String) this.joinedElement.parseValue(source, args) : args.next(); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringElement.java new file mode 100644 index 000000000..0e1deba06 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringElement.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class StringElement extends KeyElement { + public StringElement(ChatMessage key) { + super(key); + } + + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + return args.next(); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UrlElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UrlElement.java new file mode 100644 index 000000000..4a0760559 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UrlElement.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class UrlElement extends KeyElement { + public UrlElement(ChatMessage key) { + super(key); + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + String str = args.next(); + URL url; + + try { + url = new URL(str); + } catch (MalformedURLException ex) { + throw new ArgumentParseException(ChatMessage.createTextMessage("Invalid URL!"), ex, str, 0); + } + + try { + url.toURI(); + } catch (URISyntaxException ex) { + throw new ArgumentParseException(ChatMessage.createTextMessage("Invalid URL!"), ex, str, 0); + } + + return url; + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UuidElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UuidElement.java new file mode 100644 index 000000000..71d1ae067 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UuidElement.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.UUID; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class UuidElement extends KeyElement { + public UuidElement(ChatMessage key) { + super(key); + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + try { + return UUID.fromString(args.next()); + } catch (IllegalArgumentException ex) { + throw args.createError(ChatMessage.createTextMessage("Invalid UUID!")); + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/Vec3dCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/Vec3dCommandElement.java new file mode 100644 index 000000000..a56fa770f --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/Vec3dCommandElement.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.text.ChatMessage; +import net.minecraft.util.math.Vec3d; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +/** + * A {@link Vec3d} command element. + * + *

It has the following syntax:

+ * + *
 x,y,z
+ * x y z.
+ * + *

Each element can be relative to a location? so + * parseRelativeDouble() -- relative is ~(num)

+ */ +public class Vec3dCommandElement extends CommandElement { + private static final ImmutableSet SPECIAL_TOKENS = ImmutableSet.of("#target", "#me"); + + public Vec3dCommandElement(@Nullable ChatMessage key) { + super(key); + } + + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + String xStr; + String yStr; + String zStr; + xStr = args.next(); + + if (xStr.contains(",")) { + String[] split = xStr.split(","); + + if (split.length != 3) { + throw args.createError(ChatMessage.createTextMessage(String.format("Comma-separated location must have 3 elements, not %s", split.length))); + } + + xStr = split[0]; + yStr = split[1]; + zStr = split[2]; + } else if (xStr.equalsIgnoreCase("#me")) { + return source.method_4086(); + } else { + yStr = args.next(); + zStr = args.next(); + } + + double x = this.parseRelativeDouble(args, xStr, (double) source.method_4086().x); + double y = this.parseRelativeDouble(args, yStr, (double) source.method_4086().y); + double z = this.parseRelativeDouble(args, zStr, (double) source.method_4086().z); + return Vec3d.method_604(x, y, z); + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + Optional arg = args.nextIfPresent(); + + // Traverse through the possible arguments. We can't really complete arbitrary integers + if (arg.isPresent()) { + if (arg.get().startsWith("#")) { + Optional finalArg = arg; + return Collections.unmodifiableList(SPECIAL_TOKENS.stream().filter((input) -> input.startsWith(finalArg.get())).collect(Collectors.toList())); + } else if (arg.get().contains(",") || !args.hasNext()) { + return ImmutableList.of(arg.get()); + } else { + arg = args.nextIfPresent(); + + if (args.hasNext()) { + return ImmutableList.of(args.nextIfPresent().get()); + } + + return ImmutableList.of(arg.get()); + } + } + + return ImmutableList.of(); + } + + private double parseRelativeDouble(CommandArgs args, String arg, @Nullable Double relativeTo) throws ArgumentParseException { + boolean relative = arg.startsWith("~"); + + if (relative) { + if (relativeTo == null) { + throw args.createError(ChatMessage.createTextMessage("Relative position specified but source does not have a position")); + } + + arg = arg.substring(1); + + if (arg.isEmpty()) { + return relativeTo; + } + } + + try { + double ret = Double.parseDouble(arg); + return relative ? ret + relativeTo : ret; + } catch (NumberFormatException e) { + throw args.createError(ChatMessage.createTextMessage(String.format("Expected input %s to be a double, but was not", arg))); + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/WithSuggestionsElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/WithSuggestionsElement.java new file mode 100644 index 000000000..7996b6e4b --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/WithSuggestionsElement.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.command.lib.sponge.args; + +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import com.google.common.collect.ImmutableList; +import org.jetbrains.annotations.Nullable; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class WithSuggestionsElement extends CommandElement { + private final CommandElement wrapped; + private final Function> suggestions; + private final boolean requireBegin; + + public WithSuggestionsElement(CommandElement wrapped, Function> suggestions, boolean requireBegin) { + super(wrapped.getKey()); + this.wrapped = wrapped; + this.suggestions = suggestions; + this.requireBegin = requireBegin; + } + + @Nullable + @Override + public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { + return this.wrapped.parseValue(source, args); + } + + @Override + public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { + if (this.requireBegin) { + String arg = args.nextIfPresent().orElse(""); + return ImmutableList.copyOf(StreamSupport.stream(this.suggestions.apply(src).spliterator(), false).filter(f -> f.startsWith(arg)).collect(Collectors.toList())); + } else { + return ImmutableList.copyOf(this.suggestions.apply(src)); + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/ChatMessageAccessor.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/ChatMessageAccessor.java new file mode 100644 index 000000000..0d7b3a72c --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/ChatMessageAccessor.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.command; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import net.minecraft.text.ChatMessage; + +@Mixin(ChatMessage.class) +public interface ChatMessageAccessor { + @Invoker("getTranslate") + String getTranslationKey(); +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/MinecraftServerMixin.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/MinecraftServerMixin.java new file mode 100644 index 000000000..397b46b4c --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/MinecraftServerMixin.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.command; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import net.minecraft.server.MinecraftServer; + +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +@Mixin(MinecraftServer.class) +public abstract class MinecraftServerMixin implements PermissibleCommandSource { + @Shadow + public abstract boolean isDedicated(); + + @Override + public boolean hasPermission(String perm) { + return true; + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/resources/assets/legacy-fabric-sponge-command-api-v2/icon.png b/legacy-fabric-command-api-v2/1.6.4/src/main/resources/assets/legacy-fabric-sponge-command-api-v2/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2931efbf610873c0084debb8690902b0103d27fe GIT binary patch literal 1579 zcmbVMTWB0r7@iGm)TAXsYw<=rnU=;v=W=GRbL=!tc4Brl6GO7t2vVJ$IlDV#XU;e? z+r2ymsZdMQqAyaFLLUo;RumtE8Z@?uf_*4nP^4;o6fOFoSkN+o1$K?f2nE9_*b5G-l)AV)k5Qhb^- zU{V4ZnTKgnmXdpcB*Kg!W(1hvM2N&RO30x1u~eI9meGQGe@_?PDQq%q1CiV$8~M7 z?MQ_mOdqCh^a65Sv|ntwSXjV5se1;VK1|Kr8G7TQoQL&*ctt{L{fClG}xPK5k^yK3%T69N6J=>3jBqc zDNvZsrJ-yOXI^^mWf1cmY^XST)CVzIGjvEPENowmy}ax zvJ8_(Cf#+H-dBlH53`_u-~6BVAMz|(g?jCVdBWNZ(+A}(pFV7>S3QgPiQcMaflkIC z-3Ti|VT~{au*vq0ts9O&m$p&Gl=L6+q6_m$IcVq}o~+Pl{g>1esQp4%wp~|*zk1n` zZ7T6Toc4`y88s}riCP|ZXrJ?FLz@^KTcyqLjey zu95Yz%F&S{<0~f)Iomek?+hQ%MhCu%T^zsg>C_L`1`Br`xNY&))k9yTQb$JC>)w_f zpU(^tu^Q)y%W~lVz`jz;_ jF?g&s@Y=Qe&c#kW|JbvqK0Y=Rw)4XDoVqsk_>;c_`@;F@ literal 0 HcmV?d00001 diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/resources/fabric.mod.json b/legacy-fabric-command-api-v2/1.6.4/src/main/resources/fabric.mod.json new file mode 100644 index 000000000..5ff821a2a --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/resources/fabric.mod.json @@ -0,0 +1,46 @@ +{ + "schemaVersion": 1, + "id": "legacy-fabric-command-api-v2", + "name": "Legacy Fabric Command API (v2)", + "version": "${version}", + "environment": "*", + "license": "Apache-2.0", + "icon": "assets/legacy-fabric-sponge-command-api-v2/icon.png", + "contact": { + "homepage": "https://legacyfabric.net", + "irc": "irc://irc.esper.net:6667/legacyfabric", + "issues": "https://github.com/Legacy-Fabric/fabric/issues", + "sources": "https://github.com/Legacy-Fabric/fabric" + }, + "authors": [ + "Legacy-Fabric" + ], + "depends": { + "fabricloader": ">=0.4.0", + "minecraft": "${minecraft_version}" + }, + "entrypoints": { + "client": [ + "net.legacyfabric.fabric.impl.command.ImplInit" + ], + "server": [ + "net.legacyfabric.fabric.impl.command.ImplInit" + ] + }, + "description": "Powerful Command API that uses SpongeAPI's command api", + "mixins": [ + "legacy-fabric-sponge-command-api-v2.mixins.json" + ], + "custom": { + "modmenu": { + "badges": [ "library" ], + "parent": { + "id": "legacy-fabric-api", + "name": "Legacy Fabric API", + "badges": [ "library" ], + "description": "Core API module providing key hooks and inter-compatibility features for Minecraft 1.7.10-1.12.2.", + "icon": "assets/legacy-fabric-sponge-command-api-v2/icon.png" + } + } + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/resources/legacy-fabric-sponge-command-api-v2.mixins.json b/legacy-fabric-command-api-v2/1.6.4/src/main/resources/legacy-fabric-sponge-command-api-v2.mixins.json new file mode 100644 index 000000000..6d0b44d07 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/main/resources/legacy-fabric-sponge-command-api-v2.mixins.json @@ -0,0 +1,12 @@ +{ + "required": true, + "package": "net.legacyfabric.fabric.mixin.command", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "ChatMessageAccessor", + "MinecraftServerMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommand.java b/legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommand.java new file mode 100644 index 000000000..293cb137c --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommand.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.test.command; + +import net.minecraft.text.ChatMessage; + +import net.fabricmc.loader.api.ModContainer; +import net.fabricmc.loader.api.metadata.ContactInformation; + +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandManager; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandResult; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.GenericArguments; +import net.legacyfabric.fabric.api.command.v2.lib.sponge.spec.CommandSpec; +import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; + +public class ModMetadataCommand { + public static void register(CommandManager manager) { + manager.register( + CommandSpec.builder() + .arguments(GenericArguments.mod(ChatMessage.createTextMessage("modid"))) + .executor(ModMetadataCommand::execute) + .build(), + "modmetadata" + ); + } + + private static CommandResult execute(PermissibleCommandSource source, CommandContext ctx) throws CommandException { + ModContainer container = ctx.getOne("modid").orElseThrow(() -> new CommandException(ChatMessage.createTextMessage("mod not found"))); + ChatMessage builder = ChatMessage.createTextMessage(""); + + builder.addText("Mod Name: ".concat(container.getMetadata().getName()).concat("\n")); + builder.addText("Description: ".concat(container.getMetadata().getDescription()).concat("\n")); + ContactInformation contact = container.getMetadata().getContact(); + + if (contact.get("issues").isPresent()) { + ChatMessage issueText = ChatMessage.createTextMessage(""); + issueText.addText("Issues: "); + ChatMessage issueUrl = ChatMessage.createTextMessage(contact.get("issues").get()); + issueText.addUsing(issueUrl); + issueText.addText("\n"); + builder.addUsing(issueText); + } + + if (contact.get("sources").isPresent()) { + ChatMessage sourcesText = ChatMessage.createTextMessage(""); + sourcesText.addText("Sources: "); + ChatMessage sourcesUrl = ChatMessage.createTextMessage(contact.get("sources").get()); + sourcesText.addUsing(sourcesUrl); + sourcesText.addText("\n"); + builder.addUsing(sourcesText); + } + + builder.addText("Metadata Type: ".concat(container.getMetadata().getType()).concat("\n")); + source.method_5505(builder); + return CommandResult.success(); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/SpongeCommandTest.java b/legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/SpongeCommandTest.java new file mode 100644 index 000000000..af1a6c161 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/SpongeCommandTest.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.test.command; + +import net.fabricmc.api.ModInitializer; + +import net.legacyfabric.fabric.api.command.v2.CommandRegistrar; + +public class SpongeCommandTest implements ModInitializer { + @Override + public void onInitialize() { + CommandRegistrar.EVENT.register((manager, dedicated) -> { + ModMetadataCommand.register(manager); + }); + } +} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/testmod/resources/fabric.mod.json b/legacy-fabric-command-api-v2/1.6.4/src/testmod/resources/fabric.mod.json new file mode 100644 index 000000000..b8b0d6131 --- /dev/null +++ b/legacy-fabric-command-api-v2/1.6.4/src/testmod/resources/fabric.mod.json @@ -0,0 +1,14 @@ +{ + "schemaVersion": 1, + "id": "legacy-fabric-sponge-command-api-v2-testmod", + "description": "Tests for api features", + "version": "1.0.0", + "entrypoints": { + "main": [ + "net.legacyfabric.fabric.test.command.SpongeCommandTest" + ] + }, + "depends": { + "minecraft": "${minecraft_version}" + } +} From 653ed4735fc5ff2c1397982311a590745841b705 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sun, 5 May 2024 14:26:52 +0200 Subject: [PATCH 13/24] Small tweaks --- legacy-fabric-command-api-v1/common/gradle.properties | 1 + legacy-fabric-command-api-v2/1.6.4/gradle.properties | 2 +- legacy-fabric-keybindings-api-v1/1.6.4/gradle.properties | 2 +- .../1.12.2/src/testmod/resources/fabric.mod.json | 2 +- .../1.6.4/src/testmod/resources/fabric.mod.json | 2 +- .../1.7.10/src/testmod/resources/fabric.mod.json | 2 +- .../1.8.9/src/testmod/resources/fabric.mod.json | 2 +- .../common/src/testmod/resources/fabric.mod.json | 2 +- legacy-fabric-resource-loader-v1/1.6.4/gradle.properties | 2 +- 9 files changed, 9 insertions(+), 8 deletions(-) diff --git a/legacy-fabric-command-api-v1/common/gradle.properties b/legacy-fabric-command-api-v1/common/gradle.properties index 44fc6796f..900b11120 100644 --- a/legacy-fabric-command-api-v1/common/gradle.properties +++ b/legacy-fabric-command-api-v1/common/gradle.properties @@ -1,2 +1,3 @@ +minVersionIncluded=1.3 maxVersionIncluded=1.12.2 artifactSuffix= diff --git a/legacy-fabric-command-api-v2/1.6.4/gradle.properties b/legacy-fabric-command-api-v2/1.6.4/gradle.properties index bff6c84c0..72b74abca 100644 --- a/legacy-fabric-command-api-v2/1.6.4/gradle.properties +++ b/legacy-fabric-command-api-v2/1.6.4/gradle.properties @@ -1,2 +1,2 @@ -minVersionIncluded=1.6.4 +minVersionIncluded=1.3 maxVersionIncluded=1.6.4 diff --git a/legacy-fabric-keybindings-api-v1/1.6.4/gradle.properties b/legacy-fabric-keybindings-api-v1/1.6.4/gradle.properties index bff6c84c0..72b74abca 100644 --- a/legacy-fabric-keybindings-api-v1/1.6.4/gradle.properties +++ b/legacy-fabric-keybindings-api-v1/1.6.4/gradle.properties @@ -1,2 +1,2 @@ -minVersionIncluded=1.6.4 +minVersionIncluded=1.3 maxVersionIncluded=1.6.4 diff --git a/legacy-fabric-lifecycle-events-v1/1.12.2/src/testmod/resources/fabric.mod.json b/legacy-fabric-lifecycle-events-v1/1.12.2/src/testmod/resources/fabric.mod.json index 36a567c30..3ff8b8978 100644 --- a/legacy-fabric-lifecycle-events-v1/1.12.2/src/testmod/resources/fabric.mod.json +++ b/legacy-fabric-lifecycle-events-v1/1.12.2/src/testmod/resources/fabric.mod.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "id": "legacy-fabric-lifecycle-events-v1-testmod-versioned", + "id": "legacy-fabric-lifecycle-events-v1-testmod", "description": "Tests for lifecycle events", "version": "1.0.0", "entrypoints": { diff --git a/legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/resources/fabric.mod.json b/legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/resources/fabric.mod.json index 36a567c30..3ff8b8978 100644 --- a/legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/resources/fabric.mod.json +++ b/legacy-fabric-lifecycle-events-v1/1.6.4/src/testmod/resources/fabric.mod.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "id": "legacy-fabric-lifecycle-events-v1-testmod-versioned", + "id": "legacy-fabric-lifecycle-events-v1-testmod", "description": "Tests for lifecycle events", "version": "1.0.0", "entrypoints": { diff --git a/legacy-fabric-lifecycle-events-v1/1.7.10/src/testmod/resources/fabric.mod.json b/legacy-fabric-lifecycle-events-v1/1.7.10/src/testmod/resources/fabric.mod.json index 36a567c30..3ff8b8978 100644 --- a/legacy-fabric-lifecycle-events-v1/1.7.10/src/testmod/resources/fabric.mod.json +++ b/legacy-fabric-lifecycle-events-v1/1.7.10/src/testmod/resources/fabric.mod.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "id": "legacy-fabric-lifecycle-events-v1-testmod-versioned", + "id": "legacy-fabric-lifecycle-events-v1-testmod", "description": "Tests for lifecycle events", "version": "1.0.0", "entrypoints": { diff --git a/legacy-fabric-lifecycle-events-v1/1.8.9/src/testmod/resources/fabric.mod.json b/legacy-fabric-lifecycle-events-v1/1.8.9/src/testmod/resources/fabric.mod.json index 36a567c30..3ff8b8978 100644 --- a/legacy-fabric-lifecycle-events-v1/1.8.9/src/testmod/resources/fabric.mod.json +++ b/legacy-fabric-lifecycle-events-v1/1.8.9/src/testmod/resources/fabric.mod.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "id": "legacy-fabric-lifecycle-events-v1-testmod-versioned", + "id": "legacy-fabric-lifecycle-events-v1-testmod", "description": "Tests for lifecycle events", "version": "1.0.0", "entrypoints": { diff --git a/legacy-fabric-lifecycle-events-v1/common/src/testmod/resources/fabric.mod.json b/legacy-fabric-lifecycle-events-v1/common/src/testmod/resources/fabric.mod.json index ac25a1d6f..23c4a9fab 100644 --- a/legacy-fabric-lifecycle-events-v1/common/src/testmod/resources/fabric.mod.json +++ b/legacy-fabric-lifecycle-events-v1/common/src/testmod/resources/fabric.mod.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "id": "legacy-fabric-lifecycle-events-v1-testmod", + "id": "legacy-fabric-lifecycle-events-v1-common-testmod", "description": "Tests for lifecycle events", "version": "1.0.0", "entrypoints": { diff --git a/legacy-fabric-resource-loader-v1/1.6.4/gradle.properties b/legacy-fabric-resource-loader-v1/1.6.4/gradle.properties index bff6c84c0..72b74abca 100644 --- a/legacy-fabric-resource-loader-v1/1.6.4/gradle.properties +++ b/legacy-fabric-resource-loader-v1/1.6.4/gradle.properties @@ -1,2 +1,2 @@ -minVersionIncluded=1.6.4 +minVersionIncluded=1.3 maxVersionIncluded=1.6.4 From 880d8ec8b9de47f8a4b65f5daa53eca8806daa3c Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sun, 5 May 2024 15:04:16 +0200 Subject: [PATCH 14/24] networking api will probably require a rewrite later to support pre-1.7 --- legacy-fabric-networking-api-v1/1.7.10/gradle.properties | 2 +- legacy-fabric-networking-api-v1/common/gradle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/legacy-fabric-networking-api-v1/1.7.10/gradle.properties b/legacy-fabric-networking-api-v1/1.7.10/gradle.properties index 77baca0c7..af031afbf 100644 --- a/legacy-fabric-networking-api-v1/1.7.10/gradle.properties +++ b/legacy-fabric-networking-api-v1/1.7.10/gradle.properties @@ -1,2 +1,2 @@ -minVersionExcluded=1.6.4 +minVersionIncluded=1.7.10 maxVersionIncluded=1.7.10 diff --git a/legacy-fabric-networking-api-v1/common/gradle.properties b/legacy-fabric-networking-api-v1/common/gradle.properties index 197d3d229..503076051 100644 --- a/legacy-fabric-networking-api-v1/common/gradle.properties +++ b/legacy-fabric-networking-api-v1/common/gradle.properties @@ -1,2 +1,2 @@ -minVersionExcluded=1.6.4 +minVersionIncluded=1.7.10 maxVersionIncluded=1.12.2 From 9170d75b8960cf01a259ad464d9b428bbb286c10 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sun, 5 May 2024 15:59:56 +0200 Subject: [PATCH 15/24] Add 1.6.4 to supported version range --- build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 705017056..68d4116ea 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,8 @@ def supportedVersions = [ "1.9.4", "1.8.9", "1.8", - "1.7.10" + "1.7.10", + "1.6.4" ] def supportedRanges = [ // ["1.8", "1.8.9", false] // third parameter is whether or not to include snapshots in the range. From f96b8daa22023a3e6fcc97237ee0c4c683d1cffa Mon Sep 17 00:00:00 2001 From: Cat Core Date: Thu, 9 May 2024 15:10:27 +0200 Subject: [PATCH 16/24] Port Item Group module to 1.6.4 --- README.md | 34 +++++------ .../mixin/item/group/client/MixinScreen.java | 36 +++++++++++ .../legacy-fabric-item-groups-v1.mixins.json | 1 + .../1.6.4/build.gradle | 0 .../1.6.4/gradle.properties | 2 + .../impl/item/group/FabricItemGroup.java | 57 ++++++++++++++++++ .../mixin/item/group/ItemGroupMixin.java | 36 +++++++++++ .../item/group/client/HandledScreenMixin.java | 19 ++++++ .../resources/assets/legacy-fabric/icon.png | Bin 0 -> 1579 bytes .../assets/legacy-fabric/lang/en_US.lang | 1 + .../assets/legacy-fabric/lang/ru_RU.lang | 1 + .../textures/gui/creative_buttons.png | Bin 0 -> 552 bytes .../1.6.4/src/main/resources/fabric.mod.json | 37 ++++++++++++ .../legacy-fabric-item-groups-v1.mixins.json | 14 +++++ .../fabric/test/item/group/ItemGroupTest.java | 56 +++++++++++++++++ .../assets/legacy-fabric-api/lang/en_US.lang | 1 + .../src/testmod/resources/fabric.mod.json | 14 +++++ .../mixin/item/group/client/MixinScreen.java | 0 .../legacy-fabric-item-groups-v1.mixins.json | 1 + .../common/gradle.properties | 2 +- ...y-fabric-item-groups-v1-common.mixins.json | 3 +- 21 files changed, 295 insertions(+), 20 deletions(-) create mode 100644 legacy-fabric-item-groups-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/MixinScreen.java create mode 100644 legacy-fabric-item-groups-v1/1.6.4/build.gradle create mode 100644 legacy-fabric-item-groups-v1/1.6.4/gradle.properties create mode 100644 legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/item/group/FabricItemGroup.java create mode 100644 legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/item/group/ItemGroupMixin.java create mode 100644 legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/HandledScreenMixin.java create mode 100644 legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/icon.png create mode 100644 legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/en_US.lang create mode 100644 legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/ru_RU.lang create mode 100644 legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/textures/gui/creative_buttons.png create mode 100644 legacy-fabric-item-groups-v1/1.6.4/src/main/resources/fabric.mod.json create mode 100644 legacy-fabric-item-groups-v1/1.6.4/src/main/resources/legacy-fabric-item-groups-v1.mixins.json create mode 100644 legacy-fabric-item-groups-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/item/group/ItemGroupTest.java create mode 100644 legacy-fabric-item-groups-v1/1.6.4/src/testmod/resources/assets/legacy-fabric-api/lang/en_US.lang create mode 100644 legacy-fabric-item-groups-v1/1.6.4/src/testmod/resources/fabric.mod.json rename legacy-fabric-item-groups-v1/{common => 1.8.9}/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/MixinScreen.java (100%) diff --git a/README.md b/README.md index 84a0f0be5..c55e2f88a 100644 --- a/README.md +++ b/README.md @@ -14,20 +14,20 @@ For support, consider joining the [Legacy Fabric discord server](https://legacyf ? = Not sure if it was tested or working correctly\ ❌ = Not working at all, likely crashing -| | 1.6.4 | 1.7.10 | 1.8 | 1.8.9 | 1.9.4 | 1.10.2 | 1.11.2 | 1.12.2 | 1.13.2 | -|----------------------|------------------------------------|--------|-----|-------|-------|--------|--------|--------|--------| -| api-base | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| command-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| command-api-v2 | ⚠
Text formatting need rework | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| crash-report-info-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| entity-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| gamerule-api-v1 | ? | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ? | -| item-groups-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| keybindings-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| lifecycle-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| logger-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| networking-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| permissions-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| registry-sync-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| rendering-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| resource-loader-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| | 1.6.4 | 1.7.10 | 1.8 | 1.8.9 | 1.9.4 | 1.10.2 | 1.11.2 | 1.12.2 | 1.13.2 | +|----------------------|-------------------------------|--------|-----|-------|-------|--------|--------|--------|--------| +| api-base | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| command-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| command-api-v2 | ⚠ Text formatting need rework | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| crash-report-info-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| entity-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| gamerule-api-v1 | ? | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ? | +| item-groups-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| keybindings-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| lifecycle-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| logger-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| networking-api-v1 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| permissions-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| registry-sync-api-v1 | ❌ (Depends on networking-api) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| rendering-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| resource-loader-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | diff --git a/legacy-fabric-item-groups-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/MixinScreen.java b/legacy-fabric-item-groups-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/MixinScreen.java new file mode 100644 index 000000000..151346441 --- /dev/null +++ b/legacy-fabric-item-groups-v1/1.12.2/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/MixinScreen.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.item.group.client; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import net.minecraft.client.gui.screen.Screen; + +import net.legacyfabric.fabric.impl.item.group.ScreenAccessor; + +@Mixin(Screen.class) +public abstract class MixinScreen implements ScreenAccessor { + @Shadow + public abstract void renderTooltip(String text, int x, int y); + + @Override + public void callRenderTooltip(String text, int x, int y) { + this.renderTooltip(text, x, y); + } +} diff --git a/legacy-fabric-item-groups-v1/1.12.2/src/main/resources/legacy-fabric-item-groups-v1.mixins.json b/legacy-fabric-item-groups-v1/1.12.2/src/main/resources/legacy-fabric-item-groups-v1.mixins.json index f0b4add64..4302b11d7 100644 --- a/legacy-fabric-item-groups-v1/1.12.2/src/main/resources/legacy-fabric-item-groups-v1.mixins.json +++ b/legacy-fabric-item-groups-v1/1.12.2/src/main/resources/legacy-fabric-item-groups-v1.mixins.json @@ -6,6 +6,7 @@ "ItemGroupMixin" ], "client": [ + "client.MixinScreen" ], "injectors": { "defaultRequire": 1 diff --git a/legacy-fabric-item-groups-v1/1.6.4/build.gradle b/legacy-fabric-item-groups-v1/1.6.4/build.gradle new file mode 100644 index 000000000..e69de29bb diff --git a/legacy-fabric-item-groups-v1/1.6.4/gradle.properties b/legacy-fabric-item-groups-v1/1.6.4/gradle.properties new file mode 100644 index 000000000..72b74abca --- /dev/null +++ b/legacy-fabric-item-groups-v1/1.6.4/gradle.properties @@ -0,0 +1,2 @@ +minVersionIncluded=1.3 +maxVersionIncluded=1.6.4 diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/item/group/FabricItemGroup.java b/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/item/group/FabricItemGroup.java new file mode 100644 index 000000000..e0e216f07 --- /dev/null +++ b/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/item/group/FabricItemGroup.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.impl.item.group; + +import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.Supplier; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.itemgroup.ItemGroup; + +public class FabricItemGroup extends ItemGroup { + private final Supplier itemSupplier; + private final BiConsumer, ItemGroup> stacksForDisplay; + + public FabricItemGroup(int index, String id, Supplier itemSupplier, BiConsumer, ItemGroup> stacksForDisplay) { + super(index, id); + this.itemSupplier = itemSupplier; + this.stacksForDisplay = stacksForDisplay; + } + + @Override + @Environment(EnvType.CLIENT) + public Item method_3320() { + return this.itemSupplier.get().getItem(); + } + + @Override + @Environment(EnvType.CLIENT) + public void showItems(List stacks) { + if (stacksForDisplay != null) { + stacksForDisplay.accept(stacks, this); + return; + } + + super.showItems(stacks); + } +} diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/item/group/ItemGroupMixin.java b/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/item/group/ItemGroupMixin.java new file mode 100644 index 000000000..5eb3f5ebe --- /dev/null +++ b/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/item/group/ItemGroupMixin.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.mixin.item.group; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.item.itemgroup.ItemGroup; + +import net.legacyfabric.fabric.impl.item.group.FabricCreativeGuiComponents; +import net.legacyfabric.fabric.impl.item.group.FabricItemGroup; + +@Mixin(ItemGroup.class) +public class ItemGroupMixin { + @Inject(method = "", at = @At("RETURN")) + private static void classInit(CallbackInfo ci) { + FabricCreativeGuiComponents.ITEM_GROUP_CREATOR = FabricItemGroup::new; + } +} diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/HandledScreenMixin.java b/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/HandledScreenMixin.java new file mode 100644 index 000000000..b35d36780 --- /dev/null +++ b/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/HandledScreenMixin.java @@ -0,0 +1,19 @@ +package net.legacyfabric.fabric.mixin.item.group.client; + +import net.legacyfabric.fabric.impl.item.group.ScreenAccessor; + +import net.minecraft.client.gui.screen.ingame.HandledScreen; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(HandledScreen.class) +public abstract class HandledScreenMixin implements ScreenAccessor { + @Shadow + protected abstract void method_1128(String par1, int par2, int par3); + + @Override + public void callRenderTooltip(String text, int x, int y) { + this.method_1128(text, x, y); + } +} diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/icon.png b/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2931efbf610873c0084debb8690902b0103d27fe GIT binary patch literal 1579 zcmbVMTWB0r7@iGm)TAXsYw<=rnU=;v=W=GRbL=!tc4Brl6GO7t2vVJ$IlDV#XU;e? z+r2ymsZdMQqAyaFLLUo;RumtE8Z@?uf_*4nP^4;o6fOFoSkN+o1$K?f2nE9_*b5G-l)AV)k5Qhb^- zU{V4ZnTKgnmXdpcB*Kg!W(1hvM2N&RO30x1u~eI9meGQGe@_?PDQq%q1CiV$8~M7 z?MQ_mOdqCh^a65Sv|ntwSXjV5se1;VK1|Kr8G7TQoQL&*ctt{L{fClG}xPK5k^yK3%T69N6J=>3jBqc zDNvZsrJ-yOXI^^mWf1cmY^XST)CVzIGjvEPENowmy}ax zvJ8_(Cf#+H-dBlH53`_u-~6BVAMz|(g?jCVdBWNZ(+A}(pFV7>S3QgPiQcMaflkIC z-3Ti|VT~{au*vq0ts9O&m$p&Gl=L6+q6_m$IcVq}o~+Pl{g>1esQp4%wp~|*zk1n` zZ7T6Toc4`y88s}riCP|ZXrJ?FLz@^KTcyqLjey zu95Yz%F&S{<0~f)Iomek?+hQ%MhCu%T^zsg>C_L`1`Br`xNY&))k9yTQb$JC>)w_f zpU(^tu^Q)y%W~lVz`jz;_ jF?g&s@Y=Qe&c#kW|JbvqK0Y=Rw)4XDoVqsk_>;c_`@;F@ literal 0 HcmV?d00001 diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/en_US.lang b/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/en_US.lang new file mode 100644 index 000000000..c82f116d6 --- /dev/null +++ b/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/en_US.lang @@ -0,0 +1 @@ +fabric.gui.creativeTabPage=Page %d/%d diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/ru_RU.lang b/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/ru_RU.lang new file mode 100644 index 000000000..31292b1be --- /dev/null +++ b/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/ru_RU.lang @@ -0,0 +1 @@ +fabric.gui.creativeTabPage=Страница %d/%d diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/textures/gui/creative_buttons.png b/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/textures/gui/creative_buttons.png new file mode 100644 index 0000000000000000000000000000000000000000..27b9a1499ec857ad5ccebcc442b7ad5ca995b99d GIT binary patch literal 552 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5FjO4;u=vBoS#-wo>-L1;Fyx1 zl&avFo0y&&l$w}QS$Hzl2B=6Pz$e62TU)!kyZitD|3HDJ?gOErp=pK7fb2+txPBnT zQ4-`A43q@{hI`F>BY`$e@^o;cw79Pj!0`G?6e>JP63-&HywBS`ZcJZ-KgGPgeph8*$!vjugTe~DWM4f1-NUU literal 0 HcmV?d00001 diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/fabric.mod.json b/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/fabric.mod.json new file mode 100644 index 000000000..ab1f44bd4 --- /dev/null +++ b/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/fabric.mod.json @@ -0,0 +1,37 @@ +{ + "schemaVersion": 1, + "id": "legacy-fabric-item-groups-v1", + "name": "Legacy Fabric Item Groups (V1)", + "version": "${version}", + "environment": "*", + "license": "Apache-2.0", + "icon": "assets/legacy-fabric/icon.png", + "contact": { + "homepage": "https://legacyfabric.net/", + "issues": "https://github.com/Legacy-Fabric/fabric/issues", + "sources": "https://github.com/Legacy-Fabric/fabric" + }, + "authors": [ + "FabricMC", + "Legacy Fabric" + ], + "mixins": [ + "legacy-fabric-item-groups-v1.mixins.json" + ], + "description": "Advanced item groups.", + "depends": { + "minecraft": "${minecraft_version}" + }, + "custom": { + "modmenu": { + "badges": [ "library" ], + "parent": { + "id": "legacy-fabric-api", + "name": "Legacy Fabric API", + "badges": [ "library" ], + "description": "Core API module providing key hooks and inter-compatibility features for Minecraft 1.7.10-1.12.2.", + "icon": "assets/legacy-fabric/icon.png" + } + } + } +} diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/legacy-fabric-item-groups-v1.mixins.json b/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/legacy-fabric-item-groups-v1.mixins.json new file mode 100644 index 000000000..926003ea4 --- /dev/null +++ b/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/legacy-fabric-item-groups-v1.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "package": "net.legacyfabric.fabric.mixin.item.group", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "ItemGroupMixin" + ], + "client": [ + "client.HandledScreenMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/item/group/ItemGroupTest.java b/legacy-fabric-item-groups-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/item/group/ItemGroupTest.java new file mode 100644 index 000000000..3adb96689 --- /dev/null +++ b/legacy-fabric-item-groups-v1/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/item/group/ItemGroupTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.legacyfabric.fabric.test.item.group; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.StreamSupport; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.itemgroup.ItemGroup; + +import net.fabricmc.api.ModInitializer; + +import net.legacyfabric.fabric.api.client.itemgroup.FabricItemGroupBuilder; +import net.legacyfabric.fabric.api.util.Identifier; + +public class ItemGroupTest implements ModInitializer { + //Adds an item group with all items in it + private static final ItemGroup ITEM_GROUP = FabricItemGroupBuilder.create(new Identifier("legacy-fabric-item-groups-v1-testmod", "test_group")) + .iconWithItemStack(() -> new ItemStack(Item.DIAMOND)) + .appendItems(stacks -> + StreamSupport.stream(Arrays.stream(Item.ITEMS).spliterator(), false) + .filter(Objects::nonNull) + .map(ItemStack::new) + .forEach(stacks::add) + ).build(); + + private static final ItemGroup ITEM_GROUP_2 = FabricItemGroupBuilder.create(new Identifier("legacy-fabric-item-groups-v1-testmod", "test_group_two")) + .iconWithItemStack(() -> new ItemStack(Item.REDSTONE)) + .appendItems((stacks, itemGroup) -> { + for (Item item : Item.ITEMS) { + if (item != null && (item.getItemGroup() == ItemGroup.FOOD || item.getItemGroup() == itemGroup)) { + stacks.add(new ItemStack(item)); + } + } + }).build(); + + @Override + public void onInitialize() { } +} diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/testmod/resources/assets/legacy-fabric-api/lang/en_US.lang b/legacy-fabric-item-groups-v1/1.6.4/src/testmod/resources/assets/legacy-fabric-api/lang/en_US.lang new file mode 100644 index 000000000..92e649b84 --- /dev/null +++ b/legacy-fabric-item-groups-v1/1.6.4/src/testmod/resources/assets/legacy-fabric-api/lang/en_US.lang @@ -0,0 +1 @@ +itemGroup.dmn.testgroup=Test Group by DomamaN202 diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/testmod/resources/fabric.mod.json b/legacy-fabric-item-groups-v1/1.6.4/src/testmod/resources/fabric.mod.json new file mode 100644 index 000000000..ffa7dbef4 --- /dev/null +++ b/legacy-fabric-item-groups-v1/1.6.4/src/testmod/resources/fabric.mod.json @@ -0,0 +1,14 @@ +{ + "schemaVersion": 1, + "id": "legacy-fabric-item-groups-v0-testmod", + "description": "Tests for Item Groups", + "version": "1.0.0", + "entrypoints": { + "main": [ + "net.legacyfabric.fabric.test.item.group.ItemGroupTest" + ] + }, + "depends": { + "minecraft": "${minecraft_version}" + } +} diff --git a/legacy-fabric-item-groups-v1/common/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/MixinScreen.java b/legacy-fabric-item-groups-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/MixinScreen.java similarity index 100% rename from legacy-fabric-item-groups-v1/common/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/MixinScreen.java rename to legacy-fabric-item-groups-v1/1.8.9/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/MixinScreen.java diff --git a/legacy-fabric-item-groups-v1/1.8.9/src/main/resources/legacy-fabric-item-groups-v1.mixins.json b/legacy-fabric-item-groups-v1/1.8.9/src/main/resources/legacy-fabric-item-groups-v1.mixins.json index f0b4add64..4302b11d7 100644 --- a/legacy-fabric-item-groups-v1/1.8.9/src/main/resources/legacy-fabric-item-groups-v1.mixins.json +++ b/legacy-fabric-item-groups-v1/1.8.9/src/main/resources/legacy-fabric-item-groups-v1.mixins.json @@ -6,6 +6,7 @@ "ItemGroupMixin" ], "client": [ + "client.MixinScreen" ], "injectors": { "defaultRequire": 1 diff --git a/legacy-fabric-item-groups-v1/common/gradle.properties b/legacy-fabric-item-groups-v1/common/gradle.properties index 503076051..d523a75a0 100644 --- a/legacy-fabric-item-groups-v1/common/gradle.properties +++ b/legacy-fabric-item-groups-v1/common/gradle.properties @@ -1,2 +1,2 @@ -minVersionIncluded=1.7.10 +minVersionIncluded=1.3 maxVersionIncluded=1.12.2 diff --git a/legacy-fabric-item-groups-v1/common/src/main/resources/legacy-fabric-item-groups-v1-common.mixins.json b/legacy-fabric-item-groups-v1/common/src/main/resources/legacy-fabric-item-groups-v1-common.mixins.json index 1f9907d0b..b0ead9873 100644 --- a/legacy-fabric-item-groups-v1/common/src/main/resources/legacy-fabric-item-groups-v1-common.mixins.json +++ b/legacy-fabric-item-groups-v1/common/src/main/resources/legacy-fabric-item-groups-v1-common.mixins.json @@ -7,8 +7,7 @@ ], "client": [ "client.MixinCreativePlayerInventoryGui", - "client.MixinItemGroup", - "client.MixinScreen" + "client.MixinItemGroup" ], "injectors": { "defaultRequire": 1 From 19b5d091e6e4a0fb98bff0d4ff294b7a3d25a9df Mon Sep 17 00:00:00 2001 From: Cat Core Date: Thu, 9 May 2024 15:12:29 +0200 Subject: [PATCH 17/24] Item group lang files already exist in common module --- .../src/main/resources/assets/legacy-fabric/lang/en_US.lang | 1 - .../src/main/resources/assets/legacy-fabric/lang/ru_RU.lang | 1 - .../src/main/resources/assets/legacy-fabric/lang/en_US.lang | 1 - .../src/main/resources/assets/legacy-fabric/lang/ru_RU.lang | 1 - 4 files changed, 4 deletions(-) delete mode 100644 legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/en_US.lang delete mode 100644 legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/ru_RU.lang delete mode 100644 legacy-fabric-item-groups-v1/1.8.9/src/main/resources/assets/legacy-fabric/lang/en_US.lang delete mode 100644 legacy-fabric-item-groups-v1/1.8.9/src/main/resources/assets/legacy-fabric/lang/ru_RU.lang diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/en_US.lang b/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/en_US.lang deleted file mode 100644 index c82f116d6..000000000 --- a/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/en_US.lang +++ /dev/null @@ -1 +0,0 @@ -fabric.gui.creativeTabPage=Page %d/%d diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/ru_RU.lang b/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/ru_RU.lang deleted file mode 100644 index 31292b1be..000000000 --- a/legacy-fabric-item-groups-v1/1.6.4/src/main/resources/assets/legacy-fabric/lang/ru_RU.lang +++ /dev/null @@ -1 +0,0 @@ -fabric.gui.creativeTabPage=Страница %d/%d diff --git a/legacy-fabric-item-groups-v1/1.8.9/src/main/resources/assets/legacy-fabric/lang/en_US.lang b/legacy-fabric-item-groups-v1/1.8.9/src/main/resources/assets/legacy-fabric/lang/en_US.lang deleted file mode 100644 index c82f116d6..000000000 --- a/legacy-fabric-item-groups-v1/1.8.9/src/main/resources/assets/legacy-fabric/lang/en_US.lang +++ /dev/null @@ -1 +0,0 @@ -fabric.gui.creativeTabPage=Page %d/%d diff --git a/legacy-fabric-item-groups-v1/1.8.9/src/main/resources/assets/legacy-fabric/lang/ru_RU.lang b/legacy-fabric-item-groups-v1/1.8.9/src/main/resources/assets/legacy-fabric/lang/ru_RU.lang deleted file mode 100644 index 31292b1be..000000000 --- a/legacy-fabric-item-groups-v1/1.8.9/src/main/resources/assets/legacy-fabric/lang/ru_RU.lang +++ /dev/null @@ -1 +0,0 @@ -fabric.gui.creativeTabPage=Страница %d/%d From 24f31ffd31cf79e70e3471ba4b392df14315f1f1 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Thu, 9 May 2024 15:16:39 +0200 Subject: [PATCH 18/24] Improve command-api-v1 testmod --- .../fabric/test/command/ModMetadataCommandV1.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/legacy-fabric-command-api-v1/common/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommandV1.java b/legacy-fabric-command-api-v1/common/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommandV1.java index afcf17ff1..d37c38c81 100644 --- a/legacy-fabric-command-api-v1/common/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommandV1.java +++ b/legacy-fabric-command-api-v1/common/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommandV1.java @@ -17,11 +17,14 @@ package net.legacyfabric.fabric.test.command; +import java.util.Optional; + import net.minecraft.command.AbstractCommand; import net.minecraft.command.CommandException; import net.minecraft.command.CommandSource; import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.metadata.ContactInformation; public class ModMetadataCommandV1 extends AbstractCommand { @@ -38,7 +41,11 @@ public String getUsageTranslationKey(CommandSource source) { @Override public void execute(CommandSource source, String[] args) throws CommandException { if (args.length > 0) { - FabricLoader.getInstance().getModContainer(args[0]).ifPresent(container -> { + Optional optionalModContainer = FabricLoader.getInstance().getModContainer(args[0]); + + if (optionalModContainer.isPresent()) { + ModContainer container = optionalModContainer.get(); + StringBuilder builder = new StringBuilder(); builder.append("Mod Name: ".concat(container.getMetadata().getName()).concat("\n")); builder.append("Description: ".concat(container.getMetadata().getDescription()).concat("\n")); @@ -64,7 +71,9 @@ public void execute(CommandSource source, String[] args) throws CommandException builder.append("Metadata Type: ".concat(container.getMetadata().getType()).concat("\n")); CommandV1Test.LOGGER.info(builder.toString()); - }); + } else { + CommandV1Test.LOGGER.error("Couldn't find Mod container for mod id '" + args[0] + "'"); + } } } } From 85719bee297e9a3617427b8d14a716a07ad53475 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Thu, 9 May 2024 15:17:40 +0200 Subject: [PATCH 19/24] Fix style --- .../impl/item/group/FabricItemGroup.java | 6 ++--- .../item/group/client/HandledScreenMixin.java | 23 ++++++++++++++++--- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/item/group/FabricItemGroup.java b/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/item/group/FabricItemGroup.java index e0e216f07..4ff47d1d9 100644 --- a/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/item/group/FabricItemGroup.java +++ b/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/item/group/FabricItemGroup.java @@ -21,13 +21,13 @@ import java.util.function.BiConsumer; import java.util.function.Supplier; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; - import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.itemgroup.ItemGroup; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + public class FabricItemGroup extends ItemGroup { private final Supplier itemSupplier; private final BiConsumer, ItemGroup> stacksForDisplay; diff --git a/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/HandledScreenMixin.java b/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/HandledScreenMixin.java index b35d36780..14d8ccf80 100644 --- a/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/HandledScreenMixin.java +++ b/legacy-fabric-item-groups-v1/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/item/group/client/HandledScreenMixin.java @@ -1,11 +1,28 @@ +/* + * Copyright (c) 2020 - 2024 Legacy Fabric + * Copyright (c) 2016 - 2022 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.legacyfabric.fabric.mixin.item.group.client; -import net.legacyfabric.fabric.impl.item.group.ScreenAccessor; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import net.minecraft.client.gui.screen.ingame.HandledScreen; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; +import net.legacyfabric.fabric.impl.item.group.ScreenAccessor; @Mixin(HandledScreen.class) public abstract class HandledScreenMixin implements ScreenAccessor { From 4d4f2ee23935bff8299b87ccb162d7da962a7717 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Thu, 9 May 2024 15:32:50 +0200 Subject: [PATCH 20/24] Remove command-api-v2 port for now to be redone later --- README.md | 2 +- .../1.6.4/build.gradle | 0 .../1.6.4/gradle.properties | 2 - .../api/command/v2/CommandRegistrar.java | 42 - .../fabric/api/command/v2/Selector.java | 109 -- .../fabric/api/command/v2/StringType.java | 36 - .../v2/lib/sponge/CommandCallable.java | 120 --- .../v2/lib/sponge/CommandException.java | 84 -- .../command/v2/lib/sponge/CommandManager.java | 139 --- .../command/v2/lib/sponge/CommandMapping.java | 56 -- .../lib/sponge/CommandMessageFormatting.java | 54 - .../lib/sponge/CommandNotFoundException.java | 61 -- .../sponge/CommandPermissionException.java | 54 - .../command/v2/lib/sponge/CommandResult.java | 271 ----- .../lib/sponge/ImmutableCommandMapping.java | 109 -- .../sponge/InvocationCommandException.java | 38 - .../v2/lib/sponge/TextMessageException.java | 90 -- .../sponge/args/ArgumentParseException.java | 150 --- .../args/ChildCommandElementExecutor.java | 276 ----- .../v2/lib/sponge/args/CommandArgs.java | 339 ------- .../v2/lib/sponge/args/CommandContext.java | 328 ------ .../v2/lib/sponge/args/CommandElement.java | 123 --- .../v2/lib/sponge/args/CommandFlags.java | 543 ---------- .../v2/lib/sponge/args/GenericArguments.java | 949 ------------------ .../v2/lib/sponge/args/KeyElement.java | 40 - .../args/PatternMatchingCommandElement.java | 142 --- .../sponge/args/SelectorCommandElement.java | 65 -- .../sponge/args/parsing/InputTokenizer.java | 73 -- .../args/parsing/QuotedStringTokenizer.java | 164 --- .../args/parsing/RawStringInputTokenizer.java | 33 - .../v2/lib/sponge/args/parsing/SingleArg.java | 100 -- .../parsing/SpaceSplitInputTokenizer.java | 57 -- .../sponge/args/parsing/TokenizerState.java | 66 -- .../lib/sponge/dispatcher/Disambiguator.java | 40 - .../v2/lib/sponge/dispatcher/Dispatcher.java | 115 --- .../sponge/dispatcher/SimpleDispatcher.java | 459 --------- .../v2/lib/sponge/spec/CommandExecutor.java | 41 - .../v2/lib/sponge/spec/CommandSpec.java | 491 --------- .../impl/command/CommandManagerImpl.java | 258 ----- .../fabric/impl/command/CommandWrapper.java | 123 --- .../fabric/impl/command/ImplInit.java | 46 - .../fabric/impl/command/InternalObjects.java | 28 - .../lib/sponge/args/AllOfCommandElement.java | 83 -- .../lib/sponge/args/BigDecimalElement.java | 47 - .../lib/sponge/args/BigIntegerElement.java | 47 - .../sponge/args/ChoicesCommandElement.java | 90 -- .../lib/sponge/args/DateTimeElement.java | 94 -- .../lib/sponge/args/DurationElement.java | 66 -- .../lib/sponge/args/EntityCommandElement.java | 164 --- .../lib/sponge/args/EnumValueElement.java | 60 -- .../args/FilteredSuggestionsElement.java | 53 - .../args/FirstParsingCommandElement.java | 101 -- .../command/lib/sponge/args/IpElement.java | 57 -- .../sponge/args/LiteralCommandElement.java | 85 -- .../sponge/args/MarkTrueCommandElement.java | 50 - .../lib/sponge/args/ModCommandElement.java | 48 - .../lib/sponge/args/NumericElement.java | 63 -- .../sponge/args/OnlyOneCommandElement.java | 65 -- .../sponge/args/OptionalCommandElement.java | 94 -- .../sponge/args/PermissionCommandElement.java | 92 -- .../lib/sponge/args/PlayerCommandElement.java | 92 -- .../RemainingJoinedStringsCommandElement.java | 62 -- .../sponge/args/RepeatedCommandElement.java | 73 -- .../sponge/args/SequenceCommandElement.java | 125 --- .../lib/sponge/args/StringCommandElement.java | 45 - .../lib/sponge/args/StringElement.java | 36 - .../command/lib/sponge/args/UrlElement.java | 58 -- .../command/lib/sponge/args/UuidElement.java | 45 - .../lib/sponge/args/Vec3dCommandElement.java | 133 --- .../sponge/args/WithSuggestionsElement.java | 61 -- .../mixin/command/ChatMessageAccessor.java | 29 - .../mixin/command/MinecraftServerMixin.java | 36 - .../icon.png | Bin 1579 -> 0 bytes .../1.6.4/src/main/resources/fabric.mod.json | 46 - ...y-fabric-sponge-command-api-v2.mixins.json | 12 - .../test/command/ModMetadataCommand.java | 74 -- .../test/command/SpongeCommandTest.java | 31 - .../src/testmod/resources/fabric.mod.json | 14 - 78 files changed, 1 insertion(+), 8646 deletions(-) delete mode 100644 legacy-fabric-command-api-v2/1.6.4/build.gradle delete mode 100644 legacy-fabric-command-api-v2/1.6.4/gradle.properties delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/CommandRegistrar.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/Selector.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/StringType.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandCallable.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandException.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandManager.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMapping.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMessageFormatting.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandNotFoundException.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandPermissionException.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandResult.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/ImmutableCommandMapping.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/InvocationCommandException.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/TextMessageException.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ArgumentParseException.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ChildCommandElementExecutor.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandArgs.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandContext.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandFlags.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/GenericArguments.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/KeyElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/PatternMatchingCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/SelectorCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/InputTokenizer.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/QuotedStringTokenizer.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/RawStringInputTokenizer.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SingleArg.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SpaceSplitInputTokenizer.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/TokenizerState.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Disambiguator.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Dispatcher.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/SimpleDispatcher.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandExecutor.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandSpec.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandManagerImpl.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandWrapper.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/ImplInit.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/InternalObjects.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/AllOfCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigDecimalElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigIntegerElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ChoicesCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DateTimeElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DurationElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EntityCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EnumValueElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FilteredSuggestionsElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FirstParsingCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/IpElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/LiteralCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/MarkTrueCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ModCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/NumericElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OnlyOneCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OptionalCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PermissionCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PlayerCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RemainingJoinedStringsCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RepeatedCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/SequenceCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UrlElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UuidElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/Vec3dCommandElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/WithSuggestionsElement.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/ChatMessageAccessor.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/MinecraftServerMixin.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/resources/assets/legacy-fabric-sponge-command-api-v2/icon.png delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/resources/fabric.mod.json delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/main/resources/legacy-fabric-sponge-command-api-v2.mixins.json delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommand.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/SpongeCommandTest.java delete mode 100644 legacy-fabric-command-api-v2/1.6.4/src/testmod/resources/fabric.mod.json diff --git a/README.md b/README.md index c55e2f88a..e7a2f5fc2 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ For support, consider joining the [Legacy Fabric discord server](https://legacyf |----------------------|-------------------------------|--------|-----|-------|-------|--------|--------|--------|--------| | api-base | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | command-api-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | -| command-api-v2 | ⚠ Text formatting need rework | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| command-api-v2 | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | crash-report-info-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | entity-events-v1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | gamerule-api-v1 | ? | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ? | diff --git a/legacy-fabric-command-api-v2/1.6.4/build.gradle b/legacy-fabric-command-api-v2/1.6.4/build.gradle deleted file mode 100644 index e69de29bb..000000000 diff --git a/legacy-fabric-command-api-v2/1.6.4/gradle.properties b/legacy-fabric-command-api-v2/1.6.4/gradle.properties deleted file mode 100644 index 72b74abca..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/gradle.properties +++ /dev/null @@ -1,2 +0,0 @@ -minVersionIncluded=1.3 -maxVersionIncluded=1.6.4 diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/CommandRegistrar.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/CommandRegistrar.java deleted file mode 100644 index c81a2e7d7..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/CommandRegistrar.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandManager; -import net.legacyfabric.fabric.api.event.Event; -import net.legacyfabric.fabric.api.event.EventFactory; - -/** - * An entrypoint and event for registering commands to the {@link CommandManager}. - */ -@FunctionalInterface -public interface CommandRegistrar { - Event EVENT = EventFactory.createArrayBacked(CommandRegistrar.class, listeners -> (manager, dedicated) -> { - for (CommandRegistrar registrar : listeners) { - registrar.register(manager, dedicated); - } - }); - - /** - * Register your commands here. - * - * @param manager The command manager - * @param dedicated Whether the mod is running on a dedicated server - */ - void register(CommandManager manager, boolean dedicated); -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/Selector.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/Selector.java deleted file mode 100644 index d17d16814..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/Selector.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Sets; - -import net.minecraft.command.CommandSource; -import net.minecraft.entity.Entity; -import net.minecraft.server.MinecraftServer; - -public enum Selector { - ALL_ENTITIES('e') { - @Override - public Set resolve(CommandSource sender) { - return Sets.newHashSet(sender.getWorld().entities); - } - }, - ALL_PLAYERS('a') { - @Override - public Set resolve(CommandSource sender) { - return (Set) sender.getWorld().playerEntities.stream().map(e -> (Entity) e).collect(Collectors.toSet()); - } - }, - NEAREST_PLAYER('p') { - @Override - public Set resolve(CommandSource sender) { - return Sets.newHashSet(sender.getWorld().getClosestPlayer(sender.method_4086().x, sender.method_4086().y, sender.method_4086().z, 50.0D)); - } - }, - RANDOM_PLAYER('r') { - @Override - public Set resolve(CommandSource sender) { - try { - return Sets.newHashSet((Entity) MinecraftServer.getServer().getPlayerManager().players.stream().findAny().orElseThrow(NullPointerException::new)); - } catch (Throwable e) { - throw new RuntimeException(e); - } - } - }, - EXECUTING_ENTITY('s') { - @Override - public Set resolve(CommandSource sender) { - //TODO @s didn't exist this early in the game's development, and there seems to be no code to handle it, so maybe this'll work? - return Sets.newHashSet(sender.getWorld().getPlayerByName(sender.getUsername())); - } - }; - - private final char key; - private static final Map MAP; - - Selector(char key) { - this.key = key; - } - - public char getKey() { - return this.key; - } - - public abstract Set resolve(CommandSource sender); - - public static List complete(String s) { - if (s.startsWith("@") && s.length() == 2) { - return Arrays.stream(values()).map(Selector::getKey).map(String::valueOf).distinct().collect(Collectors.toList()); - } - - return ImmutableList.of(); - } - - public static Selector parse(String value) { - if (MAP.containsKey(value)) { - return MAP.get(value); - } - - throw new IllegalArgumentException("Unknown selector"); - } - - static { - ImmutableMap.Builder builder = ImmutableMap.builder(); - - for (Selector s : values()) { - builder.put("@" + s.getKey(), s); - } - - MAP = builder.build(); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/StringType.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/StringType.java deleted file mode 100644 index f294fb603..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/StringType.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2; - -/** - * Specifies a method to parse {@link String}s in a command. - */ -public enum StringType { - SINGLE_WORD(false), - GREEDY_PHRASE(true); - - private final boolean all; - - StringType(boolean all) { - this.all = all; - } - - public boolean isAll() { - return this.all; - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandCallable.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandCallable.java deleted file mode 100644 index fbcffdb4a..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandCallable.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge; - -import java.util.List; -import java.util.Optional; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; -import net.minecraft.world.World; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.spec.CommandSpec; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; -import net.legacyfabric.fabric.api.util.Location; - -/** - * A low-level interface for commands that can be executed. For almost all use - * cases, higher-level tools should be used instead, like {@link CommandSpec}. - * - *

Implementations are not required to implement a sane - * {@link Object#equals(Object)} but really should.

- */ -public interface CommandCallable { - /** - * Execute the command based on input arguments. - * - *

The implementing class must perform the necessary permission - * checks.

- * - * @param source The caller of the command - * @param arguments The raw arguments for this command - * @return The result of a command being processed - * @throws CommandException Thrown on a command error - */ - CommandResult process(PermissibleCommandSource source, String arguments) throws CommandException; - - /** - * Gets a list of suggestions based on input. - * - *

If a suggestion is chosen by the user, it will replace the last - * word.

- * - * @param source The command source - * @param arguments The arguments entered up to this point - * @param targetPosition The position the source is looking at when - * performing tab completion - * @return A list of suggestions - * @throws CommandException Thrown if there was a parsing error - */ - List getSuggestions(PermissibleCommandSource source, String arguments, @Nullable Location targetPosition) throws CommandException; - - /** - * Test whether this command can probably be executed by the given source. - * - *

If implementations are unsure if the command can be executed by - * the source, {@code true} should be returned. Return values of this method - * may be used to determine whether this command is listed in command - * listings.

- * - * @param source The caller of the command - * @return Whether permission is (probably) granted - */ - boolean testPermission(PermissibleCommandSource source); - - /** - * Gets a short one-line description of this command. - * - *

The help system may display the description in the command list.

- * - * @param source The source of the help request - * @return A description - */ - Optional getShortDescription(PermissibleCommandSource source); - - /** - * Gets a longer formatted help message about this command. - * - *

It is recommended to use the default text color and style. Sections - * with text actions (e.g. hyperlinks) should be underlined.

- * - *

Multi-line messages can be created by separating the lines with - * {@code \n}.

- * - *

The help system may display this message when a source requests - * detailed information about a command.

- * - * @param source The source of the help request - * @return A help text - */ - Optional getHelp(PermissibleCommandSource source); - - /** - * Gets the usage string of this command. - * - *

A usage string may look like - * {@code [-w <world>] <var1> <var2>}.

- * - *

The string must not contain the command alias.

- * - * @param source The source of the help request - * @return A usage string - */ - ChatMessage getUsage(PermissibleCommandSource source); -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandException.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandException.java deleted file mode 100644 index 44190ca1f..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandException.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge; - -import net.minecraft.text.ChatMessage; - -/** - * Thrown when an executed command raises an error or when execution of - * the command failed. - */ -public class CommandException extends TextMessageException { - private static final long serialVersionUID = 4626722485860074825L; - - private final boolean includeUsage; - - /** - * Constructs a new {@link CommandException} with the given message. - * - * @param message The detail message - */ - public CommandException(ChatMessage message) { - this(message, false); - } - - /** - * Constructs a new {@link CommandException} with the given message and - * the given cause. - * - * @param message The detail message - * @param cause The cause - */ - public CommandException(ChatMessage message, Throwable cause) { - this(message, cause, false); - } - - /** - * Constructs a new {@link CommandException} with the given message. - * - * @param message The detail message - * @param includeUsage Whether to include usage in the exception - */ - public CommandException(ChatMessage message, boolean includeUsage) { - super(message); - this.includeUsage = includeUsage; - } - - /** - * Constructs a new {@link CommandException} with the given message and - * the given cause. - * - * @param message The detail message - * @param cause The cause - * @param includeUsage Whether to include the usage in the exception - */ - public CommandException(ChatMessage message, Throwable cause, boolean includeUsage) { - super(message, cause); - this.includeUsage = includeUsage; - } - - /** - * Gets whether the exception should include usage in - * the presentation of the exception/stack-trace. - * - * @return Whether to include usage in the exception - */ - public boolean shouldIncludeUsage() { - return this.includeUsage; - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandManager.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandManager.java deleted file mode 100644 index 8004c9a72..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandManager.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge; - -import java.util.List; -import java.util.Optional; -import java.util.function.Function; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.world.World; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher.Dispatcher; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; -import net.legacyfabric.fabric.api.util.Location; - -/** - * A command dispatcher watches for commands (such as those said in chat) - * and dispatches them to the correct command handler. - */ -public interface CommandManager extends Dispatcher { - /** - * Register a given command using the given list of aliases. - * - *

If there is a conflict with one of the aliases (i.e. that alias - * is already assigned to another command), then the alias will be skipped. - * It is possible for there to be no alias to be available out of - * the provided list of aliases, which would mean that the command would not - * be assigned to any aliases.

- * - *

The first non-conflicted alias becomes the "primary alias."

- * - * @param callable The command - * @param alias An array of aliases - * @return The registered command mapping, unless no aliases could be - * registered - */ - Optional register(CommandCallable callable, String... alias); - - /** - * Register a given command using the given list of aliases. - * - *

If there is a conflict with one of the aliases (i.e. that alias - * is already assigned to another command), then the alias will be skipped. - * It is possible for there to be no alias to be available out of - * the provided list of aliases, which would mean that the command would - * not be assigned to any aliases.

- * - *

The first non-conflicted alias becomes the "primary alias."

- * - * @param callable The command - * @param aliases A list of aliases - * @return The registered command mapping, unless no aliases could be - * registered - * @throws IllegalArgumentException Thrown if {@code plugin} is not a - * plugin instance - */ - Optional register(CommandCallable callable, List aliases); - - /** - * Register a given command using a given list of aliases. - * - *

The provided callback function will be called with a list of aliases - * that are not taken (from the list of aliases that were requested) and - * it should return a list of aliases to actually register. Aliases may be - * removed, and if no aliases remain, then the command will not be - * registered. It may be possible that no aliases are available, and thus - * the callback would receive an empty list. New aliases should not be added - * to the list in the callback as this may cause - * {@link IllegalArgumentException} to be thrown.

- * - *

The first non-conflicted alias becomes the "primary alias."

- * - * @param callable The command - * @param aliases A list of aliases - * @param callback The callback - * @return The registered command mapping, unless no aliases could be - * registered - * @throws IllegalArgumentException Thrown if new conflicting aliases are - * added in the callback - */ - Optional register(CommandCallable callable, List aliases, Function, List> callback); - - /** - * Remove a command identified by the given mapping. - * - * @param mapping The mapping - * @return The previous mapping associated with the alias, if one was found - */ - Optional removeMapping(CommandMapping mapping); - - /** - * Gets the number of registered aliases. - * - * @return The number of aliases - */ - int size(); - - /** - * Execute the command based on input arguments. - * - *

The implementing class must perform the necessary permission - * checks.

- * - * @param source The caller of the command - * @param arguments The raw arguments for this command - * @return The result of a command being processed - */ - @Override - CommandResult process(PermissibleCommandSource source, String arguments); - - /** - * Gets a list of suggestions based on input. - * - *

If a suggestion is chosen by the user, it will replace the last - * word.

- * - * @param source The command source - * @param arguments The arguments entered up to this point - * @return A list of suggestions - */ - @Override - List getSuggestions(PermissibleCommandSource source, String arguments, @Nullable Location targetPosition); -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMapping.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMapping.java deleted file mode 100644 index 500a26515..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMapping.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge; - -import java.util.Set; - -/** - * Provides information about a mapping between a command and its aliases. - * - *

Implementations are not required to implement a sane - * {@link Object#equals(Object)} but may choose to do so.

- */ -public interface CommandMapping { - /** - * Gets the primary alias. - * - * @return The primary alias - */ - String getPrimaryAlias(); - - /** - * Gets an immutable list of all aliases. - * - *

The returned list must contain at least one entry, of which one must - * be the one returned by {@link #getPrimaryAlias()}.

- * - *

There may be several versions of the same alias with different - * casing, although generally implementations should ignore the casing - * of aliases.

- * - * @return A set of aliases - */ - Set getAllAliases(); - - /** - * Gets the callable. - * - * @return The callable - */ - CommandCallable getCallable(); -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMessageFormatting.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMessageFormatting.java deleted file mode 100644 index e172fe9a7..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandMessageFormatting.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge; - -import net.minecraft.text.ChatMessage; -import net.minecraft.util.Formatting; - -public class CommandMessageFormatting { - private CommandMessageFormatting() { - } - - public static final ChatMessage PIPE_TEXT = ChatMessage.createTextMessage("|"); - public static final ChatMessage SPACE_TEXT = ChatMessage.createTextMessage(" "); - public static final ChatMessage STAR_TEXT = ChatMessage.createTextMessage("*"); - public static final ChatMessage LT_TEXT = ChatMessage.createTextMessage("<"); - public static final ChatMessage GT_TEXT = ChatMessage.createTextMessage(">"); - public static final ChatMessage ELLIPSIS_TEXT = ChatMessage.createTextMessage("…"); - - /** - * Format text to be output as an error directly to a sender. Not necessary - * when creating an exception to be thrown - * - * @param error The error message - * @return The formatted error message. - */ - public static ChatMessage error(ChatMessage error) { - return error.setColor(Formatting.RED); - } - - /** - * Format text to be output as a debug message directly to a sender. - * - * @param debug The debug message - * @return The formatted debug message. - */ - public static ChatMessage debug(ChatMessage debug) { - return debug.setColor(Formatting.GRAY); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandNotFoundException.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandNotFoundException.java deleted file mode 100644 index fdf65e9b7..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandNotFoundException.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge; - -import com.google.common.base.Preconditions; - -import net.minecraft.text.ChatMessage; - -/** - * This exception is thrown when a sender tries to execute a command that does - * not exist. - */ -public class CommandNotFoundException extends CommandException { - private static final long serialVersionUID = -7714518367616848051L; - - private final String command; - - /** - * Create an exception with the default message. - * - * @param command The command that was queried for - */ - public CommandNotFoundException(String command) { - this(ChatMessage.createTextMessage("No such command"), command); - } - - /** - * Create an exception with a custom message. - * - * @param message The message - * @param command The command that was queried for - */ - public CommandNotFoundException(ChatMessage message, String command) { - super(message); - this.command = Preconditions.checkNotNull(command, "command"); - } - - /** - * Returns the command that was queried for. - * - * @return The command - */ - public String getCommand() { - return this.command; - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandPermissionException.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandPermissionException.java deleted file mode 100644 index 7b6ea274b..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandPermissionException.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge; - -import net.minecraft.text.ChatMessage; - -/** - * This exception is thrown when a subject does not have permission to execute - * a command. - */ -public class CommandPermissionException extends CommandException { - private static final long serialVersionUID = -6057386975881181213L; - - /** - * Create an exception with the default message. - */ - public CommandPermissionException() { - this(ChatMessage.createTextMessage("You do not have permission to use this command!")); - } - - /** - * Create a permissions exception with a custom message. - * - * @param message The message - */ - public CommandPermissionException(ChatMessage message) { - super(message); - } - - /** - * Create a permissions exception with a custom message and cause. - * - * @param message the message - * @param cause the cause - */ - public CommandPermissionException(ChatMessage message, Throwable cause) { - super(message, cause); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandResult.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandResult.java deleted file mode 100644 index 3637eb2c9..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/CommandResult.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge; - -import java.util.Optional; - -import org.jetbrains.annotations.Nullable; - -/** - * Represents the result of a command in Sponge. - */ -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") -public class CommandResult { - private static final CommandResult EMPTY = builder().build(); - private static final CommandResult SUCCESS = builder().successCount(1).build(); - private final Optional successCount; - private final Optional affectedBlocks; - private final Optional affectedEntities; - private final Optional affectedItems; - private final Optional queryResult; - - /** - * Returns a {@link Builder}. - * - * @return A new command result builder - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Returns a new {@link CommandResult} indicating that a command was - * processed. - * - * @return The command result - */ - public static CommandResult empty() { - return EMPTY; - } - - /** - * Returns a result indicating the command was processed with a single - * success. - * - * @return The result - */ - public static CommandResult success() { - return SUCCESS; - } - - /** - * Returns a result indicating the command was processed with a single - * success. - * - * @param count The success count - * @return The result - */ - public static CommandResult successCount(int count) { - return builder().successCount(count).build(); - } - - /** - * Returns a result indicating the command was processed with an - * amount of affected blocks. - * - * @param count The amount of blocks affected - * @return The result - */ - public static CommandResult affectedBlocks(int count) { - return builder().affectedBlocks(count).build(); - } - - /** - * Returns a result indicating the command was processed with an - * amount of affected entities. - * - * @param count The amount of entities affected - * @return The result - */ - public static CommandResult affectedEntities(int count) { - return builder().affectedEntities(count).build(); - } - - /** - * Returns a result indicating the command was processed with an - * amount of affected items. - * - * @param count The amount of items affected - * @return The result - */ - public static CommandResult affectedItems(int count) { - return builder().affectedItems(count).build(); - } - - /** - * Returns a result indicating the command was processed with an - * amount of queries. - * - * @param count The amount of queries - * @return The result - */ - public static CommandResult queryResult(int count) { - return builder().queryResult(count).build(); - } - - /** - * Constructs a new command result. - * - * @param successCount The success count - * @param affectedBlocks The number of affected blocks - * @param affectedEntities The number of affected entities - * @param affectedItems The number of affected items - * @param queryResult The query result - */ - CommandResult(@Nullable Integer successCount, @Nullable Integer affectedBlocks, @Nullable Integer affectedEntities, @Nullable Integer affectedItems, @Nullable Integer queryResult) { - this.successCount = Optional.ofNullable(successCount); - this.affectedBlocks = Optional.ofNullable(affectedBlocks); - this.affectedEntities = Optional.ofNullable(affectedEntities); - this.affectedItems = Optional.ofNullable(affectedItems); - this.queryResult = Optional.ofNullable(queryResult); - } - - /** - * Gets the success count of the command. - * - * @return The success count of the command - */ - public Optional getSuccessCount() { - return this.successCount; - } - - /** - * Gets the number of blocks affected by the command. - * - * @return The number of blocks affected by the command, if such a count - * exists - */ - public Optional getAffectedBlocks() { - return this.affectedBlocks; - } - - /** - * Gets the number of entities affected by the command. - * - * @return The number of entities affected by the command, if such a count - * exists - */ - public Optional getAffectedEntities() { - return this.affectedEntities; - } - - /** - * Gets the number of items affected by the command. - * - * @return The number of items affected by the command, if such a count - * exists - */ - public Optional getAffectedItems() { - return this.affectedItems; - } - - /** - * Gets the query result of the command, e.g. the time of the day, - * an amount of money or a player's amount of XP. - * - * @return The query result of the command, if one exists - */ - public Optional getQueryResult() { - return this.queryResult; - } - - /** - * A builder for {@link CommandResult}s. - */ - public static class Builder { - @Nullable - private Integer successCount; - @Nullable - private Integer affectedBlocks; - @Nullable - private Integer affectedEntities; - @Nullable - private Integer affectedItems; - @Nullable - private Integer queryResult; - - Builder() { - } - - /** - * Sets if the command has been processed. - * - * @param successCount If the command has been processed - * @return This builder, for chaining - */ - public Builder successCount(@Nullable Integer successCount) { - this.successCount = successCount; - return this; - } - - /** - * Sets the amount of blocks affected by the command. - * - * @param affectedBlocks The amount of blocks affected by the command - * @return This builder, for chaining - */ - public Builder affectedBlocks(@Nullable Integer affectedBlocks) { - this.affectedBlocks = affectedBlocks; - return this; - } - - /** - * Sets the amount of entities affected by the command. - * - * @param affectedEntities The amount of entities affected by the - * command - * @return This builder, for chaining - */ - public Builder affectedEntities(@Nullable Integer affectedEntities) { - this.affectedEntities = affectedEntities; - return this; - } - - /** - * Sets the amount of items affected by the command. - * - * @param affectedItems The amount of items affected by the command - * @return This builder, for chaining - */ - public Builder affectedItems(@Nullable Integer affectedItems) { - this.affectedItems = affectedItems; - return this; - } - - /** - * Sets the query result of the command, e.g. the time of the day, - * an amount of money or a player's amount of XP. - * - * @param queryResult The query result of the command - * @return This builder, for chaining - */ - public Builder queryResult(@Nullable Integer queryResult) { - this.queryResult = queryResult; - return this; - } - - /** - * Builds the {@link CommandResult}. - * - * @return A CommandResult with the specified settings - */ - public CommandResult build() { - return new CommandResult(this.successCount, this.affectedBlocks, this.affectedEntities, this.affectedItems, this.queryResult); - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/ImmutableCommandMapping.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/ImmutableCommandMapping.java deleted file mode 100644 index a02b51051..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/ImmutableCommandMapping.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge; - -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableSet; - -/** - * An immutable command mapping instance that returns the same objects that - * this instance is constructed with. - */ -public final class ImmutableCommandMapping implements CommandMapping { - private final String primary; - private final Set aliases; - private final CommandCallable callable; - - /** - * Create a new instance. - * - * @param callable The command callable - * @param primary The primary alias - * @param alias A list of all aliases - * @throws IllegalArgumentException Thrown if aliases are duplicated - */ - public ImmutableCommandMapping(CommandCallable callable, String primary, String... alias) { - this(callable, primary, Arrays.asList(Preconditions.checkNotNull(alias, "alias"))); - } - - /** - * Create a new instance. - * - * @param callable The command callable - * @param primary The primary alias - * @param aliases A collection of all aliases - * @throws IllegalArgumentException Thrown if aliases are duplicated - */ - public ImmutableCommandMapping(CommandCallable callable, String primary, Collection aliases) { - Preconditions.checkNotNull(primary, "primary"); - Preconditions.checkNotNull(aliases, "aliases"); - this.primary = primary; - this.aliases = new HashSet<>(aliases); - this.aliases.add(primary); - this.callable = Preconditions.checkNotNull(callable, "callable"); - } - - @Override - public String getPrimaryAlias() { - return this.primary; - } - - @Override - public Set getAllAliases() { - return ImmutableSet.copyOf(this.aliases); - } - - @Override - public CommandCallable getCallable() { - return this.callable; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o == null || this.getClass() != o.getClass()) { - return false; - } - - ImmutableCommandMapping that = (ImmutableCommandMapping) o; - return this.primary.equals(that.primary) && this.aliases.equals(that.aliases) && this.callable.equals(that.callable); - } - - @Override - public int hashCode() { - return Objects.hash(this.primary, this.aliases, this.callable); - } - - @Override - public String toString() { - return "ImmutableCommandMapping{" - + "primary='" + this.primary + '\'' - + ", aliases=" + this.aliases - + ", spec=" + this.callable - + '}'; - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/InvocationCommandException.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/InvocationCommandException.java deleted file mode 100644 index 91ce6bf70..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/InvocationCommandException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge; - -import net.minecraft.text.ChatMessage; - -/** - * Thrown when invocation of a command fails, wrapping the exception that - * is thrown. - */ -public class InvocationCommandException extends CommandException { - private static final long serialVersionUID = 2123904283741023948L; - - /** - * Constructs a new exception with the given message and the given cause. - * - * @param message The detail message - * @param cause The cause - */ - public InvocationCommandException(ChatMessage message, Throwable cause) { - super(message, cause); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/TextMessageException.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/TextMessageException.java deleted file mode 100644 index 9005c0cab..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/TextMessageException.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge; - -import net.minecraft.text.ChatMessage; - -/** - * A subclass of Exception that contains a rich message that is an instance of - * {@link Text} rather than a String. This allows formatted and localized - * exception messages. - */ -public class TextMessageException extends Exception { - private static final long serialVersionUID = -5281221645176698853L; - - private final ChatMessage message; - - /** - * Constructs a new {@link TextMessageException}. - */ - public TextMessageException() { - this.message = null; - } - - /** - * Constructs a new {@link TextMessageException} with the given message. - * - * @param message The detail message - */ - public TextMessageException(ChatMessage message) { - this.message = message; - } - - /** - * Constructs a new {@link TextMessageException} with the given message and - * cause. - * - * @param message The detail message - * @param throwable The cause - */ - public TextMessageException(ChatMessage message, Throwable throwable) { - super(throwable); - this.message = message; - } - - /** - * Constructs a new {@link TextMessageException} with the given cause. - * - * @param throwable The cause - */ - public TextMessageException(Throwable throwable) { - super(throwable); - this.message = null; - } - - @Override - public String getMessage() { - ChatMessage message = this.getText(); - return message == null ? null : message.toString(); - } - - /** - * Returns the text message for this exception, or null if nothing is - * present. - * - * @return The text for this message - */ - public ChatMessage getText() { - return this.message; - } - - @Override - public String getLocalizedMessage() { - return this.getMessage(); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ArgumentParseException.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ArgumentParseException.java deleted file mode 100644 index 4ce87f733..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ArgumentParseException.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; - -import com.google.common.base.Strings; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; - -/** - * Exception thrown when an error occurs while parsing arguments. - */ -public class ArgumentParseException extends CommandException { - private static final long serialVersionUID = -8555316116315990226L; - - private final String source; - private final int position; - - /** - * Return a new {@link ArgumentParseException} with the given message, source and position. - * - * @param message The message to use for this exception - * @param source The source string being parsed - * @param position The current position in the source string - */ - public ArgumentParseException(ChatMessage message, String source, int position) { - super(message, true); - this.source = source; - this.position = position; - } - - /** - * Return a new {@link ArgumentParseException} with the given message, cause, source and position. - * - * @param message The message to use for this exception - * @param cause The cause for this exception - * @param source The source string being parsed - * @param position The current position in the source string - */ - public ArgumentParseException(ChatMessage message, Throwable cause, String source, int position) { - super(message, cause, true); - this.source = source; - this.position = position; - } - - @Override - public ChatMessage getText() { - ChatMessage superText = super.getText(); - - if (this.source == null || this.source.isEmpty()) { - return super.getText(); - } else if (superText == null) { - return ChatMessage.createTextMessage(this.getAnnotatedPosition()); - } else { - return ChatMessage.createTextMessage(superText.toString() + "\n" + this.getAnnotatedPosition()); - } - } - - private ChatMessage getSuperText() { - return super.getText(); - } - - /** - * Return a string pointing to the position of the arguments when this - * exception occurs. - * - * @return The appropriate position string - */ - public String getAnnotatedPosition() { - String source = this.source; - int position = this.position; - - if (source.length() > 80) { - if (position >= 37) { - int startPos = position - 37; - int endPos = Math.min(source.length(), position + 37); - - if (endPos < source.length()) { - source = "..." + source.substring(startPos, endPos) + "..."; - } else { - source = "..." + source.substring(startPos, endPos); - } - - position -= 40; - } else { - source = source.substring(0, 77) + "..."; - } - } - - return source + "\n" + Strings.repeat(" ", position) + "^"; - } - - /** - * Gets the position of the last fetched argument in the provided source - * string. - * - * @return The source string to get position for - */ - public int getPosition() { - return this.position; - } - - /** - * Returns the source string arguments are being parsed from. - * - * @return The source string - */ - public String getSourceString() { - return this.source; - } - - /** - * An {@link ArgumentParseException} where the usage is already specified. - */ - public static class WithUsage extends ArgumentParseException { - private static final long serialVersionUID = -786214501012293475L; - - private final ChatMessage usage; - - public WithUsage(ArgumentParseException wrapped, ChatMessage usage) { - super(wrapped.getSuperText(), wrapped.getCause(), wrapped.getSourceString(), wrapped.getPosition()); - this.usage = usage; - } - - /** - * Gets the usage associated with this exception. - * - * @return The usage - */ - public ChatMessage getUsage() { - return this.usage; - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ChildCommandElementExecutor.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ChildCommandElementExecutor.java deleted file mode 100644 index 10e4f57aa..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/ChildCommandElementExecutor.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; - -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; -import java.util.stream.Collectors; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.common.collect.Multimaps; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; -import net.minecraft.world.World; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandCallable; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMapping; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandResult; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher.SimpleDispatcher; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.spec.CommandExecutor; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.spec.CommandSpec; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; -import net.legacyfabric.fabric.api.util.Location; - -public class ChildCommandElementExecutor extends CommandElement implements CommandExecutor { - private static final AtomicInteger COUNTER = new AtomicInteger(); - private static final CommandElement NONE = GenericArguments.none(); - - @Nullable - private final CommandExecutor fallbackExecutor; - @Nullable - private final CommandElement fallbackElements; - private final SimpleDispatcher dispatcher = new SimpleDispatcher(SimpleDispatcher.FIRST_DISAMBIGUATOR); - private final boolean fallbackOnFail; - - /** - * Create a new combined argument element and executor to handle the - * parsing and execution of child commands. - * - * @param fallbackExecutor The executor to execute if the child command - * has been marked optional (Generally when this is wrapped in a - * {@link GenericArguments#optional(CommandElement)} - * @param fallbackElements The alternate {@link CommandElement}s that should - * be parsed if a child element fails to be parsed - * @param fallbackOnFail If true, then if a child command cannot parse the - * elements, the exception is discarded and the parent command attempts - * to parse the elements. If false, a child command will not pass - * control back to the parent, displaying its own exception message - */ - public ChildCommandElementExecutor(@Nullable CommandExecutor fallbackExecutor, @Nullable CommandElement fallbackElements, boolean fallbackOnFail) { - super(ChatMessage.createTextMessage("child" + COUNTER.getAndIncrement())); - this.fallbackExecutor = fallbackExecutor; - this.fallbackElements = NONE == fallbackElements ? null : fallbackElements; - this.fallbackOnFail = fallbackOnFail; - } - - /** - * Register a child command for a given set of aliases. - * - * @param callable The command to register - * @param aliases The aliases to register it as - * @return The child command's mapping, if present - */ - public Optional register(CommandCallable callable, List aliases) { - return this.dispatcher.register(callable, aliases); - } - - /** - * Register a child command for a given set of aliases. - * - * @param callable The command to register - * @param aliases The aliases to register it as - * @return The child command's mapping, if present - */ - public Optional register(CommandCallable callable, String... aliases) { - return this.dispatcher.register(callable, aliases); - } - - @Override - public List complete(final PermissibleCommandSource src, CommandArgs args, CommandContext context) { - List completions = Lists.newArrayList(); - - if (this.fallbackElements != null) { - CommandArgs.Snapshot state = args.getSnapshot(); - completions.addAll(this.fallbackElements.complete(src, args, context)); - args.applySnapshot(state); - } - - final Optional commandComponent = args.nextIfPresent(); - - if (!commandComponent.isPresent()) { - return ImmutableList.copyOf(this.filterCommands(src)); - } - - if (args.hasNext()) { - Optional child = this.dispatcher.get(commandComponent.get(), src); - - if (!child.isPresent()) { - return ImmutableList.of(); - } - - if (child.get().getCallable() instanceof CommandSpec) { - return ((CommandSpec) child.get().getCallable()).complete(src, args, context); - } - - args.nextIfPresent(); - final String arguments = args.getRaw().substring(args.getRawPosition()); - - while (args.hasNext()) { - args.nextIfPresent(); - } - - try { - return child.get() - .getCallable() - .getSuggestions(src, arguments, context.>getOne(CommandContext.TARGET_BLOCK_ARG).orElse(null)); - } catch (CommandException e) { - ChatMessage eText = e.getText(); - - if (eText != null) { - src.method_5505(CommandMessageFormatting.error(eText)); - } - - return ImmutableList.of(); - } - } - - completions.addAll(this.filterCommands(src).stream() - .filter(((input) -> { - String test = commandComponent.get(); - return input.toLowerCase().startsWith(test.toLowerCase()); - })) - .collect(Collectors.toList())); - return completions; - } - - private Set filterCommands(final PermissibleCommandSource src) { - return Multimaps.filterValues( - this.dispatcher.getAll(), - (input) -> - input != null && input.getCallable().testPermission(src) - ).keys().elementSet(); - } - - @Override - public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { - if (this.fallbackExecutor != null && !args.hasNext()) { - if (this.fallbackElements != null) { - // there might be optionals to take account of that would parse this successfully. - this.fallbackElements.parse(source, args, context); - } - - return; // execute the fallback regardless in this scenario. - } - - CommandArgs.Snapshot state = args.getSnapshot(); - final String key = args.next(); - Optional optionalCommandMapping = this.dispatcher.get(key, source).map(Function.identity()); - - if (optionalCommandMapping.isPresent()) { - final CommandMapping mapping = optionalCommandMapping.get(); - - try { - if ((mapping.getCallable() instanceof CommandSpec)) { - CommandSpec spec = ((CommandSpec) mapping.getCallable()); - spec.populateContext(source, args, context); - } else { - if (args.hasNext()) { - args.next(); - context.putArg(this.getUntranslatedKey() + "_args", args.getRaw().substring(args.getRawPosition())); - } - - while (args.hasNext()) { - args.next(); - } - } - - // Success, add to context now so that we don't execute the wrong executor in the first place. - context.putArg(this.getUntranslatedKey(), mapping); - } catch (ArgumentParseException ex) { - // If we get here, fallback to the elements, if they exist. - args.applySnapshot(state); - - if (this.fallbackOnFail && this.fallbackElements != null) { - this.fallbackElements.parse(source, args, context); - return; - } - - // Get the usage - args.next(); - - if (ex instanceof ArgumentParseException.WithUsage) { - // This indicates a previous child failed, so we just prepend our child - throw new ArgumentParseException.WithUsage(ex, ChatMessage.createTextMessage(key + " " + ((ArgumentParseException.WithUsage) ex).getUsage())); - } - - throw new ArgumentParseException.WithUsage(ex, ChatMessage.createTextMessage(key + " " + mapping.getCallable().getUsage(source))); - } - } else { - // Not a child, so let's continue with the fallback. - if (this.fallbackExecutor != null && this.fallbackElements != null) { - args.applySnapshot(state); - this.fallbackElements.parse(source, args, context); - } else { - // If we have no elements to parse, then we throw this error - this is the only element - // so specifying it implicitly means we have a child command to execute. - throw args.createError(ChatMessage.createTextMessage(String.format("Input command %s was not a valid subcommand!", key))); - } - } - } - - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - return null; - } - - @Override - public CommandResult execute(PermissibleCommandSource src, CommandContext args) throws CommandException { - CommandMapping mapping = args.getOne(this.getUntranslatedKey()).orElse(null); - - if (mapping == null) { - if (this.fallbackExecutor == null) { - throw new CommandException(ChatMessage.createTextMessage(String.format("Invalid subcommand state -- no more than one mapping may be provided for child arg %s", this.getKey()))); - } - - return this.fallbackExecutor.execute(src, args); - } - - if (mapping.getCallable() instanceof CommandSpec) { - CommandSpec spec = ((CommandSpec) mapping.getCallable()); - spec.checkPermission(src); - return spec.getExecutor().execute(src, args); - } - - final String arguments = args.getOne(this.getUntranslatedKey() + "_args").orElse(""); - return mapping.getCallable().process(src, arguments); - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource src) { - ChatMessage usage = this.dispatcher.getUsage(src); - - if (this.fallbackElements == null) { - return usage; - } - - ChatMessage elementUsage = this.fallbackElements.getUsage(src); - - if (elementUsage.toString().isEmpty()) { - return usage; - } - - return ChatMessage.createTextMessage("").addUsing(usage).addUsing(CommandMessageFormatting.PIPE_TEXT).addUsing(elementUsage); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandArgs.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandArgs.java deleted file mode 100644 index 4179f942c..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandArgs.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing.SingleArg; - -/** - * Holder for command arguments. - */ -public final class CommandArgs { - private final String rawInput; - private final List args; - private int index = -1; - - /** - * Create a new CommandArgs instance with the given raw input and arguments. - * - * @param rawInput Raw input - * @param args Arguments extracted from the raw input - */ - public CommandArgs(String rawInput, List args) { - this.rawInput = rawInput; - this.args = new ArrayList<>(args); - } - - /** - * Return whether more arguments remain to be read. - * - * @return Whether more arguments remain - */ - public boolean hasNext() { - return this.index + 1 < this.args.size(); - } - - /** - * Returns true if: - * - *
    - *
  • The next element returned by {@link #next()} is the last
  • - *
  • {@link #hasNext()} is false
  • - *
- * Else returns false. - * - * @return True if a completion can occur - */ - public boolean canComplete() { - return this.index + 2 >= this.args.size(); - } - - /** - * Try to read the next argument without advancing the current index. - * - * @return The next argument - * @throws ArgumentParseException if not enough arguments are present - */ - public String peek() throws ArgumentParseException { - if (!this.hasNext()) { - throw this.createError(ChatMessage.createTextMessage("Not enough arguments")); - } - - return this.args.get(this.index + 1).getValue(); - } - - /** - * Try to read the next argument, advancing the current index if successful. - * - * @return The next argument - * @throws ArgumentParseException if not enough arguments are present - */ - public String next() throws ArgumentParseException { - if (!this.hasNext()) { - throw this.createError(ChatMessage.createTextMessage("Not enough arguments!")); - } - - return this.args.get(++this.index).getValue(); - } - - /** - * Try to read the next argument, advancing the current index if successful - * or returning an absent optional if not. - * - * @return The optional next argument. - */ - public Optional nextIfPresent() { - return this.hasNext() ? Optional.of(this.args.get(++this.index).getValue()) : Optional.empty(); - } - - /** - * Create a parse exception with the provided message which has the position - * of the last parsed argument attached. The returned exception must be - * thrown at the target - * - * @param message The message for the exception - * @return the newly created, but unthrown exception - */ - public ArgumentParseException createError(ChatMessage message) { - return new ArgumentParseException(message, this.rawInput, this.index < 0 ? 0 : this.args.get(this.index).getStartIdx()); - } - - /** - * Gets a list of all arguments as a string. The returned list is immutable. - * - * @return all arguments - */ - public List getAll() { - return Collections.unmodifiableList(this.args.stream().map(SingleArg::getValue).collect(Collectors.toList())); - } - - List getArgs() { - return this.args; - } - - /** - * Return this arguments object's current state. Can be used to reset with - * the {@link #setState(Object)} method. - * - * @return The current state - * @deprecated Use {@link #getSnapshot()} and - * {@link #applySnapshot(Snapshot)} instead - */ - @Deprecated - public Object getState() { - return this.getSnapshot(); - } - - /** - * Restore the arguments object's state to a state previously used. - * - * @param state the previous state - * @deprecated Use {@link #getSnapshot()} and - * {@link #applySnapshot(Snapshot)} instead - */ - @Deprecated - public void setState(Object state) { - if (!(state instanceof Snapshot)) { - throw new IllegalArgumentException("Provided state was not of appropriate format returned by getState!"); - } - - this.applySnapshot((Snapshot) state, false); // keep parity with before - } - - /** - * Return the raw string used to provide input to this arguments object. - * - * @return The raw input - */ - public String getRaw() { - return this.rawInput; - } - - /** - * Get an arg at the specified position. - * - * @param index index of the element to return - */ - public String get(int index) { - return this.args.get(index).getValue(); - } - - /** - * Insert an arg as the next arg to be returned by {@link #next()}. - * - * @param value The argument to insert - */ - public void insertArg(String value) { - int index = this.index < 0 ? 0 : this.args.get(this.index).getEndIdx(); - this.args.add(this.index + 1, new SingleArg(value, index, index)); - } - - /** - * Remove the arguments parsed between startState and endState. - * - * @param startState The starting state - * @param endState The ending state - * @deprecated Use with {@link #getSnapshot()} instead of - * {@link #getState()} with {@link #removeArgs(Snapshot, Snapshot)} - */ - @Deprecated - public void removeArgs(Object startState, Object endState) { - if (!(startState instanceof Integer) || !(endState instanceof Integer)) { - throw new IllegalArgumentException("One of the states provided was not of the correct type!"); - } - - this.removeArgs((int) startState, (int) endState); - } - - /** - * Remove the arguments parsed between two snapshots. - * - * @param startSnapshot The starting state - * @param endSnapshot The ending state - */ - public void removeArgs(Snapshot startSnapshot, Snapshot endSnapshot) { - this.removeArgs(startSnapshot.index, endSnapshot.index); - } - - private void removeArgs(int startIdx, int endIdx) { - if (this.index >= startIdx) { - if (this.index < endIdx) { - this.index = startIdx - 1; - } else { - this.index -= (endIdx - startIdx) + 1; - } - } - - for (int i = startIdx; i <= endIdx; ++i) { - this.args.remove(startIdx); - } - } - - /** - * Returns the number of arguments. - * - * @return the number of arguments - */ - public int size() { - return this.args.size(); - } - - /** - * Go back to the previous argument. - */ - void previous() { - if (this.index > -1) { - --this.index; - } - } - - /** - * Gets the current position in raw input. - * - * @return the raw position - */ - public int getRawPosition() { - return this.index < 0 ? 0 : this.args.get(this.index).getStartIdx(); - } - - /** - * Gets a snapshot of the data inside this context to allow it to be - * restored later. - * - * @return The {@link Snapshot} containing the current state of the - * {@link CommandArgs} - */ - public Snapshot getSnapshot() { - return new Snapshot(this.index, this.args); - } - - /** - * Resets a {@link CommandArgs} to a previous state using a previously - * created {@link Snapshot}. - * - * @param snapshot The {@link Snapshot} to restore this context - * with - */ - public void applySnapshot(Snapshot snapshot) { - this.applySnapshot(snapshot, true); - } - - /** - * Resets a {@link CommandArgs} to a previous state using a previously - * created {@link Snapshot}. - * - *

If resetArgs is set to false, this snapshot will not reset the - * argument list to its previous state, only the index.

- * - * @param snapshot The {@link Snapshot} to restore this context - * with - * @param resetArgs Whether to restore the argument list - */ - public void applySnapshot(Snapshot snapshot, boolean resetArgs) { - this.index = snapshot.index; - - if (resetArgs) { - this.args.clear(); - this.args.addAll(snapshot.args); - } - } - - /** - * A snapshot of a {@link CommandArgs}. This object does not contain any - * public API methods, a snapshot should be considered a black box. - */ - public final class Snapshot { - final int index; - final ImmutableList args; - - Snapshot(int index, List args) { - this.index = index; - this.args = ImmutableList.copyOf(args); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o == null || this.getClass() != o.getClass()) { - return false; - } - - Snapshot snapshot = (Snapshot) o; - return this.index == snapshot.index - && Objects.equals(this.args, snapshot.args); - } - - @Override - public int hashCode() { - return Objects.hash(this.index, this.args); - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandContext.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandContext.java deleted file mode 100644 index b40b46a40..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandContext.java +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; - -import java.util.Collection; -import java.util.Collections; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.Set; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Multimap; -import com.google.common.collect.Sets; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; -import net.legacyfabric.fabric.api.util.Location; -import net.legacyfabric.fabric.mixin.command.ChatMessageAccessor; - -/** - * Context that a command is executed in. - * This object stores parsed arguments from other commands - */ -public final class CommandContext { - /** - * The argument key for a target block position that may be present - * during tab completion, of type {@link Location Location<World>}. - */ - public static final String TARGET_BLOCK_ARG = "targetblock-pos048658"; // Random junk afterwards so we don't accidentally conflict with other args - - /** - * The argument key to indicate that a tab completion is taking place. - */ - public static final String TAB_COMPLETION = "tab-complete-50456"; // Random junk afterwards so we don't accidentally conflict with other args - - private final Multimap parsedArgs; - private final Set definedFlags; - - /** - * Create a new empty CommandContext. - */ - public CommandContext() { - this.parsedArgs = ArrayListMultimap.create(); - this.definedFlags = Sets.newHashSet(); - } - - /** - * Gets all values for the given argument. May return an empty list if no - * values are present. - * - * @param key The key to get values for - * @param the type of value to get - * @return the collection of all values - */ - @SuppressWarnings("unchecked") - public Collection getAll(String key) { - return Collections.unmodifiableCollection((Collection) this.parsedArgs.get(key)); - } - - /** - * Gets all values for the given argument. May return an empty list if no - * values are present. - * - * @param key The key to get values for - * @param the type of value to get - * @return the collection of all values - */ - public Collection getAll(ChatMessage key) { - return this.getAll(CommandContext.textToArgKey(key)); - } - - /** - * Gets the value for the given key if the key has only one value. - * - *

An empty {@link Optional} indicates that there are either zero or more - * than one values for the given key. Use {@link #hasAny(Text)} to verify - * which.

- * - * @param key the key to get - * @param the expected type of the argument - * @return the argument - */ - @SuppressWarnings("unchecked") - public Optional getOne(String key) { - Collection values = this.parsedArgs.get(key); - - if (values.size() != 1) { - return Optional.empty(); - } - - return Optional.ofNullable((T) values.iterator().next()); - } - - /** - * Gets the value for the given key if the key has only one value. - * - *

An empty {@link Optional} indicates that there are either zero or more - * than one values for the given key. Use {@link #hasAny(Text)} to verify - * which.

- * - * @param key the key to get - * @param the expected type of the argument - * @return the argument - */ - public Optional getOne(ChatMessage key) { - return this.getOne(CommandContext.textToArgKey(key)); - } - - /** - * Gets the value for the given key if the key has only one value, throws an - * exception otherwise. - * - * @param key the key to get - * @param the expected type of the argument - * @return the argument - * @throws NoSuchElementException if there is no element with the - * associated key - * @throws IllegalArgumentException if there are more than one element - * associated with the key (thus, the argument is illegal in this - * context) - * @throws ClassCastException if the element type is not what is expected - * by the caller - */ - @SuppressWarnings("unchecked") - public T requireOne(String key) throws NoSuchElementException, IllegalArgumentException, ClassCastException { - Collection values = this.parsedArgs.get(key); - - if (values.size() == 1) { - return (T) values.iterator().next(); - } else if (values.isEmpty()) { - throw new NoSuchElementException(); - } - - throw new IllegalArgumentException(); - } - - /** - * Gets the value for the given key if the key has only one value, throws an - * exception otherwise. - * - * @param key the key to get - * @param the expected type of the argument - * @return the argument - * @throws NoSuchElementException if there is no element with the - * associated key - * @throws IllegalArgumentException if there are more than one element - * associated with the key (thus, the argument is illegal in this - * context) - * @throws ClassCastException if the element type is not what is expected - */ - public T requireOne(ChatMessage key) - throws NoSuchElementException, IllegalArgumentException, ClassCastException { - return this.requireOne(CommandContext.textToArgKey(key)); - } - - /** - * Insert an argument into this context. - * - * @param key the key to store the arg under - * @param value the value for this argument - */ - public void putArg(String key, Object value) { - Preconditions.checkNotNull(value, "value"); - this.parsedArgs.put(key, value); - } - - /** - * Insert an argument into this context. - * - * @param key the key to store the arg under - * @param value the value for this argument - */ - public void putArg(ChatMessage key, Object value) { - this.putArg(CommandContext.textToArgKey(key), value); - } - - /** - * Defines the flag as being present when parsing this context. - * - * @param key the key for the flag defined - */ - public void addFlag(String key) { - this.definedFlags.add(key); - } - - /** - * Defines the flag as being present when parsing this context. - * - * @param key the key for the flag defined - */ - public void addFlag(ChatMessage key) { - this.addFlag(CommandContext.textToArgKey(key)); - } - - /** - * Perform a permissions check, throwing an exception if the required - * permissions are not present. - * - * @param commander the source to check against - * @param permission The permission to check - * @throws CommandException if the source does not have permission - */ - public void checkPermission(PermissibleCommandSource commander, String permission) throws CommandException { - if (!commander.hasPermission(permission)) { - throw new CommandException(ChatMessage.createTextMessage("You do not have permission to use this command!")); - } - } - - /** - * Returns whether this context has any value for the given argument key. - * - * @param key The key to look up - * @return whether there are any values present - */ - public boolean hasAny(String key) { - return this.parsedArgs.containsKey(key); - } - - /** - * Returns whether this context has any value for the given argument key. - * - * @param key The key to look up - * @return whether there are any values present - */ - public boolean hasAny(ChatMessage key) { - return this.hasAny(CommandContext.textToArgKey(key)); - } - - /** - * Returns whether the given flag has been defined in this context. - * - * @param key The key to look up - * @return whether the flag is defined - */ - public boolean hasFlag(String key) { - return this.definedFlags.contains(key); - } - - /** - * Returns whether the given flag has been defined in this context. - * - * @param key The key to look up - * @return whether the flag is defined - */ - public boolean hasFlag(ChatMessage key) { - return this.hasFlag(CommandContext.textToArgKey(key)); - } - - /** - * Gets a snapshot of the data inside this context to allow it to be - * restored later. - * - *

This is only guaranteed to create a shallow copy of the - * backing store. If any value is mutable, any changes to that value - * will be reflected in this snapshot. It is therefore not recommended - * that you keep this snapshot around for longer than is necessary.

- * - * @return The {@link Snapshot} containing the current state of the - * {@link CommandContext} - */ - public Snapshot createSnapshot() { - return new Snapshot(this.parsedArgs, this.definedFlags); - } - - /** - * Resets a {@link CommandContext} to a previous state using a previously - * created {@link Snapshot}. - * - * @param snapshot The {@link Snapshot} to restore this context with - */ - public void applySnapshot(Snapshot snapshot) { - this.parsedArgs.clear(); - this.parsedArgs.putAll(snapshot.args); - this.definedFlags.clear(); - this.definedFlags.addAll(snapshot.flags); - } - - /** - * A snapshot of a {@link CommandContext}. This object does not contain any - * public API methods, a snapshot should be considered a black box. - */ - public static final class Snapshot { - final Multimap args; - final Set flags; - - Snapshot(Multimap args, Set flags) { - this.args = ArrayListMultimap.create(args); - this.flags = Sets.newHashSet(flags); - } - } - - /** - * Converts a {@link Text} into a String key. - * - * @param key the text to be converted into a string key - * @return the string key. if {@code key} is a {@link TranslatableText}, the translation key. - */ - public static String textToArgKey(@Nullable ChatMessage key) { - if (key == null) { - return null; - } - - if (((ChatMessageAccessor) key).getTranslationKey() != null) { // Use translation key - return ((ChatMessageAccessor) key).getTranslationKey(); - } - - return key.toString(); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandElement.java deleted file mode 100644 index 502c1506d..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandElement.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; - -import java.util.List; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -/** - * Represents a command argument element. - */ -public abstract class CommandElement { - @Nullable - private final ChatMessage key; - - protected CommandElement(@Nullable ChatMessage key) { - this.key = key; - } - - /** - * Return the key to be used for this object. - * - * @return the user-facing representation of the key - */ - @Nullable - public ChatMessage getKey() { - return this.key; - } - - /** - * Return the plain key, to be used when looking up this command element in - * a {@link CommandContext}. If the key is a {@link TranslatableText}, this - * is the translation's id. Otherwise, this is the result of - * {@link Text#asString()} ()} ()}. - * - * @return the raw key - */ - @Nullable - public String getUntranslatedKey() { - return CommandContext.textToArgKey(this.key); - } - - /** - * Attempt to extract a value for this element from the given arguments and - * put it in the given context. This method normally delegates to - * {@link #parseValue(PermissibleCommandSource, CommandArgs)} for getting the values. - * This method is expected to have no side-effects for the source, meaning - * that executing it will not change the state of the {@link PermissibleCommandSource} - * in any way. - * - * @param source The source to parse for - * @param args The args to extract from - * @param context The context to supply to - * @throws ArgumentParseException if unable to extract a value - */ - public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { - Object val = this.parseValue(source, args); - String key = this.getUntranslatedKey(); - - if (key != null && val != null) { - if (val instanceof Iterable) { - for (Object ent : ((Iterable) val)) { - context.putArg(key, ent); - } - } else { - context.putArg(key, val); - } - } - } - - /** - * Attempt to extract a value for this element from the given arguments. - * This method is expected to have no side-effects for the source, meaning - * that executing it will not change the state of the {@link PermissibleCommandSource} - * in any way. - * - * @param source The source to parse for - * @param args the arguments - * @return The extracted value - * @throws ArgumentParseException if unable to extract a value - */ - @Nullable - public abstract Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException; - - /** - * Fetch completions for command arguments. - * - * @param src The source requesting tab completions - * @param args The arguments currently provided - * @param context The context to store state in - * @return Any relevant completions - */ - public abstract List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context); - - /** - * Return a usage message for this specific argument. - * - * @param src The source requesting usage - * @return The formatted usage - */ - public ChatMessage getUsage(PermissibleCommandSource src) { - return this.getKey() == null ? ChatMessage.createTextMessage("") : ChatMessage.createTextMessage("<" + this.getKey() + ">"); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandFlags.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandFlags.java deleted file mode 100644 index cab7d8638..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/CommandFlags.java +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -import com.google.common.collect.ImmutableList; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public final class CommandFlags extends CommandElement { - @Nullable - private final CommandElement childElement; - private final Map, CommandElement> usageFlags; - private final Map shortFlags; - private final Map longFlags; - private final UnknownFlagBehavior unknownShortFlagBehavior; - private final UnknownFlagBehavior unknownLongFlagBehavior; - private final boolean anchorFlags; - - protected CommandFlags(@Nullable CommandElement childElement, Map, CommandElement> usageFlags, Map shortFlags, Map longFlags, UnknownFlagBehavior unknownShortFlagBehavior, UnknownFlagBehavior unknownLongFlagBehavior, boolean anchorFlags) { - super(null); - this.childElement = childElement; - this.usageFlags = usageFlags; - this.shortFlags = shortFlags; - this.longFlags = longFlags; - this.unknownShortFlagBehavior = unknownShortFlagBehavior; - this.unknownLongFlagBehavior = unknownLongFlagBehavior; - this.anchorFlags = anchorFlags; - } - - @Override - public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { - CommandArgs.Snapshot state = args.getSnapshot(); - - while (args.hasNext()) { - String arg = args.next(); - - if (arg.startsWith("-")) { - CommandArgs.Snapshot start = args.getSnapshot(); - boolean remove; - - if (arg.startsWith("--")) { // Long flag - remove = this.parseLongFlag(source, arg.substring(2), args, context); - } else { - remove = this.parseShortFlags(source, arg.substring(1), args, context); - } - - if (remove) { - args.removeArgs(start, args.getSnapshot()); - } - } else if (this.anchorFlags) { - break; - } - } - - // We removed the arguments so we don't parse them as they have already been parsed as flags, - // so don't restore them here! - args.applySnapshot(state, false); - - if (this.childElement != null) { - this.childElement.parse(source, args, context); - } - } - - private boolean parseLongFlag(PermissibleCommandSource source, String longFlag, CommandArgs args, CommandContext context) throws ArgumentParseException { - String[] flagSplit = longFlag.split("=", 2); - String flag = flagSplit[0].toLowerCase(); - CommandElement element = this.longFlags.get(flag); - - if (element == null) { - switch (this.unknownLongFlagBehavior) { - case ERROR: - throw args.createError(ChatMessage.createTextMessage(String.format("Unknown long flag %s specified", flagSplit[0]))); - case ACCEPT_NONVALUE: - context.addFlag(flag); - context.putArg(flag, flagSplit.length == 2 ? flagSplit[1] : true); - return true; - case ACCEPT_VALUE: - context.addFlag(flag); - context.putArg(flag, flagSplit.length == 2 ? flagSplit[1] : args.next()); - return true; - case IGNORE: - return false; - default: - throw new Error("New UnknownFlagBehavior added without corresponding case clauses"); - } - } else if (flagSplit.length == 2) { - args.insertArg(flagSplit[1]); - } - - element.parse(source, args, context); - return true; - } - - private boolean parseShortFlags(PermissibleCommandSource source, String shortFlags, CommandArgs args, CommandContext context) throws ArgumentParseException { - for (int i = 0; i < shortFlags.length(); i++) { - String shortFlag = shortFlags.substring(i, i + 1); - CommandElement element = this.shortFlags.get(shortFlag); - - if (element == null) { - switch (this.unknownShortFlagBehavior) { - case IGNORE: - if (i == 0) { - return false; - } - - throw args.createError(ChatMessage.createTextMessage(String.format("Unknown short flag %s specified", shortFlag))); - case ERROR: - throw args.createError(ChatMessage.createTextMessage(String.format("Unknown short flag %s specified", shortFlag))); - case ACCEPT_NONVALUE: - context.addFlag(shortFlag); - context.putArg(shortFlag, true); - break; - case ACCEPT_VALUE: - context.addFlag(shortFlag); - context.putArg(shortFlag, args.next()); - break; - default: - throw new Error("New UnknownFlagBehavior added without corresponding case clauses"); - } - } else { - element.parse(source, args, context); - } - } - - return true; - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource src) { - final List builder = new ArrayList<>(); - - for (Map.Entry, CommandElement> arg : this.usageFlags.entrySet()) { - builder.add("["); - - for (Iterator it = arg.getKey().iterator(); it.hasNext(); ) { - String flag = it.next(); - builder.add(flag.length() > 1 ? "--" : "-"); - builder.add(flag); - - if (it.hasNext()) { - builder.add("|"); - } - } - - ChatMessage usage = arg.getValue().getUsage(src); - - if (!usage.toString().trim().isEmpty()) { - builder.add(" "); - builder.add(usage); - } - - builder.add("]"); - builder.add(" "); - } - - if (this.childElement != null) { - builder.add(this.childElement.getUsage(src)); - } - - return ChatMessage.createTextMessage(Arrays.stream(builder.toArray()).map(Object::toString).collect(Collectors.joining())); - } - - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - return null; - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - CommandArgs.Snapshot state = args.getSnapshot(); - - while (args.hasNext()) { - String next = args.nextIfPresent().get(); - - if (next.startsWith("-")) { - CommandArgs.Snapshot start = args.getSnapshot(); - List ret; - - if (next.startsWith("--")) { - ret = this.tabCompleteLongFlag(next.substring(2), src, args, context); - } else { - ret = this.tabCompleteShortFlags(next.substring(1), src, args, context); - } - - if (ret != null) { - return ret; - } - - args.removeArgs(start, args.getSnapshot()); - } else if (this.anchorFlags) { - break; - } - } - - // the modifications are intentional - args.applySnapshot(state, false); - - // Prevent tab completion gobbling up an argument if the value parsed. - if (!args.hasNext() && !args.getRaw().matches("\\s+$")) { - return ImmutableList.of(); - } - - return this.childElement != null ? this.childElement.complete(src, args, context) : ImmutableList.of(); - } - - @Nullable - private List tabCompleteLongFlag(String longFlag, PermissibleCommandSource src, CommandArgs args, CommandContext context) { - String[] flagSplit = longFlag.split("=", 2); - boolean isSplitFlag = flagSplit.length == 2; - CommandElement element = this.longFlags.get(flagSplit[0].toLowerCase()); - - if (element == null || !isSplitFlag && !args.hasNext()) { - return this.longFlags.keySet().stream() - .filter((input) -> input.startsWith(flagSplit[0])) - .map(f -> "--" + f) - .collect(Collectors.toList()); - } else if (isSplitFlag) { - args.insertArg(flagSplit[1]); - } - - CommandArgs.Snapshot state = args.getSnapshot(); - List completion; - - try { - element.parse(src, args, context); - - if (args.getSnapshot().equals(state)) { - // Not iterated, but succeeded. Check completions to account for optionals - completion = element.complete(src, args, context); - } else { - args.previous(); - String res = args.peek(); - completion = element.complete(src, args, context); - - if (!completion.contains(res)) { - completion = ImmutableList.builder().addAll(completion).add(res).build(); - } - } - } catch (ArgumentParseException ex) { - args.applySnapshot(state); - completion = element.complete(src, args, context); - } - - if (completion.isEmpty()) { - if (isSplitFlag) { - return ImmutableList.of(); // so we don't overwrite the flag - } - - return null; - } - - if (isSplitFlag) { - return completion.stream().map(x -> "--" + flagSplit[0] + "=" + x).collect(Collectors.toList()); - } - - return completion; - } - - @Nullable - private List tabCompleteShortFlags(String shortFlags, PermissibleCommandSource src, CommandArgs args, CommandContext context) { - for (int i = 0; i < shortFlags.length(); i++) { - CommandElement element = this.shortFlags.get(shortFlags.substring(i, i + 1)); - - if (element == null) { - if (i == 0 && this.unknownShortFlagBehavior == UnknownFlagBehavior.ACCEPT_VALUE) { - args.nextIfPresent(); - return null; - } - } else { - CommandArgs.Snapshot start = args.getSnapshot(); - - try { - element.parse(src, args, context); - - // if the iterator hasn't moved, then just try to complete, no point going backwards. - if (args.getSnapshot().equals(start)) { - return element.complete(src, args, context); - } - - // if we managed to parse this, then go back to get the completions for it. - args.previous(); - String currentText = args.peek(); - - // ensure this is returned as a valid option - List elements = element.complete(src, args, context); - - if (!elements.contains(currentText)) { - return ImmutableList.builder().add(args.peek()).addAll(element.complete(src, args, context)).build(); - } else { - return elements; - } - } catch (ArgumentParseException ex) { - args.applySnapshot(start); - return element.complete(src, args, context); - } - } - } - - return null; - } - - /** - * Indicates to the flag parser how it should treat an argument that looks - * like a flag that it does not recognise. - */ - public enum UnknownFlagBehavior { - /** - * Throw an {@link ArgumentParseException} when an unknown flag is - * encountered. - */ - ERROR, - /** - * Mark the flag as a non-value flag. - */ - ACCEPT_NONVALUE, - - /** - * Mark the flag as a string-valued flag. - */ - ACCEPT_VALUE, - /** - * Act as if the unknown flag is an ordinary argument, allowing the - * parsers specified in {@link Builder#buildWith(CommandElement)} to - * attempt to parse the element instead. - */ - IGNORE, - } - - public static class Builder { - private final Map, CommandElement> usageFlags = new HashMap<>(); - private final Map shortFlags = new HashMap<>(); - private final Map longFlags = new HashMap<>(); - private UnknownFlagBehavior unknownLongFlagBehavior = UnknownFlagBehavior.ERROR; - private UnknownFlagBehavior unknownShortFlagBehavior = UnknownFlagBehavior.ERROR; - private boolean anchorFlags = false; - - Builder() { - } - - private Builder flag(Function func, String... specs) { - final List availableFlags = new ArrayList<>(specs.length); - CommandElement el = null; - - for (String spec : specs) { - if (spec.startsWith("-")) { - final String flagKey = spec.substring(1); - - if (el == null) { - el = func.apply(flagKey); - } - - availableFlags.add(flagKey); - this.longFlags.put(flagKey.toLowerCase(), el); - } else { - for (int i = 0; i < spec.length(); ++i) { - final String flagKey = spec.substring(i, i + 1); - - if (el == null) { - el = func.apply(flagKey); - } - - availableFlags.add(flagKey); - this.shortFlags.put(flagKey, el); - } - } - } - - this.usageFlags.put(availableFlags, el); - return this; - } - - /** - * Allow a flag with any of the provided specifications that has no - * value. This flag will be exposed in a {@link CommandContext} under - * the key equivalent to the first flag in the specification array. - * The specifications are handled as so for each element in the - * {@code specs} array: - *
    - *
  • If the element starts with -, the remainder of the element - * is interpreted as a long flag (so, "-flag" means "--flag" will - * be matched in an argument string)
  • - *
  • Otherwise, each code point of the element is interpreted - * as a short flag (meaning "flag" will cause "-f", "-l", "-a" and - * "-g" to be matched in an argument string, storing "true" under - * the key "f".)
  • - *
- * - * @param specs The flag specifications - * @return this - */ - public Builder flag(String... specs) { - return this.flag(input -> new FlagElement(ChatMessage.createTextMessage(input), null), specs); - } - - /** - * Allow a flag with any of the provided specifications that has no - * value but requires the source to have a specific permission to - * specify the command. - * - * @param flagPermission The required permission - * @param specs The flag specifications - * @return this - * @see #flag(String...) for details on the format - */ - public Builder permissionFlag(final String flagPermission, String... specs) { - return this.flag(input -> GenericArguments.requiringPermission(new FlagElement(ChatMessage.createTextMessage(input), null), flagPermission), specs); - } - - /** - * Allow a flag with any of the provided specifications, with the given - * command element. The flag may be present multiple times, and may - * therefore have multiple values. - * - * @param value The command element used to parse any occurrences - * @param specs The flag specifications - * @return this - * @see #flag(String...) for information on how the flag specifications - * are parsed - */ - public Builder valueFlag(CommandElement value, String... specs) { - return this.flag(input -> new FlagElement(ChatMessage.createTextMessage(input), value), specs); - } - - /** - * Sets how long flags that are not registered should be handled when - * encountered. - * - * @param behavior The behavior to use - * @return this - */ - public Builder setUnknownLongFlagBehavior(UnknownFlagBehavior behavior) { - this.unknownLongFlagBehavior = behavior; - return this; - } - - /** - * Sets how long flags that are not registered should be handled when - * encountered. - * - *

If a command that supports flags accepts negative numbers (or - * arguments that may begin with a dash), setting this to - * {@link UnknownFlagBehavior#IGNORE} will cause these elements to - * be ignored by the flag parser and will be parsed by the command's - * non-flag elements instead.

- * - * @param behavior The behavior to use - * @return this - */ - public Builder setUnknownShortFlagBehavior(UnknownFlagBehavior behavior) { - this.unknownShortFlagBehavior = behavior; - return this; - } - - /** - * Whether flags should be anchored to the beginning of the text (so - * flags will only be picked up if they are at the beginning of the - * input). - * - * @param anchorFlags Whether flags are anchored - * @return this - */ - public Builder setAnchorFlags(boolean anchorFlags) { - this.anchorFlags = anchorFlags; - return this; - } - - /** - * Build a flag command element using the given command element to - * handle all non-flag arguments. - * - *

If you wish to add multiple elements here, wrap them in - * {@link GenericArguments#seq(CommandElement...)}

- * - * @param wrapped The wrapped command element - * @return the new command element - */ - public CommandElement buildWith(CommandElement wrapped) { - return new CommandFlags(wrapped, this.usageFlags, this.shortFlags, this.longFlags, this.unknownShortFlagBehavior, this.unknownLongFlagBehavior, this.anchorFlags); - } - } - - private static class FlagElement extends CommandElement { - @Nullable - private final CommandElement valueElement; - - private FlagElement(ChatMessage key, @Nullable CommandElement valueElement) { - super(key); - this.valueElement = valueElement; - } - - @Override - public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { - String key = this.getUntranslatedKey(); - - if (this.valueElement != null) { - this.valueElement.parse(source, args, context); - } else { - context.putArg(key, true); - } - - context.addFlag(key); - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - return null; //unused - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - return this.valueElement != null ? this.valueElement.complete(src, args, context) : Collections.emptyList(); - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/GenericArguments.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/GenericArguments.java deleted file mode 100644 index b370fa9dc..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/GenericArguments.java +++ /dev/null @@ -1,949 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.net.InetAddress; -import java.net.URL; -import java.time.Duration; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.util.Collection; -import java.util.Map; -import java.util.UUID; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.text.ChatMessage; -import net.minecraft.util.math.Vec3d; - -import net.fabricmc.loader.api.ModContainer; - -import net.legacyfabric.fabric.api.command.v2.StringType; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; -import net.legacyfabric.fabric.api.util.TriState; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.AllOfCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.BigDecimalElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.BigIntegerElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.ChoicesCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.DateTimeElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.DurationElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.EntityCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.EnumValueElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.FilteredSuggestionsElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.FirstParsingCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.IpElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.LiteralCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.MarkTrueCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.ModCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.NumericElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.OnlyOneCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.OptionalCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.PermissionCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.PlayerCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.RemainingJoinedStringsCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.RepeatedCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.SequenceCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.StringCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.StringElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.UrlElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.UuidElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.Vec3dCommandElement; -import net.legacyfabric.fabric.impl.command.lib.sponge.args.WithSuggestionsElement; - -/** - * Class containing factory methods for common command elements. - */ -@SuppressWarnings({"UnstableApiUsage"}) -public class GenericArguments { - private static final CommandElement NONE = new SequenceCommandElement(ImmutableList.of()); - - private GenericArguments() { - } - - /** - * Expects no arguments, returns no values. - * - * @return An expectation of no arguments - */ - public static CommandElement none() { - return NONE; - } - - /** - * Expects no arguments. Adds 'true' to the context when parsed. - * - *

This will return only one value.

- * - * @param key the key to store 'true' under - * @return the argument - */ - public static CommandElement markTrue(ChatMessage key) { - return new MarkTrueCommandElement(key); - } - - /** - * Expect an argument to represent online players, or if nothing matches - * and the source is a {@link PlayerEntity}, give the player. If nothing matches - * and the source is not a player, throw an exception. - * - *

Gives values of type {@link PlayerEntity}.

- * - *

This argument accepts the following inputs:

- * - *
    - *
  • A player's name
  • - *
  • A regex that matches the beginning of one or more player's names - *
  • - *
  • A selector
  • - *
- * - *

This may return multiple players. If you must only return one, wrap - * this element in an {@link #onlyOne(CommandElement)} call.

- * - * @param key The key to store under - * @return the argument - */ - public static CommandElement playerOrSource(ChatMessage key) { - return new PlayerCommandElement(key, true); - } - - /** - * Expect an argument to represent online players. Returns values of type - * {@link PlayerEntity}. - * - *

This argument accepts the following inputs:

- * - *
    - *
  • A player's name
  • - *
  • A regex that matches the beginning of one or more player's names - *
  • - *
  • A selector
  • - *
- * - *

This may return multiple players. If you must only return one, wrap - * this element in an {@link #onlyOne(CommandElement)} call.

- * - * @param key The key to store under - * @return the argument - */ - public static CommandElement player(ChatMessage key) { - return new PlayerCommandElement(key, false); - } - - /** - * Expect an argument to represent a {@link Vec3d}. - * - *

This will return one value.

- * - * @param key The key to store under - * @return the argument - */ - public static CommandElement vec3d(ChatMessage key) { - return new Vec3dCommandElement(key); - } - - /** - * Expect an argument to represent a {@link ModContainer}'s id. - * - *

This argument accepts the following inputs:

- * - *
    - *
  • The specified {@link ModContainer}'s id
  • - *
  • A regex that matches the beginning of one or more plugin id
  • - *
- * - *

This may return multiple {@link ModContainer}s. If you must only - * return one, wrap this element in an {@link #onlyOne(CommandElement)} - * call.

- * - * @param key The key to store under - * @return the argument - */ - public static CommandElement mod(ChatMessage key) { - return new ModCommandElement(key); - } - - /** - * Gets a builder to create a command element that parses flags. - * - *

There should only be ONE of these in a command element sequence if you - * wish to use flags. A {@link CommandFlags.Builder} can handle multiple - * flags that have different behaviors. Using multiple builders in the same - * sequence may cause unexpected behavior.

- * - *

Any command elements that are not associated with flags should be - * placed into the {@link CommandFlags.Builder#buildWith(CommandElement)} - * parameter, allowing the flags to be used throughout the argument string. - *

- * - * @return the newly created builder - */ - public static CommandFlags.Builder flags() { - return new CommandFlags.Builder(); - } - - /** - * Consumes a series of arguments. Usage is the elements concatenated - * - * @param elements The series of arguments to expect - * @return the element to match the input - */ - public static CommandElement seq(CommandElement... elements) { - return new SequenceCommandElement(ImmutableList.copyOf(elements)); - } - - /** - * Return an argument that allows selecting from a limited set of values. - * - *

If there are 5 or fewer choices available, the choices will be shown - * in the command usage. Otherwise, the usage will only display only the - * key.

- * - *

Choices are case sensitive. If you do not require - * case sensitivity, see {@link #choicesInsensitive(Text, Map)}.

- * - *

To override this behavior, see - * {@link #choices(Text, Map, boolean, boolean)}.

- * - *

When parsing, only one choice may be selected, returning its - * associated value.

- * - * @param key The key to store the resulting value under - * @param choices The choices users can choose from - * @return the element to match the input - */ - public static CommandElement choices(ChatMessage key, Map choices) { - return choices(key, choices, choices.size() <= ChoicesCommandElement.CUTOFF, true); - } - - /** - * Return an argument that allows selecting from a limited set of values. - * - *

If there are 5 or fewer choices available, the choices will be shown - * in the command usage. Otherwise, the usage will only display only the - * key.

- * - *

Choices are not case sensitive. If you require - * case sensitivity, see {@link #choices(Text, Map)}

- * - *

To override this behavior, see - * {@link #choices(Text, Map, boolean, boolean)}.

- * - *

When parsing, only one choice may be selected, returning its - * associated value.

- * - * @param key The key to store the resulting value under - * @param choices The choices users can choose from - * @return the element to match the input - */ - public static CommandElement choicesInsensitive(ChatMessage key, Map choices) { - return choices(key, choices, choices.size() <= ChoicesCommandElement.CUTOFF, false); - } - - /** - * Return an argument that allows selecting from a limited set of values. - * - *

Unless {@code choicesInUsage} is true, general command usage will only - * display the provided key.

- * - *

Choices are case sensitive. If you do not require - * case sensitivity, see {@link #choices(Text, Map, boolean, boolean)}

- * - *

When parsing, only one choice may be selected, returning its - * associated value.

- * - * @param key The key to store the resulting value under - * @param choices The choices users can choose from - * @param choicesInUsage Whether to display the available choices, or simply - * the provided key, as part of usage - * @return the element to match the input - */ - public static CommandElement choices(ChatMessage key, Map choices, boolean choicesInUsage) { - return choices(key, choices, choicesInUsage, true); - } - - /** - * Return an argument that allows selecting from a limited set of values. - * - *

Unless {@code choicesInUsage} is true, general command usage will only - * display the provided key.

- * - *

When parsing, only one choice may be selected, returning its - * associated value.

- * - * @param key The key to store the resulting value under - * @param choices The choices users can choose from - * @param choicesInUsage Whether to display the available choices, or simply - * the provided key, as part of usage - * @param caseSensitive Whether the matches should be case sensitive - * @return the element to match the input - */ - public static CommandElement choices(ChatMessage key, Map choices, boolean choicesInUsage, boolean caseSensitive) { - if (!caseSensitive) { - Map choicesMap = choices.entrySet().stream().collect(Collectors.toMap(x -> x.getKey().toLowerCase(), Map.Entry::getValue)); - return choices(key, choicesMap::keySet, selection -> choicesMap.get(selection.toLowerCase()), choicesInUsage); - } - - Map immChoices = ImmutableMap.copyOf(choices); - return choices(key, immChoices::keySet, immChoices::get, choicesInUsage); - } - - /** - * Return an argument that allows selecting from a limited set of values. - * - *

If there are 5 or fewer choices available, the choices will be shown - * in the command usage. Otherwise, the usage will only display only the - * key.

- * - *

To override this behavior, see {@link #choices(Text, Map, boolean)}. - *

- * - *

Only one choice may be selected, returning its associated value.

- * - * @param key The key to store the resulting value under - * @param keys The function that will supply available keys - * @param values The function that maps an element of {@code key} to a value - * and any other key to {@code null} - * @return the element to match the input - */ - public static CommandElement choices(ChatMessage key, Supplier> keys, Function values) { - return new ChoicesCommandElement(key, keys, values, TriState.DEFAULT); - } - - /** - * Return an argument that allows selecting from a limited set of values. - * Unless {@code choicesInUsage} is true, general command usage will only - * display the provided key. - * - *

Only one choice may be selected, returning its associated value.

- * - * @param key The key to store the resulting value under - * @param keys The function that will supply available keys - * @param values The function that maps an element of {@code key} to a value - * and any other key to {@code null} - * @param choicesInUsage Whether to display the available choices, or simply - * the provided key, as part of usage - * @return the element to match the input - */ - public static CommandElement choices(ChatMessage key, Supplier> keys, Function values, boolean choicesInUsage) { - return new ChoicesCommandElement(key, keys, values, choicesInUsage ? TriState.TRUE : TriState.FALSE); - } - - /** - * Returns a command element that matches the first of the provided elements - * that parses tab completion matches from all options. - * - * @param elements The elements to check against - * @return The command element matching the first passing of the elements - * provided - */ - public static CommandElement firstParsing(CommandElement... elements) { - return new FirstParsingCommandElement(ImmutableList.copyOf(elements)); - } - - /** - * Make the provided command element optional. - * - *

This means the command element is not required. However, if the - * element is provided with invalid format and there are no more args - * specified, any errors will still be passed on.

- * - * @param element The element to optionally require - * @return the element to match the input - */ - public static CommandElement optional(CommandElement element) { - return new OptionalCommandElement(element, null, false); - } - - /** - * Make the provided command element optional. - * - *

This means the command element is not required. However, if the - * element is provided with invalid format and there are no more args - * specified, any errors will still be passed on. If the given element's key - * and {@code value} are not null and this element is not provided the - * element's key will be set to the given value.

- * - * @param element The element to optionally require - * @param value The default value to set - * @return the element to match the input - */ - public static CommandElement optional(CommandElement element, Object value) { - return new OptionalCommandElement(element, value, false); - } - - /** - * Make the provided command element optional - * This means the command element is not required. - * If the argument is provided but of invalid format, it will be skipped. - * - * @param element The element to optionally require - * @return the element to match the input - */ - public static CommandElement optionalWeak(CommandElement element) { - return new OptionalCommandElement(element, null, true); - } - - /** - *

Make the provided command element optional.

- * - *

This means the command element is not required.

- * - *
    - *
  • If the argument is provided but of invalid format, it will be - * skipped.
  • - *
  • If the given element's key and {@code value} are not null and - * this element is not provided the element's key will be set to the - * given value.
  • - *
- * - * @param element The element to optionally require - * @param value The default value to set - * @return the element to match the input - */ - public static CommandElement optionalWeak(CommandElement element, Object value) { - return new OptionalCommandElement(element, value, true); - } - - /** - * Require a given command element to be provided a certain number of times. - * - *

Command values will be stored under their provided keys in the - * CommandContext.

- * - * @param element The element to repeat - * @param times The number of times to repeat the element. - * @return the element to match the input - */ - public static CommandElement repeated(CommandElement element, int times) { - return new RepeatedCommandElement(element, times); - } - - /** - * Require all remaining args to match as many instances of - * {@link CommandElement} as will fit. Command element values will be stored - * under their provided keys in the CommandContext. - * - * @param element The element to repeat - * @return the element to match the input - */ - public static CommandElement allOf(CommandElement element) { - return new AllOfCommandElement(element); - } - - // -- Argument types for basic java types - - /** - * Require an argument to be a string. Any provided argument will fit in - * under this argument. - * - *

Gives values of type {@link String}. This will return only one value. - *

- * - * @param key The key to store the parsed argument under - * @return the element to match the input - */ - public static CommandElement string(ChatMessage key) { - return new StringElement(key); - } - - /** - * Require an argument to be an integer (base 10). - * - *

Gives values of type {@link Integer}. This will return only one value. - *

- * - * @param key The key to store the parsed argument under - * @return the element to match the input - */ - public static CommandElement integer(ChatMessage key) { - return new NumericElement<>(key, Integer::parseInt, Integer::parseInt, input -> ChatMessage.createTextMessage(String.format("Expected an integer, but input '%s' was not", input))); - } - - /** - * Require an argument to be a long (base 10). - * - *

Gives values of type {@link Long}. This will return only one value. - *

- * - * @param key The key to store the parsed argument under - * @return the element to match the input - */ - public static CommandElement longNum(ChatMessage key) { - return new NumericElement<>(key, Long::parseLong, Long::parseLong, input -> ChatMessage.createTextMessage(String.format("Expected a long, but input '%s' was not", input))); - } - - /** - * Require an argument to be an double-precision floating point number. - * - *

Gives values of type {@link Double}. This will return only one value. - *

- * - * @param key The key to store the parsed argument under - * @return the element to match the input - */ - public static CommandElement doubleNum(ChatMessage key) { - return new NumericElement<>(key, Double::parseDouble, null, input -> ChatMessage.createTextMessage(String.format("Expected a number, but input '%s' was not", input))); - } - - private static final Map BOOLEAN_CHOICES = ImmutableMap.builder() - .put("true", true) - .put("t", true) - .put("y", true) - .put("yes", true) - .put("verymuchso", true) - .put("1", true) - .put("false", false) - .put("f", false) - .put("n", false) - .put("no", false) - .put("notatall", false) - .put("0", false) - .build(); - - /** - * Require an argument to be a boolean. - * - *

The recognized true values are:

- * - *
    - *
  • true
  • - *
  • t
  • - *
  • yes
  • - *
  • y
  • - *
  • verymuchso
  • - *
- * - * - *

The recognized false values are:

- * - *
    - *
  • false
  • - *
  • f
  • - *
  • no
  • - *
  • n
  • - *
  • notatall
  • - *
- * - *

Gives values of type {@link Boolean}. This will return only one value. - *

- * - * @param key The key to store the parsed argument under - * @return the element to match the input - */ - public static CommandElement bool(ChatMessage key) { - return GenericArguments.choices(key, BOOLEAN_CHOICES); - } - - /** - * Require the argument to be a key under the provided enum. - * - *

Gives values of type T. This will return only one value.

- * - * @param key The key to store the matched enum value under - * @param type The enum class to get enum constants from - * @param The type of enum - * @return the element to match the input - */ - public static > CommandElement enumValue(ChatMessage key, Class type) { - return new EnumValueElement<>(key, type); - } - - /** - * Require one or more strings, which are combined into a single, - * space-separated string. - * - *

Gives values of type {@link String}. This will return only one value. - *

- * - * @param key The key to store the parsed argument under - * @return the element to match the input - */ - public static CommandElement remainingJoinedStrings(ChatMessage key) { - return new RemainingJoinedStringsCommandElement(key, false); - } - - /** - * Require one or more strings, without any processing, which are combined - * into a single, space-separated string. - * - *

Gives values of type {@link String}. This will return only one value. - *

- * - * @param key The key to store the parsed argument under - * @return the element to match the input - */ - public static CommandElement remainingRawJoinedStrings(ChatMessage key) { - return new RemainingJoinedStringsCommandElement(key, true); - } - - /** - * Expect a literal sequence of arguments. This element matches the input - * against a predefined array of arguments expected to be present, - * case-insensitively. - * - *

This will return only one value.

- * - * @param key The key to add to the context. Will be set to a value of true - * if this element matches - * @param expectedArgs The sequence of arguments expected - * @return the appropriate command element - */ - public static CommandElement literal(ChatMessage key, String... expectedArgs) { - return new LiteralCommandElement(key, ImmutableList.copyOf(expectedArgs), true); - } - - /** - * Expect a literal sequence of arguments. This element matches the input - * against a predefined array of arguments expected to be present, - * case-insensitively. - * - *

This will return only one value.

- * - * @param key The key to store this argument as - * @param putValue The value to put at key if this argument matches. May be - * null - * @param expectedArgs The sequence of arguments expected - * @return the appropriate command element - */ - public static CommandElement literal(ChatMessage key, @Nullable Object putValue, String... expectedArgs) { - return new LiteralCommandElement(key, ImmutableList.copyOf(expectedArgs), putValue); - } - - /** - * Restricts the given command element to only insert one value into the - * context at the provided key. - * - *

If more than one value is returned by an element, or the target key - * already contains a value, this will throw an - * {@link ArgumentParseException}

- * - * @param element The element to restrict - * @return the restricted element - */ - public static CommandElement onlyOne(CommandElement element) { - return new OnlyOneCommandElement(element); - } - - /** - * Checks a permission for a given command argument to be used. - * - *

If the element attempts to parse an argument and the user does not - * have the permission, an {@link ArgumentParseException} will be thrown.

- * - * @param element The element to wrap - * @param permission The permission to check - * @return the element - */ - public static CommandElement requiringPermission(CommandElement element, String permission) { - return new PermissionCommandElement(element, permission, false); - } - - /** - * Checks a permission for a given command argument to be used. - * - *

If the element attempts to parse an argument and the user does not - * have the permission, the element will be skipped over.

- * - *

If the invoking {@link PermissibleCommandSource} has permission to use the - * element, but the wrapped element fails to parse, an exception will - * be reported in the normal way. If you require this element to be - * truly optional, wrap this element in either - * {@link #optional(CommandElement)} or - * {@link #optionalWeak(CommandElement)}, as required.

- * - * @param element The element to wrap - * @param permission The permission to check - * @return the element - */ - public static CommandElement requiringPermissionWeak(CommandElement element, String permission) { - return new PermissionCommandElement(element, permission, true); - } - - /** - * Expect an argument to represent an {@link Entity}. - * - *

This argument accepts the following inputs:

- * - *
    - *
  • A player's name
  • - *
  • An entity's {@link UUID}
  • - *
  • A regex that matches the beginning of one or more player's names - * or entities UUIDs. - *
  • - *
  • A selector
  • - *
- * - * @param key The key to store under - * @return the argument - */ - public static CommandElement entity(ChatMessage key) { - return new EntityCommandElement(key, false, false, null); - } - - /** - * Expect an argument to represent an {@link Entity} of the specified type. - * - *

This argument accepts the following inputs:

- * - *
    - *
  • A player's name (if appropriate)
  • - *
  • An entity's {@link UUID}
  • - *
  • A regex that matches the beginning of one or more player's names - * or entities UUIDs. - *
  • - *
  • A selector
  • - *
- * - * @param key The key to store under - * @param clazz The type which the entity must subclass - * @return the argument - */ - public static CommandElement entity(ChatMessage key, Class clazz) { - return new EntityCommandElement(key, false, false, clazz); - } - - /** - * Expect an argument to represent an {@link Entity} of the specified type, - * or if the argument is not present and the {@link PermissibleCommandSource} is - * looking at an applicable entity, return that entity. - * - *

This argument accepts the following inputs:

- * - *
    - *
  • A player's name (if appropriate)
  • - *
  • An entity's {@link UUID}
  • - *
  • A regex that matches the beginning of one or more player's names - * or entities UUIDs. - *
  • - *
  • A selector
  • - *
- * - * @param key The key to store under - * @param clazz The type which the entity must subclass - * @return the argument - */ - public static CommandElement entityOrTarget(ChatMessage key, Class clazz) { - return new EntityCommandElement(key, false, true, clazz); - } - - /** - * Expect an argument to represent a {@link URL}. - * - *

This will return only one value.

- * - * @param key The key to store under - * @return the argument - */ - public static CommandElement url(ChatMessage key) { - return new UrlElement(key); - } - - /** - * Expect an argument to return an IP address, in the form of an - * {@link InetAddress}. - * - *

This will return only one value.

- * - * @param key The key to store under - * @return the argument - */ - public static CommandElement ip(ChatMessage key) { - return new IpElement(key); - } - - /** - * Expect an argument to return a {@link BigDecimal}. - * - * @param key The key to store under - * @return the argument - */ - public static CommandElement bigDecimal(ChatMessage key) { - return new BigDecimalElement(key); - } - - /** - * Expect an argument to return a {@link BigInteger}. - * - *

This will return only one value.

- * - * @param key The key to store under - * @return the argument - */ - public static CommandElement bigInteger(ChatMessage key) { - return new BigIntegerElement(key); - } - - /** - * Expect an argument to be a {@link UUID}. - * - *

This will return only one value.

- * - * @param key The key to store under - * @return the argument - */ - public static CommandElement uuid(ChatMessage key) { - return new UuidElement(key); - } - - /** - * Expect an argument to be a {@link String}. - * - *

This will return only one value.

- * - * @param key The key to store under - * @param type The type of parsing to be followed - * @return the argument - */ - public static CommandElement string(ChatMessage key, StringType type) { - return new StringCommandElement(key, type); - } - - /** - * Expect an argument to be a date-time, in the form of a - * {@link LocalDateTime}. If no date is specified, {@link LocalDate#now()} - * is used; if no time is specified, {@link LocalTime#MIDNIGHT} is used. - * - *

Date-times are expected in the ISO-8601 format.

- * - *

This will return only one value.

- * - * @param key The key to store under - * @return the argument - * @see ISO-8601 - */ - public static CommandElement dateTime(ChatMessage key) { - return new DateTimeElement(key, false); - } - - /** - * Expect an argument to be a date-time, in the form of a - * {@link LocalDateTime}. If no date is specified, {@link LocalDate#now()} - * is used; if no time is specified, {@link LocalTime#MIDNIGHT} is used. - * - *

If no argument at all is specified, defaults to - * {@link LocalDateTime#now()}.

- * - *

Date-times are expected in the ISO-8601 format.

- * - *

This will return only one value.

- * - * @param key The key to store under - * @return the argument - */ - public static CommandElement dateTimeOrNow(ChatMessage key) { - return new DateTimeElement(key, true); - } - - /** - * Expect an argument to be a {@link Duration}. - * - *

Durations are expected in the following format: {@code #D#H#M#S}. - * This is not case sensitive.

- * - *

This will return only one value.

- * - * @param key The key to store under - * @return the argument - */ - public static CommandElement duration(ChatMessage key) { - return new DurationElement(key); - } - - /** - * Uses a custom set of suggestions for an argument. The provided - * suggestions will replace the regular ones. - * - * @param argument The element to replace the suggestions of - * @param suggestions The suggestions to use - * @return the argument - */ - public static CommandElement withSuggestions(CommandElement argument, Iterable suggestions) { - return withSuggestions(argument, suggestions, true); - } - - /** - * Uses a custom set of suggestions for an argument. The provided - * suggestions will replace the regular ones. - * - *

If {@code requireBegin} is false, then the already typed argument - * will not be used to filter the provided suggestions.

- * - * @param argument The element to replace the suggestions of - * @param suggestions The suggestions to use - * @param requireBegin Whether or not to require the current argument to - * begin provided arguments - * @return the argument - */ - public static CommandElement withSuggestions(CommandElement argument, Iterable suggestions, boolean requireBegin) { - return withSuggestions(argument, (s) -> suggestions, requireBegin); - } - - /** - * Uses a custom set of suggestions for an argument. The provided - * suggestions will replace the regular ones. - * - * @param argument The element to replace the suggestions of - * @param suggestions A function to return the suggestions to use - * @return the argument - */ - public static CommandElement withSuggestions(CommandElement argument, Function> suggestions) { - return withSuggestions(argument, suggestions, true); - } - - /** - * Uses a custom set of suggestions for an argument. The provided - * suggestions will replace the regular ones. - * - *

If {@code requireBegin} is false, then the already typed argument - * will not be used to filter the provided suggestions.

- * - * @param argument The element to replace the suggestions of - * @param suggestions A function to return the suggestions to use - * @param requireBegin Whether or not to require the current argument to - * begin provided arguments - * @return the argument - */ - public static CommandElement withSuggestions(CommandElement argument, Function> suggestions, boolean requireBegin) { - return new WithSuggestionsElement(argument, suggestions, requireBegin); - } - - /** - * Filters an argument's suggestions. A suggestion will only be used if it - * matches the predicate. - * - * @param argument The element to filter the suggestions of - * @param predicate The predicate to test suggestions against - * @return the argument - */ - public static CommandElement withConstrainedSuggestions(CommandElement argument, Predicate predicate) { - return new FilteredSuggestionsElement(argument, predicate); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/KeyElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/KeyElement.java deleted file mode 100644 index f70b70e01..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/KeyElement.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; - -import java.util.Collections; -import java.util.List; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -/** - * Parent class that specifies elements as having no tab completions. - * Useful for inputs with a very large domain, like strings and integers. - */ -public abstract class KeyElement extends CommandElement { - protected KeyElement(ChatMessage key) { - super(key); - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - return Collections.emptyList(); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/PatternMatchingCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/PatternMatchingCommandElement.java deleted file mode 100644 index 57c638d55..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/PatternMatchingCommandElement.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -/** - * Abstract command element that matches values based on a regex pattern. - */ -public abstract class PatternMatchingCommandElement extends CommandElement { - private static final ChatMessage nullKeyArg = ChatMessage.createTextMessage("argument"); - final boolean useRegex; - - /** - * @param yesIWantRegex Specify if you want to allow regex for users of - * the command element. Note that this will open up for DoS attacks. - */ - protected PatternMatchingCommandElement(@Nullable ChatMessage key, boolean yesIWantRegex) { - super(key); - this.useRegex = yesIWantRegex; - } - - protected PatternMatchingCommandElement(@Nullable ChatMessage key) { - this(key, false); - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - Iterable choices = this.getChoices(source); - Iterable ret; - String arg = args.next(); - - // Check to see if we have an exact match first - Optional exactMatch = this.getExactMatch(choices, arg); - - if (exactMatch.isPresent()) { - // Return this as a collection as this can get transformed by the subclass. - return Collections.singleton(exactMatch.get()); - } - - if (this.useRegex) { - Pattern pattern = this.getFormattedPattern(arg); - ret = StreamSupport.stream(choices.spliterator(), false).filter(element -> pattern.matcher(element).find()).collect(Collectors.toList()).stream().map(this::getValue).collect(Collectors.toList()); - } else { - Iterable startsWith = StreamSupport.stream(choices.spliterator(), false).filter(element -> element.regionMatches(true, 0, arg, 0, arg.length())).collect(Collectors.toList()); - ret = StreamSupport.stream(startsWith.spliterator(), false).map(this::getValue).collect(Collectors.toList()); - } - - if (!ret.iterator().hasNext()) { - throw args.createError(ChatMessage.createTextMessage(String.format("No values matching pattern '%s' present for %s!", arg, this.getKey() == null - ? nullKeyArg : this.getKey()))); - } - - return ret; - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - Iterable choices = this.getChoices(src); - final Optional nextArg = args.nextIfPresent(); - - if (nextArg.isPresent()) { - if (this.useRegex) { - choices = StreamSupport.stream(choices.spliterator(), false).filter(input -> this.getFormattedPattern(nextArg.get()).matcher(input).find()).collect(Collectors.toList()); - } else { - String arg = nextArg.get(); - choices = StreamSupport.stream(choices.spliterator(), false).filter(input -> input.regionMatches(true, 0, arg, 0, arg.length())).collect(Collectors.toList()); - } - } - - return ImmutableList.copyOf(choices); - } - - Pattern getFormattedPattern(String input) { - if (!input.startsWith("^")) { // Anchor matches to the beginning -- this lets us use find() - input = "^" + input; - } - - return Pattern.compile(input, Pattern.CASE_INSENSITIVE); - } - - /** - * Tests a string against a set of valid choices to see if it is a - * case-insensitive match. - * - * @param choices The choices available to match against - * @param potentialChoice The potential choice - * @return If matched, an {@link Optional} containing the matched value - */ - protected Optional getExactMatch(final Iterable choices, final String potentialChoice) { - return Optional.ofNullable(Iterables.tryFind(choices, potentialChoice::equalsIgnoreCase).orNull()).map(this::getValue); - } - - /** - * Gets the available choices for this command source. - * - * @param source The source requesting choices - * @return the possible choices - */ - protected abstract Iterable getChoices(PermissibleCommandSource source); - - /** - * Gets the value for a given choice. For any result in - * {@link #getChoices(PermissibleCommandSource)}, this must return a non-null value. - * Otherwise, an {@link IllegalArgumentException} may be throw. - * - * @param choice The specified choice - * @return the choice's value - * @throws IllegalArgumentException if the input string is not any return - * value of {@link #getChoices(PermissibleCommandSource)} - */ - protected abstract Object getValue(String choice) throws IllegalArgumentException; -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/SelectorCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/SelectorCommandElement.java deleted file mode 100644 index 09610c43e..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/SelectorCommandElement.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args; - -import java.util.List; -import java.util.Optional; - -import com.google.common.collect.ImmutableList; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.Selector; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public abstract class SelectorCommandElement extends PatternMatchingCommandElement { - protected SelectorCommandElement(@Nullable ChatMessage key) { - super(key); - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - String arg = args.peek(); - - if (arg.startsWith("@")) { // Possibly a selector - try { - return Selector.parse(args.next()).resolve(source); - } catch (IllegalArgumentException ex) { - throw args.createError(ChatMessage.createTextMessage(ex.getMessage())); - } - } - - return super.parseValue(source, args); - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - CommandArgs.Snapshot state = args.getSnapshot(); - final Optional nextArg = args.nextIfPresent(); - args.applySnapshot(state); - List choices = nextArg.isPresent() ? Selector.complete(nextArg.get()) : ImmutableList.of(); - - if (choices.isEmpty()) { - choices = super.complete(src, args, context); - } - - return choices; - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/InputTokenizer.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/InputTokenizer.java deleted file mode 100644 index 837cc4d9c..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/InputTokenizer.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing; - -import java.util.List; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; - -public interface InputTokenizer { - /** - * Use an input string tokenizer that supports quoted arguments and - * character escapes. - * - *

Forcing lenient to true makes the following apply:

- * - *
    - *
  • Unclosed quotations are treated as a single string from the - * opening quotation to the end of the arguments rather than throwing - * an exception
  • - *
- * - * @param forceLenient Whether the tokenizer is forced into lenient mode - * @return the appropriate tokenizer - */ - static InputTokenizer quotedStrings(boolean forceLenient) { - return new QuotedStringTokenizer(true, forceLenient, false); - } - - /** - * Returns an input tokenizer that takes input strings and splits them by - * space. - * - * @return The appropriate tokenizer - */ - static InputTokenizer spaceSplitString() { - return SpaceSplitInputTokenizer.INSTANCE; - } - - /** - * Returns an input tokenizer that returns the input string as a single - * argument. - * - * @return The appropriate tokenizer - */ - static InputTokenizer rawInput() { - return RawStringInputTokenizer.INSTANCE; - } - - /** - * Take the input string and split it as appropriate into argument tokens. - * - * @param arguments The provided arguments - * @param lenient Whether to parse leniently - * @return The tokenized strings. Empty list if error occurs - * @throws ArgumentParseException if an invalid input is provided - */ - List tokenize(String arguments, boolean lenient) throws ArgumentParseException; -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/QuotedStringTokenizer.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/QuotedStringTokenizer.java deleted file mode 100644 index 106d51cdf..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/QuotedStringTokenizer.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; - -/** - * Parser for converting a quoted string into a list of arguments. - * - *

Grammar is roughly (yeah, this is not really a proper grammar but it gives - * you an idea of what's happening:

- * - *
 WHITESPACE = Character.isWhiteSpace(codePoint)
- * CHAR := (all unicode)
- * ESCAPE := '\' CHAR
- * QUOTE = ' | "
- * UNQUOTED_ARG := (CHAR | ESCAPE)+ WHITESPACE
- * QUOTED_ARG := QUOTE (CHAR | ESCAPE)+ QUOTE
- * ARGS := ((UNQUOTED_ARG | QUOTED_ARG) WHITESPACE+)+
- */ -class QuotedStringTokenizer implements InputTokenizer { - private static final int CHAR_BACKSLASH = '\\'; - private static final int CHAR_SINGLE_QUOTE = '\''; - private static final int CHAR_DOUBLE_QUOTE = '"'; - private final boolean handleQuotedStrings; - private final boolean forceLenient; - private final boolean trimTrailingSpace; - - QuotedStringTokenizer(boolean handleQuotedStrings, boolean forceLenient, boolean trimTrailingSpace) { - this.handleQuotedStrings = handleQuotedStrings; - this.forceLenient = forceLenient; - this.trimTrailingSpace = trimTrailingSpace; - } - - @Override - public List tokenize(String arguments, boolean lenient) throws ArgumentParseException { - if (arguments.length() == 0) { - return Collections.emptyList(); - } - - final TokenizerState state = new TokenizerState(arguments, lenient); - List returnedArgs = new ArrayList<>(arguments.length() / 4); - - if (this.trimTrailingSpace) { - this.skipWhiteSpace(state); - } - - while (state.hasMore()) { - if (!this.trimTrailingSpace) { - this.skipWhiteSpace(state); - } - - int startIdx = state.getIndex() + 1; - String arg = this.nextArg(state); - returnedArgs.add(new SingleArg(arg, startIdx, state.getIndex())); - - if (this.trimTrailingSpace) { - this.skipWhiteSpace(state); - } - } - - return returnedArgs; - } - - // Parsing methods - - private void skipWhiteSpace(TokenizerState state) throws ArgumentParseException { - if (!state.hasMore()) { - return; - } - - while (state.hasMore() && Character.isWhitespace(state.peek())) { - state.next(); - } - } - - private String nextArg(TokenizerState state) throws ArgumentParseException { - StringBuilder argBuilder = new StringBuilder(); - - if (state.hasMore()) { - int codePoint = state.peek(); - - if (this.handleQuotedStrings && (codePoint == CHAR_DOUBLE_QUOTE || codePoint == CHAR_SINGLE_QUOTE)) { - // quoted string - this.parseQuotedString(state, codePoint, argBuilder); - } else { - this.parseUnquotedString(state, argBuilder); - } - } - - return argBuilder.toString(); - } - - private void parseQuotedString(TokenizerState state, int startQuotation, StringBuilder builder) throws ArgumentParseException { - // Consume the start quotation character - int nextCodePoint = state.next(); - - if (nextCodePoint != startQuotation) { - throw state.createException(ChatMessage.createTextMessage(String.format("Actual next character '%c' did not match expected quotation character '%c'", - nextCodePoint, startQuotation))); - } - - while (true) { - if (!state.hasMore()) { - if (state.isLenient() || this.forceLenient) { - return; - } - - throw state.createException(ChatMessage.createTextMessage("Unterminated quoted string found")); - } - - nextCodePoint = state.peek(); - - if (nextCodePoint == startQuotation) { - state.next(); - return; - } else if (nextCodePoint == CHAR_BACKSLASH) { - this.parseEscape(state, builder); - } else { - builder.appendCodePoint(state.next()); - } - } - } - - private void parseUnquotedString(TokenizerState state, StringBuilder builder) throws ArgumentParseException { - while (state.hasMore()) { - int nextCodePoint = state.peek(); - - if (Character.isWhitespace(nextCodePoint)) { - return; - } else if (nextCodePoint == CHAR_BACKSLASH) { - this.parseEscape(state, builder); - } else { - builder.appendCodePoint(state.next()); - } - } - } - - private void parseEscape(TokenizerState state, StringBuilder builder) throws ArgumentParseException { - state.next(); // Consume \ - builder.appendCodePoint(state.next()); // TODO: Unicode character escapes (\u00A7 type thing)? - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/RawStringInputTokenizer.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/RawStringInputTokenizer.java deleted file mode 100644 index 7e9ca53f9..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/RawStringInputTokenizer.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing; - -import java.util.Collections; -import java.util.List; - -class RawStringInputTokenizer implements InputTokenizer { - static final RawStringInputTokenizer INSTANCE = new RawStringInputTokenizer(); - - private RawStringInputTokenizer() { - } - - @Override - public List tokenize(String arguments, boolean lenient) { - return Collections.singletonList(new SingleArg(arguments, 0, arguments.length())); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SingleArg.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SingleArg.java deleted file mode 100644 index bf8b5bbf2..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SingleArg.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing; - -import com.google.common.base.Objects; - -/** - * This represents a single argument with its start and end indexes - * in the associated raw input string. - */ -public class SingleArg { - private final String value; - private final int startIdx; - private final int endIdx; - - /** - * Create a new argument. - * - * @param value The argument string - * @param startIdx The starting index of {@code value} in an input string - * @param endIdx The ending index of {@code value} in an input string - */ - public SingleArg(String value, int startIdx, int endIdx) { - this.value = value; - this.startIdx = startIdx; - this.endIdx = endIdx; - } - - /** - * Gets the string used. - * - * @return The string used - */ - public String getValue() { - return this.value; - } - - /** - * Gets the starting index. - * - * @return The starting index - */ - public int getStartIdx() { - return this.startIdx; - } - - /** - * Gets the ending index. - * - * @return The ending index - */ - public int getEndIdx() { - return this.endIdx; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (!(o instanceof SingleArg)) { - return false; - } - - SingleArg singleArg = (SingleArg) o; - return this.startIdx == singleArg.startIdx - && this.endIdx == singleArg.endIdx - && Objects.equal(this.value, singleArg.value); - } - - @Override - public int hashCode() { - return Objects.hashCode(this.value, this.startIdx, this.endIdx); - } - - @Override - public String toString() { - return Objects.toStringHelper(this) - .add("value", this.value) - .add("startIdx", this.startIdx) - .add("endIdx", this.endIdx) - .toString(); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SpaceSplitInputTokenizer.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SpaceSplitInputTokenizer.java deleted file mode 100644 index b8e0e16dd..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/SpaceSplitInputTokenizer.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; - -import com.google.common.collect.ImmutableList; - -class SpaceSplitInputTokenizer implements InputTokenizer { - public static final SpaceSplitInputTokenizer INSTANCE = new SpaceSplitInputTokenizer(); - private static final Pattern SPACE_REGEX = Pattern.compile("^[ ]*$"); - - private SpaceSplitInputTokenizer() { - } - - @Override - public List tokenize(String arguments, boolean lenient) { - if (SPACE_REGEX.matcher(arguments).matches()) { - return ImmutableList.of(); - } - - List ret = new ArrayList<>(); - int lastIndex = 0; - int spaceIndex; - - while ((spaceIndex = arguments.indexOf(" ")) != -1) { - if (spaceIndex != 0) { - ret.add(new SingleArg(arguments.substring(0, spaceIndex), lastIndex, lastIndex + spaceIndex)); - arguments = arguments.substring(spaceIndex); - } else { - arguments = arguments.substring(1); - } - - lastIndex += spaceIndex + 1; - } - - ret.add(new SingleArg(arguments, lastIndex, lastIndex + arguments.length())); - return ret; - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/TokenizerState.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/TokenizerState.java deleted file mode 100644 index 8a83c351b..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/args/parsing/TokenizerState.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; - -class TokenizerState { - private final boolean lenient; - private final String buffer; - private int index = -1; - - TokenizerState(String buffer, boolean lenient) { - this.buffer = buffer; - this.lenient = lenient; - } - - // Utility methods - public boolean hasMore() { - return this.index + 1 < this.buffer.length(); - } - - public int peek() throws ArgumentParseException { - if (!this.hasMore()) { - throw this.createException(ChatMessage.createTextMessage("Buffer overrun while parsing args")); - } - - return this.buffer.codePointAt(this.index + 1); - } - - public int next() throws ArgumentParseException { - if (!this.hasMore()) { - throw this.createException(ChatMessage.createTextMessage("Buffer overrun while parsing args")); - } - - return this.buffer.codePointAt(++this.index); - } - - public ArgumentParseException createException(ChatMessage message) { - return new ArgumentParseException(message, this.buffer, this.index); - } - - public boolean isLenient() { - return this.lenient; - } - - public int getIndex() { - return this.index; - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Disambiguator.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Disambiguator.java deleted file mode 100644 index f82134407..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Disambiguator.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher; - -import java.util.List; -import java.util.Optional; - -import org.jetbrains.annotations.Nullable; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMapping; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -@FunctionalInterface -public interface Disambiguator { - /** - * Disambiguate an alias in cases where there are multiple command mappings - * registered for a given alias. - * - * @param source The PermissibleCommandSource executing the command, if any - * @param aliasUsed The alias input by the user - * @param availableOptions The commands registered to this alias - * @return The specific command to use - */ - Optional disambiguate(@Nullable PermissibleCommandSource source, String aliasUsed, List availableOptions); -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Dispatcher.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Dispatcher.java deleted file mode 100644 index 40cb5346c..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/Dispatcher.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher; - -import java.util.Optional; -import java.util.Set; - -import com.google.common.collect.Multimap; -import org.jetbrains.annotations.Nullable; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandCallable; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMapping; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -/** - * Executes a command based on user input. - */ -public interface Dispatcher extends CommandCallable { - /** - * Gets a list of commands. Each command, regardless of how many aliases it - * may have, will only appear once in the returned set. - * - *

The returned collection cannot be modified.

- * - * @return A list of registrations - */ - Set getCommands(); - - /** - * Gets a list of primary aliases. - * - *

The returned collection cannot be modified.

- * - * @return A list of aliases - */ - Set getPrimaryAliases(); - - /** - * Gets a list of all the command aliases, which includes the primary alias. - * - *

A command may have more than one alias assigned to it. The returned - * collection cannot be modified.

- * - * @return A list of aliases - */ - Set getAliases(); - - /** - * Gets the {@link CommandMapping} associated with an alias. Returns null if - * no command is named by the given alias. - * - * @param alias The alias - * @return The command mapping, if available - */ - Optional get(String alias); - - /** - * Gets the {@link CommandMapping} associated with an alias in the context - * of a given {@link PermissibleCommandSource}. Returns null if no command is named by - * the given alias. - * - * @param alias The alias to look up - * @param source The source this alias is being looked up for - * @return The command mapping, if available - */ - Optional get(String alias, @Nullable PermissibleCommandSource source); - - /** - * Gets all the {@link CommandMapping}s associated with an alias. - * - * @param alias The alias - * @return The command mappings associated with the alias - */ - Set getAll(String alias); - - /** - * Gets all commands currently registered with this dispatcher. The returned - * value is immutable. - * - * @return a multimap from alias to mapping of every registered command - */ - Multimap getAll(); - - /** - * Returns whether the dispatcher contains a registered command for the - * given alias. - * - * @param alias The alias - * @return True if a registered command exists - */ - boolean containsAlias(String alias); - - /** - * Returns whether the dispatcher contains the given mapping. - * - * @param mapping The mapping - * @return True if a mapping exists - */ - boolean containsMapping(CommandMapping mapping); -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/SimpleDispatcher.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/SimpleDispatcher.java deleted file mode 100644 index 9017acc49..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/dispatcher/SimpleDispatcher.java +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ListMultimap; -import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; -import net.minecraft.util.Formatting; -import net.minecraft.world.World; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandCallable; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMapping; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandNotFoundException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandResult; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.ImmutableCommandMapping; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.InvocationCommandException; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; -import net.legacyfabric.fabric.api.util.Location; - -/** - * A simple implementation of a {@link Dispatcher}. - */ -public final class SimpleDispatcher implements Dispatcher { - /** - * This is a disambiguator function that returns the first matching command. - */ - public static final Disambiguator FIRST_DISAMBIGUATOR = (source, aliasUsed, availableOptions) -> { - for (CommandMapping mapping : availableOptions) { - if (mapping.getPrimaryAlias().toLowerCase().equals(aliasUsed.toLowerCase())) { - return Optional.of(mapping); - } - } - - return Optional.of(availableOptions.get(0)); - }; - - private final Disambiguator disambiguatorFunc; - private final ListMultimap commands = ArrayListMultimap.create(); - - /** - * Creates a basic new dispatcher. - */ - public SimpleDispatcher() { - this(FIRST_DISAMBIGUATOR); - } - - /** - * Creates a new dispatcher with a specific disambiguator. - * - * @param disambiguatorFunc Function that returns the preferred command if - * multiple exist for a given alias - */ - public SimpleDispatcher(Disambiguator disambiguatorFunc) { - this.disambiguatorFunc = disambiguatorFunc; - } - - /** - * Register a given command using the given list of aliases. - * - *

If there is a conflict with one of the aliases (i.e. that alias - * is already assigned to another command), then the alias will be skipped. - * It is possible for there to be no alias to be available out of - * the provided list of aliases, which would mean that the command would not - * be assigned to any aliases.

- * - *

The first non-conflicted alias becomes the "primary alias."

- * - * @param callable The command - * @param alias An array of aliases - * @return The registered command mapping, unless no aliases could be - * registered - */ - public Optional register(CommandCallable callable, String... alias) { - Preconditions.checkNotNull(alias, "alias"); - return this.register(callable, Arrays.asList(alias)); - } - - /** - * Register a given command using the given list of aliases. - * - *

If there is a conflict with one of the aliases (i.e. that alias - * is already assigned to another command), then the alias will be skipped. - * It is possible for there to be no alias to be available out of - * the provided list of aliases, which would mean that the command would not - * be assigned to any aliases.

- * - *

The first non-conflicted alias becomes the "primary alias."

- * - * @param callable The command - * @param aliases A list of aliases - * @return The registered command mapping, unless no aliases could be - * registered - */ - public Optional register(CommandCallable callable, List aliases) { - return this.register(callable, aliases, Function.identity()); - } - - /** - * Register a given command using a given list of aliases. - * - *

The provided callback function will be called with a list of aliases - * that are not taken (from the list of aliases that were requested) and - * it should return a list of aliases to actually register. Aliases may be - * removed, and if no aliases remain, then the command will not be - * registered. It may be possible that no aliases are available, and thus - * the callback would receive an empty list. New aliases should not be added - * to the list in the callback as this may cause - * {@link IllegalArgumentException} to be thrown.

- * - *

The first non-conflicted alias becomes the "primary alias."

- * - * @param callable The command - * @param aliases A list of aliases - * @param callback The callback - * @return The registered command mapping, unless no aliases could - * be registered - */ - public synchronized Optional register(CommandCallable callable, List aliases, Function, List> callback) { - Preconditions.checkNotNull(aliases, "aliases"); - Preconditions.checkNotNull(callable, "callable"); - Preconditions.checkNotNull(callback, "callback"); - - // Invoke the callback with the commands that /can/ be registered - aliases = ImmutableList.copyOf(callback.apply(aliases)); - - if (aliases.isEmpty()) { - return Optional.empty(); - } - - String primary = aliases.get(0); - List secondary = aliases.subList(1, aliases.size()); - CommandMapping mapping = new ImmutableCommandMapping(callable, primary, secondary); - - for (String alias : aliases) { - this.commands.put(alias.toLowerCase(), mapping); - } - - return Optional.of(mapping); - } - - /** - * Remove a mapping identified by the given alias. - * - * @param alias The alias - * @return The previous mapping associated with the alias, if one was found - */ - public synchronized Collection remove(String alias) { - return this.commands.removeAll(alias.toLowerCase()); - } - - /** - * Remove all mappings identified by the given aliases. - * - * @param aliases A collection of aliases - * @return Whether any were found - */ - public synchronized boolean removeAll(Collection aliases) { - Preconditions.checkNotNull(aliases, "aliases"); - - boolean found = false; - - for (Object alias : aliases) { - if (!this.commands.removeAll(alias.toString().toLowerCase()).isEmpty()) { - found = true; - } - } - - return found; - } - - /** - * Remove a command identified by the given mapping. - * - * @param mapping The mapping - * @return The previous mapping associated with the alias, if one was found - */ - public synchronized Optional removeMapping(CommandMapping mapping) { - Preconditions.checkNotNull(mapping, "mapping"); - - CommandMapping found = null; - - Iterator it = this.commands.values().iterator(); - - while (it.hasNext()) { - CommandMapping current = it.next(); - - if (current.equals(mapping)) { - it.remove(); - found = current; - } - } - - return Optional.ofNullable(found); - } - - /** - * Remove all mappings contained with the given collection. - * - * @param mappings The collection - * @return Whether the at least one command was removed - */ - public synchronized boolean removeMappings(Collection mappings) { - Preconditions.checkNotNull(mappings, "mappings"); - boolean found = false; - Iterator it = this.commands.values().iterator(); - - while (it.hasNext()) { - if (mappings.contains(it.next())) { - it.remove(); - found = true; - } - } - - return found; - } - - @Override - public synchronized Set getCommands() { - return ImmutableSet.copyOf(this.commands.values()); - } - - @Override - public synchronized Set getPrimaryAliases() { - Set aliases = new HashSet<>(); - - for (CommandMapping mapping : this.commands.values()) { - aliases.add(mapping.getPrimaryAlias()); - } - - return Collections.unmodifiableSet(aliases); - } - - @Override - public synchronized Set getAliases() { - Set aliases = new HashSet<>(); - - for (CommandMapping mapping : this.commands.values()) { - aliases.addAll(mapping.getAllAliases()); - } - - return Collections.unmodifiableSet(aliases); - } - - @Override - public Optional get(String alias) { - return this.get(alias, null); - } - - @Override - public synchronized Optional get(String alias, @Nullable PermissibleCommandSource source) { - List results = this.commands.get(alias.toLowerCase()); - Optional result = Optional.empty(); - - if (results.size() == 1) { - result = Optional.of(results.get(0)); - } else if (results.size() > 1) { - result = this.disambiguatorFunc.disambiguate(source, alias, results); - } - - if (source != null) { - result = result.filter(m -> m.getCallable().testPermission(source)); - } - - return result; - } - - @Override - public synchronized boolean containsAlias(String alias) { - return this.commands.containsKey(alias.toLowerCase()); - } - - @Override - public boolean containsMapping(CommandMapping mapping) { - Preconditions.checkNotNull(mapping, "mapping"); - - for (CommandMapping test : this.commands.values()) { - if (mapping.equals(test)) { - return true; - } - } - - return false; - } - - @Override - public CommandResult process(PermissibleCommandSource source, String commandLine) throws CommandException { - final String[] argSplit = commandLine.split(" ", 2); - Optional cmdOptional = this.get(argSplit[0], source); - - if (!cmdOptional.isPresent()) { - throw new CommandNotFoundException(ChatMessage.createTranslateMessage("commands.generic.notFound"), argSplit[0]); - } - - final String arguments = argSplit.length > 1 ? argSplit[1] : ""; - CommandMapping mapping = cmdOptional.get(); - final CommandCallable spec = mapping.getCallable(); - - try { - return spec.process(source, arguments); - } catch (CommandNotFoundException e) { - throw new CommandException(ChatMessage.createTextMessage("No such child command: " + e.getCommand())); - } catch (RuntimeException e) { - throw new InvocationCommandException(ChatMessage.createTextMessage("An unexpected error happened executing the command"), e); - } - } - - @Override - public List getSuggestions(PermissibleCommandSource src, final String arguments, @Nullable Location targetPosition) throws CommandException { - final String[] argSplit = arguments.split(" ", 2); - Optional cmdOptional = this.get(argSplit[0], src); - - if (argSplit.length == 1) { - return Collections.unmodifiableList(new ArrayList<>(this.filterCommands(src, argSplit[0]))); - } else if (!cmdOptional.isPresent()) { - return ImmutableList.of(); - } - - return cmdOptional.get().getCallable().getSuggestions(src, argSplit[1], targetPosition); - } - - @Override - public boolean testPermission(PermissibleCommandSource source) { - for (CommandMapping mapping : this.commands.values()) { - if (mapping.getCallable().testPermission(source)) { - return true; - } - } - - return false; - } - - @Override - public Optional getShortDescription(PermissibleCommandSource source) { - return Optional.empty(); - } - - @Override - public Optional getHelp(PermissibleCommandSource source) { - if (this.commands.isEmpty()) { - return Optional.empty(); - } - - ChatMessage build = ChatMessage.createTextMessage("Available commands:\n"); - - for (Iterator it = this.filterCommands(source).iterator(); it.hasNext(); ) { - final Optional mappingOpt = this.get(it.next(), source); - - if (!mappingOpt.isPresent()) { - continue; - } - - CommandMapping mapping = mappingOpt.get(); - final Optional description = mapping.getCallable().getShortDescription(source); - ChatMessage text = ChatMessage.createTextMessage(mapping.getPrimaryAlias()); - build.addUsing( - text.setColor(Formatting.GREEN).setUnderlined(true) - ).addUsing(CommandMessageFormatting.SPACE_TEXT) - .addUsing(description.orElse(mapping.getCallable().getUsage(source))); - - if (it.hasNext()) { - build.addText("\n"); - } - } - - return Optional.of(ChatMessage.createTextMessage(build.toString())); - } - - private Set filterCommands(final PermissibleCommandSource src) { - return Multimaps.filterValues(this.commands, input -> input.getCallable().testPermission(src)).keys().elementSet(); - } - - // Filter out commands by String first - private Set filterCommands(final PermissibleCommandSource src, String start) { - Multimap map = Multimaps.filterKeys(this.commands, - input -> input != null && input.toLowerCase().startsWith(start.toLowerCase())); - return Multimaps.filterValues(map, input -> input.getCallable().testPermission(src)).keys().elementSet(); - } - - /** - * Gets the number of registered aliases. - * - * @return The number of aliases - */ - public synchronized int size() { - return this.commands.size(); - } - - @Override - public ChatMessage getUsage(final PermissibleCommandSource source) { - final StringBuilder build = new StringBuilder(); - Iterable filteredCommands = this.filterCommands(source).stream() - .filter(input -> { - if (input == null) { - return false; - } - - final Optional ret = this.get(input, source); - return ret.isPresent() && ret.get().getPrimaryAlias().equals(input); - }) - .collect(Collectors.toList()); - - for (Iterator it = filteredCommands.iterator(); it.hasNext(); ) { - build.append(it.next()); - - if (it.hasNext()) { - build.append(CommandMessageFormatting.PIPE_TEXT); - } - } - - return ChatMessage.createTextMessage(build.toString()); - } - - @Override - public synchronized Set getAll(String alias) { - return ImmutableSet.copyOf(this.commands.get(alias)); - } - - @Override - public Multimap getAll() { - return ImmutableMultimap.copyOf(this.commands); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandExecutor.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandExecutor.java deleted file mode 100644 index 56d09b002..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandExecutor.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.spec; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandResult; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -/** - * Interface containing the method directing how a certain command will - * be executed. - */ -@FunctionalInterface -public interface CommandExecutor { - /** - * Callback for the execution of a command. - * - * @param src The commander who is executing this command - * @param args The parsed command arguments for this command - * @return the result of executing this command - * @throws CommandException If a user-facing error occurs while - * executing this command - */ - CommandResult execute(PermissibleCommandSource src, CommandContext args) throws CommandException; -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandSpec.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandSpec.java deleted file mode 100644 index 0ab9a3d0e..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/api/command/v2/lib/sponge/spec/CommandSpec.java +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.api.command.v2.lib.sponge.spec; - -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import com.google.common.base.Objects; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; -import net.minecraft.world.World; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandCallable; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandPermissionException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandResult; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ChildCommandElementExecutor; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.GenericArguments; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.parsing.InputTokenizer; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; -import net.legacyfabric.fabric.api.util.Location; - -/** - * Specification for how command arguments should be parsed. - */ -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") -public final class CommandSpec implements CommandCallable { - private final CommandElement args; - private final CommandExecutor executor; - private final Optional description; - private final Optional extendedDescription; - @Nullable - private final String permission; - private final InputTokenizer argumentParser; - - CommandSpec(CommandElement args, CommandExecutor executor, @Nullable ChatMessage description, @Nullable ChatMessage extendedDescription, - @Nullable String permission, InputTokenizer parser) { - this.args = args; - this.executor = executor; - this.permission = permission; - this.description = Optional.ofNullable(description); - this.extendedDescription = Optional.ofNullable(extendedDescription); - this.argumentParser = parser; - } - - /** - * Return a new builder for a CommandSpec. - * - * @return a new builder - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Builder for command specs. - */ - public static final class Builder { - private static final CommandElement DEFAULT_ARG = GenericArguments.none(); - private CommandElement args = DEFAULT_ARG; - @Nullable - private ChatMessage description; - @Nullable - private ChatMessage extendedDescription; - @Nullable - private String permission; - @Nullable - private CommandExecutor executor; - @Nullable - private Map, CommandCallable> childCommandMap; - private boolean childCommandFallback = true; - private InputTokenizer argumentParser = InputTokenizer.quotedStrings(false); - - Builder() { - } - - /** - * Sets the permission that will be checked before using this command. - * - * @param permission The permission to check - * @return this - */ - public Builder permission(String permission) { - this.permission = permission; - return this; - } - - /** - * Sets the callback that will handle this command's execution. - * - * @param executor The executor that will be called with this command's - * parsed arguments - * @return this - */ - public Builder executor(CommandExecutor executor) { - Preconditions.checkNotNull(executor, "executor"); - this.executor = executor; - return this; - } - - /** - * Adds more child arguments for this command. - * If an executor or arguments are set, they are used as fallbacks. - * - * @param children The children to use - * @return this - */ - public Builder children(Map, ? extends CommandCallable> children) { - Preconditions.checkNotNull(children, "children"); - - if (this.childCommandMap == null) { - this.childCommandMap = new HashMap<>(); - } - - this.childCommandMap.putAll(children); - return this; - } - - /** - * Add a single child command to this command. - * - * @param child The child to add - * @param aliases Aliases to make the child available under. First - * one is primary and is the only one guaranteed to be listed in - * usage outputs. - * @return this - */ - public Builder child(CommandCallable child, String... aliases) { - if (this.childCommandMap == null) { - this.childCommandMap = new HashMap<>(); - } - - this.childCommandMap.put(ImmutableList.copyOf(aliases), child); - return this; - } - - /** - * Add a single child command to this command. - * - * @param child The child to add. - * @param aliases Aliases to make the child available under. First - * one is primary and is the only one guaranteed to be listed in - * usage outputs. - * @return this - */ - public Builder child(CommandCallable child, Collection aliases) { - if (this.childCommandMap == null) { - this.childCommandMap = new HashMap<>(); - } - - this.childCommandMap.put(ImmutableList.copyOf(aliases), child); - return this; - } - - /** - * A short, one-line description of this command's purpose. - * - * @param description The description to set - * @return this - */ - public Builder description(@Nullable ChatMessage description) { - this.description = description; - return this; - } - - /** - * Sets an extended description to use in longer help listings for this - * command. Will be appended to the short description and the command's - * usage. - * - * @param extendedDescription The description to set - * @return this - */ - public Builder extendedDescription(@Nullable ChatMessage extendedDescription) { - this.extendedDescription = extendedDescription; - return this; - } - - /** - * If a child command is selected but fails to parse arguments passed to - * it, the following determines the behavior. - * - *
    - *
  • If this is set to false, this command (the - * parent) will not attempt to parse the command, and will send back - * the error from the child.
  • - *
  • If this is set to true, the error from the - * child will simply be discarded, and the parent command will - * execute.
  • - *
- * - *

The default for this is true, which emulates the - * behavior from previous API revisions.

- * - * @param childCommandFallback Whether to fallback on argument parse - * failure - * @return this - */ - public Builder childArgumentParseExceptionFallback(boolean childCommandFallback) { - this.childCommandFallback = childCommandFallback; - return this; - } - - /** - * Sets the argument specification for this command. Generally, for a - * multi-argument command the {@link GenericArguments#seq(CommandElement...)} - * method is used to parse a sequence of args. - * - * @param args The arguments object to use - * @return this - * @see GenericArguments - */ - public Builder arguments(CommandElement args) { - Preconditions.checkNotNull(args, "args"); - this.args = GenericArguments.seq(args); - return this; - } - - /** - * Sets the argument specification for this command. This method accepts - * a sequence of arguments. This is equivalent to calling {@code - * arguments(seq(args))}. - * - * @param args The arguments object to use - * @return this - * @see GenericArguments - */ - public Builder arguments(CommandElement... args) { - Preconditions.checkNotNull(args, "args"); - this.args = GenericArguments.seq(args); - return this; - } - - /** - * Sets the input tokenizer to be used to convert input from a string - * into a list of argument tokens. - * - * @param parser The parser to use - * @return this - * @see InputTokenizer for common input parser implementations - */ - public Builder inputTokenizer(InputTokenizer parser) { - Preconditions.checkNotNull(parser, "parser"); - this.argumentParser = parser; - return this; - } - - /** - * Create a new {@link CommandSpec} based on the data provided in this - * builder. - * - * @return the new spec - */ - public CommandSpec build() { - if (this.childCommandMap == null || this.childCommandMap.isEmpty()) { - Preconditions.checkNotNull(this.executor, "An executor is required"); - } else if (this.executor == null) { - ChildCommandElementExecutor childCommandElementExecutor = - this.registerInDispatcher(new ChildCommandElementExecutor(null, null, false)); - if (this.args == DEFAULT_ARG) { - this.arguments(childCommandElementExecutor); - } else { - this.arguments(this.args, childCommandElementExecutor); - } - } else { - this.arguments(this.registerInDispatcher(new ChildCommandElementExecutor(this.executor, this.args, this.childCommandFallback))); - } - - return new CommandSpec(this.args, this.executor, this.description, this.extendedDescription, this.permission, - this.argumentParser); - } - - @SuppressWarnings({"ConstantConditions"}) - private ChildCommandElementExecutor registerInDispatcher(ChildCommandElementExecutor childDispatcher) { - for (Map.Entry, ? extends CommandCallable> spec : this.childCommandMap.entrySet()) { - childDispatcher.register(spec.getValue(), spec.getKey()); - } - - this.executor(childDispatcher); - return childDispatcher; - } - } - - /** - * Check the relevant permission for this command with the provided source, - * throwing an exception if the source does not have permission to use - * the command. - * - * @param source The source to check - * @throws CommandException if the source does not have permission - */ - public void checkPermission(PermissibleCommandSource source) throws CommandException { - Preconditions.checkNotNull(source, "source"); - - if (!this.testPermission(source)) { - throw new CommandPermissionException(); - } - } - - /** - * Process this command with existing arguments and context objects. - * - * @param source The source to populate the context with - * @param args The arguments to process with - * @param context The context to put data in - * @throws ArgumentParseException if an invalid argument is provided - */ - public void populateContext(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { - this.args.parse(source, args, context); - - if (args.hasNext()) { - args.next(); - throw args.createError(ChatMessage.createTextMessage("Too many arguments!")); - } - } - - /** - * Return tab completion results using the existing parsed arguments and - * context. Primarily useful when including a subcommand in an existing - * specification. - * - * @param source The source to parse arguments for - * @param args The arguments object - * @param context The context object - * @return possible completions, or an empty list if none - */ - public List complete(PermissibleCommandSource source, CommandArgs args, CommandContext context) { - Preconditions.checkNotNull(source, "source"); - List ret = this.args.complete(source, args, context); - return ret == null ? ImmutableList.of() : ImmutableList.copyOf(ret); - } - - /** - * Gets the active executor for this command. Generally not a good idea to - * call this directly, unless you are handling arg parsing specially - * - * @return The active executor for this command - */ - public CommandExecutor getExecutor() { - return this.executor; - } - - /** - * Gets the active input tokenizer used for this command. - * - * @return This command's input tokenizer - */ - public InputTokenizer getInputTokenizer() { - return this.argumentParser; - } - - @Override - public CommandResult process(PermissibleCommandSource source, String arguments) throws CommandException { - this.checkPermission(source); - final CommandArgs args = new CommandArgs(arguments, this.getInputTokenizer().tokenize(arguments, false)); - final CommandContext context = new CommandContext(); - this.populateContext(source, args, context); - return this.getExecutor().execute(source, context); - } - - @Override - public List getSuggestions(PermissibleCommandSource source, String arguments, @Nullable Location targetPos) throws CommandException { - CommandArgs args = new CommandArgs(arguments, this.getInputTokenizer().tokenize(arguments, true)); - CommandContext ctx = new CommandContext(); - - if (targetPos != null) { - ctx.putArg(CommandContext.TARGET_BLOCK_ARG, targetPos); - } - - ctx.putArg(CommandContext.TAB_COMPLETION, true); - return this.complete(source, args, ctx); - } - - @Override - public boolean testPermission(PermissibleCommandSource source) { - return source.hasPermission(this.permission); - } - - /** - * Gets a short, one-line description used with this command if any is - * present. - * - * @return the short description. - */ - @Override - public Optional getShortDescription(PermissibleCommandSource source) { - return this.description; - } - - /** - * Gets the extended description used with this command if any is present. - * - * @param source The source to get the description for - * @return the extended description. - */ - public Optional getExtendedDescription(PermissibleCommandSource source) { - return this.extendedDescription; - } - - /** - * Gets the usage for this command appropriate for the provided command - * source. - * - * @param source The source - * @return the usage for the source - */ - @Override - public ChatMessage getUsage(PermissibleCommandSource source) { - Preconditions.checkNotNull(source, "source"); - return this.args.getUsage(source); - } - - /** - * Return a longer description for this command. This description is - * composed of at least all present of the short description, the usage - * statement, and the extended description - * - * @param source The source to get the extended description for - * @return the extended description - */ - @Override - public Optional getHelp(PermissibleCommandSource source) { - Preconditions.checkNotNull(source, "source"); - StringBuilder builder = new StringBuilder(); - this.getShortDescription(source).ifPresent((a) -> builder.append(a.toString()).append("\n")); - builder.append(this.getUsage(source)); - this.getExtendedDescription(source).ifPresent((a) -> builder.append(a.toString()).append("\n")); - return Optional.of(ChatMessage.createTextMessage(builder.toString())); - } - - @Override - public boolean equals(@Nullable Object o) { - if (this == o) { - return true; - } - - if (o == null || this.getClass() != o.getClass()) { - return false; - } - - CommandSpec that = (CommandSpec) o; - return Objects.equal(this.args, that.args) - && Objects.equal(this.executor, that.executor) - && Objects.equal(this.description, that.description) - && Objects.equal(this.extendedDescription, that.extendedDescription) - && Objects.equal(this.permission, that.permission) - && Objects.equal(this.argumentParser, that.argumentParser); - } - - @Override - public int hashCode() { - return Objects.hashCode(this.args, this.executor, this.description, this.extendedDescription, this.permission, this.argumentParser); - } - - @Override - public String toString() { - return Objects.toStringHelper(this) - .add("args", this.args) - .add("executor", this.executor) - .add("description", this.description) - .add("extendedDescription", this.extendedDescription) - .add("permission", this.permission) - .add("argumentParser", this.argumentParser) - .toString(); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandManagerImpl.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandManagerImpl.java deleted file mode 100644 index ad14b1452..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandManagerImpl.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.function.Function; - -import com.google.common.collect.Lists; -import com.google.common.collect.Multimap; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; -import net.minecraft.world.World; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandCallable; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandManager; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMapping; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandPermissionException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandResult; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.InvocationCommandException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher.Disambiguator; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher.SimpleDispatcher; -import net.legacyfabric.fabric.api.logger.v1.Logger; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; -import net.legacyfabric.fabric.api.util.Location; -import net.legacyfabric.fabric.impl.logger.LoggerImpl; - -public class CommandManagerImpl implements CommandManager { - private static final Logger LOGGER = Logger.get(LoggerImpl.API, "Command Manager"); - private final Object lock = new Object(); - private final SimpleDispatcher dispatcher; - private final List mappings = Lists.newArrayList(); - - public CommandManagerImpl(Disambiguator disambiguator) { - this.dispatcher = new SimpleDispatcher(disambiguator); - } - - @Override - public Optional register(CommandCallable callable, String... alias) { - return this.register(callable, Arrays.asList(alias)); - } - - @Override - public Optional register(CommandCallable callable, List aliases) { - return this.register(callable, aliases, Function.identity()); - } - - @Override - public Optional register(CommandCallable callable, List aliases, Function, List> callback) { - synchronized (this.lock) { - return this.dispatcher.register(callable, aliases, callback).map(mapping -> { - this.mappings.add(mapping); - return mapping; - }); - } - } - - @Override - public Optional removeMapping(CommandMapping mapping) { - synchronized (this.lock) { - return this.dispatcher.removeMapping(mapping).map(commandMapping -> { - this.mappings.remove(commandMapping); - return commandMapping; - }); - } - } - - @Override - public int size() { - synchronized (this.lock) { - return this.dispatcher.size(); - } - } - - @Override - public CommandResult process(PermissibleCommandSource source, String command) { - final String[] argSplit = command.split(" ", 2); - - try { - try { - this.dispatcher.process(source, command); - } catch (InvocationCommandException e) { - if (e.getCause() != null) { - throw e.getCause(); - } - } catch (CommandPermissionException e) { - if (e.getText() != null) { - source.method_5505(CommandMessageFormatting.error(e.getText())); - } - } catch (CommandException e) { - ChatMessage text = e.getText(); - - if (text != null) { - source.method_5505(CommandMessageFormatting.error(text)); - } - - if (e.shouldIncludeUsage()) { - Optional mapping = this.dispatcher.get(argSplit[0], source); - - if (mapping.isPresent()) { - ChatMessage usage; - - if (e instanceof ArgumentParseException.WithUsage) { - usage = ((ArgumentParseException.WithUsage) e).getUsage(); - } else { - usage = mapping.get().getCallable().getUsage(source); - } - - source.method_5505(CommandMessageFormatting.error(ChatMessage.createTextMessage(String.format("Usage: /%s %s", argSplit[0], usage)))); - } - } - } - } catch (Throwable t) { - LOGGER.error("An unexpected error happened executing a command"); - t.printStackTrace(); - - if (t instanceof Error) { - throw (Error) t; - } - - ChatMessage message = CommandMessageFormatting.error(ChatMessage.createTextMessage("An unexpected error happened executing the command")); - // message.setStyle(message.getStyle().setHoverEvent(new HoverEvent(HoverEventAction.SHOW_TEXT, new LiteralText("Stacktrace: \n" + Arrays.stream(t.getStackTrace()).map(StackTraceElement::toString).collect(Collectors.joining("\n")))))); - source.method_5505(message); - } - - return CommandResult.empty(); - } - - @Override - public List getSuggestions(PermissibleCommandSource source, String arguments, @Nullable Location targetPosition) { - try { - final String[] argSplit = arguments.split(" ", 2); - return Lists.newArrayList(this.dispatcher.getSuggestions(source, arguments, targetPosition)); - } catch (CommandException e) { - source.method_5505(CommandMessageFormatting.error(ChatMessage.createTextMessage(String.format("Error getting suggestions: %s", e.getText().toString())))); - return Collections.emptyList(); - } catch (Exception e) { - throw new RuntimeException(String.format("Error occured while tab completing '%s'", arguments), e); - } - } - - @Override - public boolean testPermission(PermissibleCommandSource source) { - synchronized (this.lock) { - return this.dispatcher.testPermission(source); - } - } - - @Override - public Optional getShortDescription(PermissibleCommandSource source) { - synchronized (this.lock) { - return this.dispatcher.getShortDescription(source); - } - } - - @Override - public Optional getHelp(PermissibleCommandSource source) { - synchronized (this.lock) { - return this.dispatcher.getHelp(source); - } - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource source) { - synchronized (this.lock) { - return this.dispatcher.getUsage(source); - } - } - - @Override - public Set getCommands() { - synchronized (this.lock) { - return this.dispatcher.getCommands(); - } - } - - @Override - public Set getPrimaryAliases() { - synchronized (this.lock) { - return this.dispatcher.getPrimaryAliases(); - } - } - - @Override - public Set getAliases() { - synchronized (this.lock) { - return this.dispatcher.getAliases(); - } - } - - @Override - public Optional get(String alias) { - synchronized (this.lock) { - return this.dispatcher.get(alias); - } - } - - @Override - public Optional get(String alias, @Nullable PermissibleCommandSource source) { - synchronized (this.lock) { - return this.dispatcher.get(alias, source); - } - } - - @Override - public Set getAll(String alias) { - synchronized (this.lock) { - return this.dispatcher.getAll(alias); - } - } - - protected List getMappings() { - return this.mappings; - } - - @Override - public Multimap getAll() { - synchronized (this.lock) { - return this.dispatcher.getAll(); - } - } - - @Override - public boolean containsAlias(String alias) { - synchronized (this.lock) { - return this.dispatcher.containsAlias(alias); - } - } - - @Override - public boolean containsMapping(CommandMapping mapping) { - synchronized (this.lock) { - return this.dispatcher.containsMapping(mapping); - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandWrapper.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandWrapper.java deleted file mode 100644 index 26fd98ea3..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/CommandWrapper.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import org.jetbrains.annotations.NotNull; - -import net.minecraft.command.AbstractCommand; -import net.minecraft.command.CommandSource; -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMapping; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandPermissionException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.InvocationCommandException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; -import net.legacyfabric.fabric.api.util.Location; - -public class CommandWrapper extends AbstractCommand { - private final CommandMapping mapping; - - public CommandWrapper(CommandMapping mapping) { - this.mapping = mapping; - } - - @Override - public String getCommandName() { - return this.mapping.getPrimaryAlias(); - } - - @Override - public List getAliases() { - return new ArrayList<>(this.mapping.getAllAliases()); - } - - @Override - public String getUsageTranslationKey(CommandSource source) { - return this.mapping.getCallable().getHelp((PermissibleCommandSource) source).map(ChatMessage::toJson).orElse(""); - } - - @Override - public void execute(CommandSource source, String[] args) { - try { - try { - this.mapping.getCallable().process((PermissibleCommandSource) source, String.join(" ", args)); - } catch (InvocationCommandException e) { - if (e.getCause() != null) { - throw e.getCause(); - } - } catch (CommandPermissionException e) { - if (e.getText() != null) { - source.method_5505(CommandMessageFormatting.error(e.getText())); - } - } catch (CommandException e) { - ChatMessage text = e.getText(); - - if (text != null) { - source.method_5505(CommandMessageFormatting.error(text)); - } - - if (e.shouldIncludeUsage()) { - ChatMessage usage; - - if (e instanceof ArgumentParseException.WithUsage) { - usage = ((ArgumentParseException.WithUsage) e).getUsage(); - } else { - usage = this.mapping.getCallable().getUsage((PermissibleCommandSource) source); - } - - source.method_5505(CommandMessageFormatting.error(ChatMessage.createTextMessage(String.format("Usage: /%s %s", this.getCommandName(), usage)))); - } - } - } catch (Throwable t) { - // Minecraft handles these exceptions for us - throw new RuntimeException(t); - } - } - - @Override - public boolean isAccessible(CommandSource source) { - return this.mapping.getCallable().testPermission((PermissibleCommandSource) source); - } - - @Override - public List method_3276(CommandSource source, String[] args) { - try { - return this.mapping.getCallable().getSuggestions((PermissibleCommandSource) source, Arrays.stream(args).collect(Collectors.joining(" ")), new Location<>(source.getWorld(), source.method_4086())); - } catch (CommandException e) { - source.method_5505(CommandMessageFormatting.error(ChatMessage.createTextMessage(String.format("Error getting suggestions: %s", e.getText().toString())))); - return Collections.emptyList(); - } catch (Exception e) { - throw new RuntimeException(String.format("Error occurred while providing auto complete hints for '%s'", String.join(" ", args)), e); - } - } - - //TODO: Autogenerated stub, make this actually work. - @Override - public int compareTo(@NotNull Object o) { - return 0; - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/ImplInit.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/ImplInit.java deleted file mode 100644 index 8858416fe..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/ImplInit.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command; - -import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.api.DedicatedServerModInitializer; - -import net.legacyfabric.fabric.api.command.v2.CommandRegistrar; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandManager; -import net.legacyfabric.fabric.api.registry.CommandRegistry; - -public class ImplInit implements DedicatedServerModInitializer, ClientModInitializer, CommandRegistrar { - @Override - public void register(CommandManager manager, boolean dedicated) { - CommandRegistrar.EVENT.invoker().register(manager, dedicated); - InternalObjects.getCommandManager().getCommands().forEach(mapping -> { - CommandWrapper wrapper = new CommandWrapper(mapping); - CommandRegistry.INSTANCE.register(wrapper); - }); - } - - @Override - public void onInitializeClient() { - this.register(InternalObjects.getCommandManager(), false); - } - - @Override - public void onInitializeServer() { - this.register(InternalObjects.getCommandManager(), true); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/InternalObjects.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/InternalObjects.java deleted file mode 100644 index aa590d8c4..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/InternalObjects.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.dispatcher.SimpleDispatcher; - -public class InternalObjects { - private static final CommandManagerImpl COMMAND_MANAGER = new CommandManagerImpl(SimpleDispatcher.FIRST_DISAMBIGUATOR); - - public static CommandManagerImpl getCommandManager() { - return COMMAND_MANAGER; - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/AllOfCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/AllOfCommandElement.java deleted file mode 100644 index 6f90c2996..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/AllOfCommandElement.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.Collections; -import java.util.List; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class AllOfCommandElement extends CommandElement { - private final CommandElement element; - - public AllOfCommandElement(CommandElement element) { - super(null); - this.element = element; - } - - @Override - public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { - while (args.hasNext()) { - this.element.parse(source, args, context); - } - } - - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - return null; - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - CommandArgs.Snapshot startState = null; - - try { - while (args.hasNext()) { - startState = args.getSnapshot(); - this.element.parse(src, args, context); - } - } catch (ArgumentParseException e) { - // ignored - } - - // The final element, if an exception was not thrown, might have more completions available to it. - // Therefore, we reapply the last snapshot and complete from it. - if (startState != null) { - args.applySnapshot(startState); - } - - if (args.canComplete()) { - return this.element.complete(src, args, context); - } - - // If we have more elements, do not complete. - return Collections.emptyList(); - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource context) { - return ChatMessage.createTextMessage(this.element.getUsage(context).toString() + CommandMessageFormatting.STAR_TEXT.toString()); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigDecimalElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigDecimalElement.java deleted file mode 100644 index 85fcfe1c3..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigDecimalElement.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.math.BigDecimal; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class BigDecimalElement extends KeyElement { - public BigDecimalElement(ChatMessage key) { - super(key); - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - String next = args.next(); - - try { - return new BigDecimal(next); - } catch (NumberFormatException ex) { - throw args.createError(ChatMessage.createTextMessage("Expected a number, but input " + next + " was not")); - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigIntegerElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigIntegerElement.java deleted file mode 100644 index 44f3208ea..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/BigIntegerElement.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.math.BigInteger; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class BigIntegerElement extends KeyElement { - public BigIntegerElement(ChatMessage key) { - super(key); - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - String integerString = args.next(); - - try { - return new BigInteger(integerString); - } catch (NumberFormatException ex) { - throw args.createError(ChatMessage.createTextMessage("Expected an integer, but input " + integerString + " was not")); - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ChoicesCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ChoicesCommandElement.java deleted file mode 100644 index 347d62295..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ChoicesCommandElement.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; -import net.legacyfabric.fabric.api.util.TriState; - -public class ChoicesCommandElement extends CommandElement { - public static final int CUTOFF = 5; - private final Supplier> keySupplier; - private final Function valueSupplier; - private final TriState choicesInUsage; - - public ChoicesCommandElement(ChatMessage key, Supplier> keySupplier, Function valueSupplier, TriState choicesInUsage) { - super(key); - this.keySupplier = keySupplier; - this.valueSupplier = valueSupplier; - this.choicesInUsage = choicesInUsage; - } - - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - Object value = this.valueSupplier.apply(args.next()); - - if (value == null) { - throw args.createError(ChatMessage.createTextMessage(String.format("Argument was not a valid choice. Valid choices: %s", this.keySupplier.get().toString()))); - } - - return value; - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - final String prefix = args.nextIfPresent().orElse(""); - return Collections.unmodifiableList(this.keySupplier.get().stream().filter((input) -> input.startsWith(prefix)).collect(Collectors.toList())); - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource commander) { - Collection keys = this.keySupplier.get(); - - if (this.choicesInUsage == TriState.TRUE || (this.choicesInUsage == TriState.DEFAULT && keys.size() <= CUTOFF)) { - final ChatMessage build = ChatMessage.createTextMessage(""); - build.addUsing(CommandMessageFormatting.LT_TEXT); - - for (Iterator it = keys.iterator(); it.hasNext(); ) { - build.addUsing(ChatMessage.createTextMessage(it.next())); - - if (it.hasNext()) { - build.addUsing(CommandMessageFormatting.PIPE_TEXT); - } - } - - build.addUsing(CommandMessageFormatting.GT_TEXT); - return ChatMessage.createTextMessage(build.toString()); - } - - return super.getUsage(commander); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DateTimeElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DateTimeElement.java deleted file mode 100644 index a7169d94c..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DateTimeElement.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.format.DateTimeParseException; -import java.util.List; - -import com.google.common.collect.ImmutableList; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class DateTimeElement extends CommandElement { - private final boolean returnNow; - - public DateTimeElement(ChatMessage key, boolean returnNow) { - super(key); - this.returnNow = returnNow; - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - if (!args.hasNext() && this.returnNow) { - return LocalDateTime.now(); - } - - CommandArgs.Snapshot state = args.getSnapshot(); - String date = args.next(); - - try { - return LocalDateTime.parse(date); - } catch (DateTimeParseException ex) { - try { - return LocalDateTime.of(LocalDate.now(), LocalTime.parse(date)); - } catch (DateTimeParseException ex2) { - try { - return LocalDateTime.of(LocalDate.parse(date), LocalTime.MIDNIGHT); - } catch (DateTimeParseException ex3) { - if (this.returnNow) { - args.applySnapshot(state); - return LocalDateTime.now(); - } - - throw args.createError(ChatMessage.createTextMessage("Invalid date-time!")); - } - } - } - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - String date = LocalDateTime.now().withNano(0).toString(); - - if (date.startsWith(args.nextIfPresent().orElse(""))) { - return ImmutableList.of(date); - } else { - return ImmutableList.of(); - } - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource src) { - if (!this.returnNow) { - return super.getUsage(src); - } else { - return ChatMessage.createTextMessage("[" + this.getKey().toString() + "]"); - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DurationElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DurationElement.java deleted file mode 100644 index 45557f8f6..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/DurationElement.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.time.Duration; -import java.time.format.DateTimeParseException; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class DurationElement extends KeyElement { - public DurationElement(ChatMessage key) { - super(key); - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - String s = args.next().toUpperCase(); - - if (!s.contains("T")) { - if (s.contains("D")) { - if (s.contains("H") || s.contains("M") || s.contains("S")) { - s = s.replace("D", "DT"); - } - } else { - if (s.startsWith("P")) { - s = "PT" + s.substring(1); - } else { - s = "T" + s; - } - } - } - - if (!s.startsWith("P")) { - s = "P" + s; - } - - try { - return Duration.parse(s); - } catch (DateTimeParseException ex) { - throw args.createError(ChatMessage.createTextMessage("Invalid duration!")); - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EntityCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EntityCommandElement.java deleted file mode 100644 index 24d71ad11..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EntityCommandElement.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; - -import com.google.common.collect.Sets; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.server.MinecraftServer; -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.SelectorCommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class EntityCommandElement extends SelectorCommandElement { - private final boolean returnTarget; - private final boolean returnSource; - @Nullable - private final Class clazz; - - public EntityCommandElement(ChatMessage key, boolean returnSource, boolean returnTarget, @Nullable Class clazz) { - super(key); - this.returnSource = returnSource; - this.returnTarget = returnTarget; - this.clazz = clazz; - } - - @SuppressWarnings("unchecked") - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - if (!args.hasNext()) { - if (this.returnSource) { - return this.tryReturnSource(source, args, true); - } - - if (this.returnTarget) { - return this.tryReturnTarget(source, args); - } - } - - CommandArgs.Snapshot state = args.getSnapshot(); - - try { - Iterable entities = (Iterable) super.parseValue(source, args); - - for (Entity entity : entities) { - if (!this.checkEntity(entity)) { - ChatMessage name = ChatMessage.createTextMessage(this.clazz == null ? "null" : this.clazz.getSimpleName()); - throw args.createError(ChatMessage.createTextMessage("The entity is not of the required type! (").addUsing(name).addText(")")); - } - } - - return entities; - } catch (ArgumentParseException ex) { - if (this.returnSource) { - args.applySnapshot(state); - return this.tryReturnSource(source, args, true); - } - - throw ex; - } - } - - @Override - protected Iterable getChoices(PermissibleCommandSource source) { - Set worldEntities = (Set) Arrays.stream(MinecraftServer.getServer().worlds).flatMap(world -> world.entities.stream()) - .filter(o -> this.checkEntity((Entity) o)) - .map(entity -> ((Entity) entity).getUuid().toString()).collect(Collectors.toSet()); - Collection players = Sets.newHashSet(MinecraftServer.getServer().getPlayerManager().players); - - if (!players.isEmpty() && this.checkEntity(players.iterator().next())) { - final Set setToReturn = Sets.newHashSet(worldEntities); // to ensure mutability - players.forEach(x -> setToReturn.add(x.getTranslationKey())); - return setToReturn; - } - - return worldEntities; - } - - @Override - protected Object getValue(String choice) throws IllegalArgumentException { - UUID uuid; - - try { - uuid = UUID.fromString(choice); - } catch (IllegalArgumentException ignored) { - // Player could be a name - return Optional.ofNullable(MinecraftServer.getServer().getPlayerManager().getPlayer(choice)).orElseThrow(() -> new IllegalArgumentException("Input value " + choice + " does not represent a valid entity")); - } - - boolean found = false; - Optional ret = Optional.ofNullable((Entity) MinecraftServer.getServer().getWorld().entities.stream() - .filter(o -> ((Entity) o).getUuid().equals(uuid)).findFirst().orElse(null)); - - if (ret.isPresent()) { - Entity entity = ret.get(); - - if (this.checkEntity(entity)) { - return entity; - } - - found = true; - } - - if (found) { - throw new IllegalArgumentException("Input value " + choice + " was not an entity of the required type!"); - } - - throw new IllegalArgumentException("Input value " + choice + " was not an entity"); - } - - private Entity tryReturnSource(PermissibleCommandSource source, CommandArgs args, boolean check) throws ArgumentParseException { - if (source instanceof Entity && (!check || this.checkEntity((Entity) source))) { - return (Entity) source; - } - - throw args.createError(ChatMessage.createTextMessage("No entities matched and source was not an entity!")); - } - - // TODO - private Entity tryReturnTarget(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - Entity entity = this.tryReturnSource(source, args, false); - throw args.createError(ChatMessage.createTextMessage("No entities matched and source was not looking at a valid entity!")); - // return entity.getWorld().getIntersectingEntities(entity, 10).stream().filter(e -> !e.getEntity().equals(entity)).map(EntityUniverse.EntityHit::getEntity).filter(this::checkEntity).findFirst().orElseThrow(() -> args.createError(new LiteralText("No entities matched and source was not looking at a valid entity!"))); - } - - private boolean checkEntity(Entity entity) { - if (this.clazz == null) { - return true; - } else { - return this.clazz.isAssignableFrom(entity.getClass()); - } - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource src) { - return src instanceof Entity && (this.returnSource || this.returnTarget) ? ChatMessage.createTextMessage("[" + this.getKey().toString() + "]") : super.getUsage(src); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EnumValueElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EnumValueElement.java deleted file mode 100644 index 8056677a7..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/EnumValueElement.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.Arrays; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.PatternMatchingCommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class EnumValueElement> extends PatternMatchingCommandElement { - private final Class type; - private final Map values; - - public EnumValueElement(ChatMessage key, Class type) { - super(key); - this.type = type; - this.values = Arrays.stream(type.getEnumConstants()) - .collect(Collectors.toMap(value -> value.name().toLowerCase(), - Function.identity(), (value, value2) -> { - throw new UnsupportedOperationException(type.getCanonicalName() + " contains more than one enum constant " + "with the same name, only differing by capitalization, which is unsupported."); - } - )); - } - - @Override - protected Iterable getChoices(PermissibleCommandSource source) { - return this.values.keySet(); - } - - @Override - protected Object getValue(String choice) throws IllegalArgumentException { - T value = this.values.get(choice.toLowerCase()); - - if (value == null) { - throw new IllegalArgumentException("No enum constant " + this.type.getCanonicalName() + "." + choice); - } - - return value; - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FilteredSuggestionsElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FilteredSuggestionsElement.java deleted file mode 100644 index 11cc5ba78..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FilteredSuggestionsElement.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.Collections; -import java.util.List; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import org.jetbrains.annotations.Nullable; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class FilteredSuggestionsElement extends CommandElement { - private final CommandElement wrapped; - private final Predicate predicate; - - public FilteredSuggestionsElement(CommandElement wrapped, Predicate predicate) { - super(wrapped.getKey()); - this.wrapped = wrapped; - this.predicate = predicate; - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - return this.wrapped.parseValue(source, args); - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - return Collections.unmodifiableList(this.wrapped.complete(src, args, context).stream().filter(this.predicate).collect(Collectors.toList())); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FirstParsingCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FirstParsingCommandElement.java deleted file mode 100644 index 4032395fa..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/FirstParsingCommandElement.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.Iterator; -import java.util.List; -import java.util.stream.Collectors; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class FirstParsingCommandElement extends CommandElement { - private final List elements; - - public FirstParsingCommandElement(List elements) { - super(null); - this.elements = elements; - } - - @Override - public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { - ArgumentParseException lastException = null; - - for (CommandElement element : this.elements) { - CommandArgs.Snapshot startState = args.getSnapshot(); - CommandContext.Snapshot contextSnapshot = context.createSnapshot(); - - try { - element.parse(source, args, context); - return; - } catch (ArgumentParseException ex) { - lastException = ex; - args.applySnapshot(startState); - context.applySnapshot(contextSnapshot); - } - } - - if (lastException != null) { - throw lastException; - } - } - - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - return null; - } - - @Override - public List complete(final PermissibleCommandSource src, final CommandArgs args, final CommandContext context) { - return Lists.newLinkedList(Iterables.concat(this.elements.stream().map(element -> { - if (element == null) { - return ImmutableList.of(); - } else { - CommandArgs.Snapshot snapshot = args.getSnapshot(); - List ret = element.complete(src, args, context); - args.applySnapshot(snapshot); - return ret; - } - }).collect(Collectors.toSet()))); - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource commander) { - final ChatMessage ret = ChatMessage.createTextMessage(""); - - for (Iterator it = this.elements.iterator(); it.hasNext(); ) { - ret.addUsing(it.next().getUsage(commander)); - - if (it.hasNext()) { - ret.addUsing(CommandMessageFormatting.PIPE_TEXT); - } - } - - return ChatMessage.createTextMessage(ret.toString()); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/IpElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/IpElement.java deleted file mode 100644 index 2ff15bd71..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/IpElement.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Objects; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class IpElement extends KeyElement { - private final PlayerCommandElement possiblePlayer; - - public IpElement(ChatMessage key) { - super(key); - this.possiblePlayer = new PlayerCommandElement(key, false); - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - String s = args.next(); - - try { - return InetAddress.getByName(s); - } catch (UnknownHostException e) { - try { - return ((ServerPlayerEntity) Objects.requireNonNull(this.possiblePlayer.parseValue(source, args))).getIp(); - } catch (ArgumentParseException ex) { - throw args.createError(ChatMessage.createTextMessage("Invalid IP address!")); - } - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/LiteralCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/LiteralCommandElement.java deleted file mode 100644 index 60d48b4ef..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/LiteralCommandElement.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.List; -import java.util.Optional; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class LiteralCommandElement extends CommandElement { - private final List expectedArgs; - @Nullable - private final Object putValue; - - public LiteralCommandElement(@Nullable ChatMessage key, List expectedArgs, @Nullable Object putValue) { - super(key); - this.expectedArgs = ImmutableList.copyOf(expectedArgs); - this.putValue = putValue; - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - for (String arg : this.expectedArgs) { - String current; - - if (!(current = args.next()).equalsIgnoreCase(arg)) { - throw args.createError(ChatMessage.createTextMessage(String.format("Argument %s did not match expected next argument %s", current, arg))); - } - } - - return this.putValue; - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - for (String arg : this.expectedArgs) { - final Optional next = args.nextIfPresent(); - - if (!next.isPresent()) { - break; - } else if (args.hasNext()) { - if (!next.get().equalsIgnoreCase(arg)) { - break; - } - } else { - if (arg.toLowerCase().startsWith(next.get().toLowerCase())) { // Case-insensitive compare - return ImmutableList.of(arg); // TODO: Possibly complete all remaining args? Does that even work - } - } - } - - return ImmutableList.of(); - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource src) { - return ChatMessage.createTextMessage(Joiner.on(' ').join(this.expectedArgs)); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/MarkTrueCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/MarkTrueCommandElement.java deleted file mode 100644 index 4cd1d0276..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/MarkTrueCommandElement.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.Collections; -import java.util.List; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class MarkTrueCommandElement extends CommandElement { - public MarkTrueCommandElement(ChatMessage key) { - super(key); - } - - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - return true; - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - return Collections.emptyList(); - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource src) { - return ChatMessage.createTextMessage(""); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ModCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ModCommandElement.java deleted file mode 100644 index fe89e8e4d..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/ModCommandElement.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.Optional; -import java.util.stream.Collectors; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.ModContainer; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.PatternMatchingCommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class ModCommandElement extends PatternMatchingCommandElement { - public ModCommandElement(@Nullable ChatMessage key) { - super(key); - } - - @Override - protected Iterable getChoices(PermissibleCommandSource source) { - return FabricLoader.getInstance().getAllMods().stream().map(container -> container.getMetadata().getId()).collect(Collectors.toSet()); - } - - @Override - protected Object getValue(String choice) throws IllegalArgumentException { - Optional plugin = FabricLoader.getInstance().getModContainer(choice); - return plugin.orElseThrow(() -> new IllegalArgumentException("Mod " + choice + " was not found")); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/NumericElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/NumericElement.java deleted file mode 100644 index f767d5c57..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/NumericElement.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.function.BiFunction; -import java.util.function.Function; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class NumericElement extends KeyElement { - private final Function parseFunc; - @Nullable - private final BiFunction parseRadixFunction; - private final Function errorSupplier; - - public NumericElement(ChatMessage key, Function parseFunc, @Nullable BiFunction parseRadixFunction, Function errorSupplier) { - super(key); - this.parseFunc = parseFunc; - this.parseRadixFunction = parseRadixFunction; - this.errorSupplier = errorSupplier; - } - - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - final String input = args.next(); - - try { - if (this.parseRadixFunction != null) { - if (input.startsWith("0x")) { - return this.parseRadixFunction.apply(input.substring(2), 16); - } else if (input.startsWith("0b")) { - return this.parseRadixFunction.apply(input.substring(2), 2); - } - } - - return this.parseFunc.apply(input); - } catch (NumberFormatException ex) { - throw args.createError(this.errorSupplier.apply(input)); - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OnlyOneCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OnlyOneCommandElement.java deleted file mode 100644 index 1473dc4e4..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OnlyOneCommandElement.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.List; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class OnlyOneCommandElement extends CommandElement { - private final CommandElement element; - - public OnlyOneCommandElement(CommandElement element) { - super(element.getKey()); - this.element = element; - } - - @Override - public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { - this.element.parse(source, args, context); - - if (context.getAll(this.element.getUntranslatedKey()).size() > 1) { - ChatMessage key = this.element.getKey(); - throw args.createError(ChatMessage.createTextMessage(String.format("Argument %s may have only one value!", key != null ? key : "unknown"))); - } - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource src) { - return this.element.getUsage(src); - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - return this.element.parseValue(source, args); - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - return this.element.complete(src, args, context); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OptionalCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OptionalCommandElement.java deleted file mode 100644 index b02c1bf0d..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/OptionalCommandElement.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.List; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class OptionalCommandElement extends CommandElement { - private final CommandElement element; - @Nullable - private final Object value; - private final boolean considerInvalidFormatEmpty; - - public OptionalCommandElement(CommandElement element, @Nullable Object value, boolean considerInvalidFormatEmpty) { - super(null); - this.element = element; - this.value = value; - this.considerInvalidFormatEmpty = considerInvalidFormatEmpty; - } - - @Override - public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { - if (!args.hasNext()) { - ChatMessage key = this.element.getKey(); - - if (key != null && this.value != null) { - context.putArg(key.toString(), this.value); - } - - return; - } - - CommandArgs.Snapshot startState = args.getSnapshot(); - - try { - this.element.parse(source, args, context); - } catch (ArgumentParseException ex) { - if (this.considerInvalidFormatEmpty || args.hasNext()) { // If there are more args, suppress. Otherwise, throw the error - args.applySnapshot(startState); - - if (this.element.getKey() != null && this.value != null) { - context.putArg(this.element.getUntranslatedKey(), this.value); - } - } else { - throw ex; - } - } - } - - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - return args.hasNext() ? null : this.element.parseValue(source, args); - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - return this.element.complete(src, args, context); - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource src) { - final ChatMessage containingUsage = this.element.getUsage(src); - - if (containingUsage.toString().isEmpty()) { - return ChatMessage.createTextMessage(""); - } - - return ChatMessage.createTextMessage("[" + this.element.getUsage(src) + "]"); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PermissionCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PermissionCommandElement.java deleted file mode 100644 index 8c1bb112d..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PermissionCommandElement.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.List; - -import com.google.common.collect.ImmutableList; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class PermissionCommandElement extends CommandElement { - private final CommandElement element; - private final String permission; - private final boolean isOptional; - - public PermissionCommandElement(CommandElement element, String permission, boolean isOptional) { - super(element.getKey()); - this.element = element; - this.permission = permission; - this.isOptional = isOptional; - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - if (this.checkPermission(source, args)) { - return this.element.parseValue(source, args); - } - - return null; - } - - private boolean checkPermission(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - boolean hasPermission = source.hasPermission(this.permission); - - if (!hasPermission && !this.isOptional) { - ChatMessage key = this.getKey(); - throw args.createError(ChatMessage.createTextMessage(String.format("You do not have permission to use the %s argument", key != null ? key : "unknown"))); - } - - return hasPermission; - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - boolean flag = /*src.hasPermission(this.permission)*/ true; - - if (!flag) { - return ImmutableList.of(); - } - - return this.element.complete(src, args, context); - } - - @Override - public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { - if (this.checkPermission(source, args)) { - this.element.parse(source, args, context); - } - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource src) { - if (this.isOptional && !src.hasPermission(this.permission)) { - return ChatMessage.createTextMessage(""); - } - - return this.element.getUsage(src); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PlayerCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PlayerCommandElement.java deleted file mode 100644 index 09012256b..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/PlayerCommandElement.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.Optional; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.server.MinecraftServer; -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.SelectorCommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class PlayerCommandElement extends SelectorCommandElement { - private final boolean returnSource; - - public PlayerCommandElement(ChatMessage key, boolean returnSource) { - super(key); - this.returnSource = returnSource; - } - - @SuppressWarnings("unchecked") - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - if (!args.hasNext() && this.returnSource) { - return this.tryReturnSource(source, args); - } - - CommandArgs.Snapshot state = args.getSnapshot(); - - try { - return StreamSupport.stream(((Iterable) super.parseValue(source, args)).spliterator(), false).filter(e -> e instanceof PlayerEntity).collect(Collectors.toList()); - } catch (ArgumentParseException ex) { - if (this.returnSource) { - args.applySnapshot(state); - return this.tryReturnSource(source, args); - } - - throw ex; - } - } - - @Override - protected Iterable getChoices(PermissibleCommandSource source) { - return (Iterable) MinecraftServer.getServer().getPlayerManager().players.stream().map(player -> ((PlayerEntity) player).getUsername()).collect(Collectors.toSet()); - } - - @Override - protected Object getValue(String choice) throws IllegalArgumentException { - Optional ret = MinecraftServer.getServer().getPlayerManager().players.stream().findFirst().map(Function.identity()); - - if (!ret.isPresent()) { - throw new IllegalArgumentException("Input value " + choice + " was not a player"); - } - - return ret.get(); - } - - private PlayerEntity tryReturnSource(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - if (source instanceof PlayerEntity) { - return ((PlayerEntity) source); - } else { - throw args.createError(ChatMessage.createTextMessage("No players matched and source was not a player!")); - } - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource src) { - return src != null && this.returnSource ? ChatMessage.createTextMessage("[" + super.getUsage(src) + "]") : super.getUsage(src); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RemainingJoinedStringsCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RemainingJoinedStringsCommandElement.java deleted file mode 100644 index b6ad018a1..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RemainingJoinedStringsCommandElement.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class RemainingJoinedStringsCommandElement extends KeyElement { - private final boolean raw; - - public RemainingJoinedStringsCommandElement(ChatMessage key, boolean raw) { - super(key); - this.raw = raw; - } - - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - if (this.raw) { - args.next(); - String ret = args.getRaw().substring(args.getRawPosition()); - - while (args.hasNext()) { // Consume remaining args - args.next(); - } - - return ret; - } - - final StringBuilder ret = new StringBuilder(args.next()); - - while (args.hasNext()) { - ret.append(' ').append(args.next()); - } - - return ret.toString(); - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource src) { - return ChatMessage.createTextMessage("").addText(CommandMessageFormatting.LT_TEXT.toString()).addUsing(this.getKey()).addUsing(CommandMessageFormatting.ELLIPSIS_TEXT).addUsing(CommandMessageFormatting.GT_TEXT); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RepeatedCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RepeatedCommandElement.java deleted file mode 100644 index 2cd715f55..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/RepeatedCommandElement.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.Collections; -import java.util.List; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class RepeatedCommandElement extends CommandElement { - private final CommandElement element; - private final int times; - - public RepeatedCommandElement(CommandElement element, int times) { - super(null); - this.element = element; - this.times = times; - } - - @Override - public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { - for (int i = 0; i < this.times; ++i) { - this.element.parse(source, args, context); - } - } - - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - return null; - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - for (int i = 0; i < this.times; ++i) { - CommandArgs.Snapshot startState = args.getSnapshot(); - - try { - this.element.parse(src, args, context); - } catch (ArgumentParseException e) { - args.applySnapshot(startState); - return this.element.complete(src, args, context); - } - } - - return Collections.emptyList(); - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource src) { - return ChatMessage.createTextMessage(this.times + '*' + this.element.getUsage(src).toString()); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/SequenceCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/SequenceCommandElement.java deleted file mode 100644 index c0b1e2d14..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/SequenceCommandElement.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandMessageFormatting; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class SequenceCommandElement extends CommandElement { - private final List elements; - - public SequenceCommandElement(List elements) { - super(null); - this.elements = elements; - } - - @Override - public void parse(PermissibleCommandSource source, CommandArgs args, CommandContext context) throws ArgumentParseException { - for (CommandElement element : this.elements) { - element.parse(source, args, context); - } - } - - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - return null; - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - Set completions = Sets.newHashSet(); - - for (CommandElement element : this.elements) { - CommandArgs.Snapshot state = args.getSnapshot(); - CommandContext.Snapshot contextSnapshot = context.createSnapshot(); - - try { - element.parse(src, args, context); - - // If we get here, the parse occurred successfully. - // However, if nothing was consumed, then we should consider - // what could have been. - CommandContext.Snapshot afterSnapshot = context.createSnapshot(); - - if (state.equals(args.getSnapshot())) { - context.applySnapshot(contextSnapshot); - completions.addAll(element.complete(src, args, context)); - args.applySnapshot(state); - context.applySnapshot(afterSnapshot); - } else if (args.hasNext()) { - completions.clear(); - } else { - // What we might also have - we have no args left to parse so - // while the parse itself was successful, there could be other - // valid entries to add... - context.applySnapshot(contextSnapshot); - args.applySnapshot(state); - completions.addAll(element.complete(src, args, context)); - - if (!(element instanceof OptionalCommandElement)) { - break; - } - - // The last element was optional, so we go back to before this - // element would have been parsed, and assume it never existed... - context.applySnapshot(contextSnapshot); - args.applySnapshot(state); - } - } catch (ArgumentParseException ignored) { - args.applySnapshot(state); - context.applySnapshot(contextSnapshot); - completions.addAll(element.complete(src, args, context)); - break; - } - } - - return Lists.newArrayList(completions); - } - - @Override - public ChatMessage getUsage(PermissibleCommandSource commander) { - final ChatMessage build = ChatMessage.createTextMessage(""); - - for (Iterator it = this.elements.iterator(); it.hasNext(); ) { - ChatMessage usage = it.next().getUsage(commander); - - if (!usage.toString().isEmpty()) { - build.addUsing(usage); - - if (it.hasNext()) { - build.addUsing(CommandMessageFormatting.SPACE_TEXT); - } - } - } - - return ChatMessage.createTextMessage(build.toString()); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringCommandElement.java deleted file mode 100644 index 398215c95..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringCommandElement.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.StringType; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class StringCommandElement extends KeyElement { - private final StringType stringType; - private final RemainingJoinedStringsCommandElement joinedElement; - - public StringCommandElement(ChatMessage key, StringType type) { - super(key); - this.stringType = type; - this.joinedElement = type.isAll() ? new RemainingJoinedStringsCommandElement(key, false) : null; - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - return this.stringType.isAll() ? (String) this.joinedElement.parseValue(source, args) : args.next(); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringElement.java deleted file mode 100644 index 0e1deba06..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/StringElement.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class StringElement extends KeyElement { - public StringElement(ChatMessage key) { - super(key); - } - - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - return args.next(); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UrlElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UrlElement.java deleted file mode 100644 index 4a0760559..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UrlElement.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.net.MalformedURLException; -import java.net.URISyntaxException; -import java.net.URL; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class UrlElement extends KeyElement { - public UrlElement(ChatMessage key) { - super(key); - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - String str = args.next(); - URL url; - - try { - url = new URL(str); - } catch (MalformedURLException ex) { - throw new ArgumentParseException(ChatMessage.createTextMessage("Invalid URL!"), ex, str, 0); - } - - try { - url.toURI(); - } catch (URISyntaxException ex) { - throw new ArgumentParseException(ChatMessage.createTextMessage("Invalid URL!"), ex, str, 0); - } - - return url; - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UuidElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UuidElement.java deleted file mode 100644 index 71d1ae067..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/UuidElement.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.UUID; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.KeyElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class UuidElement extends KeyElement { - public UuidElement(ChatMessage key) { - super(key); - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - try { - return UUID.fromString(args.next()); - } catch (IllegalArgumentException ex) { - throw args.createError(ChatMessage.createTextMessage("Invalid UUID!")); - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/Vec3dCommandElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/Vec3dCommandElement.java deleted file mode 100644 index a56fa770f..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/Vec3dCommandElement.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.text.ChatMessage; -import net.minecraft.util.math.Vec3d; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -/** - * A {@link Vec3d} command element. - * - *

It has the following syntax:

- * - *
 x,y,z
- * x y z.
- * - *

Each element can be relative to a location? so - * parseRelativeDouble() -- relative is ~(num)

- */ -public class Vec3dCommandElement extends CommandElement { - private static final ImmutableSet SPECIAL_TOKENS = ImmutableSet.of("#target", "#me"); - - public Vec3dCommandElement(@Nullable ChatMessage key) { - super(key); - } - - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - String xStr; - String yStr; - String zStr; - xStr = args.next(); - - if (xStr.contains(",")) { - String[] split = xStr.split(","); - - if (split.length != 3) { - throw args.createError(ChatMessage.createTextMessage(String.format("Comma-separated location must have 3 elements, not %s", split.length))); - } - - xStr = split[0]; - yStr = split[1]; - zStr = split[2]; - } else if (xStr.equalsIgnoreCase("#me")) { - return source.method_4086(); - } else { - yStr = args.next(); - zStr = args.next(); - } - - double x = this.parseRelativeDouble(args, xStr, (double) source.method_4086().x); - double y = this.parseRelativeDouble(args, yStr, (double) source.method_4086().y); - double z = this.parseRelativeDouble(args, zStr, (double) source.method_4086().z); - return Vec3d.method_604(x, y, z); - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - Optional arg = args.nextIfPresent(); - - // Traverse through the possible arguments. We can't really complete arbitrary integers - if (arg.isPresent()) { - if (arg.get().startsWith("#")) { - Optional finalArg = arg; - return Collections.unmodifiableList(SPECIAL_TOKENS.stream().filter((input) -> input.startsWith(finalArg.get())).collect(Collectors.toList())); - } else if (arg.get().contains(",") || !args.hasNext()) { - return ImmutableList.of(arg.get()); - } else { - arg = args.nextIfPresent(); - - if (args.hasNext()) { - return ImmutableList.of(args.nextIfPresent().get()); - } - - return ImmutableList.of(arg.get()); - } - } - - return ImmutableList.of(); - } - - private double parseRelativeDouble(CommandArgs args, String arg, @Nullable Double relativeTo) throws ArgumentParseException { - boolean relative = arg.startsWith("~"); - - if (relative) { - if (relativeTo == null) { - throw args.createError(ChatMessage.createTextMessage("Relative position specified but source does not have a position")); - } - - arg = arg.substring(1); - - if (arg.isEmpty()) { - return relativeTo; - } - } - - try { - double ret = Double.parseDouble(arg); - return relative ? ret + relativeTo : ret; - } catch (NumberFormatException e) { - throw args.createError(ChatMessage.createTextMessage(String.format("Expected input %s to be a double, but was not", arg))); - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/WithSuggestionsElement.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/WithSuggestionsElement.java deleted file mode 100644 index 7996b6e4b..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/impl/command/lib/sponge/args/WithSuggestionsElement.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.impl.command.lib.sponge.args; - -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -import com.google.common.collect.ImmutableList; -import org.jetbrains.annotations.Nullable; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.ArgumentParseException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandArgs; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandElement; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class WithSuggestionsElement extends CommandElement { - private final CommandElement wrapped; - private final Function> suggestions; - private final boolean requireBegin; - - public WithSuggestionsElement(CommandElement wrapped, Function> suggestions, boolean requireBegin) { - super(wrapped.getKey()); - this.wrapped = wrapped; - this.suggestions = suggestions; - this.requireBegin = requireBegin; - } - - @Nullable - @Override - public Object parseValue(PermissibleCommandSource source, CommandArgs args) throws ArgumentParseException { - return this.wrapped.parseValue(source, args); - } - - @Override - public List complete(PermissibleCommandSource src, CommandArgs args, CommandContext context) { - if (this.requireBegin) { - String arg = args.nextIfPresent().orElse(""); - return ImmutableList.copyOf(StreamSupport.stream(this.suggestions.apply(src).spliterator(), false).filter(f -> f.startsWith(arg)).collect(Collectors.toList())); - } else { - return ImmutableList.copyOf(this.suggestions.apply(src)); - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/ChatMessageAccessor.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/ChatMessageAccessor.java deleted file mode 100644 index 0d7b3a72c..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/ChatMessageAccessor.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.mixin.command; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -import net.minecraft.text.ChatMessage; - -@Mixin(ChatMessage.class) -public interface ChatMessageAccessor { - @Invoker("getTranslate") - String getTranslationKey(); -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/MinecraftServerMixin.java b/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/MinecraftServerMixin.java deleted file mode 100644 index 397b46b4c..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/java/net/legacyfabric/fabric/mixin/command/MinecraftServerMixin.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.mixin.command; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.server.MinecraftServer; - -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -@Mixin(MinecraftServer.class) -public abstract class MinecraftServerMixin implements PermissibleCommandSource { - @Shadow - public abstract boolean isDedicated(); - - @Override - public boolean hasPermission(String perm) { - return true; - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/resources/assets/legacy-fabric-sponge-command-api-v2/icon.png b/legacy-fabric-command-api-v2/1.6.4/src/main/resources/assets/legacy-fabric-sponge-command-api-v2/icon.png deleted file mode 100644 index 2931efbf610873c0084debb8690902b0103d27fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1579 zcmbVMTWB0r7@iGm)TAXsYw<=rnU=;v=W=GRbL=!tc4Brl6GO7t2vVJ$IlDV#XU;e? z+r2ymsZdMQqAyaFLLUo;RumtE8Z@?uf_*4nP^4;o6fOFoSkN+o1$K?f2nE9_*b5G-l)AV)k5Qhb^- zU{V4ZnTKgnmXdpcB*Kg!W(1hvM2N&RO30x1u~eI9meGQGe@_?PDQq%q1CiV$8~M7 z?MQ_mOdqCh^a65Sv|ntwSXjV5se1;VK1|Kr8G7TQoQL&*ctt{L{fClG}xPK5k^yK3%T69N6J=>3jBqc zDNvZsrJ-yOXI^^mWf1cmY^XST)CVzIGjvEPENowmy}ax zvJ8_(Cf#+H-dBlH53`_u-~6BVAMz|(g?jCVdBWNZ(+A}(pFV7>S3QgPiQcMaflkIC z-3Ti|VT~{au*vq0ts9O&m$p&Gl=L6+q6_m$IcVq}o~+Pl{g>1esQp4%wp~|*zk1n` zZ7T6Toc4`y88s}riCP|ZXrJ?FLz@^KTcyqLjey zu95Yz%F&S{<0~f)Iomek?+hQ%MhCu%T^zsg>C_L`1`Br`xNY&))k9yTQb$JC>)w_f zpU(^tu^Q)y%W~lVz`jz;_ jF?g&s@Y=Qe&c#kW|JbvqK0Y=Rw)4XDoVqsk_>;c_`@;F@ diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/resources/fabric.mod.json b/legacy-fabric-command-api-v2/1.6.4/src/main/resources/fabric.mod.json deleted file mode 100644 index 5ff821a2a..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "schemaVersion": 1, - "id": "legacy-fabric-command-api-v2", - "name": "Legacy Fabric Command API (v2)", - "version": "${version}", - "environment": "*", - "license": "Apache-2.0", - "icon": "assets/legacy-fabric-sponge-command-api-v2/icon.png", - "contact": { - "homepage": "https://legacyfabric.net", - "irc": "irc://irc.esper.net:6667/legacyfabric", - "issues": "https://github.com/Legacy-Fabric/fabric/issues", - "sources": "https://github.com/Legacy-Fabric/fabric" - }, - "authors": [ - "Legacy-Fabric" - ], - "depends": { - "fabricloader": ">=0.4.0", - "minecraft": "${minecraft_version}" - }, - "entrypoints": { - "client": [ - "net.legacyfabric.fabric.impl.command.ImplInit" - ], - "server": [ - "net.legacyfabric.fabric.impl.command.ImplInit" - ] - }, - "description": "Powerful Command API that uses SpongeAPI's command api", - "mixins": [ - "legacy-fabric-sponge-command-api-v2.mixins.json" - ], - "custom": { - "modmenu": { - "badges": [ "library" ], - "parent": { - "id": "legacy-fabric-api", - "name": "Legacy Fabric API", - "badges": [ "library" ], - "description": "Core API module providing key hooks and inter-compatibility features for Minecraft 1.7.10-1.12.2.", - "icon": "assets/legacy-fabric-sponge-command-api-v2/icon.png" - } - } - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/main/resources/legacy-fabric-sponge-command-api-v2.mixins.json b/legacy-fabric-command-api-v2/1.6.4/src/main/resources/legacy-fabric-sponge-command-api-v2.mixins.json deleted file mode 100644 index 6d0b44d07..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/main/resources/legacy-fabric-sponge-command-api-v2.mixins.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "required": true, - "package": "net.legacyfabric.fabric.mixin.command", - "compatibilityLevel": "JAVA_8", - "mixins": [ - "ChatMessageAccessor", - "MinecraftServerMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommand.java b/legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommand.java deleted file mode 100644 index 293cb137c..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/ModMetadataCommand.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.test.command; - -import net.minecraft.text.ChatMessage; - -import net.fabricmc.loader.api.ModContainer; -import net.fabricmc.loader.api.metadata.ContactInformation; - -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandException; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandManager; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.CommandResult; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.CommandContext; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.args.GenericArguments; -import net.legacyfabric.fabric.api.command.v2.lib.sponge.spec.CommandSpec; -import net.legacyfabric.fabric.api.permission.v1.PermissibleCommandSource; - -public class ModMetadataCommand { - public static void register(CommandManager manager) { - manager.register( - CommandSpec.builder() - .arguments(GenericArguments.mod(ChatMessage.createTextMessage("modid"))) - .executor(ModMetadataCommand::execute) - .build(), - "modmetadata" - ); - } - - private static CommandResult execute(PermissibleCommandSource source, CommandContext ctx) throws CommandException { - ModContainer container = ctx.getOne("modid").orElseThrow(() -> new CommandException(ChatMessage.createTextMessage("mod not found"))); - ChatMessage builder = ChatMessage.createTextMessage(""); - - builder.addText("Mod Name: ".concat(container.getMetadata().getName()).concat("\n")); - builder.addText("Description: ".concat(container.getMetadata().getDescription()).concat("\n")); - ContactInformation contact = container.getMetadata().getContact(); - - if (contact.get("issues").isPresent()) { - ChatMessage issueText = ChatMessage.createTextMessage(""); - issueText.addText("Issues: "); - ChatMessage issueUrl = ChatMessage.createTextMessage(contact.get("issues").get()); - issueText.addUsing(issueUrl); - issueText.addText("\n"); - builder.addUsing(issueText); - } - - if (contact.get("sources").isPresent()) { - ChatMessage sourcesText = ChatMessage.createTextMessage(""); - sourcesText.addText("Sources: "); - ChatMessage sourcesUrl = ChatMessage.createTextMessage(contact.get("sources").get()); - sourcesText.addUsing(sourcesUrl); - sourcesText.addText("\n"); - builder.addUsing(sourcesText); - } - - builder.addText("Metadata Type: ".concat(container.getMetadata().getType()).concat("\n")); - source.method_5505(builder); - return CommandResult.success(); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/SpongeCommandTest.java b/legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/SpongeCommandTest.java deleted file mode 100644 index af1a6c161..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/testmod/java/net/legacyfabric/fabric/test/command/SpongeCommandTest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 Legacy Fabric - * Copyright (c) 2016 - 2022 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.legacyfabric.fabric.test.command; - -import net.fabricmc.api.ModInitializer; - -import net.legacyfabric.fabric.api.command.v2.CommandRegistrar; - -public class SpongeCommandTest implements ModInitializer { - @Override - public void onInitialize() { - CommandRegistrar.EVENT.register((manager, dedicated) -> { - ModMetadataCommand.register(manager); - }); - } -} diff --git a/legacy-fabric-command-api-v2/1.6.4/src/testmod/resources/fabric.mod.json b/legacy-fabric-command-api-v2/1.6.4/src/testmod/resources/fabric.mod.json deleted file mode 100644 index b8b0d6131..000000000 --- a/legacy-fabric-command-api-v2/1.6.4/src/testmod/resources/fabric.mod.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "schemaVersion": 1, - "id": "legacy-fabric-sponge-command-api-v2-testmod", - "description": "Tests for api features", - "version": "1.0.0", - "entrypoints": { - "main": [ - "net.legacyfabric.fabric.test.command.SpongeCommandTest" - ] - }, - "depends": { - "minecraft": "${minecraft_version}" - } -} From 3c1a0717a5ade51bc0175e0bb4f0db299572ca61 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Thu, 9 May 2024 15:42:13 +0200 Subject: [PATCH 21/24] Bump modules versions --- gradle.properties | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gradle.properties b/gradle.properties index 81e82aade..b3706e1d6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,17 +7,17 @@ yarn_mappings_build = 530 ## Module versions legacy-fabric-api-base.version = 1.1.0 -legacy-fabric-command-api-v1.version = 1.0.0 -legacy-fabric-command-api-v2.version = 1.0.1 +legacy-fabric-command-api-v1.version = 1.0.1 +legacy-fabric-command-api-v2.version = 1.0.2 legacy-fabric-crash-report-info-v1.version = 1.0.0 legacy-fabric-entity-events-v1.version = 1.0.0 legacy-fabric-gamerule-api-v1.version = 1.0.0 -legacy-fabric-item-groups-v1.version = 2.0.0 -legacy-fabric-keybindings-api-v1.version = 1.0.1 -legacy-fabric-lifecycle-events-v1.version = 1.0.1 +legacy-fabric-item-groups-v1.version = 2.1.0 +legacy-fabric-keybindings-api-v1.version = 1.0.2 +legacy-fabric-lifecycle-events-v1.version = 1.1.0 legacy-fabric-logger-api-v1.version = 1.0.4 -legacy-fabric-networking-api-v1.version = 2.0.1 -legacy-fabric-permissions-api-v1.version = 1.0.1 +legacy-fabric-networking-api-v1.version = 2.0.2 +legacy-fabric-permissions-api-v1.version = 1.1.0 legacy-fabric-registry-sync-api-v1.version = 2.2.0 legacy-fabric-rendering-api-v1.version = 1.0.0 -legacy-fabric-resource-loader-v1.version = 2.1.1 +legacy-fabric-resource-loader-v1.version = 2.2.0 From df20342a50fe36e4275d40817b7ad18b4f001b30 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Thu, 9 May 2024 15:45:01 +0200 Subject: [PATCH 22/24] Update README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e7a2f5fc2..d0d13d639 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ Fabric API is the library for essential hooks and interoperability mechanisms fo For support, consider joining the [Legacy Fabric discord server](https://legacyfabric.net/discord) or opening an issue. ## Modules available and tested by minecraft version -✅ = Working as expected\ +✅ = Working as expected.\ ⚠ = Working but has some issues.\ -? = Not sure if it was tested or working correctly\ -❌ = Not working at all, likely crashing +? = Not tested, might not work as intended.\ +❌ = Not ported or probably not working. | | 1.6.4 | 1.7.10 | 1.8 | 1.8.9 | 1.9.4 | 1.10.2 | 1.11.2 | 1.12.2 | 1.13.2 | |----------------------|-------------------------------|--------|-----|-------|-------|--------|--------|--------|--------| From 3ccda76ff49ab49add735dbc7cfdcb6e11d7b212 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Thu, 9 May 2024 15:57:48 +0200 Subject: [PATCH 23/24] Update mod description --- legacyfabric-api/1.6.4/src/main/resources/fabric.mod.json | 2 +- src/main/resources/fabric.mod.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/legacyfabric-api/1.6.4/src/main/resources/fabric.mod.json b/legacyfabric-api/1.6.4/src/main/resources/fabric.mod.json index 676b475e1..95213e984 100644 --- a/legacyfabric-api/1.6.4/src/main/resources/fabric.mod.json +++ b/legacyfabric-api/1.6.4/src/main/resources/fabric.mod.json @@ -31,7 +31,7 @@ } } ], - "description": "Core API module providing key hooks and inter-compatibility features for Minecraft 1.7.10-1.12.2.", + "description": "Core API module providing key hooks and inter-compatibility features for Minecraft 1.6.4-1.12.2.", "depends": { "minecraft": "${minecraft_version}" }, diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 74afb3a70..5190561ab 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -31,5 +31,5 @@ } } ], - "description": "Core API module providing key hooks and inter-compatibility features for Minecraft 1.7.10-1.12.2." + "description": "Core API module providing key hooks and inter-compatibility features for Minecraft 1.6.4-1.12.2." } From 2ce7a52a28bcb564537fccd68a4bd14604bde1c7 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Thu, 27 Jun 2024 20:27:16 +0200 Subject: [PATCH 24/24] Clean up unnecessary code in permission-api-v1 --- .../fabric/impl/permission/PermissionImpl.java | 18 +----------------- .../fabric/impl/permission/PermissionImpl.java | 18 +----------------- 2 files changed, 2 insertions(+), 34 deletions(-) diff --git a/legacy-fabric-permissions-api-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java b/legacy-fabric-permissions-api-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java index 13e91de82..af30c8179 100644 --- a/legacy-fabric-permissions-api-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java +++ b/legacy-fabric-permissions-api-v1/1.6.4/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java @@ -17,13 +17,9 @@ package net.legacyfabric.fabric.impl.permission; -import net.minecraft.client.MinecraftClient; import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.server.MinecraftServer; -import net.fabricmc.api.EnvType; import net.fabricmc.api.ModInitializer; -import net.fabricmc.loader.api.FabricLoader; import net.legacyfabric.fabric.api.permission.v1.PermissionsApiHolder; import net.legacyfabric.fabric.api.permission.v1.PlayerPermissionsApi; @@ -44,19 +40,7 @@ public String getId() { @Override public boolean hasPermission(ServerPlayerEntity player, String perm) { - return getServer().getPlayerManager().canCheat(player.getUsername()); - } - } - - protected static MinecraftServer getServer() { - try { - return MinecraftServer.getServer(); - } catch (NoSuchMethodError e) { - if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) { - return MinecraftClient.getInstance().getServer(); - } else { - return (MinecraftServer) FabricLoader.getInstance().getGameInstance(); - } + return player.server.getPlayerManager().canCheat(player.getUsername()); } } } diff --git a/legacy-fabric-permissions-api-v1/1.8.9/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java b/legacy-fabric-permissions-api-v1/1.8.9/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java index 6d1861698..a9f2f0a59 100644 --- a/legacy-fabric-permissions-api-v1/1.8.9/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java +++ b/legacy-fabric-permissions-api-v1/1.8.9/src/main/java/net/legacyfabric/fabric/impl/permission/PermissionImpl.java @@ -17,13 +17,9 @@ package net.legacyfabric.fabric.impl.permission; -import net.minecraft.client.MinecraftClient; import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.server.MinecraftServer; -import net.fabricmc.api.EnvType; import net.fabricmc.api.ModInitializer; -import net.fabricmc.loader.api.FabricLoader; import net.legacyfabric.fabric.api.permission.v1.PermissionsApiHolder; import net.legacyfabric.fabric.api.permission.v1.PlayerPermissionsApi; @@ -44,19 +40,7 @@ public String getId() { @Override public boolean hasPermission(ServerPlayerEntity player, String perm) { - return getServer().getPlayerManager().isOperator(player.getGameProfile()); - } - } - - protected static MinecraftServer getServer() { - try { - return MinecraftServer.getServer(); - } catch (NoSuchMethodError e) { - if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) { - return MinecraftClient.getInstance().getServer(); - } else { - return (MinecraftServer) FabricLoader.getInstance().getGameInstance(); - } + return player.server.getPlayerManager().isOperator(player.getGameProfile()); } } }