From 7a1a7deb2e21d0f5f84b251fb882e0840c9473da Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Fri, 8 Sep 2023 11:23:01 +0100 Subject: [PATCH] add chat method + event to api --- APITestMod/APITestMod.cs | 4 ++++ APITestMod/IQSBAPI.cs | 20 ++++++++++++++++++++ QSB/API/IQSBAPI.cs | 20 ++++++++++++++++++++ QSB/API/QSBAPI.cs | 14 ++++++++++++++ QSB/HUD/Messages/ChatMessage.cs | 23 +++++++++++++++++++++++ QSB/HUD/MultiplayerHUDManager.cs | 7 ++++++- 6 files changed, 87 insertions(+), 1 deletion(-) diff --git a/APITestMod/APITestMod.cs b/APITestMod/APITestMod.cs index 50c26fc2..1d3fb575 100644 --- a/APITestMod/APITestMod.cs +++ b/APITestMod/APITestMod.cs @@ -23,6 +23,7 @@ public class APITestMod : ModBehaviour qsbAPI.OnPlayerJoin().AddListener((uint playerId) => ModHelper.Console.WriteLine($"{playerId} joined the game!", MessageType.Success)); qsbAPI.OnPlayerLeave().AddListener((uint playerId) => ModHelper.Console.WriteLine($"{playerId} left the game!", MessageType.Success)); + qsbAPI.OnChatMessage().AddListener((string message, uint from) => ModHelper.Console.WriteLine($"Chat message \"{message}\" from {from} ({(from == uint.MaxValue ? "QSB" : qsbAPI.GetPlayerName(from))})")); button.onClick.AddListener(() => { @@ -52,6 +53,9 @@ public class APITestMod : ModBehaviour ModHelper.Console.WriteLine("Sending float message test..."); qsbAPI.RegisterHandler("apitest-float", MessageHandler); qsbAPI.SendMessage("apitest-float", 3.14f, receiveLocally: true); + + qsbAPI.SendChatMessage("Non-system chat message", false, Color.white); + qsbAPI.SendChatMessage("System chat message", true, Color.cyan); }); }; } diff --git a/APITestMod/IQSBAPI.cs b/APITestMod/IQSBAPI.cs index 8f795e0e..eadb98ce 100644 --- a/APITestMod/IQSBAPI.cs +++ b/APITestMod/IQSBAPI.cs @@ -1,5 +1,6 @@ using System; using OWML.Common; +using UnityEngine; using UnityEngine.Events; public interface IQSBAPI @@ -96,4 +97,23 @@ public interface IQSBAPI void RegisterHandler(string messageType, Action handler); #endregion + + #region Chat + + /// + /// Invoked when a chat message is received. + /// The string is the message body. + /// The uint is the player who sent the message. If it's a system message, this is uint.MaxValue. + /// + UnityEvent OnChatMessage(); + + /// + /// Sends a message in chat. + /// + /// The text of the message. + /// If false, the message is sent as if the local player wrote it manually. If true, the message has no player attached to it, like the player join messages. + /// The color of the message. + void SendChatMessage(string message, bool systemMessage, Color color); + + #endregion } diff --git a/QSB/API/IQSBAPI.cs b/QSB/API/IQSBAPI.cs index 8f795e0e..eadb98ce 100644 --- a/QSB/API/IQSBAPI.cs +++ b/QSB/API/IQSBAPI.cs @@ -1,5 +1,6 @@ using System; using OWML.Common; +using UnityEngine; using UnityEngine.Events; public interface IQSBAPI @@ -96,4 +97,23 @@ public interface IQSBAPI void RegisterHandler(string messageType, Action handler); #endregion + + #region Chat + + /// + /// Invoked when a chat message is received. + /// The string is the message body. + /// The uint is the player who sent the message. If it's a system message, this is uint.MaxValue. + /// + UnityEvent OnChatMessage(); + + /// + /// Sends a message in chat. + /// + /// The text of the message. + /// If false, the message is sent as if the local player wrote it manually. If true, the message has no player attached to it, like the player join messages. + /// The color of the message. + void SendChatMessage(string message, bool systemMessage, Color color); + + #endregion } diff --git a/QSB/API/QSBAPI.cs b/QSB/API/QSBAPI.cs index 9fe0969c..1430e142 100644 --- a/QSB/API/QSBAPI.cs +++ b/QSB/API/QSBAPI.cs @@ -5,7 +5,10 @@ using QSB.Messaging; using QSB.Player; using System; using System.Linq; +using QSB.HUD; +using QSB.HUD.Messages; using UnityEngine.Events; +using UnityEngine; namespace QSB.API; @@ -35,6 +38,17 @@ public class QSBAPI : IQSBAPI public void RegisterHandler(string messageType, Action handler) => AddonDataManager.RegisterHandler(messageType.GetStableHashCode(), handler); + + public UnityEvent OnChatMessage() => MultiplayerHUDManager.OnChatMessageEvent; + + public void SendChatMessage(string message, bool systemMessage, Color color) + { + var fromName = systemMessage + ? "QSB" + : QSBPlayerManager.LocalPlayer.Name; + + new ChatMessage($"{fromName}: {message}", color).Send(); + } } internal static class QSBAPIEvents diff --git a/QSB/HUD/Messages/ChatMessage.cs b/QSB/HUD/Messages/ChatMessage.cs index b8333299..b21e1e24 100644 --- a/QSB/HUD/Messages/ChatMessage.cs +++ b/QSB/HUD/Messages/ChatMessage.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using QSB.Player; using UnityEngine; namespace QSB.HUD.Messages; @@ -17,5 +18,27 @@ public class ChatMessage : QSBMessage<(string message, Color color)> public override void OnReceiveRemote() { MultiplayerHUDManager.Instance.WriteMessage(Data.message, Data.color); + + var fromPlayer = QSBPlayerManager.GetPlayer(From); + var qsb = false; + string name; + if (Data.message.StartsWith("QSB: ")) + { + name = "QSB: "; + qsb = true; + } + else if (Data.message.StartsWith($"{fromPlayer.Name}: ")) + { + name = $"{fromPlayer.Name}: "; + } + else + { + // uhhh idk what happened + MultiplayerHUDManager.OnChatMessageEvent.Invoke(Data.message, From); + return; + } + + var messageWithoutName = Data.message.Remove(Data.message.IndexOf(name), name.Length); + MultiplayerHUDManager.OnChatMessageEvent.Invoke(messageWithoutName, qsb ? uint.MaxValue : From); } } \ No newline at end of file diff --git a/QSB/HUD/MultiplayerHUDManager.cs b/QSB/HUD/MultiplayerHUDManager.cs index 36a77183..ec719592 100644 --- a/QSB/HUD/MultiplayerHUDManager.cs +++ b/QSB/HUD/MultiplayerHUDManager.cs @@ -9,6 +9,7 @@ using QSB.WorldSync; using System; using System.Linq; using UnityEngine; +using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; using UnityEngine.UI; @@ -42,6 +43,9 @@ public class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart public static readonly ListStack HUDIconStack = new(true); + public class ChatEvent : UnityEvent { } + public static readonly ChatEvent OnChatMessageEvent = new(); + private void Start() { Instance = this; @@ -87,7 +91,8 @@ public class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart // perks of being a qsb dev :-) public void WriteSystemMessage(string message, Color color) { - WriteMessage(message, color); + WriteMessage($"QSB: {message}", color); + OnChatMessageEvent.Invoke(message, uint.MaxValue); } public void WriteMessage(string message, Color color)