diff --git a/src/main/java/de/bixilon/minosoft/data/registries/ResourceLocation.kt b/src/main/java/de/bixilon/minosoft/data/registries/ResourceLocation.kt index 74fc78052..81d1318f9 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/ResourceLocation.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/ResourceLocation.kt @@ -21,6 +21,7 @@ open class ResourceLocation( val namespace: String = ProtocolDefinition.DEFAULT_NAMESPACE, val path: String, ) : Comparable, Translatable { // compare is for moshi + private val hashCode = Objects.hash(namespace, path) open val full: String = "$namespace:$path" override val translationKey: ResourceLocation @@ -30,7 +31,7 @@ open class ResourceLocation( override fun hashCode(): Int { - return Objects.hash(namespace, path) + return hashCode } override fun equals(other: Any?): Boolean { diff --git a/src/main/java/de/bixilon/minosoft/data/scoreboard/ScoreboardManager.kt b/src/main/java/de/bixilon/minosoft/data/scoreboard/ScoreboardManager.kt index 3421468ea..904c348ce 100644 --- a/src/main/java/de/bixilon/minosoft/data/scoreboard/ScoreboardManager.kt +++ b/src/main/java/de/bixilon/minosoft/data/scoreboard/ScoreboardManager.kt @@ -12,9 +12,40 @@ */ package de.bixilon.minosoft.data.scoreboard +import de.bixilon.minosoft.protocol.packets.s2c.play.scoreboard.ScoreboardPositionSetS2CP import de.bixilon.minosoft.util.KUtil.synchronizedMapOf class ScoreboardManager { val teams: MutableMap = synchronizedMapOf() val objectives: MutableMap = synchronizedMapOf() + + val positions: MutableMap = synchronizedMapOf() + + + fun getTeamsOf(member: String): Set { + val teams: MutableSet = mutableSetOf() + + for ((name, team) in this.teams) { + if (!team.members.contains(member)) { + continue + } + teams += team + } + + return teams + } + + fun updateScoreTeams(team: Team, members: Set, remove: Boolean = false) { + for ((_, objective) in objectives) { + for ((_, score) in objective.scores) { + if (score.entity in members) { + if (remove) { + score.teams -= team + } else { + score.teams += team + } + } + } + } + } } diff --git a/src/main/java/de/bixilon/minosoft/data/scoreboard/ScoreboardScore.kt b/src/main/java/de/bixilon/minosoft/data/scoreboard/ScoreboardScore.kt index eb8f930e0..7b2de2466 100644 --- a/src/main/java/de/bixilon/minosoft/data/scoreboard/ScoreboardScore.kt +++ b/src/main/java/de/bixilon/minosoft/data/scoreboard/ScoreboardScore.kt @@ -14,6 +14,7 @@ package de.bixilon.minosoft.data.scoreboard class ScoreboardScore( val entity: String, - var objective: String, - var score: Int, + var objective: ScoreboardObjective, + val teams: MutableSet, + var value: Int, ) diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/ScoreboardPositionSetS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/ScoreboardPositionSetS2CP.kt index 098e177c3..87492d3db 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/ScoreboardPositionSetS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/ScoreboardPositionSetS2CP.kt @@ -12,6 +12,7 @@ */ package de.bixilon.minosoft.protocol.packets.s2c.play.scoreboard +import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer import de.bixilon.minosoft.util.KUtil @@ -22,10 +23,19 @@ import de.bixilon.minosoft.util.logging.LogMessageType class ScoreboardPositionSetS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() { private val position: ScoreboardPositions = ScoreboardPositions[buffer.readUnsignedByte()] - private val score: String = buffer.readString() + private val objective: String? = buffer.readNullString() + + override fun handle(connection: PlayConnection) { + val scoreboardManager = connection.scoreboardManager + if (objective == null) { + scoreboardManager.positions -= position + return + } + scoreboardManager.positions[position] = scoreboardManager.objectives[objective] ?: return + } override fun log() { - Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Scoreboard position set (position=$position, score=$score)" } + Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Scoreboard position set (position=$position, objective=$objective)" } } enum class ScoreboardPositions { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/objective/RemoveScoreboardObjectiveS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/objective/RemoveScoreboardObjectiveS2CP.kt index be6115938..387293fdc 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/objective/RemoveScoreboardObjectiveS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/objective/RemoveScoreboardObjectiveS2CP.kt @@ -16,6 +16,7 @@ package de.bixilon.minosoft.protocol.packets.s2c.play.scoreboard.objective import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer +import de.bixilon.minosoft.util.KUtil.toSynchronizedMap import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogMessageType @@ -28,6 +29,13 @@ class RemoveScoreboardObjectiveS2CP(val objective: String, buffer: PlayInByteBuf override fun handle(connection: PlayConnection) { connection.scoreboardManager.objectives.remove(objective) + + for ((position, objective) in connection.scoreboardManager.positions.toSynchronizedMap()) { + if (objective.name != this.objective) { + continue + } + connection.scoreboardManager.positions -= position + } } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/score/PutScoreboardScoreS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/score/PutScoreboardScoreS2CP.kt index 2874fb5c1..a91c8db4e 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/score/PutScoreboardScoreS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/score/PutScoreboardScoreS2CP.kt @@ -18,12 +18,13 @@ import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer import de.bixilon.minosoft.protocol.protocol.ProtocolVersions +import de.bixilon.minosoft.util.KUtil.toSynchronizedSet import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogMessageType class PutScoreboardScoreS2CP(val entity: String, val objective: String?, buffer: PlayInByteBuffer) : PlayS2CPacket() { - val score: Int = if (buffer.versionId < ProtocolVersions.V_14W04A) { // ToDo + val value: Int = if (buffer.versionId < ProtocolVersions.V_14W04A) { // ToDo buffer.readInt() } else { buffer.readVarInt() @@ -31,11 +32,12 @@ class PutScoreboardScoreS2CP(val entity: String, val objective: String?, buffer: override fun handle(connection: PlayConnection) { check(objective != null) { "Can not update null objective!" } - connection.scoreboardManager.objectives[objective]?.scores?.put(entity, ScoreboardScore(entity, objective, score)) + val objective = connection.scoreboardManager.objectives[objective] ?: return + objective.scores[entity] = ScoreboardScore(entity, objective, connection.scoreboardManager.getTeamsOf(entity).toSynchronizedSet(), value) } override fun log() { - Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Put scoreboard score (entity=$entity§r, objective=$objective§r, score=$score)" } + Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Put scoreboard score (entity=$entity§r, objective=$objective§r, value=$value)" } } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamCreateS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamCreateS2CP.kt index d2cb0f6a8..3e8990134 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamCreateS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamCreateS2CP.kt @@ -24,6 +24,7 @@ import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer import de.bixilon.minosoft.protocol.protocol.ProtocolVersions import de.bixilon.minosoft.util.BitByte.isBitMask +import de.bixilon.minosoft.util.KUtil.toSynchronizedSet import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogMessageType @@ -111,13 +112,15 @@ class TeamCreateS2CP(val name: String, buffer: PlayInByteBuffer) : PlayS2CPacket collisionRule = collisionRule, nameTagVisibility = nameTagVisibility, formattingCode = formattingCode, - members = members.toMutableSet(), + members = members.toSynchronizedSet(), ) connection.scoreboardManager.teams[name] = team for (member in members) { connection.tabList.tabListItemsByName[member]?.team = team } + + connection.scoreboardManager.updateScoreTeams(team, members) } override fun log() { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamMemberAddS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamMemberAddS2CP.kt index 8546c20d1..40a5d7891 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamMemberAddS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamMemberAddS2CP.kt @@ -38,6 +38,8 @@ class TeamMemberAddS2CP(val name: String, buffer: PlayInByteBuffer) : PlayS2CPac for (member in members) { connection.tabList.tabListItemsByName[member]?.team = team } + + connection.scoreboardManager.updateScoreTeams(team, members) } override fun log() { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamMemberRemoveS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamMemberRemoveS2CP.kt index 8a0cf57bc..8cae0cb15 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamMemberRemoveS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamMemberRemoveS2CP.kt @@ -41,6 +41,8 @@ class TeamMemberRemoveS2CP(val name: String, buffer: PlayInByteBuffer) : PlayS2C } item.team = team } + + connection.scoreboardManager.updateScoreTeams(team, members, true) } override fun log() { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamRemoveS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamRemoveS2CP.kt index e6d5a2aa9..ae50b9585 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamRemoveS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/scoreboard/teams/TeamRemoveS2CP.kt @@ -22,7 +22,9 @@ import de.bixilon.minosoft.util.logging.LogMessageType class TeamRemoveS2CP(val name: String) : PlayS2CPacket() { override fun handle(connection: PlayConnection) { - connection.scoreboardManager.teams.remove(name) + val team = connection.scoreboardManager.teams.remove(name) ?: return + + connection.scoreboardManager.updateScoreTeams(team, team.members, true) } override fun log() {