From 02aeddbadd7c1366c3719b74d22ba52a6920f82c Mon Sep 17 00:00:00 2001
From: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
Date: Mon, 21 Sep 2020 23:55:13 -0400
Subject: [PATCH] Scoreboard: Fix various issues (#1286)

* Scoreboard: update score on UpdateType.ADD

* Actually fix

* Readd the Objective when a score changes

It looks like Objectives only update when you Remove the Objective and add it back using the SetDisplayObjective. This is hopefully a hotfix, but I think that there is no better way.

* Explain score tracking

Co-authored-by: Tim203 <mctim203@gmail.com>
---
 .../geysermc/connector/scoreboard/Objective.java    |  2 +-
 .../geysermc/connector/scoreboard/Scoreboard.java   | 13 ++++++++++---
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/connector/src/main/java/org/geysermc/connector/scoreboard/Objective.java b/connector/src/main/java/org/geysermc/connector/scoreboard/Objective.java
index 92a1add34..b2f648612 100644
--- a/connector/src/main/java/org/geysermc/connector/scoreboard/Objective.java
+++ b/connector/src/main/java/org/geysermc/connector/scoreboard/Objective.java
@@ -83,7 +83,7 @@ public class Objective {
 
     public void setScore(String id, int score) {
         if (scores.containsKey(id)) {
-            scores.get(id).setScore(score).setUpdateType(UpdateType.ADD);
+            scores.get(id).setScore(score);
             return;
         }
         registerScore(id, score);
diff --git a/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java b/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java
index 9f89d9d2b..ae1b82757 100644
--- a/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java
+++ b/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java
@@ -26,7 +26,6 @@
 package org.geysermc.connector.scoreboard;
 
 import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition;
-import com.nukkitx.protocol.bedrock.BedrockPacket;
 import com.nukkitx.protocol.bedrock.data.ScoreInfo;
 import com.nukkitx.protocol.bedrock.packet.RemoveObjectivePacket;
 import com.nukkitx.protocol.bedrock.packet.SetDisplayObjectivePacket;
@@ -153,6 +152,10 @@ public class Scoreboard {
             boolean globalAdd = objective.getUpdateType() == ADD;
             boolean globalRemove = objective.getUpdateType() == REMOVE;
 
+            // Track if any scores changed
+            // Used to delete and resend scoreboard objectives; otherwise they won't update on Bedrock
+            boolean scoreChanged = false;
+
             for (Score score : objective.getScores().values()) {
                 Team team = score.getTeam();
 
@@ -187,6 +190,10 @@ public class Scoreboard {
                 if (remove) {
                     removeScores.add(score.getCachedInfo());
                 }
+
+                if (add || remove) {
+                    scoreChanged = true;
+                }
                 // score is pending to be updated, so we use the current score as the old score
                 score.setOldScore(score.getScore());
 
@@ -198,7 +205,7 @@ public class Scoreboard {
                 score.setUpdateType(NOTHING);
             }
 
-            if (globalRemove || globalUpdate) {
+            if (globalRemove || globalUpdate || scoreChanged) {
                 RemoveObjectivePacket removeObjectivePacket = new RemoveObjectivePacket();
                 removeObjectivePacket.setObjectiveId(objective.getObjectiveName());
                 session.sendUpstreamPacket(removeObjectivePacket);
@@ -208,7 +215,7 @@ public class Scoreboard {
                 }
             }
 
-            if (globalAdd || globalUpdate) {
+            if (globalAdd || globalUpdate || scoreChanged) {
                 SetDisplayObjectivePacket displayObjectivePacket = new SetDisplayObjectivePacket();
                 displayObjectivePacket.setObjectiveId(objective.getObjectiveName());
                 displayObjectivePacket.setDisplayName(objective.getDisplayName());