improve team data structure

This commit is contained in:
Moritz Zwerger 2023-11-07 18:50:58 +01:00
parent 1a55742f8f
commit 1567b14583
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
21 changed files with 108 additions and 65 deletions

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.data.entities.entities.player.additional package de.bixilon.minosoft.data.entities.entities.player.additional
import de.bixilon.minosoft.data.scoreboard.Team import de.bixilon.minosoft.data.scoreboard.team.Team
import de.bixilon.minosoft.data.text.BaseComponent import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.TextComponent import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.data.text.formatting.color.ChatColors import de.bixilon.minosoft.data.text.formatting.color.ChatColors

View File

@ -27,6 +27,7 @@ import org.testng.annotations.Test
class RenderTestLoader { class RenderTestLoader {
fun init() { fun init() {
return
val connection = createConnection(5) val connection = createConnection(5)
val latch = SimpleLatch(1) val latch = SimpleLatch(1)
connection::assetsManager.forceSet(AssetsLoader.create(connection.profiles.resources, connection.version, latch)) connection::assetsManager.forceSet(AssetsLoader.create(connection.profiles.resources, connection.version, latch))

View File

@ -73,7 +73,6 @@ class EntityScoreFeatureTest {
fun `name offset without score`() { fun `name offset without score`() {
val score = createScore() val score = createScore()
score.setScore()
score.updateScore() score.updateScore()
score.updateNameOffset() score.updateNameOffset()
assertEquals(score.renderer.name.offset, BillboardTextFeature.DEFAULT_OFFSET) assertEquals(score.renderer.name.offset, BillboardTextFeature.DEFAULT_OFFSET)

View File

@ -132,10 +132,7 @@ abstract class PlayerEntity(
if (chestPlate != null && chestPlate.item.item is DyeableItem) { if (chestPlate != null && chestPlate.item.item is DyeableItem) {
chestPlate._display?.dyeColor?.let { return it } chestPlate._display?.dyeColor?.let { return it }
} }
val formattingCode = additional.team?.color additional.team?.formatting?.color?.let { return it }
if (formattingCode is RGBColor) {
return formattingCode
}
return ChatColors.RED return ChatColors.RED
} }

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger * Copyright (C) 2020-2023 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. * 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.
* *
@ -15,7 +15,7 @@ package de.bixilon.minosoft.data.entities.entities.player.additional
import de.bixilon.minosoft.data.abilities.Gamemodes import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.entities.entities.player.properties.PlayerProperties import de.bixilon.minosoft.data.entities.entities.player.properties.PlayerProperties
import de.bixilon.minosoft.data.scoreboard.Team import de.bixilon.minosoft.data.scoreboard.team.Team
import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.protocol.PlayerPublicKey import de.bixilon.minosoft.protocol.PlayerPublicKey

View File

@ -16,7 +16,7 @@ package de.bixilon.minosoft.data.entities.entities.player.additional
import de.bixilon.kutil.observer.DataObserver.Companion.observed import de.bixilon.kutil.observer.DataObserver.Companion.observed
import de.bixilon.minosoft.data.abilities.Gamemodes import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.entities.entities.player.properties.PlayerProperties import de.bixilon.minosoft.data.entities.entities.player.properties.PlayerProperties
import de.bixilon.minosoft.data.scoreboard.Team import de.bixilon.minosoft.data.scoreboard.team.Team
import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.protocol.PlayerPublicKey import de.bixilon.minosoft.protocol.PlayerPublicKey
import de.bixilon.minosoft.util.KUtil.nullCompare import de.bixilon.minosoft.util.KUtil.nullCompare
@ -41,7 +41,7 @@ class PlayerAdditional(
var listed by observed(listed) var listed by observed(listed)
val tabDisplayName: ChatComponent val tabDisplayName: ChatComponent
get() = displayName ?: ChatComponent.of(name).let { team?.decorateName(it) ?: it } get() = displayName ?: ChatComponent.of(name).let { team?.formatting?.decorate(it) ?: it }
fun merge(data: AdditionalDataUpdate) { fun merge(data: AdditionalDataUpdate) {
spareMerge(data) spareMerge(data)

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger * Copyright (C) 2020-2023 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. * 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.
* *
@ -16,6 +16,7 @@ import de.bixilon.kutil.collections.CollectionUtil.lockMapOf
import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf
import de.bixilon.kutil.collections.map.LockMap import de.bixilon.kutil.collections.map.LockMap
import de.bixilon.kutil.primitive.BooleanUtil.decide import de.bixilon.kutil.primitive.BooleanUtil.decide
import de.bixilon.minosoft.data.scoreboard.team.Team
import de.bixilon.minosoft.modding.event.events.scoreboard.ScoreTeamChangeEvent import de.bixilon.minosoft.modding.event.events.scoreboard.ScoreTeamChangeEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
@ -49,7 +50,7 @@ class ScoreboardManager(private val connection: PlayConnection) {
if (!fireEvent) { if (!fireEvent) {
continue continue
} }
connection.fire(ScoreTeamChangeEvent(connection, objective, score, team, remove)) connection.events.fire(ScoreTeamChangeEvent(connection, objective, score, team, remove))
} }
} }
objective.scores.lock.release() objective.scores.lock.release()

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020 Moritz Zwerger * Copyright (C) 2020-2023 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. * 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,6 +12,8 @@
*/ */
package de.bixilon.minosoft.data.scoreboard package de.bixilon.minosoft.data.scoreboard
import de.bixilon.minosoft.data.scoreboard.team.Team
class ScoreboardScore( class ScoreboardScore(
val entity: String, val entity: String,
var objective: ScoreboardObjective, var objective: ScoreboardObjective,

View File

@ -0,0 +1,38 @@
/*
* Minosoft
* Copyright (C) 2020-2023 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.scoreboard.team
import de.bixilon.minosoft.data.scoreboard.TeamCollisionRules
import de.bixilon.minosoft.data.text.TextComponent
data class Team(
val name: String,
val formatting: TeamFormatting = TeamFormatting(TextComponent(name)),
var friendlyFire: Boolean = true,
val visibility: TeamVisibility = TeamVisibility(),
var collisions: TeamCollisionRules = TeamCollisionRules.ALWAYS,
val members: MutableSet<String> = mutableSetOf(),
) {
override fun toString(): String {
return name
}
fun canSee(other: Team?): Boolean {
// TODO
if (other == null) return false
if (other.name == this.name && visibility.invisibleTeam) return true
return false
}
}

View File

@ -10,30 +10,21 @@
* *
* This software is not affiliated with Mojang AB, the original developer of Minecraft. * This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/ */
package de.bixilon.minosoft.data.scoreboard
package de.bixilon.minosoft.data.scoreboard.team
import de.bixilon.minosoft.data.text.BaseComponent import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.data.text.formatting.color.RGBColor import de.bixilon.minosoft.data.text.formatting.color.RGBColor
data class Team( data class TeamFormatting(
val name: String, var name: ChatComponent,
var displayName: ChatComponent = TextComponent(name),
var prefix: ChatComponent? = null, var prefix: ChatComponent? = null,
var suffix: ChatComponent? = null, var suffix: ChatComponent? = null,
var friendlyFire: Boolean = true,
var canSeeInvisibleTeam: Boolean = true,
var collisionRule: TeamCollisionRules = TeamCollisionRules.ALWAYS,
var nameTagVisibility: NameTagVisibilities = NameTagVisibilities.ALWAYS,
var color: RGBColor? = null, var color: RGBColor? = null,
val members: MutableSet<String> = mutableSetOf(),
) { ) {
override fun toString(): String {
return name
}
fun decorateName(name: ChatComponent): ChatComponent { fun decorate(name: ChatComponent): ChatComponent {
val displayName = BaseComponent() val displayName = BaseComponent()
prefix?.let { displayName += it } prefix?.let { displayName += it }
displayName += name.apply { displayName += name.apply {
@ -42,11 +33,4 @@ data class Team(
suffix?.let { displayName += it } suffix?.let { displayName += it }
return displayName return displayName
} }
fun canSee(other: Team?): Boolean {
if (other == null) return false
if (other.name == this.name && canSeeInvisibleTeam) return true
return false
}
} }

View File

@ -0,0 +1,21 @@
/*
* Minosoft
* Copyright (C) 2020-2023 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.scoreboard.team
import de.bixilon.minosoft.data.scoreboard.NameTagVisibilities
data class TeamVisibility(
var invisibleTeam: Boolean = true,
var name: NameTagVisibilities = NameTagVisibilities.ALWAYS,
)

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger * Copyright (C) 2020-2023 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. * 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.
* *
@ -54,7 +54,7 @@ class ScoreboardScoreElement(
override fun forceSilentApply() { override fun forceSilentApply() {
val entityName = ChatComponent.of(score.entity) val entityName = ChatComponent.of(score.entity)
nameElement.text = score.team?.decorateName(entityName) ?: entityName nameElement.text = score.team?.formatting?.decorate(entityName) ?: entityName
scoreElement.text = TextComponent(score.value).color(ChatColors.RED) scoreElement.text = TextComponent(score.value).color(ChatColors.RED)

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger * Copyright (C) 2020-2023 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. * 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.
* *
@ -15,7 +15,7 @@ package de.bixilon.minosoft.modding.event.events.scoreboard
import de.bixilon.minosoft.data.scoreboard.ScoreboardObjective import de.bixilon.minosoft.data.scoreboard.ScoreboardObjective
import de.bixilon.minosoft.data.scoreboard.ScoreboardScore import de.bixilon.minosoft.data.scoreboard.ScoreboardScore
import de.bixilon.minosoft.data.scoreboard.Team import de.bixilon.minosoft.data.scoreboard.team.Team
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger * Copyright (C) 2020-2023 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. * 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.
* *
@ -13,7 +13,7 @@
package de.bixilon.minosoft.modding.event.events.scoreboard package de.bixilon.minosoft.modding.event.events.scoreboard
import de.bixilon.minosoft.data.scoreboard.Team import de.bixilon.minosoft.data.scoreboard.team.Team
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger * Copyright (C) 2020-2023 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. * 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.
* *
@ -13,7 +13,7 @@
package de.bixilon.minosoft.modding.event.events.scoreboard package de.bixilon.minosoft.modding.event.events.scoreboard
import de.bixilon.minosoft.data.scoreboard.Team import de.bixilon.minosoft.data.scoreboard.team.Team
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger * Copyright (C) 2020-2023 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. * 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.
* *
@ -13,7 +13,7 @@
package de.bixilon.minosoft.modding.event.events.scoreboard.team package de.bixilon.minosoft.modding.event.events.scoreboard.team
import de.bixilon.minosoft.data.scoreboard.Team import de.bixilon.minosoft.data.scoreboard.team.Team
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger * Copyright (C) 2020-2023 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. * 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.
* *
@ -13,7 +13,7 @@
package de.bixilon.minosoft.modding.event.events.scoreboard.team package de.bixilon.minosoft.modding.event.events.scoreboard.team
import de.bixilon.minosoft.data.scoreboard.Team import de.bixilon.minosoft.data.scoreboard.team.Team
import de.bixilon.minosoft.modding.event.events.scoreboard.ScoreboardTeamMemberEvent import de.bixilon.minosoft.modding.event.events.scoreboard.ScoreboardTeamMemberEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger * Copyright (C) 2020-2023 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. * 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.
* *
@ -13,7 +13,7 @@
package de.bixilon.minosoft.modding.event.events.scoreboard.team package de.bixilon.minosoft.modding.event.events.scoreboard.team
import de.bixilon.minosoft.data.scoreboard.Team import de.bixilon.minosoft.data.scoreboard.team.Team
import de.bixilon.minosoft.modding.event.events.scoreboard.ScoreboardTeamMemberEvent import de.bixilon.minosoft.modding.event.events.scoreboard.ScoreboardTeamMemberEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger * Copyright (C) 2020-2023 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. * 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.
* *
@ -13,7 +13,7 @@
package de.bixilon.minosoft.modding.event.events.scoreboard.team package de.bixilon.minosoft.modding.event.events.scoreboard.team
import de.bixilon.minosoft.data.scoreboard.Team import de.bixilon.minosoft.data.scoreboard.team.Team
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection

View File

@ -16,8 +16,10 @@ package de.bixilon.minosoft.protocol.packets.s2c.play.scoreboard.teams
import de.bixilon.kutil.bit.BitByte.isBitMask import de.bixilon.kutil.bit.BitByte.isBitMask
import de.bixilon.kutil.collections.CollectionUtil.toSynchronizedSet import de.bixilon.kutil.collections.CollectionUtil.toSynchronizedSet
import de.bixilon.minosoft.data.scoreboard.NameTagVisibilities import de.bixilon.minosoft.data.scoreboard.NameTagVisibilities
import de.bixilon.minosoft.data.scoreboard.Team
import de.bixilon.minosoft.data.scoreboard.TeamCollisionRules import de.bixilon.minosoft.data.scoreboard.TeamCollisionRules
import de.bixilon.minosoft.data.scoreboard.team.Team
import de.bixilon.minosoft.data.scoreboard.team.TeamFormatting
import de.bixilon.minosoft.data.scoreboard.team.TeamVisibility
import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.formatting.color.ChatColors import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.data.text.formatting.color.RGBColor import de.bixilon.minosoft.data.text.formatting.color.RGBColor
@ -106,16 +108,14 @@ class CreateTeamS2CP(
override fun handle(connection: PlayConnection) { override fun handle(connection: PlayConnection) {
val visibility = TeamVisibility(canSeeInvisibleTeam, nameTagVisibility)
val formatting = TeamFormatting(displayName, prefix, suffix, color)
val team = Team( val team = Team(
name = name, name = name,
displayName = displayName, formatting = formatting,
prefix = prefix,
suffix = suffix,
friendlyFire = friendlyFire, friendlyFire = friendlyFire,
canSeeInvisibleTeam = canSeeInvisibleTeam, collisions = collisionRule,
collisionRule = collisionRule, visibility = visibility,
nameTagVisibility = nameTagVisibility,
color = color,
members = members.toSynchronizedSet(), members = members.toSynchronizedSet(),
) )
connection.scoreboard.teams[name] = team connection.scoreboard.teams[name] = team

View File

@ -96,14 +96,14 @@ class UpdateTeamS2CP(
override fun handle(connection: PlayConnection) { override fun handle(connection: PlayConnection) {
val team = connection.scoreboard.teams[name] ?: return val team = connection.scoreboard.teams[name] ?: return
team.displayName = displayName val formatting = team.formatting
team.prefix = prefix formatting.name = displayName; formatting.prefix = prefix; formatting.suffix = suffix; formatting.color = color
team.suffix = suffix
val visibility = team.visibility
visibility.invisibleTeam = canSeeInvisibleTeam; visibility.name = nameTagVisibility
team.friendlyFire = friendlyFire team.friendlyFire = friendlyFire
team.canSeeInvisibleTeam = canSeeInvisibleTeam team.collisions = collisionRule
team.collisionRule = collisionRule
team.nameTagVisibility = nameTagVisibility
team.color = color
connection.events.fire(TeamUpdateEvent(connection, team)) connection.events.fire(TeamUpdateEvent(connection, team))
} }