diff --git a/api/src/main/java/net/md_5/bungee/api/scoreboard/Scoreboard.java b/api/src/main/java/net/md_5/bungee/api/scoreboard/Scoreboard.java index 67917748..b0510d1d 100644 --- a/api/src/main/java/net/md_5/bungee/api/scoreboard/Scoreboard.java +++ b/api/src/main/java/net/md_5/bungee/api/scoreboard/Scoreboard.java @@ -1,7 +1,13 @@ package net.md_5.bungee.api.scoreboard; +import com.google.common.base.Preconditions; import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import lombok.AccessLevel; import lombok.Data; +import lombok.Getter; @Data public class Scoreboard @@ -18,9 +24,43 @@ public class Scoreboard /** * Objectives for this scoreboard. */ - private final Collection objectives; + @Getter(AccessLevel.NONE) + private final Map objectives = new HashMap<>(); /** * Scores for this scoreboard. */ - private final Collection scores; + @Getter(AccessLevel.NONE) + private final Map scores = new HashMap<>(); + + public Collection getObjectives() + { + return Collections.unmodifiableCollection( objectives.values() ); + } + + public Collection getScores() + { + return Collections.unmodifiableCollection( scores.values() ); + } + + public void addObjective(Objective objective) + { + Preconditions.checkArgument( !objectives.containsKey( objective.getName() ), "Objective %s already exists in this scoreboard", objective ); + objectives.put( objective.getName(), objective ); + } + + public void addScore(Score score) + { + Preconditions.checkArgument( !scores.containsKey( score.getItemName() ), "Score %s already exists in this scoreboard", score ); + scores.put( score.getItemName(), score ); + } + + public void removeObjective(String objectiveName) + { + objectives.remove( objectiveName ); + } + + public void removeScore(String scoreName) + { + scores.remove( scoreName ); + } } diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java index 5baa32bb..2e9b3901 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java @@ -8,6 +8,8 @@ import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.event.ServerConnectedEvent; +import net.md_5.bungee.api.scoreboard.Objective; +import net.md_5.bungee.api.scoreboard.Score; import net.md_5.bungee.connection.CancelSendSignal; import net.md_5.bungee.connection.DownstreamBridge; import net.md_5.bungee.netty.HandlerBoss; @@ -16,6 +18,7 @@ import net.md_5.bungee.packet.Packet1Login; import net.md_5.bungee.packet.Packet9Respawn; import net.md_5.bungee.packet.PacketCDClientStatus; import net.md_5.bungee.packet.PacketCEScoreboardObjective; +import net.md_5.bungee.packet.PacketCFScoreboardScore; import net.md_5.bungee.packet.PacketFDEncryptionRequest; import net.md_5.bungee.packet.PacketFFKick; import net.md_5.bungee.packet.PacketHandler; @@ -91,6 +94,18 @@ public class ServerConnector extends PacketHandler { bungee.getTabListHandler().onServerChange( user ); + if ( user.serverSentScoreboard != null ) + { + for ( Objective objective : user.serverSentScoreboard.getObjectives() ) + { + user.ch.write( new PacketCEScoreboardObjective( objective.getName(), objective.getValue(), (byte) 1 ) ); + } + for ( Score score : user.serverSentScoreboard.getScores() ) + { + user.ch.write( new PacketCFScoreboardScore( score.getItemName(), (byte) 1, null, 0 ) ); + } + } + user.sendPacket( Packet9Respawn.DIM1_SWITCH ); user.sendPacket( Packet9Respawn.DIM2_SWITCH ); diff --git a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java index deb2e6ae..f3ffb6e4 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java @@ -1,9 +1,13 @@ package net.md_5.bungee.connection; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import io.netty.channel.Channel; +import java.util.HashMap; +import java.util.HashSet; import lombok.RequiredArgsConstructor; import net.md_5.bungee.EntityMap; import net.md_5.bungee.ServerConnection; @@ -14,11 +18,16 @@ import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.ChatEvent; import net.md_5.bungee.api.event.PluginMessageEvent; +import net.md_5.bungee.api.scoreboard.Objective; +import net.md_5.bungee.api.scoreboard.Position; +import net.md_5.bungee.api.scoreboard.Score; import net.md_5.bungee.api.scoreboard.Scoreboard; import net.md_5.bungee.packet.Packet0KeepAlive; import net.md_5.bungee.packet.Packet3Chat; import net.md_5.bungee.packet.PacketC9PlayerListItem; import net.md_5.bungee.packet.PacketCEScoreboardObjective; +import net.md_5.bungee.packet.PacketCFScoreboardScore; +import net.md_5.bungee.packet.PacketD0DisplayScoreboard; import net.md_5.bungee.packet.PacketFAPluginMessage; import net.md_5.bungee.packet.PacketFFKick; import net.md_5.bungee.packet.PacketHandler; @@ -85,6 +94,46 @@ public class DownstreamBridge extends PacketHandler } } + @Override + public void handle(PacketCEScoreboardObjective objective) throws Exception + { + if ( con.serverSentScoreboard != null ) + { + switch ( objective.action ) + { + case 0: + con.serverSentScoreboard.addObjective( new Objective( objective.name, objective.text ) ); + break; + case 1: + con.serverSentScoreboard.removeObjective( objective.name ); + break; + } + } + } + + @Override + public void handle(PacketCFScoreboardScore score) throws Exception + { + if ( con.serverSentScoreboard != null ) + { + switch ( score.action ) + { + case 0: + con.serverSentScoreboard.addScore( new Score( score.itemName, score.scoreName, score.value ) ); + break; + case 1: + con.serverSentScoreboard.removeScore( score.itemName ); + break; + } + } + } + + @Override + public void handle(PacketD0DisplayScoreboard displayScoreboard) throws Exception + { + con.serverSentScoreboard = new Scoreboard( displayScoreboard.name, Position.values()[displayScoreboard.position] ); + } + @Override public void handle(PacketFAPluginMessage pluginMessage) throws Exception { diff --git a/proxy/src/main/java/net/md_5/bungee/packet/PacketCEScoreboardObjective.java b/proxy/src/main/java/net/md_5/bungee/packet/PacketCEScoreboardObjective.java index ffae1042..e635aa80 100644 --- a/proxy/src/main/java/net/md_5/bungee/packet/PacketCEScoreboardObjective.java +++ b/proxy/src/main/java/net/md_5/bungee/packet/PacketCEScoreboardObjective.java @@ -13,7 +13,7 @@ public class PacketCEScoreboardObjective extends DefinedPacket /** * 0 to create, 1 to remove. */ - public byte status; + public byte action; public PacketCEScoreboardObjective(String name, String text, byte status) { @@ -23,7 +23,7 @@ public class PacketCEScoreboardObjective extends DefinedPacket writeByte( status ); this.name = name; this.text = text; - this.status = status; + this.action = status; } PacketCEScoreboardObjective(byte[] buf) @@ -31,7 +31,7 @@ public class PacketCEScoreboardObjective extends DefinedPacket super( 0xCE, buf ); this.name = readUTF(); this.text = readUTF(); - this.status = readByte(); + this.action = readByte(); } @Override diff --git a/proxy/src/main/java/net/md_5/bungee/packet/PacketCFScoreboardScore.java b/proxy/src/main/java/net/md_5/bungee/packet/PacketCFScoreboardScore.java index 25294a32..16d609ca 100644 --- a/proxy/src/main/java/net/md_5/bungee/packet/PacketCFScoreboardScore.java +++ b/proxy/src/main/java/net/md_5/bungee/packet/PacketCFScoreboardScore.java @@ -28,6 +28,22 @@ public class PacketCFScoreboardScore extends DefinedPacket } } + public PacketCFScoreboardScore(String itemName, byte action, String scoreName, int value) + { + super( 0xCF ); + writeUTF( itemName ); + writeByte( action ); + if ( action == 0 ) + { + writeUTF( scoreName ); + writeInt( value ); + } + this.itemName = itemName; + this.action = action; + this.scoreName = scoreName; + this.value = value; + } + @Override public void handle(PacketHandler handler) throws Exception {