using System; using System.Collections; using System.Collections.Generic; using System.Security.Cryptography; using TMPro; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; public class ChatManager : TogglePanel { public static ChatManager Instance { get; private set; } private void Awake() { if (Instance == null) Instance = this; } public enum ChatType { Location, Global, Private } [Serializable] public class UserChat { public string Name; public ulong UID; public UserChat() { Name = ""; UID = 0; } public UserChat(string name, ulong uID) { Name = name; UID = uID; } } [Header("Prefabs")] [SerializeField] private ChatText chatTextPrefab; [SerializeField] private ChatText myChatTextPrefab; [Header("Data")] [SerializeField] private ChatType chatType; [SerializeField] private TMP_InputField inputField; [Header("Global Chat Components")] [SerializeField] private Transform globalChatContent; [SerializeField] private ScrollRect globalChatRect; [Header("Location Chat Components")] [SerializeField] private Transform locationChatContent; [SerializeField] private ScrollRect locationChatRect; [Header("Private Chat Components")] [SerializeField] private Transform privateChatContent; [SerializeField] private ScrollRect privateChatRect; [SerializeField] private TMP_Dropdown userDropdown; [SerializeField] private List connectedUsers = new List(); private UserChat sendTo; private ChatNode lastChatNode = null; private void Start() { StartCoroutine(FetchGlobalChat()); userDropdown.onValueChanged.AddListener(OnDropdownValueChanged); } private IEnumerator FetchGlobalChat() { while (true) { yield return new WaitForSeconds(2f); WebRequest.Get(this, "GetMessages", (UnityWebRequest request, string data) => { if (!string.IsNullOrEmpty(data)) { ChatList list = JsonUtility.FromJson("{\"chats\":" + data + "}"); Debug.Log(list.chats.Length); int lastIndex = list.chats.Length - 1; if (lastIndex > 0) { for (int i = 0; i < list.chats.Length; i++) { if (list.chats[i].Equals(lastChatNode)) { lastIndex = i - 1; } } for (int i = lastIndex; i >= 0; i--) { lastChatNode = list.chats[i]; CreateGlobalMessage(list.chats[i].message, list.chats[i].sender, Color.black, list.chats[i].sender == LocalPlayerData.PlayerName); } } } }); } } private void ClearChat(Transform chatContent) { foreach (Transform chatTransform in chatContent) { Destroy(chatTransform); } } public void ClearGlobalChat() => ClearChat(globalChatContent); public void ClearLocationChat() => ClearChat(locationChatContent); public void ClearPrivateChat() => ClearChat(privateChatContent); private void CreateMessage(Transform chatContent, ScrollRect chatRect, string message, string owner, Color color, bool isMine) { ChatText prefab = isMine ? myChatTextPrefab : chatTextPrefab; ChatText chatText = Instantiate(prefab, chatContent); chatText.Initialize(message, owner, color); chatRect.verticalNormalizedPosition = 0f; } public void CreateGlobalMessage(string message, string owner, Color color, bool isMine) => CreateMessage(globalChatContent, globalChatRect, message, owner, color, isMine); public void CreateLocationMessage(string message, string owner, Color color, bool isMine) => CreateMessage(locationChatContent, locationChatRect, message, owner, color, isMine); public void CreatePrivateMessage(string message, string owner, Color color, bool isMine) => CreateMessage(privateChatContent, privateChatRect, message, owner, color, isMine); public void SetChatType(int chatType) => SetChatType((ChatType)chatType); public void SetChatType(ChatType chatType) { this.chatType = chatType; globalChatRect.gameObject.SetActive(chatType == ChatType.Global); locationChatRect.gameObject.SetActive(chatType == ChatType.Location); privateChatRect.gameObject.SetActive(chatType == ChatType.Private); userDropdown.gameObject.SetActive(chatType == ChatType.Private); } private void SendMessageGlobal(string message) { CreateGlobalMessage(message, LocalPlayerData.PlayerName, Color.black, true); ChatNode chatNode = new ChatNode(message, LocalPlayerData.PlayerName);//, LocalPlayerData.ID.ToString()); lastChatNode = chatNode; WebRequest.Post(this, "SendMessage", JsonUtility.ToJson(chatNode), (UnityWebRequest request, string data) => { }); } public void SendLocationMessage() { string message = inputField.text; if (string.IsNullOrEmpty(message)) return; switch (chatType) { case ChatType.Global: SendMessageGlobal(message); break; case ChatType.Location: GameManager.LocalPlayer.SendMessageLocation(inputField.text); break; case ChatType.Private: if (sendTo == null) return; GameManager.LocalPlayer.SendMessagePrivate(inputField.text, sendTo.UID); break; default: break; } inputField.text = ""; } public void ClearUsers() { connectedUsers.Clear(); UpdateDropdownList(); } public void AddUser(string name, ulong uid) { connectedUsers.Add(new UserChat(name, uid)); UpdateDropdownList(); } public void RemoveUser(ulong uid) { UserChat userChat = connectedUsers.Find(x => x.UID == uid); if (userChat != null) { connectedUsers.Remove(userChat); } UpdateDropdownList(); } public void UpdateDropdownList() { List options = new List(); foreach (var item in connectedUsers) { options.Add(item.Name); } userDropdown.ClearOptions(); userDropdown.AddOptions(options); sendTo = options.Count > 0 ? connectedUsers[0] : null; } void OnDropdownValueChanged(int index) { sendTo = connectedUsers[index]; } }