using System;
using System.Linq;
using ACE.Database.Models.Shard;
using ACE.Entity;
using ACE.Entity.Enum;
using ACE.Server.Entity;
using ACE.Server.Network.Structure;
using ACE.Server.Network.GameEvent.Events;
using ACE.Server.Network.GameMessages.Messages;
using ACE.Server.Managers;
namespace ACE.Server.WorldObjects.Managers
{
public class SquelchManager
{
///
/// The player who owns these squelches
///
public Player Player;
///
/// The SquelchDB contains the account and character squelches,
/// in the network protocol Dictionary format
///
public SquelchDB Squelches;
///
/// Constructs a new SquelchManager for a Player
///
///
public SquelchManager(Player player)
{
Player = player;
UpdateSquelchDB();
}
///
/// Returns TRUE if this player has squelched any accounts / characters / globals
///
public bool HasSquelches => Squelches.Accounts.Count > 0 || Squelches.Characters.Count > 0 || Squelches.Globals.Filters.Count > 0;
///
/// Returns TRUE if this channel can be squelched
///
public static bool IsLegalChannel(ChatMessageType channel)
{
switch (channel)
{
case ChatMessageType.Speech:
case ChatMessageType.Tell:
case ChatMessageType.Combat:
case ChatMessageType.Magic:
case ChatMessageType.Emote:
case ChatMessageType.Appraisal:
case ChatMessageType.Spellcasting:
case ChatMessageType.Allegiance:
case ChatMessageType.Fellowship:
case ChatMessageType.CombatEnemy:
case ChatMessageType.CombatSelf:
case ChatMessageType.Recall:
case ChatMessageType.Craft:
case ChatMessageType.Salvaging:
return true;
}
return false;
}
///
/// Called when adding or removing a character squelch
///
public void HandleActionModifyCharacterSquelch(bool squelch, uint playerGuid, string playerName, ChatMessageType messageType)
{
//Console.WriteLine($"{Player.Name}.HandleActionModifyCharacterSquelch({squelch}, {playerGuid:X8}, {playerName}, {messageType})");
if (messageType != ChatMessageType.AllChannels && !IsLegalChannel(messageType))
{
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{messageType} is not a legal squelch channel", ChatMessageType.Broadcast));
return;
}
IPlayer player;
if (playerGuid != 0)
{
player = PlayerManager.FindByGuid(new ObjectGuid(playerGuid));
if (player == null)
{
Player.Session.Network.EnqueueSend(new GameMessageSystemChat("Couldn't find player to squelch.", ChatMessageType.Broadcast));
return;
}
}
else
{
if (string.IsNullOrWhiteSpace(playerName)) return;
player = PlayerManager.FindByName(playerName);
if (player == null)
{
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{playerName} not found.", ChatMessageType.Broadcast));
return;
}
}
if (player.Guid == Player.Guid)
{
Player.Session.Network.EnqueueSend(new GameMessageSystemChat("You can't squelch yourself!", ChatMessageType.Broadcast));
return;
}
if (squelch)
SquelchCharacter(player, messageType);
else
UnsquelchCharacter(player, messageType);
UpdateSquelchDB();
SendSquelchDB();
}
public void SquelchCharacter(IPlayer player, ChatMessageType messageType)
{
Squelches.Characters.TryGetValue(player.Guid.Full, out SquelchInfo existing);
var newMask = messageType.ToMask();
var channelMsg = messageType == ChatMessageType.AllChannels ? "" : $" on the {messageType} channel";
if (existing != null)
{
var existingMask = existing.Filters[0];
newMask = existingMask.Add(newMask);
if (existingMask == newMask)
{
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name} is already squelched{channelMsg}.", ChatMessageType.Broadcast));
return;
}
}
Player.Character.AddOrUpdateSquelch(player.Guid.Full, 0, (uint)newMask, Player.CharacterDatabaseLock);
Player.CharacterChangesDetected = true;
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name} has been squelched{channelMsg}.", ChatMessageType.Broadcast));
}
public void UnsquelchCharacter(IPlayer player, ChatMessageType messageType)
{
Squelches.Characters.TryGetValue(player.Guid.Full, out SquelchInfo existing);
if (existing == null)
{
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name} is not squelched.", ChatMessageType.Broadcast));
return;
}
if (messageType == ChatMessageType.AllChannels)
{
Player.Character.TryRemoveSquelch(player.Guid.Full, 0, out _, Player.CharacterDatabaseLock);
Player.CharacterChangesDetected = true;
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name} has been unsquelched.", ChatMessageType.Broadcast));
}
else
{
var existingMask = existing.Filters[0];
var removeMask = messageType.ToMask();
if (!existingMask.HasFlag(removeMask))
{
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name} is not squelched on the {messageType} channel.", ChatMessageType.Broadcast));
return;
}
var newMask = existingMask.Remove(removeMask);
if (newMask != SquelchMask.None)
Player.Character.AddOrUpdateSquelch(player.Guid.Full, 0, (uint)newMask, Player.CharacterDatabaseLock);
else
Player.Character.TryRemoveSquelch(player.Guid.Full, 0, out _, Player.CharacterDatabaseLock);
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name} has been unsquelched on the {messageType} channel.", ChatMessageType.Broadcast));
}
}
///
/// Called when adding or removing an account squelch
///
public void HandleActionModifyAccountSquelch(bool squelch, string playerName)
{
//Console.WriteLine($"{Player.Name}.HandleActionModifyAccountSquelch({squelch}, {playerName})");
if (string.IsNullOrWhiteSpace(playerName)) return;
var player = PlayerManager.FindByName(playerName);
if (player == null)
{
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{playerName} not found.", ChatMessageType.Broadcast));
return;
}
if (player.Account.AccountId == Player.Account.AccountId)
{
Player.Session.Network.EnqueueSend(new GameMessageSystemChat("You can't squelch yourself!", ChatMessageType.Broadcast));
return;
}
var squelches = Player.Character.GetSquelches(Player.CharacterDatabaseLock);
var existing = squelches.FirstOrDefault(i => i.SquelchAccountId == player.Account.AccountId);
if (squelch)
{
if (existing != null)
{
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name}'s account is already squelched.", ChatMessageType.Broadcast));
return;
}
// always all channels?
Player.Character.AddOrUpdateSquelch(player.Guid.Full, player.Account.AccountId, (uint)SquelchMask.AllChannels, Player.CharacterDatabaseLock);
Player.CharacterChangesDetected = true;
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name}'s account has been squelched.", ChatMessageType.Broadcast));
}
else
{
if (existing == null)
{
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name}'s account is not squelched.", ChatMessageType.Broadcast));
return;
}
Player.Character.TryRemoveSquelch(existing.SquelchCharacterId, player.Account.AccountId, out _, Player.CharacterDatabaseLock);
Player.CharacterChangesDetected = true;
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name}'s account has been unsquelched.", ChatMessageType.Broadcast));
}
UpdateSquelchDB();
SendSquelchDB();
}
///
/// Called when modifying the global squelches - @filter
///
public void HandleActionModifyGlobalSquelch(bool squelch, ChatMessageType messageType)
{
//Console.WriteLine($"{Player.Name}.HandleActionModifyGlobalSquelch({squelch}, {messageType})");
var mask = messageType.ToMask();
var existingMask = Player.SquelchGlobal;
var newMask = squelch ? existingMask.Add(mask) : existingMask.Remove(mask);
var op = squelch ? "squelch" : "unsquelch";
if (existingMask == newMask)
{
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"The {messageType} channel is already {op}ed.", ChatMessageType.Broadcast));
return;
}
Player.SquelchGlobal = newMask;
Player.Session.Network.EnqueueSend(new GameMessageSystemChat($"The {messageType} channel has been {op}ed.", ChatMessageType.Broadcast));
UpdateSquelchDB();
SendSquelchDB();
}
///
/// Builds the SquelchDB for network sending
///
///
public void UpdateSquelchDB()
{
Squelches = new SquelchDB(Player.Character.GetSquelches(Player.CharacterDatabaseLock), Player.SquelchGlobal);
}
///
/// Sends the SquelchDB to the player
///
public void SendSquelchDB()
{
Player.Session.Network.EnqueueSend(new GameEventSetSquelchDB(Player.Session, Squelches));
}
}
}