From efb4768300d6cbbe02b085f7a6a3dd07ed6707ab Mon Sep 17 00:00:00 2001 From: Anselm Brehme Date: Sun, 11 Feb 2024 17:00:58 +0100 Subject: [PATCH] scoreboard --- .../common/scoreboard/SpongeObjective.java | 55 ++++++++++++++-- .../common/scoreboard/SpongeScore.java | 64 +++++++++++++++---- .../test/scoreboard/ScoreboardTest.java | 15 +++-- 3 files changed, 110 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/spongepowered/common/scoreboard/SpongeObjective.java b/src/main/java/org/spongepowered/common/scoreboard/SpongeObjective.java index 7aaef3b3601..987c1f18d1a 100644 --- a/src/main/java/org/spongepowered/common/scoreboard/SpongeObjective.java +++ b/src/main/java/org/spongepowered/common/scoreboard/SpongeObjective.java @@ -31,6 +31,8 @@ import net.minecraft.world.scores.ScoreHolder; import net.minecraft.world.scores.criteria.ObjectiveCriteria; import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.profile.GameProfile; import org.spongepowered.api.scoreboard.Score; import org.spongepowered.api.scoreboard.Scoreboard; import org.spongepowered.api.scoreboard.criteria.Criterion; @@ -39,6 +41,7 @@ import org.spongepowered.api.scoreboard.objective.displaymode.ObjectiveDisplayModes; import org.spongepowered.common.adventure.SpongeAdventure; import org.spongepowered.common.bridge.world.scores.ObjectiveBridge; +import org.spongepowered.common.profile.SpongeGameProfile; import java.util.HashMap; import java.util.HashSet; @@ -137,13 +140,11 @@ public void addScore(final Score score) throws IllegalArgumentException { this.scores.put(score.name(), score); final SpongeScore spongeScore = (SpongeScore) score; + for (final net.minecraft.world.scores.Scoreboard scoreboard : this.scoreboards) { final net.minecraft.world.scores.Objective mcObjective = scoreboard.getObjective(this.name); - for (final ScoreHolder holder : scoreboard.getTrackedPlayers()) { - final ScoreAccess accessor = scoreboard.getOrCreatePlayerScore(holder, mcObjective); - spongeScore.registerAndUpdate(mcObjective, accessor); - // TODO set values - } + final ScoreAccess accessor = scoreboard.getOrCreatePlayerScore(spongeScore.holder, mcObjective); + spongeScore.registerAndUpdate(mcObjective, accessor); } } @@ -163,6 +164,50 @@ public Score findOrCreateScore(final String name) { return score; } + @Override + public boolean hasScore(final Entity entity) { + return this.scores.containsKey(((ScoreHolder) entity).getScoreboardName()); + } + + @Override + public boolean hasScore(final GameProfile profile) { + return this.scores.containsKey(profile.name().get()); + } + + @Override + public Score findOrCreateScore(final Entity entity) { + if (this.scores.containsKey(((ScoreHolder) entity).getScoreboardName())) { + return this.scores.get(((ScoreHolder) entity).getScoreboardName()); + } + + final SpongeScore score = new SpongeScore(entity); + this.addScore(score); + return score; + } + + @Override + public boolean removeScore(final Entity entity) { + final Optional score = this.findScore(((ScoreHolder) entity).getScoreboardName()); + return score.filter(this::removeScore).isPresent(); + } + + @Override + public Score findOrCreateScore(final GameProfile profile) { + if (this.scores.containsKey(profile.name().get())) { + return this.scores.get(profile.name().get()); + } + + final SpongeScore score = new SpongeScore(profile); + this.addScore(score); + return score; + } + + @Override + public boolean removeScore(final GameProfile profile) { + final Optional score = this.findScore(profile.name().get()); + return score.filter(this::removeScore).isPresent(); + } + @Override public boolean removeScore(final Score spongeScore) { final ScoreHolder holder = ((SpongeScore) spongeScore).holder; diff --git a/src/main/java/org/spongepowered/common/scoreboard/SpongeScore.java b/src/main/java/org/spongepowered/common/scoreboard/SpongeScore.java index 636c2a124a7..f7b0c7eb5db 100644 --- a/src/main/java/org/spongepowered/common/scoreboard/SpongeScore.java +++ b/src/main/java/org/spongepowered/common/scoreboard/SpongeScore.java @@ -28,13 +28,17 @@ import net.minecraft.network.chat.numbers.NumberFormat; import net.minecraft.world.scores.ScoreAccess; import net.minecraft.world.scores.ScoreHolder; +import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.profile.GameProfile; import org.spongepowered.api.scoreboard.Score; import org.spongepowered.api.scoreboard.ScoreFormat; import org.spongepowered.api.scoreboard.objective.Objective; import org.spongepowered.common.adventure.SpongeAdventure; import org.spongepowered.common.bridge.world.scores.ObjectiveBridge; +import org.spongepowered.common.profile.SpongeGameProfile; import java.util.HashSet; +import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -59,6 +63,16 @@ public SpongeScore(final String name) { this.holder = ScoreHolder.forNameOnly(name); } + public SpongeScore(final GameProfile profile) { + this.holder = ScoreHolder.fromGameProfile(SpongeGameProfile.toMcProfile(profile)); + this.name = this.holder.getScoreboardName(); + } + + public SpongeScore(final Entity entity) { + this.holder = (net.minecraft.world.entity.Entity) entity; + this.name = this.holder.getScoreboardName(); + } + @Override public String name() { return this.name; @@ -94,12 +108,13 @@ public void setDisplay(final Component display) { @Override public Optional display() { - return Optional.ofNullable(SpongeAdventure.asAdventure(this.display)); + return Optional.ofNullable(this.display == null ? null : SpongeAdventure.asAdventure(this.display)); } @Override public void setNumberFormat(@org.checkerframework.checker.nullness.qual.Nullable final ScoreFormat format) { this.numberFormat = (NumberFormat) format; + this.updateScore(); } @Override @@ -110,10 +125,8 @@ public Optional numberFormat() { private void updateScore() { for (final net.minecraft.world.scores.Objective objective : this.objectives) { var scoreboard = objective.getScoreboard(); - for (final ScoreHolder holder : scoreboard.getTrackedPlayers()) { - final ScoreAccess access = scoreboard.getOrCreatePlayerScore(holder, objective); - this.registerAndUpdate(objective, access); - } + final ScoreAccess access = scoreboard.getOrCreatePlayerScore(this.holder, objective); + this.registerAndUpdate(objective, access); } } @@ -162,8 +175,12 @@ public net.minecraft.network.chat.Component display() { @Override public void set(final int var1) { final SpongeObjective spongeObjective = ((ObjectiveBridge) objective).bridge$getSpongeObjective(); - // TODO maybe stackoverflow issue - spongeObjective.findScore(holder.getScoreboardName()).ifPresent(spongeScore -> spongeScore.setScore(var1)); + + spongeObjective.findScore(holder.getScoreboardName()).ifPresent(spongeScore -> { + if (spongeScore.score() != var1) { + spongeScore.setScore(var1); + } + }); this.access.set(var1); } @@ -171,8 +188,12 @@ public void set(final int var1) { @Override public void unlock() { final SpongeObjective spongeObjective = ((ObjectiveBridge) objective).bridge$getSpongeObjective(); - // TODO maybe stackoverflow issue - spongeObjective.findScore(holder.getScoreboardName()).ifPresent(spongeScore -> spongeScore.setLocked(false)); + + spongeObjective.findScore(holder.getScoreboardName()).ifPresent(spongeScore -> { + if (spongeScore.isLocked()) { + spongeScore.setLocked(false); + } + }); this.access.unlock(); } @@ -180,8 +201,12 @@ public void unlock() { @Override public void lock() { final SpongeObjective spongeObjective = ((ObjectiveBridge) objective).bridge$getSpongeObjective(); - // TODO maybe stackoverflow issue - spongeObjective.findScore(holder.getScoreboardName()).ifPresent(spongeScore -> spongeScore.setLocked(true)); + + spongeObjective.findScore(holder.getScoreboardName()).ifPresent(spongeScore -> { + if (!spongeScore.isLocked()) { + spongeScore.setLocked(true); + } + }); this.access.lock(); } @@ -189,8 +214,21 @@ public void lock() { @Override public void display(@Nullable final net.minecraft.network.chat.Component var1) { final SpongeObjective spongeObjective = ((ObjectiveBridge) objective).bridge$getSpongeObjective(); - // TODO maybe stackoverflow issue - spongeObjective.findScore(holder.getScoreboardName()).ifPresent(spongeScore -> spongeScore.setDisplay(SpongeAdventure.asAdventure(var1))); + + spongeObjective.findScore(holder.getScoreboardName()).ifPresent(spongeScore -> { + if (spongeScore.display().isEmpty() && var1 == null) { + return; + } + if (var1 == null) { + spongeScore.setDisplay(null); + return; + } + final Component component = SpongeAdventure.asAdventure(var1); + if (Objects.equals(spongeScore.display().orElse(null), component)) { + return; + } + spongeScore.setDisplay(component); + }); this.access.display(var1); } diff --git a/testplugins/src/main/java/org/spongepowered/test/scoreboard/ScoreboardTest.java b/testplugins/src/main/java/org/spongepowered/test/scoreboard/ScoreboardTest.java index ac0cd5b8802..386b743ceb2 100644 --- a/testplugins/src/main/java/org/spongepowered/test/scoreboard/ScoreboardTest.java +++ b/testplugins/src/main/java/org/spongepowered/test/scoreboard/ScoreboardTest.java @@ -69,27 +69,30 @@ public CommandResult doScoreboardStuff(CommandContext ctx) { ctx.sendMessage(Component.text("Objective removed")); }, () -> { final Objective test = Objective.builder().criterion(Criteria.DUMMY).name("testObjective").displayName(Component.text("testObjectiveDisplay")).build(); + + scoreboard.addObjective(test); + scoreboard.updateDisplaySlot(test, DisplaySlots.SIDEBAR); + final Score score = test.findOrCreateScore("testScore"); - score.setScore(200); + score.setScore(1); score.setDisplay(Component.text("TestScoreDisplay")); final Score score2 = test.findOrCreateScore("testScoreBlank"); - score2.setScore(200); + score2.setScore(2); score2.setDisplay(Component.text("TestScoreDisplay Blank")); score2.setNumberFormat(ScoreFormat.blank()); final Score score3 = test.findOrCreateScore("testScoreFixed"); - score3.setScore(200); + score3.setScore(3); score3.setDisplay(Component.text("TestScoreDisplay Fixed")); score3.setNumberFormat(ScoreFormat.fixed(Component.text("Fix"))); final Score score4 = test.findOrCreateScore("testScoreStyled"); - score4.setScore(200); + score4.setScore(4); score4.setDisplay(Component.text("TestScoreDisplay Styled")); score4.setNumberFormat(ScoreFormat.styled(Style.style(NamedTextColor.GREEN))); - scoreboard.addObjective(test); - scoreboard.updateDisplaySlot(test, DisplaySlots.SIDEBAR); + ctx.sendMessage(Component.text("Objective set")); }); player.setScoreboard(scoreboard);