/*
* Copyright or © or Copr. Amaury Carrade (2014 - 2016)
*
* http://amaury.carrade.eu
*
* This software is governed by the CeCILL-B license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-B
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-B license and that you accept its terms.
*/
package eu.carrade.amaury.UHCReloaded.teams;
import eu.carrade.amaury.UHCReloaded.UHCReloaded;
import eu.carrade.amaury.UHCReloaded.UHConfig;
import eu.carrade.amaury.UHCReloaded.protips.ProTips;
import fr.zcraft.zlib.components.i18n.I;
import fr.zcraft.zlib.tools.runners.RunTask;
import fr.zcraft.zlib.tools.text.MessageSender;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
public class TeamChatManager
{
private final UHCReloaded p;
private final Set<UUID> teamChatLocked = new HashSet<>();
private final Map<UUID, UHTeam> otherTeamChatLocked = new HashMap<>();
private final Set<UUID> globalSpies = new HashSet<>();
public TeamChatManager(UHCReloaded p)
{
this.p = p;
}
/**
* Sends a team-message from the given sender.
*
* @param sender The sender.
* @param message The message to send.
*/
public void sendTeamMessage(Player sender, String message)
{
sendTeamMessage(sender, message, null);
}
/**
* Sends a team-message from the given sender.
*
* @param sender The sender.
* @param message The message to send.
* @param team If not null, this message will be considered as an external message from another player to this team.
*/
public void sendTeamMessage(Player sender, String message, UHTeam team)
{
// Permission check
if (team == null && !sender.hasPermission("uh.teamchat.self"))
{
sender.sendMessage(I.t("{ce}You are not allowed to send a private message to your team."));
return;
}
if (team != null && !sender.hasPermission("uh.teamchat.others"))
{
sender.sendMessage(I.t("{ce}You are not allowed to enter in the private chat of another team."));
return;
}
String rawMessage;
UHTeam recipient;
if (team == null)
{
/// Format of a private team message from a team member. {0} = sender display name, {1} = message.
rawMessage = I.t("{gold}[{0}{gold} -> his team] {reset}{1}", sender.getDisplayName(), message);
recipient = p.getTeamManager().getTeamForPlayer(sender);
if (recipient == null)
{
/// Error message if someone try to send a team private message out of any team
sender.sendMessage(I.t("{ce}You are not in a team!"));
return;
}
}
else
{
/// Format of a private team message from a non-team-member. {0} = sender display name, {1} = team display name, {2} = message.
rawMessage = I.t("{gold}[{0}{gold} -> team {1}{gold}] {reset}{2}", sender.getDisplayName(), team.getDisplayName(), message);
recipient = team;
}
sendRawTeamMessage(sender, rawMessage, recipient);
}
/**
* Sends a raw team-message from the given player.
*
* @param sender The sender of this message.
* @param rawMessage The raw message to be sent.
* @param team The recipient of this message.
*/
private void sendRawTeamMessage(final Player sender, String rawMessage, UHTeam team)
{
// The message is sent to the players of the team...
for (final Player player : team.getOnlinePlayers())
{
MessageSender.sendChatMessage(player, rawMessage);
}
// ... to the spies ...
if (otherTeamChatLocked.containsValue(team))
{
for (UUID playerId : otherTeamChatLocked.keySet())
{
// The message is only sent to the spies not in the team, to avoid double messages
if (otherTeamChatLocked.get(playerId).equals(team) && !team.containsPlayer(playerId))
{
MessageSender.sendChatMessage(p.getServer().getPlayer(playerId), rawMessage);
}
}
}
// ... to the global spies ...
for (UUID playerId : globalSpies)
{
if (!team.containsPlayer(playerId))
{
p.getServer().getPlayer(playerId).sendMessage(rawMessage);
}
}
// ... and to the console.
if (UHConfig.TEAMS_OPTIONS.TEAM_CHAT.LOG.get())
{
p.getServer().getConsoleSender().sendMessage(rawMessage);
}
RunTask.later(new Runnable()
{
@Override
public void run()
{
ProTips.LOCK_CHAT.sendTo(sender);
}
}, 30L);
}
/**
* Sends a global message from the given player.
*
* @param sender The sender of this message.
* @param message The message to be sent.
*/
public void sendGlobalMessage(Player sender, String message)
{
// This message will be sent synchronously.
// The players' messages are sent asynchronously.
// That's how we differentiates the messages sent through /g and the messages sent using
// the normal chat.
sender.chat(message);
}
/**
* Toggles the chat between the global chat and the team chat.
*
* @param player The chat of this player will be toggled.
* @return {@code true} if the chat is now the team chat; false else.
*/
public boolean toggleChatForPlayer(Player player)
{
return toggleChatForPlayer(player, null);
}
/**
* Toggles the chat between the global chat and the team chat.
*
* @param player The chat of this player will be toggled.
* @param team The team to chat with. If null, the player's team will be used.
* @return {@code true} if the chat is now the team chat; false else.
*/
public boolean toggleChatForPlayer(final Player player, UHTeam team)
{
// Permission check
if (team == null && !player.hasPermission("uh.teamchat.self"))
{
player.sendMessage(I.t("{ce}You are not allowed to send a private message to your team."));
return false;
}
if (team != null && !player.hasPermission("uh.teamchat.others"))
{
player.sendMessage(I.t("{ce}You are not allowed to enter in the private chat of another team."));
return false;
}
// If the team is not null, we will always go to the team chat
// Else, normal toggle
if (team != null)
{
// if the player was in another team chat before, we removes it.
teamChatLocked.remove(player.getUniqueId());
otherTeamChatLocked.put(player.getUniqueId(), team);
return true;
}
else
{
if (isAnyTeamChatEnabled(player))
{
teamChatLocked.remove(player.getUniqueId());
otherTeamChatLocked.remove(player.getUniqueId());
return false;
}
else
{
teamChatLocked.add(player.getUniqueId());
RunTask.later(new Runnable()
{
@Override
public void run()
{
ProTips.USE_G_COMMAND.sendTo(player);
}
}, 10L);
return true;
}
}
}
/**
* Returns true if the team chat is enabled for the given player.
*
* @param player The player.
* @param team If non-null, this will check if the given player is spying the current team.
* @return {@code true} if the team chat is enabled for the given player.
*/
public boolean isTeamChatEnabled(Player player, UHTeam team)
{
if (team == null)
{
return teamChatLocked.contains(player.getUniqueId());
}
else
{
UHTeam lockedTeam = this.otherTeamChatLocked.get(player.getUniqueId());
UHTeam playerTeam = p.getTeamManager().getTeamForPlayer(player);
return (lockedTeam != null && lockedTeam.equals(team)) || (playerTeam != null && playerTeam.equals(team));
}
}
/**
* Returns true if the team chat is enabled for the given player.
*
* @param player The player.
* @return {@code true} if the team chat is enabled for the given player.
*/
public boolean isTeamChatEnabled(Player player)
{
return this.isTeamChatEnabled(player, null);
}
/**
* Returns true if the given player is in the team chat of another team.
*
* @param player The player.
* @return {@code true} if the given player is in the team chat of another team.
*/
public boolean isOtherTeamChatEnabled(Player player)
{
return otherTeamChatLocked.containsKey(player.getUniqueId());
}
/**
* Returns true if a team chat is enabled for the given player.
*
* @param player The player.
* @return {@code true} if a team chat is enabled for the given player.
*/
public boolean isAnyTeamChatEnabled(Player player)
{
return (teamChatLocked.contains(player.getUniqueId()) || otherTeamChatLocked.containsKey(player.getUniqueId()));
}
/**
* Returns the other team viewed by the given player, or null if the player is not in
* the chat of another team.
*
* @param player The player.
* @return The other team viewed by the given player.
*/
public UHTeam getOtherTeamEnabled(Player player)
{
return otherTeamChatLocked.get(player.getUniqueId());
}
/**
* Registers a player receiving ALL the teams chats.
*
* @param id The spy's UUID.
*/
public void addGlobalSpy(UUID id)
{
globalSpies.add(id);
}
/**
* Stops a player from receiving ALL the teams chats.
*
* @param id The spy's UUID.
*/
public void removeGlobalSpy(UUID id)
{
globalSpies.remove(id);
}
/**
* Checks if the given player receives all the teams chats.
*
* @param id The spy's UUID.
* @return {@code true} if spying.
*/
public boolean isGlobalSpy(UUID id)
{
return globalSpies.contains(id);
}
}