mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-19 04:15:14 -04:00
properly synchronized scoreboard, fix other scoreboard bugs
This commit is contained in:
parent
7cb84304d0
commit
f10abc3d69
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020 Moritz Zwerger
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -12,32 +12,38 @@
|
||||
*/
|
||||
package de.bixilon.minosoft.data.scoreboard
|
||||
|
||||
import de.bixilon.kutil.collections.CollectionUtil.lockMapOf
|
||||
import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf
|
||||
import de.bixilon.kutil.collections.CollectionUtil.toSynchronizedMap
|
||||
import de.bixilon.kutil.collections.map.LockMap
|
||||
import de.bixilon.kutil.primitive.BooleanUtil.decide
|
||||
import de.bixilon.minosoft.modding.event.events.scoreboard.ScoreTeamChangeEvent
|
||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||
|
||||
class ScoreboardManager(private val connection: PlayConnection) {
|
||||
val teams: MutableMap<String, Team> = synchronizedMapOf()
|
||||
val objectives: MutableMap<String, ScoreboardObjective> = synchronizedMapOf()
|
||||
val teams: LockMap<String, Team> = lockMapOf()
|
||||
val objectives: LockMap<String, ScoreboardObjective> = lockMapOf()
|
||||
|
||||
val positions: MutableMap<ScoreboardPositions, ScoreboardObjective> = synchronizedMapOf()
|
||||
|
||||
|
||||
fun getTeam(member: String): Team? {
|
||||
for ((_, team) in this.teams.toSynchronizedMap()) {
|
||||
this.teams.lock.acquire()
|
||||
for (team in this.teams.values) {
|
||||
if (member !in team.members) {
|
||||
continue
|
||||
}
|
||||
this.teams.lock.release()
|
||||
return team
|
||||
}
|
||||
this.teams.lock.release()
|
||||
return null
|
||||
}
|
||||
|
||||
fun updateScoreTeams(team: Team, members: Set<String>, remove: Boolean = false, fireEvent: Boolean = true) {
|
||||
for ((_, objective) in objectives.toSynchronizedMap()) {
|
||||
for ((_, score) in objective.scores.toSynchronizedMap()) {
|
||||
objectives.lock.acquire()
|
||||
for (objective in objectives.values) {
|
||||
objective.scores.lock.acquire()
|
||||
for (score in objective.scores.values) {
|
||||
if (score.entity in members) {
|
||||
score.team = remove.decide(null, team)
|
||||
if (!fireEvent) {
|
||||
@ -46,6 +52,8 @@ class ScoreboardManager(private val connection: PlayConnection) {
|
||||
connection.fireEvent(ScoreTeamChangeEvent(connection, objective, score, team, remove))
|
||||
}
|
||||
}
|
||||
objective.scores.lock.release()
|
||||
}
|
||||
objectives.lock.release()
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,8 @@
|
||||
*/
|
||||
package de.bixilon.minosoft.data.scoreboard
|
||||
|
||||
import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf
|
||||
import de.bixilon.kutil.collections.CollectionUtil.lockMapOf
|
||||
import de.bixilon.kutil.collections.map.LockMap
|
||||
import de.bixilon.minosoft.data.text.ChatComponent
|
||||
import de.bixilon.minosoft.protocol.packets.s2c.play.scoreboard.objective.CreateObjectiveS2CP
|
||||
|
||||
@ -21,7 +22,7 @@ class ScoreboardObjective(
|
||||
var displayName: ChatComponent,
|
||||
var unit: CreateObjectiveS2CP.ObjectiveUnits,
|
||||
) {
|
||||
val scores: MutableMap<String, ScoreboardScore> = synchronizedMapOf()
|
||||
val scores: LockMap<String, ScoreboardScore> = lockMapOf()
|
||||
|
||||
|
||||
override fun toString(): String {
|
||||
|
@ -14,8 +14,9 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.scoreboard
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf
|
||||
import de.bixilon.kutil.collections.CollectionUtil.lockMapOf
|
||||
import de.bixilon.kutil.collections.CollectionUtil.toSynchronizedMap
|
||||
import de.bixilon.kutil.collections.map.LockMap
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.scoreboard.ScoreboardObjective
|
||||
import de.bixilon.minosoft.data.scoreboard.ScoreboardPositions
|
||||
@ -45,7 +46,7 @@ class ScoreboardSideElement(guiRenderer: GUIRenderer) : Element(guiRenderer), La
|
||||
private val backgroundElement = ColorElement(guiRenderer, size = Vec2i.EMPTY, color = RenderConstants.TEXT_BACKGROUND_COLOR)
|
||||
private val nameBackgroundElement = ColorElement(guiRenderer, size = Vec2i.EMPTY, color = RenderConstants.TEXT_BACKGROUND_COLOR)
|
||||
private val nameElement = TextElement(guiRenderer, "", background = false, parent = this)
|
||||
private val scores: MutableMap<ScoreboardScore, ScoreboardScoreElement> = synchronizedMapOf()
|
||||
private val scores: LockMap<ScoreboardScore, ScoreboardScoreElement> = lockMapOf()
|
||||
|
||||
override val layoutOffset: Vec2i
|
||||
get() = super.size.let { return@let Vec2i(guiRenderer.scaledSize.x - it.x, (guiRenderer.scaledSize.y - it.y) / 2) }
|
||||
@ -74,11 +75,14 @@ class ScoreboardSideElement(guiRenderer: GUIRenderer) : Element(guiRenderer), La
|
||||
nameElement.render(offset + Vec2i(HorizontalAlignments.CENTER.getOffset(size.x, nameElement.size.x), 0), consumer, options)
|
||||
offset.y += Font.TOTAL_CHAR_HEIGHT
|
||||
|
||||
val scores = scores.toSynchronizedMap().entries.sortedWith { a, b -> a.key.compareTo(b.key) }
|
||||
this.scores.lock.acquire()
|
||||
val scores = this.scores.unsafe.entries.sortedWith { a, b -> a.key.compareTo(b.key) }
|
||||
this.scores.lock.release()
|
||||
|
||||
var index = 0
|
||||
for ((_, score) in scores) {
|
||||
score.render(offset, consumer, options)
|
||||
offset.y += score.size.y
|
||||
offset.y += Font.TOTAL_CHAR_HEIGHT
|
||||
|
||||
if (++index >= MAX_SCORES) {
|
||||
break
|
||||
@ -93,7 +97,14 @@ class ScoreboardSideElement(guiRenderer: GUIRenderer) : Element(guiRenderer), La
|
||||
return
|
||||
}
|
||||
|
||||
this.scores.clear()
|
||||
this.scores.lock.lock()
|
||||
this.scores.unsafe.clear()
|
||||
objective.scores.lock.acquire()
|
||||
for (score in objective.scores.values) {
|
||||
this.scores.unsafe.getOrPut(score) { ScoreboardScoreElement(guiRenderer, score, this) }
|
||||
}
|
||||
objective.scores.lock.release()
|
||||
this.scores.lock.unlock()
|
||||
|
||||
updateName()
|
||||
|
||||
@ -131,7 +142,6 @@ class ScoreboardSideElement(guiRenderer: GUIRenderer) : Element(guiRenderer), La
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun queueSizeRecalculation() {
|
||||
cacheUpToDate = false
|
||||
}
|
||||
@ -142,7 +152,7 @@ class ScoreboardSideElement(guiRenderer: GUIRenderer) : Element(guiRenderer), La
|
||||
}
|
||||
|
||||
fun updateScore(score: ScoreboardScore) {
|
||||
scores.getOrPut(score) { ScoreboardScoreElement(guiRenderer, score, this) }
|
||||
scores.synchronizedGetOrPut(score) { ScoreboardScoreElement(guiRenderer, score, this) }
|
||||
queueSizeRecalculation()
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user