From ff87faacc0577f025ed096ff0b1b655ed8cafdfd Mon Sep 17 00:00:00 2001 From: Anselm Brehme Date: Fri, 9 Oct 2020 12:51:24 +0200 Subject: [PATCH] Implement Advancements --- SpongeAPI | 2 +- .../advancements/AdvancementListMixin.java | 104 ------ .../core/advancements/AdvancementMixin.java | 274 -------------- .../spongepowered/common/SpongeLifecycle.java | 4 + .../advancement/SpongeAdvancementBuilder.java | 50 +-- .../SpongeAdvancementProvider.java | 83 +++++ .../advancement/SpongeAdvancementTree.java | 70 ---- .../SpongeAdvancementTreeBuilder.java | 99 ----- .../advancement/SpongeFilteredTrigger.java | 23 ++ .../common/advancement/SpongeTreeLayout.java | 27 +- .../AbstractCriterionBuilder.java | 2 +- .../DefaultedAdvancementCriterion.java | 2 +- ...ImplementationBackedCriterionProgress.java | 2 +- .../{ => criterion}/SpongeAndCriterion.java | 17 +- .../SpongeAndCriterionProgress.java | 2 +- .../SpongeCriterionBuilder.java | 8 +- .../SpongeCriterionHelper.java | 65 +++- .../criterion/SpongeDummyTrigger.java | 70 ++++ .../{ => criterion}/SpongeEmptyCriterion.java | 2 +- .../SpongeOperatorCriterion.java | 27 +- .../SpongeOperatorCriterionProgress.java | 2 +- .../{ => criterion}/SpongeOrCriterion.java | 17 +- .../SpongeOrCriterionProgress.java | 4 +- .../{ => criterion}/SpongeScoreCriterion.java | 36 +- .../SpongeScoreCriterionBuilder.java | 2 +- .../SpongeScoreCriterionProgress.java | 2 +- .../criterion/SpongeScoreTrigger.java | 77 ++++ .../advancements/AdvancementBridge.java | 12 - .../AdvancementProgressBridge.java | 8 +- .../bridge/advancements/CriterionBridge.java | 6 +- .../advancements/CriterionProgressBridge.java | 2 + .../common/event/SpongeEventManager.java | 2 +- .../item/recipe/SpongeRecipeProvider.java | 18 +- .../common/registry/CallbackRegistry.java | 2 +- .../registry/SpongeBuilderRegistry.java | 11 +- .../registry/SpongeCatalogRegistry.java | 12 +- .../registry/SpongeFactoryRegistry.java | 6 + .../sponge/CriteriaTriggersRegistrar.java | 18 +- .../SpongeAdvancementCriterionFactory.java | 4 +- .../advancements/AdvancementMixin_API.java | 31 +- .../AdvancementProgressMixin_API.java | 10 +- .../mcp/advancements/CriterionMixin_API.java | 2 +- .../CriterionProgressMixin_API.java | 21 +- .../advancements/DisplayInfoMixin_API.java | 17 + .../EntitySelectorParserMixin_API.java | 2 +- .../player/ServerPlayerEntityMixin_API.java | 1 - .../advancements/AdvancementBuilderMixin.java | 25 +- .../core/advancements/AdvancementMixin.java | 185 ++++++++++ .../AdvancementProgressMixin.java | 91 ++--- .../AdvancementTreeNodeMixin.java | 12 +- .../core/advancements/CriterionMixin.java | 34 +- .../advancements/CriterionProgressMixin.java | 25 +- .../core/advancements/DisplayInfoMixin.java | 2 +- .../ICriterionTrigger_ListenerMixin.java | 13 +- .../advancements/PlayerAdvancementsMixin.java | 38 +- .../core/server/MinecraftServerMixin.java | 3 + src/mixins/resources/mixins.common.api.json | 2 + src/mixins/resources/mixins.common.core.json | 9 + .../test/advancement/AdvancementTest.java | 341 ++++++++++++++++++ .../src/main/resources/META-INF/plugins.json | 25 +- 60 files changed, 1280 insertions(+), 783 deletions(-) delete mode 100644 invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/AdvancementListMixin.java delete mode 100644 invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/AdvancementMixin.java rename {invalid => src}/main/java/org/spongepowered/common/advancement/SpongeAdvancementBuilder.java (75%) create mode 100644 src/main/java/org/spongepowered/common/advancement/SpongeAdvancementProvider.java delete mode 100644 src/main/java/org/spongepowered/common/advancement/SpongeAdvancementTree.java delete mode 100644 src/main/java/org/spongepowered/common/advancement/SpongeAdvancementTreeBuilder.java rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/AbstractCriterionBuilder.java (97%) rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/DefaultedAdvancementCriterion.java (97%) rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/ImplementationBackedCriterionProgress.java (96%) rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/SpongeAndCriterion.java (72%) rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/SpongeAndCriterionProgress.java (97%) rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/SpongeCriterionBuilder.java (86%) rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/SpongeCriterionHelper.java (53%) create mode 100644 src/main/java/org/spongepowered/common/advancement/criterion/SpongeDummyTrigger.java rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/SpongeEmptyCriterion.java (96%) rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/SpongeOperatorCriterion.java (85%) rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/SpongeOperatorCriterionProgress.java (98%) rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/SpongeOrCriterion.java (73%) rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/SpongeOrCriterionProgress.java (92%) rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/SpongeScoreCriterion.java (72%) rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/SpongeScoreCriterionBuilder.java (97%) rename src/main/java/org/spongepowered/common/advancement/{ => criterion}/SpongeScoreCriterionProgress.java (99%) create mode 100644 src/main/java/org/spongepowered/common/advancement/criterion/SpongeScoreTrigger.java rename {invalid/main => src/mixins}/java/org/spongepowered/common/mixin/api/mcp/advancements/CriterionProgressMixin_API.java (74%) rename invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/CriteriaTriggersMixin.java => src/mixins/java/org/spongepowered/common/mixin/core/advancements/AdvancementBuilderMixin.java (59%) create mode 100644 src/mixins/java/org/spongepowered/common/mixin/core/advancements/AdvancementMixin.java rename {invalid/main/java/org/spongepowered/common/mixin/invalid => src/mixins/java/org/spongepowered/common/mixin}/core/advancements/AdvancementProgressMixin.java (78%) rename {invalid/main/java/org/spongepowered/common/mixin/invalid => src/mixins/java/org/spongepowered/common/mixin}/core/advancements/AdvancementTreeNodeMixin.java (80%) rename {invalid/main/java/org/spongepowered/common/mixin/invalid => src/mixins/java/org/spongepowered/common/mixin}/core/advancements/CriterionMixin.java (70%) rename {invalid/main/java/org/spongepowered/common/mixin/invalid => src/mixins/java/org/spongepowered/common/mixin}/core/advancements/CriterionProgressMixin.java (81%) rename {invalid/main/java/org/spongepowered/common/mixin/invalid => src/mixins/java/org/spongepowered/common/mixin}/core/advancements/DisplayInfoMixin.java (97%) rename {invalid/main/java/org/spongepowered/common/mixin/invalid => src/mixins/java/org/spongepowered/common/mixin}/core/advancements/ICriterionTrigger_ListenerMixin.java (91%) rename {invalid/main/java/org/spongepowered/common/mixin/invalid => src/mixins/java/org/spongepowered/common/mixin}/core/advancements/PlayerAdvancementsMixin.java (88%) create mode 100644 testplugins/src/main/java/org/spongepowered/test/advancement/AdvancementTest.java diff --git a/SpongeAPI b/SpongeAPI index 259bd76aee8..54e6102bd59 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit 259bd76aee8fd1e09f7db6448e7183bbe5c421b5 +Subproject commit 54e6102bd59867aede06552dcc3b27c782a3a077 diff --git a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/AdvancementListMixin.java b/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/AdvancementListMixin.java deleted file mode 100644 index dbd2017458c..00000000000 --- a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/AdvancementListMixin.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.mixin.invalid.core.advancements; - -import net.minecraft.advancements.Advancement; -import net.minecraft.advancements.AdvancementList; -import net.minecraft.util.ResourceLocation; -import org.apache.logging.log4j.Logger; -import org.spongepowered.api.Sponge; -import org.spongepowered.api.advancement.AdvancementTree; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -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.common.SpongeCommon; -import org.spongepowered.common.SpongeImplHooks; -import org.spongepowered.common.event.registry.SpongeGameRegistryRegisterEvent; -import org.spongepowered.common.event.tracking.PhaseTracker; -import org.spongepowered.common.event.tracking.phase.plugin.EventListenerPhaseContext; -import org.spongepowered.common.event.tracking.phase.plugin.PluginPhase; -import org.spongepowered.common.registry.type.advancement.AdvancementMap; -import org.spongepowered.common.registry.type.advancement.AdvancementRegistryModule; -import org.spongepowered.common.registry.type.advancement.AdvancementTreeRegistryModule; -import org.spongepowered.common.registry.type.advancement.RootAdvancementSet; - -import java.util.Map; -import java.util.Set; - -@Mixin(AdvancementList.class) -public abstract class AdvancementListMixin { - - @Shadow @Final private static Logger LOGGER; - - @Shadow @Final @Mutable private Map advancements = new AdvancementMap(); - @Shadow @Final @Mutable private Set roots = new RootAdvancementSet(); - - @Inject(method = "loadAdvancements", at = @At(value = "INVOKE", shift = At.Shift.BEFORE, - target = "Ljava/util/Map;size()I", remap = false)) - private void impl$postRegisterAdvancements(Map advancements, CallbackInfo ci) { - // Don't post events when loading advancements on the client - if (!SpongeImplHooks.onServerThread()) { - return; - } - try (final EventListenerPhaseContext context = PluginPhase.Listener.GENERAL_LISTENER.createPhaseContext(PhaseTracker.SERVER) - .source(Sponge.getGame())) { - context.buildAndSwitch(); - - PhaseTracker.getCauseStackManager().pushCause(SpongeCommon.getRegistry()); - final SpongeGameRegistryRegisterEvent event = - new SpongeGameRegistryRegisterEvent<>( - PhaseTracker.getCauseStackManager().getCurrentCause(), - org.spongepowered.api.advancement.Advancement.class, AdvancementRegistryModule.getInstance()); - context.event(event); - SpongeCommon.postEvent(event); - } - } - - @Inject(method = "loadAdvancements", at = @At(value = "RETURN")) - private void impl$postRegisterTreeEvent(Map advancements, CallbackInfo ci) { - // Don't post events when loading advancements on the client - if (!SpongeImplHooks.onServerThread()) { - return; - } - try (final EventListenerPhaseContext context = PluginPhase.Listener.GENERAL_LISTENER.createPhaseContext(PhaseTracker.SERVER) - .source(Sponge.getGame())) { - context.buildAndSwitch(); - - PhaseTracker.getCauseStackManager().pushCause(SpongeCommon.getRegistry()); - final SpongeGameRegistryRegisterEvent event = - new SpongeGameRegistryRegisterEvent<>( - PhaseTracker.getCauseStackManager().getCurrentCause(), - AdvancementTree.class, AdvancementTreeRegistryModule.getInstance()); - context.event(event); - SpongeCommon.postEvent(event); - } - LOGGER.info("Loaded " + this.roots.size() + " advancement trees"); - } - -} diff --git a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/AdvancementMixin.java b/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/AdvancementMixin.java deleted file mode 100644 index 81c1cb6a369..00000000000 --- a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/AdvancementMixin.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.mixin.invalid.core.advancements; - -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import net.minecraft.advancements.Advancement; -import net.minecraft.advancements.AdvancementRewards; -import net.minecraft.advancements.Criterion; -import net.minecraft.advancements.DisplayInfo; -import net.minecraft.advancements.FrameType; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.text.ITextComponent; -import org.spongepowered.api.ResourceKey; -import org.spongepowered.api.CatalogType; -import org.spongepowered.api.advancement.AdvancementTree; -import org.spongepowered.api.advancement.AdvancementType; -import org.spongepowered.api.advancement.criteria.AdvancementCriterion; -import org.spongepowered.api.advancement.criteria.AndCriterion; -import org.spongepowered.api.advancement.criteria.OrCriterion; -import org.spongepowered.api.text.Text; -import org.spongepowered.api.text.translation.FixedTranslation; -import org.spongepowered.api.text.translation.Translation; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -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.common.SpongeImplHooks; -import org.spongepowered.common.advancement.DefaultedAdvancementCriterion; -import org.spongepowered.common.advancement.SpongeAdvancementTree; -import org.spongepowered.common.advancement.SpongeScoreCriterion; -import org.spongepowered.common.bridge.advancements.AdvancementBridge; -import org.spongepowered.common.bridge.advancements.CriterionBridge; -import org.spongepowered.common.bridge.advancements.DisplayInfoBridge; -import org.spongepowered.common.bridge.util.text.TextComponentBridge; -import org.spongepowered.common.event.tracking.PhaseTracker; -import org.spongepowered.common.event.tracking.phase.plugin.ListenerPhaseContext; -import org.spongepowered.common.registry.type.advancement.AdvancementRegistryModule; -import org.spongepowered.common.registry.type.advancement.AdvancementTreeRegistryModule; -import org.spongepowered.common.text.SpongeTexts; -import org.spongepowered.common.text.translation.SpongeTranslation; - -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -@Mixin(Advancement.class) -public abstract class AdvancementMixin implements AdvancementBridge { - - @Shadow @Final @Mutable @Nullable private Advancement parent; - @Shadow @Final @Mutable private String[][] requirements; - @Shadow @Final @Mutable private Map criteria; - @Shadow @Final @Nullable private DisplayInfo display; - @Shadow @Final private ITextComponent displayText; - - private ResourceKey impl$key; - private AdvancementCriterion impl$criterion; - @Nullable private AdvancementTree impl$tree; - private List impl$toastText; - private Text impl$text; - private Translation impl$translation; - @Nullable private Advancement impl$tempParent; - - @SuppressWarnings({"ConstantConditions"}) - @Inject(method = "", at = @At("RETURN")) - private void impl$setUpSpongeFields(ResourceLocation location, @Nullable Advancement parent, @Nullable DisplayInfo displayInfo, - AdvancementRewards rewards, Map criteria, String[][] requirements, CallbackInfo ci) { - // Don't do anything on the client, unless we're performing registry initialization - if (!SpongeImplHooks.onServerThread()) { - return; - } - this.impl$key = (ResourceKey) (Object) location; - if (displayInfo != null) { - ((DisplayInfoBridge) displayInfo).bridge$setAdvancement((org.spongepowered.api.advancement.Advancement) this); - } - this.impl$translation = new SpongeTranslation(location.getPath().replace('/', '_')); - if (displayInfo != null) { - this.impl$translation = new FixedTranslation(SpongeTexts.toPlain(displayInfo.getTitle())); - } - if (PhaseTracker.getInstance().getCurrentState().isEvent()) { - final Object event = ((ListenerPhaseContext) PhaseTracker.getInstance().getPhaseContext()).getEvent(); - if (event instanceof GameRegistryEvent.Register) { - final Class catalogType = ((GameRegistryEvent.Register) event).getCatalogType(); - if (catalogType.equals(org.spongepowered.api.advancement.Advancement.class) || catalogType.equals(AdvancementTree.class)) { - // Wait to set the parent until the advancement is registered - this.impl$tempParent = parent; - this.parent = AdvancementRegistryModule.DUMMY_ROOT_ADVANCEMENT; - } - } - } - - String fixedPath = this.impl$key.getValue(); - // This is only possible when REGISTER_ADVANCEMENTS_ON_CONSTRUCT is true - if (parent == null) { - // Remove the root suffix from json file tree ids - if (fixedPath.endsWith("/root")) { - fixedPath = fixedPath.substring(0, fixedPath.lastIndexOf('/')); - } - fixedPath = fixedPath.replace('/', '_'); - this.impl$tree = new SpongeAdvancementTree((org.spongepowered.api.advancement.Advancement) this, ResourceKey.of(this.impl$key - .getNamespace(), fixedPath), displayInfo != null ? this.impl$translation : new FixedTranslation(fixedPath)); - AdvancementTreeRegistryModule.getInstance().registerAdditionalCatalog(this.impl$tree); - } else { - this.impl$tree = ((org.spongepowered.api.advancement.Advancement) parent).getTree().orElse(null); - } - this.impl$text = SpongeTexts.toText(this.displayText); - final ImmutableList.Builder toastText = ImmutableList.builder(); - if (this.display != null) { - final FrameType frameType = this.display.getFrame(); - toastText.add(Text.builder(new SpongeTranslation("advancements.toast." + frameType.getName())) - .format(((AdvancementType) (Object) frameType).getTextFormat()) - .build()); - toastText.add(((TextComponentBridge) this.display.getTitle()).bridge$toText()); - } else { - toastText.add(Text.of("Unlocked advancement")); - toastText.add(Text.of(this.impl$key)); - } - this.impl$toastText = toastText.build(); - final Set scoreCriteria = new HashSet<>(); - final Map criterionMap = new HashMap<>(); - for (final Map.Entry entry : new HashMap<>(criteria).entrySet()) { - final CriterionBridge mixinCriterion = (CriterionBridge) entry.getValue(); - final DefaultedAdvancementCriterion criterion; - if (mixinCriterion.bridge$getScoreGoal() != null) { - criterion = new SpongeScoreCriterion(entry.getKey(), mixinCriterion.bridge$getScoreGoal(), - entry.getValue().getCriterionInstance()); - scoreCriteria.add(entry.getKey()); - ((SpongeScoreCriterion) criterion).internalCriteria.forEach( - criterion1 -> criteria.put(criterion1.getName(), (Criterion) criterion1)); - } else { - criterion = (DefaultedAdvancementCriterion) mixinCriterion; - ((CriterionBridge) criterion).bridge$setName(entry.getKey()); - } - criterionMap.put(entry.getKey(), criterion); - } - final List entries = new ArrayList<>(); - final List andCriteria = new ArrayList<>(); - for (final String[] array : requirements) { - final Set orCriteria = new HashSet<>(); - for (final String name : array) { - final DefaultedAdvancementCriterion criterion = criterionMap.get(name); - if (criterion instanceof SpongeScoreCriterion) { - ((SpongeScoreCriterion) criterion).internalCriteria.forEach( - criterion1 -> entries.add(new String[]{criterion1.getName()})); - } else { - entries.add(new String[]{criterion.getName()}); - } - orCriteria.add(criterion); - } - andCriteria.add(OrCriterion.of(orCriteria)); - } - this.impl$criterion = AndCriterion.of(andCriteria); - if (!scoreCriteria.isEmpty()) { - scoreCriteria.forEach(criteria::remove); - this.criteria = ImmutableMap.copyOf(criteria); - this.requirements = entries.toArray(new String[entries.size()][]); - } - } - - @Override - public ResourceKey bridge$getKey() { - return this.impl$key; - } - - @Override - public void bridge$setTranslation(Translation name) { - checkState(SpongeImplHooks.onServerThread()); - this.impl$translation = name; - } - - @Override - public Optional bridge$getParent() { - checkState(SpongeImplHooks.onServerThread()); - if (this.impl$tempParent != null) { - return Optional.of(this.impl$tempParent); - } - if (this.parent == AdvancementRegistryModule.DUMMY_ROOT_ADVANCEMENT) { - return Optional.empty(); - } - return Optional.ofNullable(this.parent); - } - - @Override - public void bridge$setParent(@Nullable final Advancement advancement) { - checkState(SpongeImplHooks.onServerThread()); - this.parent = advancement; - } - - @Override - public Optional bridge$getTree() { - checkState(SpongeImplHooks.onServerThread()); - return Optional.ofNullable(this.impl$tree); - } - - @Override - public void bridge$setTree(final AdvancementTree tree) { - checkState(SpongeImplHooks.onServerThread()); - this.impl$tree = tree; - } - - @Override - public AdvancementCriterion bridge$getCriterion() { - checkState(SpongeImplHooks.onServerThread()); - return this.impl$criterion; - } - - @Override - public void bridge$setCriterion(final AdvancementCriterion criterion) { - checkState(SpongeImplHooks.onServerThread()); - this.impl$criterion = criterion; - } - - @Override - public boolean bridge$isRegistered() { - checkState(SpongeImplHooks.onServerThread()); - return this.impl$tempParent == null; - } - - @Override - public void bridge$setRegistered() { - checkState(SpongeImplHooks.onServerThread()); - if (this.impl$tempParent == null) { - return; - } - this.parent = this.impl$tempParent; - // The child didn't get added yet to it's actual parent - this.parent.addChild((Advancement) (Object) this); - this.impl$tempParent = null; - } - - @Override - public Text bridge$getText() { - checkState(SpongeImplHooks.onServerThread()); - return this.impl$text; - } - - @Override - public List bridge$getToastText() { - checkState(SpongeImplHooks.onServerThread()); - return this.impl$toastText; - } -} diff --git a/src/main/java/org/spongepowered/common/SpongeLifecycle.java b/src/main/java/org/spongepowered/common/SpongeLifecycle.java index 14635a34309..4bace77a699 100644 --- a/src/main/java/org/spongepowered/common/SpongeLifecycle.java +++ b/src/main/java/org/spongepowered/common/SpongeLifecycle.java @@ -30,10 +30,12 @@ import com.google.inject.Singleton; import org.spongepowered.api.Engine; import org.spongepowered.api.Game; +import org.spongepowered.api.advancement.Advancement; import org.spongepowered.api.event.Cause; import org.spongepowered.api.event.EventContext; import org.spongepowered.api.event.SpongeEventFactory; import org.spongepowered.api.item.recipe.RecipeRegistration; +import org.spongepowered.common.advancement.SpongeAdvancementProvider; import org.spongepowered.common.bridge.server.MinecraftServerBridge; import org.spongepowered.common.command.manager.SpongeCommandManager; import org.spongepowered.common.data.provider.DataProviderRegistry; @@ -103,6 +105,8 @@ public void establishDataPackRegistries() { // After all plugins registered their recipes we serialize them SpongeRecipeProvider.registerRecipes(spongeCatalogRegistry.getRegistry(RecipeRegistration.class)); + SpongeAdvancementProvider.registerAdvancements(spongeCatalogRegistry.getRegistry(Advancement.class)); + } public void callRegisterChannelEvent() { diff --git a/invalid/main/java/org/spongepowered/common/advancement/SpongeAdvancementBuilder.java b/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementBuilder.java similarity index 75% rename from invalid/main/java/org/spongepowered/common/advancement/SpongeAdvancementBuilder.java rename to src/main/java/org/spongepowered/common/advancement/SpongeAdvancementBuilder.java index 467854bb01c..83d1dce7333 100644 --- a/invalid/main/java/org/spongepowered/common/advancement/SpongeAdvancementBuilder.java +++ b/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementBuilder.java @@ -28,26 +28,28 @@ import net.minecraft.advancements.AdvancementRewards; import net.minecraft.advancements.Criterion; +import net.minecraft.advancements.FrameType; import net.minecraft.util.ResourceLocation; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.ResourceKey; import org.spongepowered.api.advancement.Advancement; import org.spongepowered.api.advancement.DisplayInfo; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; -import org.spongepowered.api.text.translation.FixedTranslation; -import org.spongepowered.api.text.translation.Translation; import org.spongepowered.api.util.Tuple; +import org.spongepowered.common.advancement.criterion.SpongeCriterionHelper; +import org.spongepowered.common.adventure.SpongeAdventure; import org.spongepowered.common.bridge.advancements.AdvancementBridge; +import org.spongepowered.common.item.util.ItemStackUtil; import org.spongepowered.common.util.SpongeCatalogBuilder; import java.util.Map; -public final class SpongeAdvancementBuilder extends SpongeCatalogBuilder implements Advancement.Builder { +public final class SpongeAdvancementBuilder extends SpongeCatalogBuilder implements Advancement.Builder.RootStep { @Nullable private Advancement parent; private AdvancementCriterion criterion; @Nullable private DisplayInfo displayInfo; - private Translation translation; + @Nullable private ResourceLocation backgroundPath; public SpongeAdvancementBuilder() { this.reset(); @@ -56,31 +58,32 @@ public SpongeAdvancementBuilder() { @Override public Advancement.Builder parent(@Nullable Advancement parent) { this.parent = parent; + this.backgroundPath = null; return this; } @Override - public Advancement.Builder criterion(AdvancementCriterion criterion) { - checkNotNull(criterion, "criterion"); - this.criterion = criterion; + public Advancement.Builder.RootStep root() { + this.parent = null; return this; } @Override - public Advancement.Builder displayInfo(@Nullable DisplayInfo displayInfo) { - this.displayInfo = displayInfo; + public Advancement.Builder background(String backgroundPath) { + this.backgroundPath = new ResourceLocation(backgroundPath); return this; } @Override - public Advancement.Builder name(String name) { - this.translation = new FixedTranslation(name); + public Advancement.Builder criterion(AdvancementCriterion criterion) { + checkNotNull(criterion, "criterion"); + this.criterion = criterion; return this; } @Override - public Advancement.Builder name(Translation translation) { - this.translation = translation; + public Advancement.Builder displayInfo(@Nullable DisplayInfo displayInfo) { + this.displayInfo = displayInfo; return this; } @@ -89,18 +92,20 @@ protected Advancement build(ResourceKey key) { final Tuple, String[][]> result = SpongeCriterionHelper.toVanillaCriteriaData(this.criterion); final AdvancementRewards rewards = AdvancementRewards.EMPTY; final ResourceLocation resourceLocation = (ResourceLocation) (Object) key; - final net.minecraft.advancements.DisplayInfo displayInfo = this.displayInfo == null ? null : - (net.minecraft.advancements.DisplayInfo) DisplayInfo.builder().from(this.displayInfo).build(); // Create a copy - net.minecraft.advancements.Advancement parent = (net.minecraft.advancements.Advancement) this.parent; - if (parent == null) { - parent = AdvancementRegistryModule.DUMMY_ROOT_ADVANCEMENT; // Attach a dummy root until a tree is constructed - } + + final net.minecraft.advancements.DisplayInfo displayInfo = this.displayInfo == null ? null : new net.minecraft.advancements.DisplayInfo( + ItemStackUtil.fromSnapshotToNative(this.displayInfo.getIcon()), + SpongeAdventure.asVanilla(this.displayInfo.getTitle()), + SpongeAdventure.asVanilla(this.displayInfo.getDescription()), + this.backgroundPath, + (FrameType) (Object) this.displayInfo.getType(), + this.displayInfo.doesShowToast(), + this.displayInfo.doesAnnounceToChat(), + this.displayInfo.isHidden()); + final net.minecraft.advancements.Advancement parent = (net.minecraft.advancements.Advancement) this.parent; final Advancement advancement = (Advancement) new net.minecraft.advancements.Advancement( resourceLocation, parent, displayInfo, rewards, result.getFirst(), result.getSecond()); ((AdvancementBridge) advancement).bridge$setCriterion(this.criterion); - if (this.translation != null) { - ((AdvancementBridge) advancement).bridge$setTranslation(this.translation); - } return advancement; } @@ -110,6 +115,7 @@ public Advancement.Builder reset() { this.displayInfo = null; this.parent = null; this.key = null; + this.backgroundPath = null; return this; } } diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementProvider.java b/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementProvider.java new file mode 100644 index 00000000000..bae3d2b4534 --- /dev/null +++ b/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementProvider.java @@ -0,0 +1,83 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.advancement; + +import com.google.gson.JsonObject; +import net.minecraft.util.registry.Registry; +import org.apache.commons.io.FileUtils; +import org.spongepowered.api.advancement.Advancement; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +public final class SpongeAdvancementProvider { + private static final int PACK_VERSION_1_15 = 6; + + public static void registerAdvancements(Registry advancements) { + final Path datapackPluginAdvancements = Paths.get("world").resolve("datapacks").resolve("plugin-advancements"); + try { + FileUtils.deleteDirectory(datapackPluginAdvancements.toFile()); + } catch (IOException e) { + throw new IllegalStateException("Could not clear plugin-advancements datapack.", e); + } + for (Advancement advancement : advancements) { + final net.minecraft.advancements.Advancement mcAdvancement = (net.minecraft.advancements.Advancement) advancement; + SpongeAdvancementProvider.save(datapackPluginAdvancements, mcAdvancement); + } + if (!advancements.keySet().isEmpty()) { + final Path packMeta = datapackPluginAdvancements.resolve("pack.mcmeta"); + final JsonObject packDataRoot = new JsonObject(); + final JsonObject packData = new JsonObject(); + packDataRoot.add("pack", packData); + packData.addProperty("pack_format", SpongeAdvancementProvider.PACK_VERSION_1_15); + packData.addProperty("description", "Sponge Plugin provided Advancements"); + SpongeAdvancementProvider.saveToFile(packDataRoot, packMeta); + } + } + + private static void save(Path datpackPath, net.minecraft.advancements.Advancement advancement) { + final Path namespacedData = datpackPath.resolve("data").resolve(advancement.getId().getNamespace()); + final Path advancementFile = namespacedData.resolve("advancements").resolve(advancement.getId().getPath() + ".json"); + SpongeAdvancementProvider.saveToFile(advancement.copy().serialize(), advancementFile); + + + } + + private static void saveToFile(JsonObject json, Path pathIn) { + try { + Files.createDirectories(pathIn.getParent()); + try (BufferedWriter bufferedwriter = Files.newBufferedWriter(pathIn)) { + bufferedwriter.write(json.toString()); + } + } catch (IOException e) { + throw new IllegalStateException(e); + } + + } + +} diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementTree.java b/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementTree.java deleted file mode 100644 index 11af386803b..00000000000 --- a/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementTree.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.advancement; - -import org.spongepowered.api.ResourceKey; -import org.spongepowered.api.advancement.Advancement; -import org.spongepowered.api.advancement.AdvancementTree; -import org.spongepowered.api.advancement.DisplayInfo; -import org.spongepowered.common.bridge.advancements.DisplayInfoBridge; - -import java.util.Optional; - -public final class SpongeAdvancementTree implements AdvancementTree { - - private final Advancement rootAdvancement; - private final ResourceKey key; - private final String name; - - public SpongeAdvancementTree(Advancement rootAdvancement, ResourceKey key, String name) { - this.rootAdvancement = rootAdvancement; - this.key = key; - this.name = name; - } - - @Override - public ResourceKey getKey() { - return this.key; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public Advancement getRootAdvancement() { - return this.rootAdvancement; - } - - @Override - public String getBackgroundPath() { - final Optional displayInfo = this.rootAdvancement.getDisplayInfo(); - if (displayInfo.isPresent()) { - return ((DisplayInfoBridge) displayInfo.get()).bridge$getBackground(); - } - return "SPONGE_MISSING_BACKGROUND_PATH"; - } -} diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementTreeBuilder.java b/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementTreeBuilder.java deleted file mode 100644 index cb275b632c1..00000000000 --- a/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementTreeBuilder.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.advancement; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import org.spongepowered.api.ResourceKey; -import org.spongepowered.api.advancement.Advancement; -import org.spongepowered.api.advancement.AdvancementTree; -import org.spongepowered.common.bridge.advancements.AdvancementBridge; -import org.spongepowered.common.bridge.advancements.DisplayInfoBridge; -import org.spongepowered.common.util.SpongeCatalogBuilder; - -public final class SpongeAdvancementTreeBuilder extends SpongeCatalogBuilder implements AdvancementTree.Builder { - - private Advancement rootAdvancement; - private String name; - private String background; - - public SpongeAdvancementTreeBuilder() { - this.reset(); - } - - @Override - public AdvancementTree.Builder rootAdvancement(Advancement rootAdvancement) { - checkNotNull(rootAdvancement); - checkState(((AdvancementBridge) rootAdvancement).bridge$isRegistered(), "The root advancement must be registered."); - checkState(!rootAdvancement.getParent().isPresent(), "The root advancement cannot have a parent."); - checkState(rootAdvancement.getDisplayInfo().isPresent(), "The root advancement must have display info."); - checkState(((DisplayInfoBridge) rootAdvancement.getDisplayInfo().get()).bridge$getBackground() == null, - "The root advancement is already used by a different Advancement Tree."); - this.rootAdvancement = rootAdvancement; - return this; - } - - @Override - public AdvancementTree.Builder background(final String background) { - checkNotNull(background, "background"); - this.background = background; - return this; - } - - @Override - public AdvancementTree.Builder name(String name) { - this.name = name; - return this; - } - - @Override - protected AdvancementTree build(ResourceKey key) { - checkNotNull(key); - checkState(this.rootAdvancement != null, "The root advancement must be set"); - final SpongeAdvancementTree advancementTree = new SpongeAdvancementTree(this.rootAdvancement, key, this.name); - ((DisplayInfoBridge) this.rootAdvancement.getDisplayInfo().get()).bridge$setBackground(this.background); - ((AdvancementBridge) this.rootAdvancement).bridge$setParent(null); - applyTree(this.rootAdvancement, advancementTree); - return advancementTree; - } - - private static void applyTree(final Advancement advancement, final AdvancementTree tree) { - ((AdvancementBridge) advancement).bridge$setTree(tree); - for (final Advancement child : advancement.getChildren()) { - applyTree(child, tree); - } - } - - @Override - public AdvancementTree.Builder reset() { - this.key = null; - this.name = null; - this.background = "minecraft:textures/gui/advancements/backgrounds/stone.png"; - this.rootAdvancement = null; - return this; - } -} diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeFilteredTrigger.java b/src/main/java/org/spongepowered/common/advancement/SpongeFilteredTrigger.java index ecf1f1703b6..fddbb0e0e24 100644 --- a/src/main/java/org/spongepowered/common/advancement/SpongeFilteredTrigger.java +++ b/src/main/java/org/spongepowered/common/advancement/SpongeFilteredTrigger.java @@ -24,15 +24,24 @@ */ package org.spongepowered.common.advancement; +import com.google.gson.Gson; +import com.google.gson.JsonElement; import net.minecraft.advancements.ICriterionInstance; import net.minecraft.util.ResourceLocation; import org.spongepowered.api.advancement.criteria.trigger.FilteredTrigger; import org.spongepowered.api.advancement.criteria.trigger.FilteredTriggerConfiguration; import org.spongepowered.api.advancement.criteria.trigger.Trigger; +import org.spongepowered.api.data.persistence.DataContainer; +import org.spongepowered.api.data.persistence.DataFormats; +import org.spongepowered.api.data.persistence.DataSerializable; + +import java.io.IOException; @SuppressWarnings("rawtypes") public class SpongeFilteredTrigger implements ICriterionInstance, FilteredTrigger { + private final static Gson GSON = new Gson(); + private final SpongeTrigger triggerType; private final FilteredTriggerConfiguration configuration; @@ -55,4 +64,18 @@ public Trigger getType() { public FilteredTriggerConfiguration getConfiguration() { return this.configuration; } + + @Override + public JsonElement serialize() { + if (this.configuration instanceof DataSerializable) { + final DataContainer dataContainer = ((DataSerializable) this.configuration).toContainer(); + try { + final String json = DataFormats.JSON.get().write(dataContainer); + return SpongeFilteredTrigger.GSON.fromJson(json, JsonElement.class); + } catch (IOException e) { + e.printStackTrace(); + } + } + return SpongeFilteredTrigger.GSON.toJsonTree(this.configuration); + } } diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeTreeLayout.java b/src/main/java/org/spongepowered/common/advancement/SpongeTreeLayout.java index 6172e082968..f69d5384260 100644 --- a/src/main/java/org/spongepowered/common/advancement/SpongeTreeLayout.java +++ b/src/main/java/org/spongepowered/common/advancement/SpongeTreeLayout.java @@ -25,8 +25,10 @@ package org.spongepowered.common.advancement; import com.google.common.collect.ImmutableSet; +import org.spongepowered.api.ResourceKey; import org.spongepowered.api.advancement.Advancement; import org.spongepowered.api.advancement.AdvancementTree; +import org.spongepowered.api.advancement.DisplayInfo; import org.spongepowered.api.advancement.TreeLayout; import org.spongepowered.api.advancement.TreeLayoutElement; @@ -35,9 +37,9 @@ public final class SpongeTreeLayout implements TreeLayout { - private final SpongeAdvancementTree tree; + private final AdvancementTree tree; - public SpongeTreeLayout(final SpongeAdvancementTree tree) { + public SpongeTreeLayout(final AdvancementTree tree) { this.tree = tree; } @@ -49,20 +51,33 @@ public AdvancementTree getTree() { @Override public Collection getElements() { final ImmutableSet.Builder elements = ImmutableSet.builder(); - collectElements(this.tree.getRootAdvancement(), elements); + SpongeTreeLayout.collectElements(this.tree.getRootAdvancement(), elements); return elements.build(); } private static void collectElements(final Advancement advancement, final ImmutableSet.Builder elements) { advancement.getDisplayInfo().ifPresent(displayInfo -> elements.add((TreeLayoutElement) displayInfo)); - advancement.getChildren().forEach(child -> collectElements(child, elements)); + advancement.getChildren().forEach(child -> SpongeTreeLayout.collectElements(child, elements)); } @Override public Optional getElement(final Advancement advancement) { final Optional tree = advancement.getTree(); - if (!tree.isPresent() || !advancement.getDisplayInfo().isPresent() || tree.get() != this.tree) { + if (!tree.isPresent() || !advancement.getDisplayInfo().isPresent() || !tree.get().equals(this.tree)) { return Optional.empty(); } - return Optional.of((TreeLayoutElement) advancement.getDisplayInfo().get()); + return SpongeTreeLayout.findElementInfo(this.tree.getRootAdvancement(), advancement.getKey()).map(TreeLayoutElement.class::cast); + } + + private static Optional findElementInfo(Advancement advancement, ResourceKey key) { + if (advancement.getKey().equals(key)) { + return advancement.getDisplayInfo(); + } + for (Advancement child : advancement.getChildren()) { + final Optional info = SpongeTreeLayout.findElementInfo(child, key); + if (info.isPresent()) { + return info; + } + } + return Optional.empty(); } } diff --git a/src/main/java/org/spongepowered/common/advancement/AbstractCriterionBuilder.java b/src/main/java/org/spongepowered/common/advancement/criterion/AbstractCriterionBuilder.java similarity index 97% rename from src/main/java/org/spongepowered/common/advancement/AbstractCriterionBuilder.java rename to src/main/java/org/spongepowered/common/advancement/criterion/AbstractCriterionBuilder.java index feab5c79e64..802fbeea3ce 100644 --- a/src/main/java/org/spongepowered/common/advancement/AbstractCriterionBuilder.java +++ b/src/main/java/org/spongepowered/common/advancement/criterion/AbstractCriterionBuilder.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.advancement; +package org.spongepowered.common.advancement.criterion; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; diff --git a/src/main/java/org/spongepowered/common/advancement/DefaultedAdvancementCriterion.java b/src/main/java/org/spongepowered/common/advancement/criterion/DefaultedAdvancementCriterion.java similarity index 97% rename from src/main/java/org/spongepowered/common/advancement/DefaultedAdvancementCriterion.java rename to src/main/java/org/spongepowered/common/advancement/criterion/DefaultedAdvancementCriterion.java index dbfc84bb00f..d7324b02bf1 100644 --- a/src/main/java/org/spongepowered/common/advancement/DefaultedAdvancementCriterion.java +++ b/src/main/java/org/spongepowered/common/advancement/criterion/DefaultedAdvancementCriterion.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.advancement; +package org.spongepowered.common.advancement.criterion; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; import org.spongepowered.api.advancement.criteria.AndCriterion; diff --git a/src/main/java/org/spongepowered/common/advancement/ImplementationBackedCriterionProgress.java b/src/main/java/org/spongepowered/common/advancement/criterion/ImplementationBackedCriterionProgress.java similarity index 96% rename from src/main/java/org/spongepowered/common/advancement/ImplementationBackedCriterionProgress.java rename to src/main/java/org/spongepowered/common/advancement/criterion/ImplementationBackedCriterionProgress.java index f685c94776c..a5e2fe2666b 100644 --- a/src/main/java/org/spongepowered/common/advancement/ImplementationBackedCriterionProgress.java +++ b/src/main/java/org/spongepowered/common/advancement/criterion/ImplementationBackedCriterionProgress.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.advancement; +package org.spongepowered.common.advancement.criterion; public interface ImplementationBackedCriterionProgress { diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeAndCriterion.java b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeAndCriterion.java similarity index 72% rename from src/main/java/org/spongepowered/common/advancement/SpongeAndCriterion.java rename to src/main/java/org/spongepowered/common/advancement/criterion/SpongeAndCriterion.java index 3a561f8618e..0b28b871d33 100644 --- a/src/main/java/org/spongepowered/common/advancement/SpongeAndCriterion.java +++ b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeAndCriterion.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.advancement; +package org.spongepowered.common.advancement.criterion; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; import org.spongepowered.api.advancement.criteria.AndCriterion; @@ -31,7 +31,22 @@ public class SpongeAndCriterion extends SpongeOperatorCriterion implements AndCriterion { + public static final AndCriterion.Factory FACTORY_INSTANCE = new SpongeAndCriterion.SpongeAndCriterionFactory(); + SpongeAndCriterion(final Set criteria) { super("and", criteria); } + + private static class SpongeAndCriterionFactory implements AndCriterion.Factory { + + @Override + public AdvancementCriterion of(AdvancementCriterion... criteria) { + return AdvancementCriterion.empty().and(criteria); + } + + @Override + public AdvancementCriterion of(Iterable criteria) { + return AdvancementCriterion.empty().and(criteria); + } + } } diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeAndCriterionProgress.java b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeAndCriterionProgress.java similarity index 97% rename from src/main/java/org/spongepowered/common/advancement/SpongeAndCriterionProgress.java rename to src/main/java/org/spongepowered/common/advancement/criterion/SpongeAndCriterionProgress.java index a54ea0ba42e..8f005486f24 100644 --- a/src/main/java/org/spongepowered/common/advancement/SpongeAndCriterionProgress.java +++ b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeAndCriterionProgress.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.advancement; +package org.spongepowered.common.advancement.criterion; import org.spongepowered.api.advancement.AdvancementProgress; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeCriterionBuilder.java b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeCriterionBuilder.java similarity index 86% rename from src/main/java/org/spongepowered/common/advancement/SpongeCriterionBuilder.java rename to src/main/java/org/spongepowered/common/advancement/criterion/SpongeCriterionBuilder.java index 734a558e9b5..2bbbc57ec92 100644 --- a/src/main/java/org/spongepowered/common/advancement/SpongeCriterionBuilder.java +++ b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeCriterionBuilder.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.advancement; +package org.spongepowered.common.advancement.criterion; import net.minecraft.advancements.Criterion; import net.minecraft.advancements.ICriterionInstance; @@ -35,7 +35,11 @@ public class SpongeCriterionBuilder extends AbstractCriterionBuilder type, final A } } - static Tuple, String[][]> toVanillaCriteriaData(final AdvancementCriterion criterion) { - final Map criteria = new HashMap<>(); + public static Tuple, String[][]> toVanillaCriteriaData(final AdvancementCriterion criterion) { + final Map criteria = new LinkedHashMap<>(); if (criterion == SpongeEmptyCriterion.INSTANCE) { return new Tuple<>(criteria, new String[0][0]); } - collectCriteria(criterion, criteria); - final String[][] idsArray = new String[criteria.size()][]; - final Iterator it = criteria.values().iterator(); - for (int i = 0; i < criteria.size(); i++) { - idsArray[i] = new String[] { ((DefaultedAdvancementCriterion) it.next()).getName() }; + final List> andReq = SpongeCriterionHelper.collectCriteria(criterion, criteria); + ; + final String[][] idsArray = new String[andReq.size()][]; + for (int i = 0; i < andReq.size(); i++) { + List orReq = andReq.get(i); + idsArray[i] = orReq.toArray(new String[0]); } return new Tuple<>(criteria, idsArray); } - private static void collectCriteria(final AdvancementCriterion criterion, final Map criteria) { - if (criterion instanceof SpongeOperatorCriterion) { - ((SpongeOperatorCriterion) criterion).getCriteria() - .forEach(c -> collectCriteria(c, criteria)); + private static List> collectCriteria(final AdvancementCriterion criterion, final Map criteria) { + + List> requirements = new ArrayList<>(); + if (criterion instanceof SpongeAndCriterion) { + ((SpongeOperatorCriterion) criterion).getCriteria().forEach(c -> requirements.addAll(SpongeCriterionHelper.collectCriteria(c, criteria))); + } else if (criterion instanceof SpongeOrCriterion) { + // OR List of AND Criteria of OR Criteria + final List>> andRequirementsList = ((SpongeOperatorCriterion) criterion).getCriteria().stream().map(c -> SpongeCriterionHelper.collectCriteria(c, criteria)).collect(Collectors.toList()); + List> finalList = new ArrayList<>(); + // For every AND Criteria + for (List> andRequirements : andRequirementsList) { + if (finalList.isEmpty()) { + finalList.addAll(andRequirements); // Just take the first one in as is + } else { + List> workingList = new ArrayList<>(); + for (List andRequirement : andRequirements) { + for (List prevAndRequirement : finalList) { + // For every AND requirement and FOR every previous AND requirement + // combine their OR requirements + // !! this can get very big very quickly !! + // TODO limit requirement count? + final List newAndRequirement = new ArrayList<>(prevAndRequirement); + newAndRequirement.addAll(andRequirement); + workingList.add(newAndRequirement); + } + } + + finalList = workingList; + } + } + requirements.addAll(finalList); } else if (criterion instanceof SpongeScoreCriterion) { final SpongeScoreCriterion scoreCriterion = (SpongeScoreCriterion) criterion; - final String name = criterion.getName(); for (int i = 0; i < scoreCriterion.getGoal(); i++) { - final String id = name + SpongeScoreCriterion.INTERNAL_SUFFIX_BASE + i; - criteria.put(id, (Criterion) scoreCriterion.internalCriteria.get(i)); + final DefaultedAdvancementCriterion internalCriterion = scoreCriterion.internalCriteria.get(i); + criteria.put(internalCriterion.getName(), ((Criterion) internalCriterion)); + requirements.add(Collections.singletonList(internalCriterion.getName())); } } else { criteria.put(criterion.getName(), (Criterion) criterion); + requirements.add(Collections.singletonList(criterion.getName())); } + + return requirements; } private SpongeCriterionHelper() { diff --git a/src/main/java/org/spongepowered/common/advancement/criterion/SpongeDummyTrigger.java b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeDummyTrigger.java new file mode 100644 index 00000000000..61d2a54c207 --- /dev/null +++ b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeDummyTrigger.java @@ -0,0 +1,70 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.advancement.criterion; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.minecraft.advancements.criterion.AbstractCriterionTrigger; +import net.minecraft.advancements.criterion.CriterionInstance; +import net.minecraft.util.ResourceLocation; +import org.spongepowered.common.accessor.advancements.CriteriaTriggersAccessor; + +public class SpongeDummyTrigger extends AbstractCriterionTrigger { + + public static final SpongeDummyTrigger DUMMY_TRIGGER = CriteriaTriggersAccessor.accessor$register(new SpongeDummyTrigger(new ResourceLocation("sponge:dummy"))); + + private ResourceLocation resourceLocation; + + private SpongeDummyTrigger(ResourceLocation resourceLocation) { + this.resourceLocation = resourceLocation; + } + + @Override + public ResourceLocation getId() { + return this.resourceLocation; + } + + @Override + public SpongeDummyTrigger.Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) { + return new SpongeDummyTrigger.Instance(this.resourceLocation); + } + + public static class Instance extends CriterionInstance { + + public Instance(ResourceLocation criterionIn) { + super(criterionIn); + } + + public static Instance dummy() { + return new Instance(SpongeDummyTrigger.DUMMY_TRIGGER.getId()); + } + + @Override + public JsonElement serialize() { + return new JsonObject(); + } + } +} diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeEmptyCriterion.java b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeEmptyCriterion.java similarity index 96% rename from src/main/java/org/spongepowered/common/advancement/SpongeEmptyCriterion.java rename to src/main/java/org/spongepowered/common/advancement/criterion/SpongeEmptyCriterion.java index e7f26c32a37..b414d8634e7 100644 --- a/src/main/java/org/spongepowered/common/advancement/SpongeEmptyCriterion.java +++ b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeEmptyCriterion.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.advancement; +package org.spongepowered.common.advancement.criterion; import org.spongepowered.api.advancement.criteria.trigger.FilteredTrigger; diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeOperatorCriterion.java b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeOperatorCriterion.java similarity index 85% rename from src/main/java/org/spongepowered/common/advancement/SpongeOperatorCriterion.java rename to src/main/java/org/spongepowered/common/advancement/criterion/SpongeOperatorCriterion.java index 0d0edc864a8..a4133a10677 100644 --- a/src/main/java/org/spongepowered/common/advancement/SpongeOperatorCriterion.java +++ b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeOperatorCriterion.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.advancement; +package org.spongepowered.common.advancement.criterion; import com.google.common.collect.ImmutableSet; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; @@ -31,6 +31,7 @@ import java.util.Arrays; import java.util.Collection; +import java.util.Objects; import java.util.Optional; import javax.annotation.Nullable; @@ -102,4 +103,28 @@ public Optional findFirst(final String name) { return this.getRecursiveChildren().stream() .filter(c -> c.getName().equals(name)).findFirst(); } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof SpongeOperatorCriterion)) { + return false; + } + + SpongeOperatorCriterion that = (SpongeOperatorCriterion) o; + + if (!Objects.equals(name, that.name)) { + return false; + } + return Objects.equals(criteria, that.criteria); + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + (criteria != null ? criteria.hashCode() : 0); + return result; + } } diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeOperatorCriterionProgress.java b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeOperatorCriterionProgress.java similarity index 98% rename from src/main/java/org/spongepowered/common/advancement/SpongeOperatorCriterionProgress.java rename to src/main/java/org/spongepowered/common/advancement/criterion/SpongeOperatorCriterionProgress.java index 68e4e1c1cdf..431a037ea26 100644 --- a/src/main/java/org/spongepowered/common/advancement/SpongeOperatorCriterionProgress.java +++ b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeOperatorCriterionProgress.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.advancement; +package org.spongepowered.common.advancement.criterion; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeOrCriterion.java b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeOrCriterion.java similarity index 73% rename from src/main/java/org/spongepowered/common/advancement/SpongeOrCriterion.java rename to src/main/java/org/spongepowered/common/advancement/criterion/SpongeOrCriterion.java index 23f51a809fb..b669e26f5b4 100644 --- a/src/main/java/org/spongepowered/common/advancement/SpongeOrCriterion.java +++ b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeOrCriterion.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.advancement; +package org.spongepowered.common.advancement.criterion; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; import org.spongepowered.api.advancement.criteria.OrCriterion; @@ -31,7 +31,22 @@ public class SpongeOrCriterion extends SpongeOperatorCriterion implements OrCriterion { + public static final OrCriterion.Factory FACTORY_INSTANCE = new SpongeOrCriterionFactory(); + SpongeOrCriterion(final Set criteria) { super("or", criteria); } + + private static class SpongeOrCriterionFactory implements OrCriterion.Factory { + + @Override + public AdvancementCriterion of(AdvancementCriterion... criteria) { + return AdvancementCriterion.empty().or(criteria); + } + + @Override + public AdvancementCriterion of(Iterable criteria) { + return AdvancementCriterion.empty().or(criteria); + } + } } diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeOrCriterionProgress.java b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeOrCriterionProgress.java similarity index 92% rename from src/main/java/org/spongepowered/common/advancement/SpongeOrCriterionProgress.java rename to src/main/java/org/spongepowered/common/advancement/criterion/SpongeOrCriterionProgress.java index fa6086659d7..8c9ff5a6916 100644 --- a/src/main/java/org/spongepowered/common/advancement/SpongeOrCriterionProgress.java +++ b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeOrCriterionProgress.java @@ -22,10 +22,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.advancement; +package org.spongepowered.common.advancement.criterion; import org.spongepowered.api.advancement.AdvancementProgress; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; +import org.spongepowered.common.advancement.criterion.SpongeOperatorCriterionProgress; +import org.spongepowered.common.advancement.criterion.SpongeOrCriterion; import java.time.Instant; import java.util.Optional; diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeScoreCriterion.java b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeScoreCriterion.java similarity index 72% rename from src/main/java/org/spongepowered/common/advancement/SpongeScoreCriterion.java rename to src/main/java/org/spongepowered/common/advancement/criterion/SpongeScoreCriterion.java index cbb94538cef..924de5967b8 100644 --- a/src/main/java/org/spongepowered/common/advancement/SpongeScoreCriterion.java +++ b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeScoreCriterion.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.advancement; +package org.spongepowered.common.advancement.criterion; import net.minecraft.advancements.Criterion; import net.minecraft.advancements.ICriterionInstance; @@ -39,7 +39,7 @@ public class SpongeScoreCriterion implements ScoreAdvancementCriterion, DefaultedAdvancementCriterion { public static boolean BYPASS_EVENT = false; - static final String INTERNAL_SUFFIX_BASE = "&score_goal_id="; + public static final String INTERNAL_SUFFIX_BASE = "&score_goal_id="; private final String name; public final List internalCriteria; @@ -49,13 +49,24 @@ public SpongeScoreCriterion(final String name, final int goal, @Nullable final I this.internalCriteria = new ArrayList<>(goal); this.name = name; for (int i = 0; i < goal; i++) { - final Criterion criterion = i == 0 ? new Criterion(trigger) : new Criterion(); + final ICriterionInstance mctrigger; + if (i == 0) { + mctrigger = trigger == null ? SpongeScoreTrigger.Instance.of(goal) : trigger; + } else { + mctrigger = SpongeDummyTrigger.Instance.dummy(); + } + final Criterion criterion = new Criterion(mctrigger); ((CriterionBridge) criterion).bridge$setScoreCriterion(this); ((CriterionBridge) criterion).bridge$setName(name + INTERNAL_SUFFIX_BASE + i); this.internalCriteria.add((DefaultedAdvancementCriterion) criterion); } } + public SpongeScoreCriterion(final String name, final List internalCriteria) { + this.name = name; + this.internalCriteria = internalCriteria; + } + @Override public int getGoal() { return this.internalCriteria.size(); @@ -71,4 +82,23 @@ public Optional> getTrigger() { // The first internal criterion holds the trigger return this.internalCriteria.get(0).getTrigger(); } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof SpongeScoreCriterion)) { + return false; + } + + SpongeScoreCriterion that = (SpongeScoreCriterion) o; + + return this.name.equals(that.name); + } + + @Override + public int hashCode() { + return this.name.hashCode(); + } } diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeScoreCriterionBuilder.java b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeScoreCriterionBuilder.java similarity index 97% rename from src/main/java/org/spongepowered/common/advancement/SpongeScoreCriterionBuilder.java rename to src/main/java/org/spongepowered/common/advancement/criterion/SpongeScoreCriterionBuilder.java index 303cb5582c9..832c5814674 100644 --- a/src/main/java/org/spongepowered/common/advancement/SpongeScoreCriterionBuilder.java +++ b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeScoreCriterionBuilder.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.advancement; +package org.spongepowered.common.advancement.criterion; import static com.google.common.base.Preconditions.checkState; diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeScoreCriterionProgress.java b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeScoreCriterionProgress.java similarity index 99% rename from src/main/java/org/spongepowered/common/advancement/SpongeScoreCriterionProgress.java rename to src/main/java/org/spongepowered/common/advancement/criterion/SpongeScoreCriterionProgress.java index 8294ea16970..bfa6d8475c7 100644 --- a/src/main/java/org/spongepowered/common/advancement/SpongeScoreCriterionProgress.java +++ b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeScoreCriterionProgress.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.advancement; +package org.spongepowered.common.advancement.criterion; import static com.google.common.base.Preconditions.checkState; diff --git a/src/main/java/org/spongepowered/common/advancement/criterion/SpongeScoreTrigger.java b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeScoreTrigger.java new file mode 100644 index 00000000000..17ce144235e --- /dev/null +++ b/src/main/java/org/spongepowered/common/advancement/criterion/SpongeScoreTrigger.java @@ -0,0 +1,77 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.advancement.criterion; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.minecraft.advancements.criterion.AbstractCriterionTrigger; +import net.minecraft.advancements.criterion.CriterionInstance; +import net.minecraft.util.JSONUtils; +import net.minecraft.util.ResourceLocation; +import org.spongepowered.common.accessor.advancements.CriteriaTriggersAccessor; + +public class SpongeScoreTrigger extends AbstractCriterionTrigger { + + public static final SpongeScoreTrigger SCORE_TRIGGER = CriteriaTriggersAccessor.accessor$register(new SpongeScoreTrigger(new ResourceLocation("sponge:score"))); + + private ResourceLocation resourceLocation; + + private SpongeScoreTrigger(ResourceLocation resourceLocation) { + this.resourceLocation = resourceLocation; + } + + @Override + public ResourceLocation getId() { + return this.resourceLocation; + } + + @Override + public SpongeScoreTrigger.Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) { + return new SpongeScoreTrigger.Instance(this.resourceLocation, -1); + } + + public static class Instance extends CriterionInstance { + + private int triggerTimes; + public Instance(ResourceLocation criterionIn, int triggerTimes) { + super(criterionIn); + this.triggerTimes = triggerTimes; + } + + public static Instance of(int triggerTimes) { + return new Instance(SpongeScoreTrigger.SCORE_TRIGGER.getId(), triggerTimes); + } + + @Override + public JsonElement serialize() { + return new JsonObject(); + } + + public int getTriggerTimes() { + return this.triggerTimes; + } + } +} diff --git a/src/main/java/org/spongepowered/common/bridge/advancements/AdvancementBridge.java b/src/main/java/org/spongepowered/common/bridge/advancements/AdvancementBridge.java index 29942571a66..c8a09648064 100644 --- a/src/main/java/org/spongepowered/common/bridge/advancements/AdvancementBridge.java +++ b/src/main/java/org/spongepowered/common/bridge/advancements/AdvancementBridge.java @@ -37,25 +37,13 @@ public interface AdvancementBridge { - ResourceKey bridge$getKey(); - Optional bridge$getParent(); void bridge$setParent(@Nullable Advancement advancement); - Optional bridge$getTree(); - - void bridge$setTree(AdvancementTree tree); - AdvancementCriterion bridge$getCriterion(); void bridge$setCriterion(AdvancementCriterion criterion); - boolean bridge$isRegistered(); - - void bridge$setRegistered(); - - Component bridge$getText(); - List bridge$getToastText(); } diff --git a/src/main/java/org/spongepowered/common/bridge/advancements/AdvancementProgressBridge.java b/src/main/java/org/spongepowered/common/bridge/advancements/AdvancementProgressBridge.java index d01dc0d4482..1dc0b193128 100644 --- a/src/main/java/org/spongepowered/common/bridge/advancements/AdvancementProgressBridge.java +++ b/src/main/java/org/spongepowered/common/bridge/advancements/AdvancementProgressBridge.java @@ -25,10 +25,10 @@ package org.spongepowered.common.bridge.advancements; import net.minecraft.advancements.PlayerAdvancements; -import org.spongepowered.api.ResourceKey; +import net.minecraft.util.ResourceLocation; import org.spongepowered.api.advancement.Advancement; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; -import org.spongepowered.common.advancement.ImplementationBackedCriterionProgress; +import org.spongepowered.common.advancement.criterion.ImplementationBackedCriterionProgress; import java.util.Map; @@ -40,11 +40,11 @@ public interface AdvancementProgressBridge { void bridge$setPlayerAdvancements(PlayerAdvancements playerAdvancements); - void bridge$setAdvancementKey(ResourceKey key); + void bridge$setAdvancementId(ResourceLocation key); void bridge$invalidateAchievedState(); void bridge$updateProgressMap(); - Map bridge$getProgressMap(); + Map bridge$getProgressMap(); } diff --git a/src/main/java/org/spongepowered/common/bridge/advancements/CriterionBridge.java b/src/main/java/org/spongepowered/common/bridge/advancements/CriterionBridge.java index 55f03120a07..a1bbf1291d3 100644 --- a/src/main/java/org/spongepowered/common/bridge/advancements/CriterionBridge.java +++ b/src/main/java/org/spongepowered/common/bridge/advancements/CriterionBridge.java @@ -25,7 +25,7 @@ package org.spongepowered.common.bridge.advancements; import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.common.advancement.SpongeScoreCriterion; +import org.spongepowered.common.advancement.criterion.SpongeScoreCriterion; public interface CriterionBridge { @@ -42,4 +42,8 @@ public interface CriterionBridge { Integer bridge$getScoreGoal(); void bridge$setScoreGoal(@Nullable Integer goal); + + void bridge$setScoreCriterionName(String name); + + String bridge$getScoreCriterionName(); } diff --git a/src/main/java/org/spongepowered/common/bridge/advancements/CriterionProgressBridge.java b/src/main/java/org/spongepowered/common/bridge/advancements/CriterionProgressBridge.java index c7f012a69bd..a138048e308 100644 --- a/src/main/java/org/spongepowered/common/bridge/advancements/CriterionProgressBridge.java +++ b/src/main/java/org/spongepowered/common/bridge/advancements/CriterionProgressBridge.java @@ -35,5 +35,7 @@ public interface CriterionProgressBridge { AdvancementProgress bridge$getAdvancementProgress(); + void bridge$setAdvancementProgress(AdvancementProgress advancementProgress); + boolean bridge$isCriterionAvailable(); } diff --git a/src/main/java/org/spongepowered/common/event/SpongeEventManager.java b/src/main/java/org/spongepowered/common/event/SpongeEventManager.java index ac46cc77873..05bad4d89dd 100644 --- a/src/main/java/org/spongepowered/common/event/SpongeEventManager.java +++ b/src/main/java/org/spongepowered/common/event/SpongeEventManager.java @@ -428,7 +428,7 @@ private boolean post(final Event event, final List> handle SpongeCommon.setActivePlugin(handler.getPlugin()); handler.handle(event); } catch (Throwable e) { - this.logger.error("Could not pass {} to {}", event.getClass().getSimpleName(), handler.getPlugin(), e); + this.logger.error("Could not pass {} to {}", event.getClass().getSimpleName(), handler.getPlugin().getMetadata().getId(), e); } finally { SpongeCommon.setActivePlugin(null); } diff --git a/src/main/java/org/spongepowered/common/item/recipe/SpongeRecipeProvider.java b/src/main/java/org/spongepowered/common/item/recipe/SpongeRecipeProvider.java index 0269cd6b994..6706827d151 100644 --- a/src/main/java/org/spongepowered/common/item/recipe/SpongeRecipeProvider.java +++ b/src/main/java/org/spongepowered/common/item/recipe/SpongeRecipeProvider.java @@ -51,6 +51,16 @@ public static void registerRecipes(Registry recipes) { final IFinishedRecipe mcRecipe = (IFinishedRecipe) recipe; SpongeRecipeProvider.save(datapackPluginRecipes, mcRecipe); } + if (!recipes.keySet().isEmpty()) { + + final Path packMeta = datapackPluginRecipes.resolve("pack.mcmeta"); + final JsonObject packDataRoot = new JsonObject(); + final JsonObject packData = new JsonObject(); + packDataRoot.add("pack", packData); + packData.addProperty("pack_format", SpongeRecipeProvider.PACK_VERSION_1_15); + packData.addProperty("description", "Sponge Plugin provided Recipes"); + SpongeRecipeProvider.saveToFile(packDataRoot, packMeta); + } } private static void save(Path datpackPath, IFinishedRecipe recipe) { @@ -63,14 +73,6 @@ private static void save(Path datpackPath, IFinishedRecipe recipe) { final Path advancementFile = namespacedData.resolve("advancements").resolve(recipe.getAdvancementID().getPath() + ".json"); SpongeRecipeProvider.saveToFile(jsonobject, advancementFile); } - - final Path packMeta = datpackPath.resolve("pack.mcmeta"); - final JsonObject packDataRoot = new JsonObject(); - final JsonObject packData = new JsonObject(); - packDataRoot.add("pack", packData); - packData.addProperty("pack_format", SpongeRecipeProvider.PACK_VERSION_1_15); - packData.addProperty("description", "Sponge Plugin provided Recipes"); - SpongeRecipeProvider.saveToFile(packDataRoot, packMeta); } private static void saveToFile(JsonObject json, Path pathIn) { diff --git a/src/main/java/org/spongepowered/common/registry/CallbackRegistry.java b/src/main/java/org/spongepowered/common/registry/CallbackRegistry.java index 1fd68f53ff1..dbf57045375 100644 --- a/src/main/java/org/spongepowered/common/registry/CallbackRegistry.java +++ b/src/main/java/org/spongepowered/common/registry/CallbackRegistry.java @@ -40,7 +40,7 @@ public CallbackRegistry(BiConsumer callback) { @Override public V register(int id, ResourceLocation name, V instance) { V value = super.register(id, name, instance); - callback.accept(name, instance); + this.callback.accept(name, instance); return value; } } diff --git a/src/main/java/org/spongepowered/common/registry/SpongeBuilderRegistry.java b/src/main/java/org/spongepowered/common/registry/SpongeBuilderRegistry.java index 832bffdfb44..8e7fca25db7 100644 --- a/src/main/java/org/spongepowered/common/registry/SpongeBuilderRegistry.java +++ b/src/main/java/org/spongepowered/common/registry/SpongeBuilderRegistry.java @@ -28,7 +28,7 @@ import com.google.inject.Singleton; import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; import org.spongepowered.api.ResourceKey; -import org.spongepowered.api.advancement.AdvancementTree; +import org.spongepowered.api.advancement.Advancement; import org.spongepowered.api.advancement.DisplayInfo; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; import org.spongepowered.api.advancement.criteria.ScoreAdvancementCriterion; @@ -104,11 +104,11 @@ import org.spongepowered.api.world.WorldBorder; import org.spongepowered.api.world.biome.VirtualBiomeType; import org.spongepowered.api.world.explosion.Explosion; -import org.spongepowered.common.advancement.SpongeAdvancementTreeBuilder; -import org.spongepowered.common.advancement.SpongeCriterionBuilder; +import org.spongepowered.common.advancement.SpongeAdvancementBuilder; +import org.spongepowered.common.advancement.criterion.SpongeCriterionBuilder; import org.spongepowered.common.advancement.SpongeDisplayInfoBuilder; import org.spongepowered.common.advancement.SpongeFilteredTriggerBuilder; -import org.spongepowered.common.advancement.SpongeScoreCriterionBuilder; +import org.spongepowered.common.advancement.criterion.SpongeScoreCriterionBuilder; import org.spongepowered.common.advancement.SpongeTriggerBuilder; import org.spongepowered.common.ban.SpongeBanBuilder; import org.spongepowered.common.block.SpongeBlockSnapshotBuilder; @@ -276,8 +276,7 @@ public void registerDefaultBuilders() { .register(Enchantment.Builder.class, SpongeEnchantmentBuilder::new) .register(Enchantment.RandomListBuilder.class, SpongeRandomEnchantmentListBuilder::new) .register(Key.Builder.class, SpongeKeyBuilder::new) -// .register(Advancement.Builder.class, SpongeAdvancementBuilder::new) - .register(AdvancementTree.Builder.class, SpongeAdvancementTreeBuilder::new) + .register(Advancement.Builder.class, SpongeAdvancementBuilder::new) .register(DisplayInfo.Builder.class, SpongeDisplayInfoBuilder::new) .register(AdvancementCriterion.Builder.class, SpongeCriterionBuilder::new) .register(ScoreAdvancementCriterion.Builder.class, SpongeScoreCriterionBuilder::new) diff --git a/src/main/java/org/spongepowered/common/registry/SpongeCatalogRegistry.java b/src/main/java/org/spongepowered/common/registry/SpongeCatalogRegistry.java index 3b0b09a09ed..f6da097603e 100644 --- a/src/main/java/org/spongepowered/common/registry/SpongeCatalogRegistry.java +++ b/src/main/java/org/spongepowered/common/registry/SpongeCatalogRegistry.java @@ -29,6 +29,7 @@ import com.google.inject.Singleton; import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import net.minecraft.advancements.FrameType; import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.monster.PhantomEntity; import net.minecraft.entity.monster.SpellcastingIllagerEntity; @@ -62,6 +63,7 @@ import org.spongepowered.api.ResourceKey; import org.spongepowered.api.advancement.Advancement; import org.spongepowered.api.advancement.AdvancementTree; +import org.spongepowered.api.advancement.AdvancementType; import org.spongepowered.api.block.BlockType; import org.spongepowered.api.block.entity.BlockEntityType; import org.spongepowered.api.command.parameter.managed.clientcompletion.ClientCompletionType; @@ -426,7 +428,7 @@ public SpongeCatalogRegistry registerRegistry(final Clas return this; } - private SpongeCatalogRegistry generateCallbackRegistry(final Class catalogClass, final ResourceKey key, final BiConsumer callback) { + public SpongeCatalogRegistry generateCallbackRegistry(final Class catalogClass, final ResourceKey key, final BiConsumer callback) { Objects.requireNonNull(key); if (this.registries.containsKey(key)) { @@ -523,9 +525,7 @@ public void registerDefaultRegistries() { this .generateRegistry(AccountDeletionResultType.class, ResourceKey.sponge("account_deletion_result_type"), AccountDeletionResultTypeStreamGenerator.stream(), true, false) - .registerRegistry(Advancement.class, ResourceKey.minecraft("advancement"), false) - .registerRegistry(AdvancementTree.class, ResourceKey.minecraft("advancement_tree"), false) -// .generateRegistry(AdvancementType.class, ResourceKey.minecraft("advancement_type"), Arrays.stream(FrameType.values()), true) + .generateRegistry(AdvancementType.class, ResourceKey.minecraft("advancement_type"), Arrays.stream(FrameType.values()), true, false) .generateRegistry(ArmorMaterial.class, ResourceKey.minecraft("armor_material"), Arrays.stream(net.minecraft.item.ArmorMaterial.values()), true, false) .generateRegistry(AttachmentSurface.class, ResourceKey.minecraft("attach_face"), Arrays.stream(net.minecraft.state.properties.AttachFace.values()), true, false) .generateRegistry(AttributeOperation.class, ResourceKey.minecraft("attribute_operation"), Arrays.stream(AttributeModifier.Operation.values()), true, false) @@ -635,7 +635,9 @@ public void registerDefaultRegistries() { public void registerDatapackCatalogues() { this.datapackCatalogues.clear(); - this.registerRegistry(RecipeRegistration.class, ResourceKey.sponge("recipe"), true, true); + this.registerRegistry(RecipeRegistration.class, ResourceKey.sponge("recipe"), true, true) + .registerRegistry(Advancement.class, ResourceKey.minecraft("advancement"), true, true); + } private void registerVanillaRegistries() { diff --git a/src/main/java/org/spongepowered/common/registry/SpongeFactoryRegistry.java b/src/main/java/org/spongepowered/common/registry/SpongeFactoryRegistry.java index 0b6c2021bc4..23c0bee7986 100644 --- a/src/main/java/org/spongepowered/common/registry/SpongeFactoryRegistry.java +++ b/src/main/java/org/spongepowered/common/registry/SpongeFactoryRegistry.java @@ -30,6 +30,8 @@ import com.google.inject.Singleton; import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; +import org.spongepowered.api.advancement.criteria.AndCriterion; +import org.spongepowered.api.advancement.criteria.OrCriterion; import org.spongepowered.api.adventure.Audiences; import org.spongepowered.api.adventure.SpongeComponents; import org.spongepowered.api.command.CommandCause; @@ -49,6 +51,8 @@ import org.spongepowered.api.util.Transform; import org.spongepowered.api.world.BlockChangeFlag; import org.spongepowered.api.world.ServerLocation; +import org.spongepowered.common.advancement.criterion.SpongeAndCriterion; +import org.spongepowered.common.advancement.criterion.SpongeOrCriterion; import org.spongepowered.common.adventure.AudienceFactory; import org.spongepowered.common.adventure.SpongeAdventure; import org.spongepowered.common.command.manager.SpongeCommandCauseFactory; @@ -126,6 +130,8 @@ public void registerDefaultFactories() { .registerFactory(DataManipulator.Mutable.Factory.class, MutableDataManipulatorFactory.INSTANCE) .registerFactory(DataManipulator.Immutable.Factory.class, ImmutableDataManipulatorFactory.INSTANCE) .registerFactory(BlockChangeFlag.Factory.class, BlockChangeFlagManager.getInstance().getFactory()) + .registerFactory(OrCriterion.Factory.class, SpongeOrCriterion.FACTORY_INSTANCE) + .registerFactory(AndCriterion.Factory.class, SpongeAndCriterion.FACTORY_INSTANCE) ; } diff --git a/src/main/java/org/spongepowered/common/registry/builtin/sponge/CriteriaTriggersRegistrar.java b/src/main/java/org/spongepowered/common/registry/builtin/sponge/CriteriaTriggersRegistrar.java index fa060c8b193..27fe2c2cb1f 100644 --- a/src/main/java/org/spongepowered/common/registry/builtin/sponge/CriteriaTriggersRegistrar.java +++ b/src/main/java/org/spongepowered/common/registry/builtin/sponge/CriteriaTriggersRegistrar.java @@ -25,12 +25,13 @@ package org.spongepowered.common.registry.builtin.sponge; import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.advancements.ICriterionTrigger; +import net.minecraft.util.ResourceLocation; import org.spongepowered.api.ResourceKey; import org.spongepowered.api.advancement.criteria.trigger.Trigger; +import org.spongepowered.common.accessor.advancements.CriteriaTriggersAccessor; import org.spongepowered.common.registry.SpongeCatalogRegistry; -import java.util.stream.Stream; - public final class CriteriaTriggersRegistrar { private CriteriaTriggersRegistrar() { @@ -38,10 +39,18 @@ private CriteriaTriggersRegistrar() { // Oh Vanilla, you're fun... + private static boolean vanillaRegistered = false; + public static void registerRegistry(final SpongeCatalogRegistry registry) { - registry.generateRegistry(Trigger.class, ResourceKey.minecraft("trigger"), Stream.empty(), false, false); + registry.generateCallbackRegistry(Trigger.class, ResourceKey.minecraft("trigger"), CriteriaTriggersRegistrar::registerAdditional); } - + + private static void registerAdditional(ResourceLocation resourceLocation, Trigger t) { + if (CriteriaTriggersRegistrar.vanillaRegistered) { + CriteriaTriggersAccessor.accessor$register((ICriterionTrigger) t); + } + } + public static void registerSuppliers(final SpongeCatalogRegistry registry) { registry .registerCatalogAndSupplier(Trigger.class, "impossible", () -> (Trigger) CriteriaTriggers.IMPOSSIBLE) @@ -80,5 +89,6 @@ public static void registerSuppliers(final SpongeCatalogRegistry registry) { .registerCatalogAndSupplier(Trigger.class, "hero_of_the_village", () -> (Trigger) CriteriaTriggers.HERO_OF_THE_VILLAGE) .registerCatalogAndSupplier(Trigger.class, "voluntary_exile", () -> (Trigger) CriteriaTriggers.VOLUNTARY_EXILE) ; + CriteriaTriggersRegistrar.vanillaRegistered = true; } } diff --git a/src/main/java/org/spongepowered/common/registry/type/advancement/SpongeAdvancementCriterionFactory.java b/src/main/java/org/spongepowered/common/registry/type/advancement/SpongeAdvancementCriterionFactory.java index 908ecec51d1..a7b4347b530 100644 --- a/src/main/java/org/spongepowered/common/registry/type/advancement/SpongeAdvancementCriterionFactory.java +++ b/src/main/java/org/spongepowered/common/registry/type/advancement/SpongeAdvancementCriterionFactory.java @@ -25,8 +25,8 @@ package org.spongepowered.common.registry.type.advancement; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; -import org.spongepowered.common.advancement.SpongeCriterionBuilder; -import org.spongepowered.common.advancement.SpongeEmptyCriterion; +import org.spongepowered.common.advancement.criterion.SpongeCriterionBuilder; +import org.spongepowered.common.advancement.criterion.SpongeEmptyCriterion; public final class SpongeAdvancementCriterionFactory implements AdvancementCriterion.Factory { diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/AdvancementMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/AdvancementMixin_API.java index 9961c6a0d9c..005ba0043bc 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/AdvancementMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/AdvancementMixin_API.java @@ -28,12 +28,15 @@ import net.kyori.adventure.text.Component; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.DisplayInfo; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.ITextComponent; import org.spongepowered.api.ResourceKey; import org.spongepowered.api.advancement.AdvancementTree; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.common.adventure.SpongeAdventure; import org.spongepowered.common.bridge.advancements.AdvancementBridge; import java.util.Collection; @@ -44,14 +47,20 @@ import javax.annotation.Nullable; @Mixin(Advancement.class) -public abstract class AdvancementMixin_API implements org.spongepowered.api.advancement.Advancement { +public abstract class AdvancementMixin_API implements org.spongepowered.api.advancement.Advancement, AdvancementTree { @Shadow @Final @Nullable private DisplayInfo display; @Shadow @Final private Set children; + @Shadow @Final private ResourceLocation id; + @Shadow @Final private ITextComponent displayText; + @Shadow @Final private Advancement parent; @Override public Optional getTree() { - return ((AdvancementBridge) this).bridge$getTree(); + if (this.parent == null) { + return Optional.of(this); + } + return ((org.spongepowered.api.advancement.Advancement) this.parent).getTree(); } @SuppressWarnings({"unchecked", "rawtypes"}) @@ -83,16 +92,24 @@ public List toToastText() { @Override public ResourceKey getKey() { - return ((AdvancementBridge) this).bridge$getKey(); + return (ResourceKey) (Object) this.id; } @Override - public String getName() { - throw new UnsupportedOperationException(); + public Component asComponent() { + return SpongeAdventure.asAdventure(this.displayText); } @Override - public Component asComponent() { - return ((AdvancementBridge) this).bridge$getText(); + public org.spongepowered.api.advancement.Advancement getRootAdvancement() { + return this; + } + + @Override + public String getBackgroundPath() { + if (this.display == null) { + return null; + } + return this.display.getBackground().getPath(); } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/AdvancementProgressMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/AdvancementProgressMixin_API.java index 53368646c88..91a60197ef2 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/AdvancementProgressMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/AdvancementProgressMixin_API.java @@ -32,7 +32,7 @@ import org.spongepowered.api.advancement.criteria.ScoreAdvancementCriterion; import org.spongepowered.api.advancement.criteria.ScoreCriterionProgress; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.common.advancement.ImplementationBackedCriterionProgress; +import org.spongepowered.common.advancement.criterion.ImplementationBackedCriterionProgress; import org.spongepowered.common.bridge.advancements.AdvancementProgressBridge; import java.time.Instant; @@ -65,16 +65,16 @@ public Advancement getAdvancement() { @Override public Optional get(AdvancementCriterion criterion) { Preconditions.checkNotNull(criterion, "criterion"); - final Map map = ((AdvancementProgressBridge) this).bridge$getProgressMap(); + final Map map = ((AdvancementProgressBridge) this).bridge$getProgressMap(); Preconditions.checkState(map != null, "progressMap isn't initialized"); - return Optional.ofNullable((CriterionProgress) map.get(criterion)); + return Optional.ofNullable((CriterionProgress) map.get(criterion.getName())); } @Override public Optional get(ScoreAdvancementCriterion criterion) { Preconditions.checkNotNull(criterion); - final Map map = ((AdvancementProgressBridge) this).bridge$getProgressMap(); + final Map map = ((AdvancementProgressBridge) this).bridge$getProgressMap(); Preconditions.checkState(map != null, "progressMap isn't initialized"); - return Optional.ofNullable((ScoreCriterionProgress) map.get(criterion)); + return Optional.ofNullable((ScoreCriterionProgress) map.get(criterion.getName())); } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/CriterionMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/CriterionMixin_API.java index 780357ce873..bb39ec6a39a 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/CriterionMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/CriterionMixin_API.java @@ -30,7 +30,7 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.common.advancement.DefaultedAdvancementCriterion; +import org.spongepowered.common.advancement.criterion.DefaultedAdvancementCriterion; import org.spongepowered.common.bridge.advancements.CriterionBridge; import java.util.Optional; diff --git a/invalid/main/java/org/spongepowered/common/mixin/api/mcp/advancements/CriterionProgressMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/CriterionProgressMixin_API.java similarity index 74% rename from invalid/main/java/org/spongepowered/common/mixin/api/mcp/advancements/CriterionProgressMixin_API.java rename to src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/CriterionProgressMixin_API.java index 58dbc20511c..6521c772597 100644 --- a/invalid/main/java/org/spongepowered/common/mixin/api/mcp/advancements/CriterionProgressMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/CriterionProgressMixin_API.java @@ -25,15 +25,13 @@ package org.spongepowered.common.mixin.api.mcp.advancements; import net.minecraft.advancements.Advancement; -import net.minecraft.advancements.AdvancementProgress; import net.minecraft.advancements.CriterionProgress; +import org.spongepowered.api.advancement.AdvancementProgress; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.common.bridge.advancements.AdvancementProgressBridge; import org.spongepowered.common.bridge.advancements.CriterionProgressBridge; -import org.spongepowered.common.util.MissingImplementationException; import java.time.Instant; import java.util.Date; @@ -67,12 +65,10 @@ public Instant grant() { if (this.obtained != null) { return this.obtained.toInstant(); } - throw new MissingImplementationException("CriterionProgress", "grant()java.time.Instant;"); -// final Advancement advancement = (Advancement) ((org.spongepowered.api.advancement.AdvancementProgress) -// this.advancementProgress).getAdvancement(); -// ((AdvancementProgressBridge) this.advancementProgress).bridge$getPlayerAdvancements() -// .grantCriterion(advancement, this.getCriterion().getName()); -// return this.obtained.toInstant(); + final AdvancementProgress advancementProgress = ((CriterionProgressBridge) this).bridge$getAdvancementProgress(); + final org.spongepowered.api.advancement.Advancement advancement = advancementProgress.getAdvancement(); + ((AdvancementProgressBridge) advancementProgress).bridge$getPlayerAdvancements().grantCriterion((Advancement) advancement, this.getCriterion().getName()); + return this.obtained.toInstant(); } @Override @@ -81,10 +77,9 @@ public Optional revoke() { return Optional.empty(); } final Instant instant = this.obtained.toInstant(); - final Advancement advancement = (Advancement) ((org.spongepowered.api.advancement.AdvancementProgress) - this.advancementProgress).getAdvancement(); - ((AdvancementProgressBridge) this.advancementProgress).bridge$getPlayerAdvancements() - .revokeCriterion(advancement, this.getCriterion().getName()); + final AdvancementProgress advancementProgress = ((CriterionProgressBridge) this).bridge$getAdvancementProgress(); + final org.spongepowered.api.advancement.Advancement advancement = advancementProgress.getAdvancement(); + ((AdvancementProgressBridge) advancementProgress).bridge$getPlayerAdvancements().revokeCriterion((Advancement) advancement, this.getCriterion().getName()); return Optional.of(instant); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/DisplayInfoMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/DisplayInfoMixin_API.java index 18fafac18b1..f6a36bdca5c 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/DisplayInfoMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/mcp/advancements/DisplayInfoMixin_API.java @@ -27,10 +27,12 @@ import net.kyori.adventure.text.Component; import net.minecraft.advancements.DisplayInfo; import net.minecraft.advancements.FrameType; +import net.minecraft.item.ItemStack; import net.minecraft.util.text.ITextComponent; import org.spongepowered.api.advancement.Advancement; import org.spongepowered.api.advancement.AdvancementType; import org.spongepowered.api.advancement.TreeLayoutElement; +import org.spongepowered.api.item.inventory.ItemStackSnapshot; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Implements; import org.spongepowered.asm.mixin.Interface; @@ -39,6 +41,7 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.common.adventure.SpongeAdventure; import org.spongepowered.common.bridge.advancements.DisplayInfoBridge; +import org.spongepowered.common.item.util.ItemStackUtil; import org.spongepowered.math.vector.Vector2d; @Mixin(DisplayInfo.class) @@ -54,6 +57,10 @@ public abstract class DisplayInfoMixin_API implements TreeLayoutElement, org.spo @Shadow public abstract boolean shadow$shouldAnnounceToChat(); @Shadow public abstract boolean shadow$isHidden(); + @Shadow @Final private ItemStack icon; + + @Shadow @Final private boolean hidden; + @Override public Advancement getAdvancement() { return ((DisplayInfoBridge) this).bridge$getAdvancement(); @@ -86,6 +93,16 @@ public Component getTitle() { return SpongeAdventure.asAdventure(this.title); } + @Override + public ItemStackSnapshot getIcon() { + return ItemStackUtil.snapshotOf(this.icon); + } + + @Override + public boolean isHidden() { + return this.hidden; + } + @Override public boolean doesShowToast() { return this.showToast; diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/mcp/command/arguments/EntitySelectorParserMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/mcp/command/arguments/EntitySelectorParserMixin_API.java index f3504a0e6ef..122f5658520 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/mcp/command/arguments/EntitySelectorParserMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/mcp/command/arguments/EntitySelectorParserMixin_API.java @@ -439,7 +439,7 @@ public Selector build() throws IllegalStateException { if (this.api$criterion == null) { this.api$criterion = new HashMap<>(); } - this.api$criterion.computeIfAbsent(advancement.getName(), k -> new Object2BooleanOpenHashMap<>()).put(criterion.getName(), inverted); + this.api$criterion.computeIfAbsent(advancement.getKey().toString(), k -> new Object2BooleanOpenHashMap<>()).put(criterion.getName(), inverted); return this; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/mcp/entity/player/ServerPlayerEntityMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/mcp/entity/player/ServerPlayerEntityMixin_API.java index 39ac69ba184..4b33dfdf7a3 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/mcp/entity/player/ServerPlayerEntityMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/mcp/entity/player/ServerPlayerEntityMixin_API.java @@ -378,7 +378,6 @@ public CooldownTracker getCooldownTracker() { @Override public AdvancementProgress getProgress(final Advancement advancement) { Preconditions.checkNotNull(advancement, "advancement"); - Preconditions.checkState(((AdvancementBridge) advancement).bridge$isRegistered(), "The advancement must be registered"); return (AdvancementProgress) this.advancements.getProgress((net.minecraft.advancements.Advancement) advancement); } diff --git a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/CriteriaTriggersMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/AdvancementBuilderMixin.java similarity index 59% rename from invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/CriteriaTriggersMixin.java rename to src/mixins/java/org/spongepowered/common/mixin/core/advancements/AdvancementBuilderMixin.java index 2929d306456..aafdc3626c8 100644 --- a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/CriteriaTriggersMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/AdvancementBuilderMixin.java @@ -22,23 +22,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.mixin.invalid.core.advancements; +package org.spongepowered.common.mixin.core.advancements; -import net.minecraft.advancements.CriteriaTriggers; -import net.minecraft.advancements.ICriterionTrigger; -import org.spongepowered.api.advancement.criteria.trigger.Trigger; +import net.minecraft.advancements.Advancement; 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 org.spongepowered.common.registry.type.advancement.TriggerTypeRegistryModule; +import org.spongepowered.common.bridge.advancements.AdvancementBridge; -@Mixin(CriteriaTriggers.class) -public abstract class CriteriaTriggersMixin { +@Mixin(Advancement.Builder.class) +public abstract class AdvancementBuilderMixin implements AdvancementBridge { +// +// @Redirect(method = "serialize", at = @At(value = "INVOKE", target = "Ljava/util/Map;entrySet()Ljava/util/Set;")) +// public Set> impl$getCriteraSet(Map criteria) { +// return criteria.entrySet(); +// } - @SuppressWarnings("rawtypes") - @Inject(method = "register", at = @At("RETURN")) - private static void onRegister(ICriterionTrigger criterion, CallbackInfoReturnable ci) { - TriggerTypeRegistryModule.getInstance().register((Trigger) criterion); - } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/advancements/AdvancementMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/AdvancementMixin.java new file mode 100644 index 00000000000..223a8b0e199 --- /dev/null +++ b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/AdvancementMixin.java @@ -0,0 +1,185 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.mixin.core.advancements; + +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import net.kyori.adventure.text.Component; +import net.minecraft.advancements.Advancement; +import net.minecraft.advancements.AdvancementRewards; +import net.minecraft.advancements.Criterion; +import net.minecraft.advancements.DisplayInfo; +import net.minecraft.advancements.FrameType; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.ITextComponent; +import org.spongepowered.api.advancement.criteria.AdvancementCriterion; +import org.spongepowered.api.advancement.criteria.AndCriterion; +import org.spongepowered.api.advancement.criteria.OrCriterion; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Overwrite; +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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.common.SpongeImplHooks; +import org.spongepowered.common.advancement.criterion.DefaultedAdvancementCriterion; +import org.spongepowered.common.advancement.criterion.SpongeScoreCriterion; +import org.spongepowered.common.advancement.criterion.SpongeScoreTrigger; +import org.spongepowered.common.adventure.SpongeAdventure; +import org.spongepowered.common.bridge.advancements.AdvancementBridge; +import org.spongepowered.common.bridge.advancements.CriterionBridge; +import org.spongepowered.common.bridge.advancements.DisplayInfoBridge; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import javax.annotation.Nullable; + +@Mixin(Advancement.class) +public abstract class AdvancementMixin implements AdvancementBridge { + + @Shadow @Final @Mutable @Nullable private Advancement parent; + @Shadow @Final @Mutable private String[][] requirements; + @Shadow @Final @Mutable private Map criteria; + @Shadow @Final @Nullable private DisplayInfo display; + @Shadow @Final private ResourceLocation id; + + @Shadow @Final private ITextComponent displayText; + @Shadow @Final private AdvancementRewards rewards; + private AdvancementCriterion impl$criterion; + private List impl$toastText; + + @SuppressWarnings({"ConstantConditions"}) + @Inject(method = "", at = @At("RETURN")) + private void impl$setUpSpongeFields(ResourceLocation location, @Nullable Advancement parent, @Nullable DisplayInfo displayInfo, + AdvancementRewards rewards, Map criteria, String[][] requirements, CallbackInfo ci) { + // Don't do anything on the client, unless we're performing registry initialization + if (!SpongeImplHooks.onServerThread()) { + return; + } + if (displayInfo != null) { + ((DisplayInfoBridge) displayInfo).bridge$setAdvancement((org.spongepowered.api.advancement.Advancement) this); + } + + this.impl$toastText = this.impl$generateToastText(); + + final Map criteriaMap = new LinkedHashMap<>(); + final Map> scoreCriteria = new HashMap<>(); + for (Map.Entry entry : criteria.entrySet()) { + final CriterionBridge mixinCriterion = (CriterionBridge) entry.getValue(); + final String groupName = mixinCriterion.bridge$getScoreCriterionName(); + if (groupName != null) { + scoreCriteria.computeIfAbsent(groupName, k -> new ArrayList<>()).add((DefaultedAdvancementCriterion) entry.getValue()); + } + + criteriaMap.put(entry.getKey(), (DefaultedAdvancementCriterion) mixinCriterion); + mixinCriterion.bridge$setName(entry.getKey()); + } + for (Map.Entry> groupEntry : scoreCriteria.entrySet()) { + criteriaMap.put(groupEntry.getKey(), new SpongeScoreCriterion(groupEntry.getKey(), groupEntry.getValue())); + groupEntry.getValue().forEach(c -> criteriaMap.remove(c.getName())); + } + + final Set andCriteria = new HashSet<>(); + for (final String[] array : requirements) { + final Set orCriteria = new HashSet<>(); + for (final String name : array) { + DefaultedAdvancementCriterion criterion = criteriaMap.get(name); + if (criterion == null && criteria.get(name) != null) { // internal removed by scoreCriterion + criterion = criteriaMap.get(((CriterionBridge) criteria.get(name)).bridge$getScoreCriterionName()); + } + orCriteria.add(criterion); + } + andCriteria.add(OrCriterion.of(orCriteria)); + } + this.impl$criterion = AndCriterion.of(andCriteria); + } + + private ImmutableList impl$generateToastText() { + final ImmutableList.Builder toastText = ImmutableList.builder(); + if (this.display != null) { + final FrameType frameType = this.display.getFrame(); + toastText.add(Component.translatable("advancements.toast." + frameType.getName(), SpongeAdventure.asAdventureNamed(frameType.getFormat()))); + toastText.add(SpongeAdventure.asAdventure(this.display.getTitle())); + } else { + + toastText.add(Component.text("Unlocked advancement")); + toastText.add(Component.text(this.id.toString())); + } + return toastText.build(); + } + + @Override + public Optional bridge$getParent() { + checkState(SpongeImplHooks.onServerThread()); + return Optional.ofNullable(this.parent); + } + + @Override + public void bridge$setParent(@Nullable final Advancement advancement) { + checkState(SpongeImplHooks.onServerThread()); + this.parent = advancement; + } + + @Override + public AdvancementCriterion bridge$getCriterion() { + checkState(SpongeImplHooks.onServerThread()); + return this.impl$criterion; + } + + @Override + public void bridge$setCriterion(final AdvancementCriterion criterion) { + checkState(SpongeImplHooks.onServerThread()); + this.impl$criterion = criterion; + } + + @Override + public List bridge$getToastText() { + checkState(SpongeImplHooks.onServerThread()); + return this.impl$toastText; + } + + /** + * @author faithcaio - 2020-10-01 + * @reason Fix vanilla deserializing empty rewards as null + * + * @return the fixed AdvancementRewards + */ + @Overwrite + public AdvancementRewards getRewards() { + return this.rewards == null ? AdvancementRewards.EMPTY : this.rewards; + } +} diff --git a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/AdvancementProgressMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/AdvancementProgressMixin.java similarity index 78% rename from invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/AdvancementProgressMixin.java rename to src/mixins/java/org/spongepowered/common/mixin/core/advancements/AdvancementProgressMixin.java index 4a865b5e369..ac52e27262e 100644 --- a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/AdvancementProgressMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/AdvancementProgressMixin.java @@ -22,14 +22,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.mixin.invalid.core.advancements; +package org.spongepowered.common.mixin.core.advancements; import static com.google.common.base.Preconditions.checkState; import net.minecraft.advancements.AdvancementProgress; import net.minecraft.advancements.Criterion; import net.minecraft.advancements.PlayerAdvancements; -import org.spongepowered.api.ResourceKey; +import net.minecraft.util.ResourceLocation; import org.spongepowered.api.CatalogType; import org.spongepowered.api.advancement.Advancement; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; @@ -37,10 +37,10 @@ import org.spongepowered.api.advancement.criteria.CriterionProgress; import org.spongepowered.api.advancement.criteria.OperatorCriterion; import org.spongepowered.api.advancement.criteria.OrCriterion; -import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; +import org.spongepowered.api.event.Cause; import org.spongepowered.api.event.SpongeEventFactory; import org.spongepowered.api.event.advancement.CriterionEvent; -import org.spongepowered.api.event.cause.Cause; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -50,42 +50,47 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.common.SpongeCommon; import org.spongepowered.common.SpongeImplHooks; -import org.spongepowered.common.advancement.ImplementationBackedCriterionProgress; -import org.spongepowered.common.advancement.SpongeAndCriterion; -import org.spongepowered.common.advancement.SpongeAndCriterionProgress; -import org.spongepowered.common.advancement.SpongeEmptyCriterion; -import org.spongepowered.common.advancement.SpongeOrCriterion; -import org.spongepowered.common.advancement.SpongeOrCriterionProgress; -import org.spongepowered.common.advancement.SpongeScoreCriterion; -import org.spongepowered.common.advancement.SpongeScoreCriterionProgress; +import org.spongepowered.common.advancement.criterion.ImplementationBackedCriterionProgress; +import org.spongepowered.common.advancement.criterion.SpongeAndCriterion; +import org.spongepowered.common.advancement.criterion.SpongeAndCriterionProgress; +import org.spongepowered.common.advancement.criterion.SpongeEmptyCriterion; +import org.spongepowered.common.advancement.criterion.SpongeOrCriterion; +import org.spongepowered.common.advancement.criterion.SpongeOrCriterionProgress; +import org.spongepowered.common.advancement.criterion.SpongeScoreCriterion; +import org.spongepowered.common.advancement.criterion.SpongeScoreCriterionProgress; import org.spongepowered.common.bridge.advancements.AdvancementProgressBridge; import org.spongepowered.common.bridge.advancements.CriterionBridge; import org.spongepowered.common.bridge.advancements.CriterionProgressBridge; import org.spongepowered.common.bridge.advancements.PlayerAdvancementsBridge; import org.spongepowered.common.event.tracking.PhaseTracker; -import org.spongepowered.common.registry.type.advancement.AdvancementRegistryModule; -import javax.annotation.Nullable; import java.time.Instant; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Optional; +import javax.annotation.Nullable; + @Mixin(AdvancementProgress.class) public abstract class AdvancementProgressMixin implements AdvancementProgressBridge { @Shadow @Final private Map criteria; - @Nullable private Map impl$progressMap; - @Nullable private ResourceKey impl$advancementKey; + @Nullable private Map impl$progressMap; + @Nullable private ResourceLocation impl$advancementKey; @Nullable private PlayerAdvancements impl$playerAdvancements; @Override public Advancement bridge$getAdvancement() { checkState(SpongeImplHooks.onServerThread()); checkState(this.impl$advancementKey != null, "The advancement is not yet initialized"); - return AdvancementRegistryModule.getInstance().get(this.impl$advancementKey).orElseThrow(() -> new IllegalStateException( - "The advancement of this advancement progress is unloaded: " + this.impl$advancementKey)); + + final net.minecraft.advancements.Advancement advancement = SpongeCommon.getServer().getAdvancementManager().getAdvancement(this.impl$advancementKey); + if (advancement == null) { + throw new IllegalStateException("The advancement of this advancement progress is unloaded: " + this.impl$advancementKey); + } + return ((Advancement) advancement); } @Override @@ -102,7 +107,7 @@ public abstract class AdvancementProgressMixin implements AdvancementProgressBri } @Override - public void bridge$setAdvancementKey(ResourceKey key) { + public void bridge$setAdvancementId(ResourceLocation key) { checkState(SpongeImplHooks.onServerThread()); this.impl$advancementKey = key; } @@ -124,7 +129,7 @@ public abstract class AdvancementProgressMixin implements AdvancementProgressBri } final Optional advancement = this.getOptionalAdvancement(); if (advancement.isPresent()) { - this.impl$progressMap = new HashMap<>(); + this.impl$progressMap = new LinkedHashMap<>(); this.impl$processProgressMap(advancement.get().getCriterion(), this.impl$progressMap); } else { this.impl$progressMap = null; @@ -132,12 +137,12 @@ public abstract class AdvancementProgressMixin implements AdvancementProgressBri } @Override - public Map bridge$getProgressMap() { + public Map bridge$getProgressMap() { return this.impl$progressMap; } @Inject(method = "update", at = @At("RETURN")) - private void impl$updateCriterionsandMap(Map criteria, String[][] requirements, CallbackInfo ci) { + private void impl$updateCriterionsAndMap(Map criteria, String[][] requirements, CallbackInfo ci) { // Validate the requirements to check whether their // criterion actually exists, prevents bugs when mods // accidentally use non existent requirements @@ -157,35 +162,33 @@ public abstract class AdvancementProgressMixin implements AdvancementProgressBri this.bridge$updateProgressMap(); } - private Map impl$getProgressMap() { + private Map impl$getProgressMap() { checkState(this.impl$progressMap != null, "progressMap isn't initialized"); return this.impl$progressMap; } - private void impl$processProgressMap(AdvancementCriterion criterion, - Map progressMap) { + private void impl$processProgressMap(AdvancementCriterion criterion, Map progressMap) { if (criterion instanceof OperatorCriterion) { ((OperatorCriterion) criterion).getCriteria().forEach(child -> this.impl$processProgressMap(child, progressMap)); if (criterion instanceof AndCriterion) { - progressMap.put(criterion, - new SpongeAndCriterionProgress((org.spongepowered.api.advancement.AdvancementProgress) this, (SpongeAndCriterion) criterion)); + progressMap.put(criterion.getName(), new SpongeAndCriterionProgress((org.spongepowered.api.advancement.AdvancementProgress) this, (SpongeAndCriterion) criterion)); } else if (criterion instanceof OrCriterion) { - progressMap.put(criterion, - new SpongeOrCriterionProgress((org.spongepowered.api.advancement.AdvancementProgress) this, (SpongeOrCriterion) criterion)); + progressMap.put(criterion.getName(), new SpongeOrCriterionProgress((org.spongepowered.api.advancement.AdvancementProgress) this, (SpongeOrCriterion) criterion)); } } else if (criterion instanceof SpongeScoreCriterion) { final SpongeScoreCriterion scoreCriterion = (SpongeScoreCriterion) criterion; for (final AdvancementCriterion internalCriterion : scoreCriterion.internalCriteria) { final CriterionProgressBridge progress = (CriterionProgressBridge) this.criteria.get(internalCriterion.getName()); progress.bridge$setCriterion(internalCriterion); - progressMap.put(internalCriterion, (ImplementationBackedCriterionProgress) progress); + progress.bridge$setAdvancementProgress((org.spongepowered.api.advancement.AdvancementProgress) this); + progressMap.put(internalCriterion.getName(), (ImplementationBackedCriterionProgress) progress); } - progressMap.put(scoreCriterion, - new SpongeScoreCriterionProgress((org.spongepowered.api.advancement.AdvancementProgress) this, scoreCriterion)); + progressMap.put(scoreCriterion.getName(), new SpongeScoreCriterionProgress((org.spongepowered.api.advancement.AdvancementProgress) this, scoreCriterion)); } else if (criterion != SpongeEmptyCriterion.INSTANCE) { final CriterionProgressBridge progress = (CriterionProgressBridge) this.criteria.get(criterion.getName()); progress.bridge$setCriterion(criterion); - progressMap.put(criterion, (ImplementationBackedCriterionProgress) progress); + progress.bridge$setAdvancementProgress((org.spongepowered.api.advancement.AdvancementProgress) this); + progressMap.put(criterion.getName(), (ImplementationBackedCriterionProgress) progress); } } @@ -201,7 +204,7 @@ public abstract class AdvancementProgressMixin implements AdvancementProgressBri final Advancement advancement = this.getOptionalAdvancement().orElse(null); if (advancement != null) { - final ImplementationBackedCriterionProgress bridge = this.impl$progressMap.get(advancement.getCriterion()); + final ImplementationBackedCriterionProgress bridge = this.impl$progressMap.get(advancement.getCriterion().getName()); ci.setReturnValue(bridge != null && ((CriterionProgress) bridge).achieved()); } } @@ -229,7 +232,7 @@ public abstract class AdvancementProgressMixin implements AdvancementProgressBri return true; } final Cause cause = PhaseTracker.getCauseStackManager().getCurrentCause(); - final Player player = ((PlayerAdvancementsBridge) this.impl$playerAdvancements).bridge$getPlayer(); + final ServerPlayer player = ((PlayerAdvancementsBridge) this.impl$playerAdvancements).bridge$getPlayer(); final CriterionProgress progress = (CriterionProgress) criterionProgress; final AdvancementCriterion criterion = progress.getCriterion(); final CriterionBridge criterionBridge = (CriterionBridge) criterion; @@ -237,7 +240,7 @@ public abstract class AdvancementProgressMixin implements AdvancementProgressBri final SpongeScoreCriterion scoreCriterion = criterionBridge.bridge$getScoreCriterion(); final CriterionEvent event; if (scoreCriterion != null) { - final SpongeScoreCriterionProgress scoreProgress = (SpongeScoreCriterionProgress) this.impl$progressMap.get(scoreCriterion); + final SpongeScoreCriterionProgress scoreProgress = (SpongeScoreCriterionProgress) this.impl$progressMap.get(scoreCriterion.getName()); final int lastScore = scoreProgress.getScore(); final int score = lastScore + 1; if (lastScore == scoreCriterion.getGoal()) { @@ -284,33 +287,34 @@ public abstract class AdvancementProgressMixin implements AdvancementProgressBri return true; } final Cause cause = PhaseTracker.getCauseStackManager().getCurrentCause(); - final Player player = ((PlayerAdvancementsBridge) this.impl$playerAdvancements).bridge$getPlayer(); + final ServerPlayer player = ((PlayerAdvancementsBridge) this.impl$playerAdvancements).bridge$getPlayer(); final CriterionProgress progress = (CriterionProgress) criterionProgress; final AdvancementCriterion criterion = progress.getCriterion(); final CriterionBridge criterionBridge = (CriterionBridge) criterion; // The score criterion needs special care final SpongeScoreCriterion scoreCriterion = criterionBridge.bridge$getScoreCriterion(); final CriterionEvent event; + final Advancement advancement = ((org.spongepowered.api.advancement.AdvancementProgress) this).getAdvancement(); if (scoreCriterion != null) { - final SpongeScoreCriterionProgress scoreProgress = (SpongeScoreCriterionProgress) this.impl$progressMap.get(scoreCriterion); + final SpongeScoreCriterionProgress scoreProgress = (SpongeScoreCriterionProgress) this.impl$progressMap.get(scoreCriterion.getName()); final int lastScore = scoreProgress.getScore(); final int score = lastScore + 1; if (lastScore == scoreCriterion.getGoal()) { event = SpongeEventFactory.createCriterionEventScoreRevoke( - cause, ((org.spongepowered.api.advancement.AdvancementProgress) this).getAdvancement(), scoreCriterion, player, lastScore, + cause, advancement, scoreCriterion, player, lastScore, score); } else if (score == scoreCriterion.getGoal()) { event = SpongeEventFactory.createCriterionEventScoreGrant( - cause, ((org.spongepowered.api.advancement.AdvancementProgress) this).getAdvancement(), scoreCriterion, player, Instant.now(), + cause, advancement, scoreCriterion, player, Instant.now(), lastScore, score); } else { event = SpongeEventFactory.createCriterionEventScoreChange( - cause, ((org.spongepowered.api.advancement.AdvancementProgress) this).getAdvancement(), scoreCriterion, player, lastScore, + cause, advancement, scoreCriterion, player, lastScore, score); } } else { event = SpongeEventFactory.createCriterionEventRevoke( - cause, ((org.spongepowered.api.advancement.AdvancementProgress) this).getAdvancement(), criterion, player); + cause, advancement, criterion, player); } if (SpongeCommon.postEvent(event)) { return false; @@ -328,6 +332,7 @@ public abstract class AdvancementProgressMixin implements AdvancementProgressBri private Optional getOptionalAdvancement() { checkState(SpongeImplHooks.onServerThread()); checkState(this.impl$advancementKey != null, "The advancement is not yet initialized"); - return AdvancementRegistryModule.getInstance().get(this.impl$advancementKey); + final net.minecraft.advancements.Advancement advancement = SpongeCommon.getServer().getAdvancementManager().getAdvancement(this.impl$advancementKey); + return Optional.ofNullable((Advancement)advancement); } } diff --git a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/AdvancementTreeNodeMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/AdvancementTreeNodeMixin.java similarity index 80% rename from invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/AdvancementTreeNodeMixin.java rename to src/mixins/java/org/spongepowered/common/mixin/core/advancements/AdvancementTreeNodeMixin.java index 797f64f1e3b..e120a5e3423 100644 --- a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/AdvancementTreeNodeMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/AdvancementTreeNodeMixin.java @@ -22,20 +22,21 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.mixin.invalid.core.advancements; +package org.spongepowered.common.mixin.core.advancements; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementTreeNode; import org.spongepowered.api.Sponge; import org.spongepowered.api.advancement.AdvancementTree; import org.spongepowered.api.advancement.TreeLayout; +import org.spongepowered.api.event.Cause; import org.spongepowered.api.event.SpongeEventFactory; +import org.spongepowered.api.event.advancement.AdvancementTreeEvent; 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.common.SpongeCommon; -import org.spongepowered.common.advancement.SpongeAdvancementTree; import org.spongepowered.common.advancement.SpongeTreeLayout; @Mixin(AdvancementTreeNode.class) @@ -44,8 +45,9 @@ public abstract class AdvancementTreeNodeMixin { @Inject(method = "layout", at = @At("RETURN")) private static void onLayout(Advancement root, CallbackInfo ci) { final AdvancementTree advancementTree = ((org.spongepowered.api.advancement.Advancement) root).getTree().get(); - final TreeLayout layout = new SpongeTreeLayout((SpongeAdvancementTree) advancementTree); - SpongeCommon.postEvent(SpongeEventFactory.createAdvancementTreeEventGenerateLayout(Sponge.getCauseStackManager().getCurrentCause(), layout, - advancementTree)); + final TreeLayout layout = new SpongeTreeLayout(advancementTree); + final Cause cause = Sponge.getServer().getCauseStackManager().getCurrentCause(); + final AdvancementTreeEvent.GenerateLayout event = SpongeEventFactory.createAdvancementTreeEventGenerateLayout(cause, layout, advancementTree); + SpongeCommon.postEvent(event); } } diff --git a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/CriterionMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/CriterionMixin.java similarity index 70% rename from invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/CriterionMixin.java rename to src/mixins/java/org/spongepowered/common/mixin/core/advancements/CriterionMixin.java index b9105190a33..e5c871d638a 100644 --- a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/CriterionMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/CriterionMixin.java @@ -22,17 +22,21 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.mixin.invalid.core.advancements; +package org.spongepowered.common.mixin.core.advancements; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonObject; import net.minecraft.advancements.Criterion; +import net.minecraft.advancements.ICriterionInstance; import org.checkerframework.checker.nullness.qual.Nullable; +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.CallbackInfoReturnable; -import org.spongepowered.common.advancement.SpongeScoreCriterion; +import org.spongepowered.common.advancement.criterion.SpongeScoreCriterion; +import org.spongepowered.common.advancement.criterion.SpongeScoreTrigger; import org.spongepowered.common.bridge.advancements.CriterionBridge; import java.util.UUID; @@ -40,9 +44,11 @@ @Mixin(Criterion.class) public abstract class CriterionMixin implements CriterionBridge { + @Shadow @Final private ICriterionInstance criterionInstance; @Nullable private String impl$name; @Nullable private SpongeScoreCriterion impl$scoreCriterion; @Nullable private Integer impl$scoreGoal; + @Nullable private String impl$scoreCriterionName; @Inject(method = "criterionFromJson", at = @At("RETURN")) private static void impl$fixTriggerTimeDeserializer(final JsonObject json, final JsonDeserializationContext context, @@ -51,6 +57,19 @@ public abstract class CriterionMixin implements CriterionBridge { if (json.has("trigger_times")) { ((CriterionBridge) criterion).bridge$setScoreGoal(json.get("trigger_times").getAsInt()); } + if (json.has("criterion")) { + ((CriterionBridge) criterion).bridge$setScoreCriterionName(json.get("criterion").getAsString()); + } + } + + @Inject(method = "serialize", at = @At("RETURN")) + private void impl$serializeTriggerTimes(CallbackInfoReturnable cir) { + if (this.criterionInstance instanceof SpongeScoreTrigger.Instance) { + cir.getReturnValue().addProperty("trigger_times", ((SpongeScoreTrigger.Instance) this.criterionInstance).getTriggerTimes()); + } + if (this.impl$scoreCriterion != null) { + cir.getReturnValue().addProperty("criterion", this.impl$scoreCriterion.getName()); + } } @Override @@ -87,4 +106,15 @@ public abstract class CriterionMixin implements CriterionBridge { public void bridge$setScoreGoal(@Nullable final Integer goal) { this.impl$scoreGoal = goal; } + + @Override + public void bridge$setScoreCriterionName(String name) { + this.impl$scoreCriterionName = name; + } + + @Override + @Nullable + public String bridge$getScoreCriterionName() { + return this.impl$scoreCriterionName; + } } diff --git a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/CriterionProgressMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/CriterionProgressMixin.java similarity index 81% rename from invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/CriterionProgressMixin.java rename to src/mixins/java/org/spongepowered/common/mixin/core/advancements/CriterionProgressMixin.java index a35ab39bd69..538ab46f51c 100644 --- a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/CriterionProgressMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/CriterionProgressMixin.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.mixin.invalid.core.advancements; +package org.spongepowered.common.mixin.core.advancements; import net.minecraft.advancements.AdvancementProgress; import net.minecraft.advancements.CriterionProgress; @@ -33,30 +33,31 @@ 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.common.advancement.ImplementationBackedCriterionProgress; +import org.spongepowered.common.advancement.criterion.ImplementationBackedCriterionProgress; import org.spongepowered.common.bridge.advancements.AdvancementProgressBridge; import org.spongepowered.common.bridge.advancements.CriterionProgressBridge; -import javax.annotation.Nullable; import java.util.Date; +import javax.annotation.Nullable; + @Mixin(CriterionProgress.class) public abstract class CriterionProgressMixin implements CriterionProgressBridge, ImplementationBackedCriterionProgress { - @Shadow @Final private AdvancementProgress advancementProgress; @Shadow @Nullable private Date obtained; - @Nullable private AdvancementCriterion impl$criterion; - @Shadow public abstract void shadow$reset(); + @Nullable private AdvancementCriterion impl$criterion; + private org.spongepowered.api.advancement.AdvancementProgress impl$advancementProgress; + @Inject(method = "obtain", at = @At("RETURN")) private void onObtain(CallbackInfo ci) { - ((AdvancementProgressBridge) this.advancementProgress).bridge$invalidateAchievedState(); + ((AdvancementProgressBridge) this.impl$advancementProgress).bridge$invalidateAchievedState(); } @Inject(method = "reset", at = @At("RETURN")) private void onReset(CallbackInfo ci) { - ((AdvancementProgressBridge) this.advancementProgress).bridge$invalidateAchievedState(); + ((AdvancementProgressBridge) this.impl$advancementProgress).bridge$invalidateAchievedState(); } @Override @@ -71,9 +72,15 @@ private void onReset(CallbackInfo ci) { @Override public org.spongepowered.api.advancement.AdvancementProgress bridge$getAdvancementProgress() { - return (org.spongepowered.api.advancement.AdvancementProgress) this.advancementProgress; + return this.impl$advancementProgress; } + @Override + public void bridge$setAdvancementProgress(org.spongepowered.api.advancement.AdvancementProgress advancementProgress) { + this.impl$advancementProgress = advancementProgress; + } + + @Override public boolean bridge$isCriterionAvailable() { return this.impl$criterion != null; diff --git a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/DisplayInfoMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/DisplayInfoMixin.java similarity index 97% rename from invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/DisplayInfoMixin.java rename to src/mixins/java/org/spongepowered/common/mixin/core/advancements/DisplayInfoMixin.java index 784af34999a..0b73af4659a 100644 --- a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/DisplayInfoMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/DisplayInfoMixin.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.mixin.invalid.core.advancements; +package org.spongepowered.common.mixin.core.advancements; import static com.google.common.base.Preconditions.checkState; diff --git a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/ICriterionTrigger_ListenerMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/ICriterionTrigger_ListenerMixin.java similarity index 91% rename from invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/ICriterionTrigger_ListenerMixin.java rename to src/mixins/java/org/spongepowered/common/mixin/core/advancements/ICriterionTrigger_ListenerMixin.java index 6c228f2c347..22f8ae93c0f 100644 --- a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/ICriterionTrigger_ListenerMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/ICriterionTrigger_ListenerMixin.java @@ -22,21 +22,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.mixin.invalid.core.advancements; +package org.spongepowered.common.mixin.core.advancements; import com.google.common.reflect.TypeToken; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.ICriterionInstance; import net.minecraft.advancements.ICriterionTrigger; import net.minecraft.advancements.PlayerAdvancements; -import org.spongepowered.api.Sponge; import org.spongepowered.api.advancement.criteria.AdvancementCriterion; import org.spongepowered.api.advancement.criteria.ScoreAdvancementCriterion; import org.spongepowered.api.advancement.criteria.trigger.FilteredTrigger; -import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; +import org.spongepowered.api.event.Cause; import org.spongepowered.api.event.SpongeEventFactory; import org.spongepowered.api.event.advancement.CriterionEvent; -import org.spongepowered.api.event.cause.Cause; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -77,9 +76,9 @@ public abstract class ICriterionTrigger_ListenerMixin { if (!(this.criterionInstance instanceof SpongeFilteredTrigger)) { final FilteredTrigger filteredTrigger = (FilteredTrigger) this.criterionInstance; if (filteredTrigger.getType() instanceof SpongeTrigger) { - final Cause cause = Sponge.getCauseStackManager().getCurrentCause(); - final Player player = ((PlayerAdvancementsBridge) playerAdvancements).bridge$getPlayer(); - final TypeToken typeToken = TypeToken.of(filteredTrigger.getType().getConfigurationType()); + final Cause cause = PhaseTracker.getCauseStackManager().getCurrentCause(); + final ServerPlayer player = ((PlayerAdvancementsBridge) playerAdvancements).bridge$getPlayer(); + final TypeToken typeToken = TypeToken.of(filteredTrigger.getType().getConfigurationType()); final CriterionEvent.Trigger event = SpongeEventFactory.createCriterionEventTrigger(cause, advancement, advancementCriterion, typeToken, player, filteredTrigger, true); SpongeCommon.postEvent(event); diff --git a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/PlayerAdvancementsMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/PlayerAdvancementsMixin.java similarity index 88% rename from invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/PlayerAdvancementsMixin.java rename to src/mixins/java/org/spongepowered/common/mixin/core/advancements/PlayerAdvancementsMixin.java index 042da687f78..cb1d2d5da72 100644 --- a/invalid/main/java/org/spongepowered/common/mixin/invalid/core/advancements/PlayerAdvancementsMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/advancements/PlayerAdvancementsMixin.java @@ -22,9 +22,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.mixin.invalid.core.advancements; +package org.spongepowered.common.mixin.core.advancements; import com.google.common.collect.ImmutableSet; +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.text.Component; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementProgress; import net.minecraft.advancements.CriterionProgress; @@ -39,8 +41,6 @@ import org.spongepowered.api.event.SpongeEventFactory; import org.spongepowered.api.event.advancement.AdvancementEvent; import org.spongepowered.api.event.message.MessageEvent; -import org.spongepowered.api.text.Text; -import org.spongepowered.api.text.channel.MessageChannel; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -51,11 +51,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.common.SpongeCommon; import org.spongepowered.common.SpongeImplHooks; +import org.spongepowered.common.adventure.SpongeAdventure; import org.spongepowered.common.bridge.advancements.AdvancementProgressBridge; import org.spongepowered.common.bridge.advancements.CriterionBridge; import org.spongepowered.common.bridge.advancements.CriterionProgressBridge; import org.spongepowered.common.bridge.advancements.PlayerAdvancementsBridge; -import org.spongepowered.common.text.SpongeTexts; import java.time.Instant; import java.util.Map; @@ -71,12 +71,12 @@ public abstract class PlayerAdvancementsMixin implements PlayerAdvancementsBridg @Shadow private ServerPlayerEntity player; private boolean impl$wasSuccess; - @Nullable private Text impl$message; + @Nullable private Component impl$message; @Inject(method = "startProgress", at = @At("HEAD")) private void impl$setAdvancementsOnStart(final Advancement advancement, final AdvancementProgress progress, final CallbackInfo ci) { final AdvancementProgressBridge advancementProgress = (AdvancementProgressBridge) progress; - advancementProgress.bridge$setAdvancementKey(((org.spongepowered.api.advancement.Advancement) advancement).getKey()); + advancementProgress.bridge$setAdvancementId(advancement.getId()); advancementProgress.bridge$setPlayerAdvancements((PlayerAdvancements) (Object) this); } @@ -95,6 +95,8 @@ public abstract class PlayerAdvancementsMixin implements PlayerAdvancementsBridg final CriterionBridge mixinCriterion = (CriterionBridge) criterion; // Only remove the trigger once the goal is reached if (mixinCriterion.bridge$getScoreCriterion() != null) { + + return ((CriterionProgressBridge) progress).bridge$getAdvancementProgress() .get(mixinCriterion.bridge$getScoreCriterion()).get().achieved(); } @@ -154,7 +156,7 @@ public abstract class PlayerAdvancementsMixin implements PlayerAdvancementsBridg value = "INVOKE", target = "Lnet/minecraft/server/management/PlayerList;sendMessage(Lnet/minecraft/util/text/ITextComponent;)V")) private void impl$updateTextOnGranting(final PlayerList list, final ITextComponent component) { - this.impl$message = SpongeTexts.toText(component); + this.impl$message = SpongeAdventure.asAdventure(component); this.impl$wasSuccess = true; } @@ -176,28 +178,28 @@ public abstract class PlayerAdvancementsMixin implements PlayerAdvancementsBridg } final Instant instant = Instant.now(); - final MessageChannel channel; - final MessageEvent.MessageFormatter formatter; + + final Audience channel; if (this.impl$message != null) { - channel = MessageChannel.toPlayersAndServer(); - formatter = new MessageEvent.MessageFormatter(this.impl$message); + channel = Sponge.getServer().getBroadcastAudience(); } else { - channel = MessageChannel.toNone(); - formatter = new MessageEvent.MessageFormatter(); - formatter.clear(); + channel = Audience.empty(); } final AdvancementEvent.Grant event = SpongeEventFactory.createAdvancementEventGrant( - Sponge.getCauseStackManager().getCurrentCause(), + Sponge.getServer().getCauseStackManager().getCurrentCause(), channel, Optional.of(channel), + this.impl$message == null ? Component.empty() : this.impl$message, + this.impl$message == null ? Component.empty() : this.impl$message, (org.spongepowered.api.advancement.Advancement) advancement, - formatter, (ServerPlayer) this.player, instant, false + (ServerPlayer) this.player, instant, false ); SpongeCommon.postEvent(event); - if (!event.isMessageCancelled() && !event.getMessage().isEmpty()) { - event.getChannel().ifPresent(eventChannel -> eventChannel.send(this.player, event.getMessage())); + if (!event.isMessageCancelled()) { + event.getAudience().ifPresent(eventChannel -> eventChannel.sendMessage(event.getMessage())); +// TODO what was this.player here for? event.getChannel().ifPresent(eventChannel -> eventChannel.send(this.player, event.getMessage())); } this.impl$message = null; diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java index 861afa870d8..9b827904f9b 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java @@ -36,6 +36,7 @@ import org.apache.logging.log4j.Logger; import org.spongepowered.api.Game; import org.spongepowered.api.Sponge; +import org.spongepowered.api.advancement.Advancement; import org.spongepowered.api.event.Cause; import org.spongepowered.api.item.recipe.RecipeRegistration; import org.spongepowered.api.resourcepack.ResourcePack; @@ -53,6 +54,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.common.SpongeCommon; import org.spongepowered.common.SpongeServer; +import org.spongepowered.common.advancement.SpongeAdvancementProvider; import org.spongepowered.common.bridge.command.CommandSourceProviderBridge; import org.spongepowered.common.bridge.server.MinecraftServerBridge; import org.spongepowered.common.bridge.server.management.PlayerProfileCacheBridge; @@ -303,5 +305,6 @@ public void setDifficultyForAllWorlds(final Difficulty difficulty, final boolean ResultUtil.clearCache(); catalogRegistry.callDataPackRegisterCatalogEvents(Sponge.getServer().getCauseStackManager().getCurrentCause(), Sponge.getGame()); SpongeRecipeProvider.registerRecipes(catalogRegistry.getRegistry(RecipeRegistration.class)); + SpongeAdvancementProvider.registerAdvancements(catalogRegistry.getRegistry(Advancement.class)); } } diff --git a/src/mixins/resources/mixins.common.api.json b/src/mixins/resources/mixins.common.api.json index 25b631aacc4..cd63caa901a 100644 --- a/src/mixins/resources/mixins.common.api.json +++ b/src/mixins/resources/mixins.common.api.json @@ -19,7 +19,9 @@ "mcp.advancements.AdvancementMixin_API", "mcp.advancements.AdvancementProgressMixin_API", "mcp.advancements.CriterionMixin_API", + "mcp.advancements.CriterionProgressMixin_API", "mcp.advancements.DisplayInfoMixin_API", + "mcp.advancements.FrameTypeMixin_API", "mcp.advancements.ICriterionInstanceMixin_API", "mcp.advancements.ICriterionTriggerMixin_API", "mcp.block.BlockMixin_API", diff --git a/src/mixins/resources/mixins.common.core.json b/src/mixins/resources/mixins.common.core.json index d308ae5a229..be2c17eb972 100644 --- a/src/mixins/resources/mixins.common.core.json +++ b/src/mixins/resources/mixins.common.core.json @@ -7,7 +7,16 @@ "compatibilityLevel": "JAVA_8", "mixinPriority": 1101, "mixins": [ + "advancements.AdvancementBuilderMixin", + "advancements.AdvancementMixin", + "advancements.AdvancementProgressMixin", + "advancements.AdvancementTreeNodeMixin", + "advancements.CriterionMixin", + "advancements.CriterionProgressMixin", + "advancements.DisplayInfoMixin", "advancements.FunctionManagerMixin", + "advancements.ICriterionTrigger_ListenerMixin", + "advancements.PlayerAdvancementsMixin", "adventure.bossbar.BossBarImplMixin", "adventure.text.AbstractComponentMixin", "adventure.text.format.StyleImplMixin", diff --git a/testplugins/src/main/java/org/spongepowered/test/advancement/AdvancementTest.java b/testplugins/src/main/java/org/spongepowered/test/advancement/AdvancementTest.java new file mode 100644 index 00000000000..8eaef86bc2a --- /dev/null +++ b/testplugins/src/main/java/org/spongepowered/test/advancement/AdvancementTest.java @@ -0,0 +1,341 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.test.advancement; + +import com.google.inject.Inject; +import net.kyori.adventure.text.Component; +import org.apache.logging.log4j.Logger; +import org.spongepowered.api.ResourceKey; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.advancement.Advancement; +import org.spongepowered.api.advancement.AdvancementProgress; +import org.spongepowered.api.advancement.AdvancementTree; +import org.spongepowered.api.advancement.AdvancementTypes; +import org.spongepowered.api.advancement.DisplayInfo; +import org.spongepowered.api.advancement.TreeLayoutElement; +import org.spongepowered.api.advancement.criteria.AdvancementCriterion; +import org.spongepowered.api.advancement.criteria.AndCriterion; +import org.spongepowered.api.advancement.criteria.OrCriterion; +import org.spongepowered.api.advancement.criteria.ScoreAdvancementCriterion; +import org.spongepowered.api.advancement.criteria.trigger.FilteredTrigger; +import org.spongepowered.api.advancement.criteria.trigger.FilteredTriggerConfiguration; +import org.spongepowered.api.advancement.criteria.trigger.Trigger; +import org.spongepowered.api.block.BlockTypes; +import org.spongepowered.api.command.exception.CommandException; +import org.spongepowered.api.command.parameter.CommandContext; +import org.spongepowered.api.data.persistence.AbstractDataBuilder; +import org.spongepowered.api.data.persistence.DataContainer; +import org.spongepowered.api.data.persistence.DataSerializable; +import org.spongepowered.api.data.persistence.DataView; +import org.spongepowered.api.data.persistence.InvalidDataException; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.advancement.AdvancementEvent; +import org.spongepowered.api.event.advancement.AdvancementTreeEvent; +import org.spongepowered.api.event.advancement.CriterionEvent; +import org.spongepowered.api.event.filter.cause.First; +import org.spongepowered.api.event.item.inventory.ChangeInventoryEvent; +import org.spongepowered.api.event.item.inventory.container.InteractContainerEvent; +import org.spongepowered.api.event.lifecycle.RegisterCatalogEvent; +import org.spongepowered.api.item.ItemTypes; +import org.spongepowered.api.item.inventory.BlockCarrier; +import org.spongepowered.api.item.inventory.ItemStack; +import org.spongepowered.api.item.inventory.query.QueryTypes; +import org.spongepowered.api.item.inventory.type.CarriedInventory; +import org.spongepowered.plugin.PluginContainer; +import org.spongepowered.plugin.jvm.Plugin; +import org.spongepowered.test.LoadableModule; + +import java.util.Optional; + +@Plugin("advancementtest") +public final class AdvancementTest implements LoadableModule { + + @Inject private PluginContainer plugin; + @Inject private Logger logger; + private boolean enabled = false; + private Advancement rootAdvancement; + private Trigger inventoryChangeTrigger; + private TriggerListeners listeners = new TriggerListeners(); + private ScoreAdvancementCriterion counter1; + private AdvancementCriterion counter1Bypass; + private ScoreAdvancementCriterion counter2; + private Advancement counterAdvancement1; + private Advancement counterAdvancement2; + + @Override + public void enable(CommandContext ctx) { + this.enabled = true; + Sponge.getEventManager().registerListeners(this.plugin, this.listeners); + try { + Sponge.getCommandManager().process("reload"); + } catch (CommandException e) { + e.printStackTrace(); + } + ctx.getCause().first(ServerPlayer.class).map(player -> player.getProgress(this.rootAdvancement).grant()); + } + + @Override + public void disable(CommandContext ctx) { + this.enabled = false; + Sponge.getEventManager().unregisterListeners(this.listeners); + try { + Sponge.getCommandManager().process("reload"); + } catch (CommandException e) { + e.printStackTrace(); + } + } + + @Listener + public void onTreeAdjust(AdvancementTreeEvent.GenerateLayout event) { + final AdvancementTree tree = event.getTree(); + if (tree.equals(rootAdvancement)) { + final TreeLayoutElement layoutElement1 = event.getLayout().getElement(counterAdvancement1).get(); + final TreeLayoutElement layoutElement2 = event.getLayout().getElement(counterAdvancement2).get(); + layoutElement1.setPosition(layoutElement2.getPosition()); + layoutElement2.setPosition(layoutElement2.getPosition().add(-1,2)); + } + } + + @Listener + public void onGranted(AdvancementEvent.Grant event) { + this.logger.info("{} was granted", event.getAdvancement().getKey()); + } + + @Listener + public void onGranted(AdvancementEvent.Revoke event) { + this.logger.info("{} was revoked", event.getAdvancement().getKey()); + } + + @Listener + public void onTrigger(CriterionEvent.Trigger event) { + this.logger.info("{} for {} was triggered", event.getTrigger().getType().getKey(), event.getAdvancement().getKey()); + } + + @Listener + public void onTriggerRegistry(RegisterCatalogEvent event) { + Sponge.getDataManager().registerBuilder(InventoryChangeTriggerConfig.class, new InventoryChangeTriggerConfig.Builder()); + this.inventoryChangeTrigger = Trigger.builder() + .dataSerializableConfig(InventoryChangeTriggerConfig.class) + .listener(triggerEvent -> { + final ItemStack stack = triggerEvent.getTrigger().getConfiguration().stack; + final int found = triggerEvent.getPlayer().getInventory().query(QueryTypes.ITEM_STACK_IGNORE_QUANTITY, stack).totalQuantity(); + triggerEvent.setResult(stack.getQuantity() <= found); + }) + .id("my_inventory_trigger") + .build(); + event.register(this.inventoryChangeTrigger); + } + + + @Listener + @SuppressWarnings("unchecked") + public void onAdvancementRegistry(RegisterCatalogEvent event) { + + if (!enabled) { + return; + } + + this.rootAdvancement = Advancement.builder() + .criterion(AdvancementCriterion.dummy()) + .displayInfo(DisplayInfo.builder() + .icon(ItemTypes.COMMAND_BLOCK) + .title(Component.text("Advancement Tests")) + .description(Component.text("Dummy trigger. Granted manually after testplugin is enabled")) + .build()) + .root().background("textures/gui/advancements/backgrounds/stone.png") + .key(ResourceKey.of(this.plugin, "root")) + .build(); + event.register(rootAdvancement); + + final AdvancementCriterion someDirtCriterion = AdvancementCriterion.builder().trigger( + FilteredTrigger.builder() + .type(inventoryChangeTrigger) + .config(new InventoryChangeTriggerConfig(ItemStack.of(ItemTypes.DIRT))) + .build() + ).name("some_dirt").build(); + + final Advancement someDirt = Advancement.builder() + .criterion(someDirtCriterion) + .displayInfo(DisplayInfo.builder() + .icon(ItemTypes.DIRT) + .title(Component.text("Got dirt!")) + .type(AdvancementTypes.TASK) + .build()) + .parent(this.rootAdvancement) + .key(ResourceKey.of(this.plugin, "some_dirt")) + .build(); + event.register(someDirt); + + final AdvancementCriterion lotsOfDirtCriterion = AdvancementCriterion.builder().trigger( + FilteredTrigger.builder() + .type(inventoryChangeTrigger) + .config(new InventoryChangeTriggerConfig(ItemStack.of(ItemTypes.DIRT, 64))) + .build() + ).name("lots_of_dirt").build(); + + final Advancement lotsOfDirt = Advancement.builder() + .criterion(lotsOfDirtCriterion) + .displayInfo(DisplayInfo.builder() + .icon(ItemTypes.DIRT) + .title(Component.text("Got more dirt!")) + .type(AdvancementTypes.GOAL) + .build()) + .parent(someDirt) + .key(ResourceKey.of(this.plugin, "lots_of_dirt")) + .build(); + event.register(lotsOfDirt); + + final AdvancementCriterion tonsOfDirtCriterion = AdvancementCriterion.builder().trigger( + FilteredTrigger.builder() + .type(inventoryChangeTrigger) + .config(new InventoryChangeTriggerConfig(ItemStack.of(ItemTypes.DIRT, 64*9))) + .build() + ).name("tons_of_dirt").build(); + + final Advancement tonsOfDirt = Advancement.builder() + .criterion(tonsOfDirtCriterion) + .displayInfo(DisplayInfo.builder() + .icon(ItemTypes.DIRT) + .title(Component.text("Got tons of dirt!")) + .type(AdvancementTypes.CHALLENGE) + .hidden(true) + .build()) + .parent(lotsOfDirt) + .key(ResourceKey.of(this.plugin, "tons_of_dirt")) + .build(); + event.register(tonsOfDirt); + + this.counter1 = ScoreAdvancementCriterion.builder().goal(10).name("counter").build(); + this.counter1Bypass = AdvancementCriterion.dummy(); + this.counterAdvancement1 = Advancement.builder() + .criterion(OrCriterion.of(counter1, counter1Bypass)) + .displayInfo(DisplayInfo.builder() + .icon(ItemTypes.CHEST) + .title(Component.text("Open some chests.")) + .type(AdvancementTypes.GOAL) + .build()) + .parent(this.rootAdvancement) + .key(ResourceKey.of(this.plugin, "counting")) + .build(); + event.register(this.counterAdvancement1); + + this.counter2 = ScoreAdvancementCriterion.builder().goal(20).name("counter").build(); + this.counterAdvancement2 = Advancement.builder() + .criterion(counter2) + .displayInfo(DisplayInfo.builder() + .icon(ItemTypes.CHEST) + .title(Component.text("Open more chests")) + .type(AdvancementTypes.CHALLENGE) + .build()) + .parent(counterAdvancement1) + .key(ResourceKey.of(this.plugin, "counting_more")) + .build(); + event.register(this.counterAdvancement2); + + final AdvancementCriterion a = AdvancementCriterion.builder().name("A").build(); + final AdvancementCriterion b = AdvancementCriterion.builder().name("B").build(); + final AdvancementCriterion c = AdvancementCriterion.builder().name("C").build(); + final AdvancementCriterion d = AdvancementCriterion.builder().name("D").build(); + final AdvancementCriterion e = AdvancementCriterion.builder().name("E").build(); + final AdvancementCriterion f = AdvancementCriterion.builder().name("F").build(); + final AdvancementCriterion combinationCriterion = OrCriterion.of(a, AndCriterion.of(b, OrCriterion.of(c, d)), AndCriterion.of(e, f)); + final Advancement combinationAdvancement = Advancement.builder() + .criterion(combinationCriterion) + .displayInfo(DisplayInfo.builder() + .icon(ItemTypes.CHEST) + .title(Component.text("A || (B & (C || D)) || (E & F)")) + .description(Component.text("ABE ABF ACDE ACDF")) + .type(AdvancementTypes.CHALLENGE) + .build()) + .parent(counterAdvancement1) + .key(ResourceKey.of(this.plugin, "combination")) + .build(); + event.register(combinationAdvancement); + } + + public class TriggerListeners { + + @Listener + public void onContainerEvent(ChangeInventoryEvent event, @First ServerPlayer player) { + AdvancementTest.this.inventoryChangeTrigger.trigger(player); + } + + @Listener + public void onConainterEvent(InteractContainerEvent.Open event, @First ServerPlayer player) { + + final AdvancementProgress progress1 = player.getProgress(AdvancementTest.this.counterAdvancement1); + if (progress1.achieved()) { + final AdvancementProgress progress2 = player.getProgress(AdvancementTest.this.counterAdvancement2); + progress2.require(AdvancementTest.this.counter2).add(1); + + } else { + progress1.require(AdvancementTest.this.counter1).add(1); + final Object carrier = ((CarriedInventory) event.getContainer()).getCarrier().orElse(null); + if (carrier instanceof BlockCarrier) { + if (((BlockCarrier) carrier).getLocation().getBlockType().isAnyOf(BlockTypes.TRAPPED_CHEST)) { + progress1.require(AdvancementTest.this.counter1Bypass).grant(); + } + } + } + } + + } + + public static class InventoryChangeTriggerConfig implements FilteredTriggerConfiguration, DataSerializable { + private ItemStack stack; + + public InventoryChangeTriggerConfig(ItemStack stack) { + this.stack = stack; + } + + public InventoryChangeTriggerConfig(DataView stack) { + this.stack = ItemStack.builder().fromContainer(stack).build(); + } + + @Override + public int getContentVersion() { + return 1; + } + + @Override + public DataContainer toContainer() { + return this.stack.toContainer(); + } + + private static class Builder extends AbstractDataBuilder { + + public Builder() { + super(InventoryChangeTriggerConfig.class, 1); + } + + @Override + protected Optional buildContent(DataView container) throws InvalidDataException { + return Optional.of(new InventoryChangeTriggerConfig(container)); + } + } + } + +} diff --git a/testplugins/src/main/resources/META-INF/plugins.json b/testplugins/src/main/resources/META-INF/plugins.json index 00b1e1b92ff..50a8414b960 100644 --- a/testplugins/src/main/resources/META-INF/plugins.json +++ b/testplugins/src/main/resources/META-INF/plugins.json @@ -229,8 +229,7 @@ "version": "8.0.0" }], "extra": {} - } - , + }, { "loader": "java_plain", "id": "particletest", @@ -252,6 +251,28 @@ "version": "8.0.0" }], "extra": {} + }, + { + "loader": "java_plain", + "id": "advancementtest", + "name": "AdvancementTest", + "version": "8.0.0", + "main-class": "org.spongepowered.test.advancement.AdvancementTest", + "description": "Testing advancements", + "links": { + "homepage": "https://www.spongepowered.org", + "source": "https://www.spongepowered.org/source", + "issues": "https://www.spongepowered.org/issues" + }, + "contributors": [{ + "name": "SpongePowered", + "description": "Lead Developer" + }], + "dependencies": [{ + "id": "spongeapi", + "version": "8.0.0" + }], + "extra": {} } ] }