2021-02-20 20:57:10 +00:00
|
|
|
|
using System.Collections.Generic;
|
2021-02-27 22:15:29 +00:00
|
|
|
|
using System.Text;
|
2021-02-20 20:57:10 +00:00
|
|
|
|
using UnityEngine;
|
2019-11-15 11:37:37 +00:00
|
|
|
|
using SanAndreasUnity.Net;
|
2021-02-20 20:57:10 +00:00
|
|
|
|
using SanAndreasUnity.Utilities;
|
2019-11-15 11:37:37 +00:00
|
|
|
|
|
|
|
|
|
namespace SanAndreasUnity.Chat
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class ChatMessage
|
|
|
|
|
{
|
|
|
|
|
public ChatMessage (string msg, string sender)
|
|
|
|
|
{
|
|
|
|
|
this.msg = msg;
|
|
|
|
|
this.sender = sender;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string msg = "";
|
|
|
|
|
public string sender = "";
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-20 20:57:10 +00:00
|
|
|
|
public class ChatPreprocessorResult
|
|
|
|
|
{
|
|
|
|
|
public bool shouldBeDiscarded;
|
|
|
|
|
public string finalChatMessage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class ChatPreprocessor
|
|
|
|
|
{
|
|
|
|
|
public System.Func<Player, string, ChatPreprocessorResult> processCallback;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-15 11:37:37 +00:00
|
|
|
|
|
|
|
|
|
public class ChatManager : MonoBehaviour
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
public static ChatManager singleton { get ; private set ; }
|
2021-02-28 21:50:11 +00:00
|
|
|
|
|
2019-11-15 11:37:37 +00:00
|
|
|
|
public string serverChatNick = "<color=green>Server</color>";
|
2021-02-28 21:50:11 +00:00
|
|
|
|
public int maxChatMessageLength = 50;
|
|
|
|
|
|
2019-11-15 11:37:37 +00:00
|
|
|
|
public static event System.Action<ChatMessage> onChatMessage = delegate {};
|
|
|
|
|
|
2021-02-20 20:57:10 +00:00
|
|
|
|
List<ChatPreprocessor> m_chatPreprocessors = new List<ChatPreprocessor>();
|
|
|
|
|
|
2021-02-28 21:26:30 +00:00
|
|
|
|
static StringBuilder _stringBuilderForMessageProcessing = new StringBuilder();
|
|
|
|
|
|
2019-11-15 11:37:37 +00:00
|
|
|
|
|
|
|
|
|
void Awake ()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
singleton = this;
|
|
|
|
|
|
|
|
|
|
onChatMessage += (ChatMessage chatMsg) => Debug.Log ("<color=blue>" + chatMsg.sender + "</color> : " + chatMsg.msg);
|
|
|
|
|
|
2021-02-20 20:57:10 +00:00
|
|
|
|
ChatSync.onChatMessageReceivedOnServer += OnChatMessageReceivedOnServer;
|
2021-02-27 22:25:07 +00:00
|
|
|
|
ChatSync.onChatMessageReceivedOnLocalPlayer += (ChatMessage chatMsg) => F.InvokeEventExceptionSafe(onChatMessage, chatMsg);
|
2019-11-15 11:37:37 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnSceneChanged( SanAndreasUnity.Behaviours.SceneChangedMessage info ) {
|
|
|
|
|
|
|
|
|
|
if (NetStatus.IsServer) {
|
|
|
|
|
SendChatMessageToAllPlayersAsServer ("Map changed to " + info.s2.name + ".");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-02-20 20:57:10 +00:00
|
|
|
|
private void OnChatMessageReceivedOnServer(Player player, string msg)
|
|
|
|
|
{
|
2021-02-28 20:28:57 +00:00
|
|
|
|
if (!FilterWithPreprocessors(player, ref msg))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
SendChatMessageToAllPlayers(msg, "player " + player.netId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool FilterWithPreprocessors(Player player, ref string chatMessageToFilter)
|
|
|
|
|
{
|
|
|
|
|
string finalMsg = chatMessageToFilter;
|
|
|
|
|
|
2021-02-20 20:57:10 +00:00
|
|
|
|
foreach (var chatPreprocessor in m_chatPreprocessors)
|
|
|
|
|
{
|
|
|
|
|
ChatPreprocessorResult result = null;
|
2021-02-28 20:28:57 +00:00
|
|
|
|
F.RunExceptionSafe(() => result = chatPreprocessor.processCallback(player, finalMsg));
|
2021-02-20 20:57:10 +00:00
|
|
|
|
|
|
|
|
|
if (null == result || result.shouldBeDiscarded || null == result.finalChatMessage)
|
2021-02-28 20:28:57 +00:00
|
|
|
|
return false;
|
2021-02-20 20:57:10 +00:00
|
|
|
|
|
2021-02-28 20:28:57 +00:00
|
|
|
|
finalMsg = result.finalChatMessage;
|
2021-02-20 20:57:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-02-28 20:28:57 +00:00
|
|
|
|
chatMessageToFilter = finalMsg;
|
|
|
|
|
return true;
|
2021-02-20 20:57:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-02-28 21:53:16 +00:00
|
|
|
|
public static string ProcessChatMessage(string chatMessage, bool allowTags)
|
2021-02-27 22:15:29 +00:00
|
|
|
|
{
|
|
|
|
|
if (chatMessage == null)
|
|
|
|
|
return string.Empty;
|
|
|
|
|
|
2021-02-28 21:26:30 +00:00
|
|
|
|
if (chatMessage.Length > 2000)
|
|
|
|
|
return string.Empty;
|
|
|
|
|
|
|
|
|
|
var sb = _stringBuilderForMessageProcessing;
|
|
|
|
|
sb.Clear();
|
2021-02-28 21:50:11 +00:00
|
|
|
|
sb.Append(allowTags ? chatMessage : (chatMessage.Length > singleton.maxChatMessageLength ? chatMessage.Substring(0, singleton.maxChatMessageLength) : chatMessage));
|
2021-02-27 22:15:29 +00:00
|
|
|
|
|
|
|
|
|
// Remove tags.
|
2021-02-28 21:50:11 +00:00
|
|
|
|
if (!allowTags)
|
|
|
|
|
{
|
|
|
|
|
sb.Replace('<', ' '); // the only easy way :D
|
|
|
|
|
sb.Replace('>', ' ');
|
|
|
|
|
// msg = msg.Replace ("<color", "color");
|
|
|
|
|
// msg = msg.Replace ("<size", "size");
|
|
|
|
|
// msg = msg.Replace ("<b>", "");
|
|
|
|
|
// msg = msg.Replace ("<i>", "");
|
|
|
|
|
// msg = msg.Replace (">", "\\>");
|
|
|
|
|
}
|
2021-02-27 22:15:29 +00:00
|
|
|
|
|
|
|
|
|
sb.Replace('\r', ' ');
|
|
|
|
|
sb.Replace('\n', ' ');
|
|
|
|
|
sb.Replace('\t', ' ');
|
|
|
|
|
|
|
|
|
|
return sb.ToString().Trim();
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-28 22:07:26 +00:00
|
|
|
|
public static void SendChatMessageToAllPlayersAsServer( string msg )
|
|
|
|
|
{
|
|
|
|
|
NetStatus.ThrowIfNotOnServer();
|
2019-11-15 11:37:37 +00:00
|
|
|
|
|
2021-02-28 22:07:26 +00:00
|
|
|
|
SendChatMessageToAllPlayers (msg, singleton.serverChatNick);
|
2019-11-15 11:37:37 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void SendChatMessageToAllPlayersAsLocalPlayer( string msg ) {
|
|
|
|
|
|
|
|
|
|
if (null == Player.Local) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var chatSync = Player.Local.GetComponent<ChatSync> ();
|
|
|
|
|
if (chatSync != null) {
|
|
|
|
|
chatSync.SendChatMsgToServer (msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary> Use only on server. </summary>
|
|
|
|
|
public static void SendChatMessageToAllPlayers( string msg, string sender ) {
|
|
|
|
|
|
2021-02-28 22:07:26 +00:00
|
|
|
|
NetStatus.ThrowIfNotOnServer();
|
2021-02-20 20:57:52 +00:00
|
|
|
|
|
2021-02-28 21:53:16 +00:00
|
|
|
|
msg = ChatManager.ProcessChatMessage(msg, true);
|
2021-02-27 22:15:29 +00:00
|
|
|
|
if (string.IsNullOrEmpty(msg))
|
|
|
|
|
return;
|
2019-11-15 11:37:37 +00:00
|
|
|
|
|
|
|
|
|
foreach (var player in Player.AllPlayers) {
|
|
|
|
|
SendChatMessageToPlayer ( player, msg, sender );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!NetStatus.IsHost ()) {
|
|
|
|
|
// running as dedicated server
|
|
|
|
|
// we should invoke the event here, because there is no local player to receive the chat message
|
2021-02-27 22:25:07 +00:00
|
|
|
|
F.InvokeEventExceptionSafe(onChatMessage, new ChatMessage(msg, sender));
|
2019-11-15 11:37:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary> Use only on server. </summary>
|
|
|
|
|
public static void SendChatMessageToPlayer( Player player, string msg ) {
|
|
|
|
|
|
2021-02-28 22:07:26 +00:00
|
|
|
|
NetStatus.ThrowIfNotOnServer();
|
2019-11-15 11:37:37 +00:00
|
|
|
|
|
2021-02-28 21:53:16 +00:00
|
|
|
|
msg = ChatManager.ProcessChatMessage(msg, true);
|
2021-02-27 22:15:29 +00:00
|
|
|
|
if (string.IsNullOrEmpty(msg))
|
|
|
|
|
return;
|
|
|
|
|
|
2019-11-15 11:37:37 +00:00
|
|
|
|
SendChatMessageToPlayer (player, msg, singleton.serverChatNick);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void SendChatMessageToPlayer( Player player, string msg, string sender ) {
|
|
|
|
|
|
2021-02-28 22:07:26 +00:00
|
|
|
|
NetStatus.ThrowIfNotOnServer();
|
2019-11-15 11:37:37 +00:00
|
|
|
|
|
|
|
|
|
var chatSync = player.GetComponent<ChatSync> ();
|
|
|
|
|
if (chatSync != null) {
|
|
|
|
|
chatSync.SendChatMsgToClient (player.connectionToClient, msg, sender);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-20 20:57:10 +00:00
|
|
|
|
public void RegisterChatPreprocessor(ChatPreprocessor chatPreprocessor)
|
|
|
|
|
{
|
|
|
|
|
m_chatPreprocessors.Add(chatPreprocessor);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-15 11:37:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|