/*
* This file is part of LanternServer, licensed under the MIT License (MIT).
*
* Copyright (c) LanternPowered <https://www.lanternpowered.org>
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the Software), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.lanternpowered.server.scoreboard;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import org.lanternpowered.server.network.vanilla.message.type.play.MessagePlayOutTeams;
import org.lanternpowered.server.text.LanternTexts;
import org.spongepowered.api.scoreboard.CollisionRule;
import org.spongepowered.api.scoreboard.Scoreboard;
import org.spongepowered.api.scoreboard.Team;
import org.spongepowered.api.scoreboard.Visibility;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.text.format.TextColor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
public class LanternTeam implements Team {
private final String name;
@Nullable private LanternScoreboard scoreboard;
final Set<Text> members = Sets.newHashSet();
private TextColor color;
private Text prefix;
private String legacyPrefix;
private Text suffix;
private String legacySuffix;
private Text displayName;
private String legacyDisplayName;
private boolean allowFriendlyFire;
private boolean canSeeFriendlyInvisibles;
private Visibility nameTagVisibility;
private Visibility deathMessageVisibility;
private CollisionRule collisionRule;
LanternTeam(String name, TextColor color, Text displayName, Text prefix, Text suffix,
boolean allowFriendlyFire, boolean canSeeFriendlyInvisibles, Visibility nameTagVisibility,
Visibility deathMessageVisibility, CollisionRule collisionRule) {
this.displayName = displayName;
this.legacyDisplayName = LanternTexts.toLegacy(displayName);
this.prefix = prefix;
this.legacyPrefix = LanternTexts.toLegacy(prefix);
this.suffix = suffix;
this.legacySuffix = LanternTexts.toLegacy(suffix);
this.name = name;
this.color = color;
this.allowFriendlyFire = allowFriendlyFire;
this.canSeeFriendlyInvisibles = canSeeFriendlyInvisibles;
this.nameTagVisibility = nameTagVisibility;
this.deathMessageVisibility = deathMessageVisibility;
this.collisionRule = collisionRule;
}
void setScoreboard(@Nullable LanternScoreboard scoreboard) {
this.scoreboard = scoreboard;
}
MessagePlayOutTeams.CreateOrUpdate toCreateOrUpdateMessage(boolean create) {
return create ?
new MessagePlayOutTeams.Create(this.name, this.legacyDisplayName,
this.legacyPrefix, this.legacySuffix, this.nameTagVisibility,
this.collisionRule, this.color, this.allowFriendlyFire, this.canSeeFriendlyInvisibles,
this.members.stream().map(LanternTexts::toLegacy).collect(Collectors.toList())) :
new MessagePlayOutTeams.Update(this.name, this.legacyDisplayName,
this.legacyPrefix, this.legacySuffix, this.nameTagVisibility,
this.collisionRule, this.color, this.allowFriendlyFire, this.canSeeFriendlyInvisibles);
}
private void sendUpdate() {
if (this.scoreboard != null) {
this.scoreboard.sendToPlayers(() -> Collections.singletonList(this.toCreateOrUpdateMessage(false)));
}
}
@Override
public CollisionRule getCollisionRule() {
return this.collisionRule;
}
@Override
public void setCollisionRule(CollisionRule rule) {
final boolean update = !checkNotNull(rule, "rule").equals(this.collisionRule);
this.collisionRule = rule;
if (update) {
this.sendUpdate();
}
}
@Override
public String getName() {
return this.name;
}
@Override
public Text getDisplayName() {
return this.displayName;
}
public String getLegacyDisplayName() {
return this.legacyDisplayName;
}
@Override
public void setDisplayName(Text displayName) throws IllegalArgumentException {
final String legacyDisplayName = LanternTexts.toLegacy(checkNotNull(displayName, "displayName"));
checkArgument(legacyDisplayName.length() <= 32, "Display name is %s characters long! It must be at most 32.",
legacyDisplayName.length());
final boolean update = !this.legacyDisplayName.equals(legacyDisplayName);
this.legacyDisplayName = legacyDisplayName;
this.displayName = displayName;
if (update) {
this.sendUpdate();
}
}
@Override
public TextColor getColor() {
return this.color;
}
@Override
public void setColor(TextColor color) throws IllegalArgumentException {
final boolean update = !this.color.equals(checkNotNull(color, "color"));
this.color = color;
if (update) {
this.sendUpdate();
}
}
public String getLegacyPrefix() {
return this.legacyPrefix;
}
@Override
public Text getPrefix() {
return this.prefix;
}
@Override
public void setPrefix(Text prefix) throws IllegalArgumentException {
final String legacyPrefix = LanternTexts.toLegacy(checkNotNull(prefix, "prefix"));
checkArgument(legacyPrefix.length() <= 16, "Prefix is %s characters long! It must be at most 16.",
legacyPrefix.length());
final boolean update = !this.legacyPrefix.equals(legacyPrefix);
this.legacyPrefix = legacyPrefix;
this.prefix = prefix;
if (update) {
this.sendUpdate();
}
}
public String getLegacySuffix() {
return this.legacySuffix;
}
@Override
public Text getSuffix() {
return this.suffix;
}
@Override
public void setSuffix(Text suffix) throws IllegalArgumentException {
final String legacySuffix = LanternTexts.toLegacy(checkNotNull(suffix, "suffix"));
checkArgument(legacySuffix.length() <= 16, "Suffix is %s characters long! It must be at most 16.",
legacySuffix.length());
final boolean update = !this.legacySuffix.equals(legacySuffix);
this.legacySuffix = legacySuffix;
this.suffix = suffix;
if (update) {
this.sendUpdate();
}
}
@Override
public boolean allowFriendlyFire() {
return this.allowFriendlyFire;
}
@Override
public void setAllowFriendlyFire(boolean enabled) {
final boolean update = enabled != this.allowFriendlyFire;
this.allowFriendlyFire = enabled;
if (update) {
this.sendUpdate();
}
}
@Override
public boolean canSeeFriendlyInvisibles() {
return this.canSeeFriendlyInvisibles;
}
@Override
public void setCanSeeFriendlyInvisibles(boolean enabled) {
final boolean update = enabled != this.canSeeFriendlyInvisibles;
this.canSeeFriendlyInvisibles = enabled;
if (update) {
this.sendUpdate();
}
}
@Override
public Visibility getNameTagVisibility() {
return this.nameTagVisibility;
}
@Override
public void setNameTagVisibility(Visibility visibility) {
final boolean update = !checkNotNull(visibility, "visibility").equals(this.nameTagVisibility);
this.nameTagVisibility = visibility;
if (update) {
this.sendUpdate();
}
}
@Override
public Visibility getDeathMessageVisibility() {
return this.deathMessageVisibility;
}
@Override
public void setDeathMessageVisibility(Visibility visibility) {
final boolean update = !checkNotNull(visibility, "visibility").equals(this.deathMessageVisibility);
this.deathMessageVisibility = visibility;
if (update) {
this.sendUpdate();
}
}
@Override
public Set<Text> getMembers() {
return ImmutableSet.copyOf(this.members);
}
@Override
public void addMember(Text member) {
if (this.members.add(checkNotNull(member, "member")) && this.scoreboard != null) {
this.scoreboard.sendToPlayers(() -> Collections.singletonList(
new MessagePlayOutTeams.AddPlayers(this.name, Collections.singletonList(LanternTexts.toLegacy(member)))));
}
}
@Override
public boolean removeMember(Text member) {
if (this.members.remove(checkNotNull(member, "member"))) {
if (this.scoreboard != null) {
this.scoreboard.sendToPlayers(() -> Collections.singletonList(
new MessagePlayOutTeams.RemovePlayers(this.name, Collections.singletonList(LanternTexts.toLegacy(member)))));
}
return true;
}
return false;
}
public List<Text> addMembers(Collection<Text> members) {
checkNotNull(members, "members");
final List<Text> failedMembers = new ArrayList<>();
final List<String> addedPlayers = new ArrayList<>();
for (Text member : members) {
if (this.members.add(member)) {
addedPlayers.add(LanternTexts.toLegacy(member));
} else {
failedMembers.add(member);
}
}
if (this.scoreboard != null) {
this.scoreboard.sendToPlayers(() -> Collections.singletonList(
new MessagePlayOutTeams.AddPlayers(this.name, addedPlayers)));
}
return failedMembers;
}
public List<Text> removeMembers(Collection<Text> members) {
checkNotNull(members, "members");
final List<Text> failedMembers = new ArrayList<>();
if (this.members.isEmpty()) {
return failedMembers;
}
final List<String> removedPlayers = new ArrayList<>();
for (Text member : members) {
if (this.members.remove(member)) {
removedPlayers.add(LanternTexts.toLegacy(member));
} else {
failedMembers.add(member);
}
}
if (this.scoreboard != null) {
this.scoreboard.sendToPlayers(() -> Collections.singletonList(
new MessagePlayOutTeams.RemovePlayers(this.name, removedPlayers)));
}
return failedMembers;
}
@Override
public Optional<Scoreboard> getScoreboard() {
return Optional.ofNullable(this.scoreboard);
}
@Override
public boolean unregister() {
if (this.scoreboard == null) {
return false;
}
this.scoreboard.removeTeam(this);
this.scoreboard.sendToPlayers(() -> Collections.singletonList(new MessagePlayOutTeams.Remove(this.name)));
this.scoreboard = null;
return true;
}
}