You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

227 lines
6.8 KiB

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<UserChat> connectedUsers = new List<UserChat>();
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<ChatList>("{\"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<string> options = new List<string>();
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];
}
}