424 lines
22 KiB
C#
424 lines
22 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Numerics;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using MikeSchweitzer.WebSocket;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.Networking;
|
|
using UnityEngine.SceneManagement;
|
|
using UnityEngine.UI;
|
|
|
|
public class ChatroomMenu : MonoBehaviour
|
|
{
|
|
[SerializeField] private TMP_Text statusText;
|
|
[SerializeField] private Button backButton;
|
|
[SerializeField] private Button sendButton;
|
|
[SerializeField] private TMP_InputField messageInputField;
|
|
[SerializeField] private GameObject content;
|
|
[SerializeField] private GameObject sampleObject;
|
|
[SerializeField] private Button downButton;
|
|
[SerializeField] private ProfileMenu profilePrefab;
|
|
|
|
[SerializeField] private GameObject optionsPanel;
|
|
[SerializeField] private Button optionsPanelExitButton;
|
|
[SerializeField] private Button optionsPanelDeleteButton;
|
|
[SerializeField] private Button optionsPanelEditButton;
|
|
[SerializeField] private Button optionsPanelReportButton;
|
|
[SerializeField] private Button optionsPanelCopyButton;
|
|
private ChatroomMessage selectedMessageForOptions;
|
|
|
|
[SerializeField] private GameObject editMessagePanelSample;
|
|
private GameObject editMessagePanelCurrent;
|
|
|
|
[SerializeField] private GameObject reportMessagePanel;
|
|
[SerializeField] private Button reportMessagePanelExitButton;
|
|
[SerializeField] private Button reportMessagePanelSubmitButton;
|
|
[SerializeField] private TMP_InputField reportMessagePanelReportReason;
|
|
|
|
void Awake()
|
|
{
|
|
messageInputField.onSelect.AddListener((_) => messageInputField.caretPosition = messageInputField.text.Length);
|
|
reportMessagePanelReportReason.onSelect.AddListener((_) => reportMessagePanelReportReason.caretPosition = reportMessagePanelReportReason.text.Length);
|
|
|
|
WebsocketHandler.Instance._Connection.StateChanged += OnStateChanged;
|
|
WebsocketHandler.Instance._Connection.MessageReceived += OnMessageReceived;
|
|
if (WebsocketHandler.Instance._Connection.State == WebSocketState.Connected)
|
|
{
|
|
statusText.text = "Loading messages";
|
|
RequestInfoMessage msg = new()
|
|
{
|
|
kind = "chatroom_messages"
|
|
};
|
|
WebsocketHandler.Instance._Connection.AddOutgoingMessage(JsonUtility.ToJson(msg));
|
|
}
|
|
}
|
|
|
|
private void OnStateChanged(WebSocketConnection connection, WebSocketState oldState, WebSocketState newState)
|
|
{
|
|
if (newState == WebSocketState.Connected)
|
|
{
|
|
statusText.text = "Loading messages";
|
|
RequestInfoMessage msg = new()
|
|
{
|
|
kind = "chatroom_messages"
|
|
};
|
|
WebsocketHandler.Instance._Connection.AddOutgoingMessage(JsonUtility.ToJson(msg));
|
|
}
|
|
}
|
|
|
|
private void OnMessageReceived(WebSocketConnection connection, WebSocketMessage message)
|
|
{
|
|
if (message.String != null && connection.State == WebSocketState.Connected)
|
|
{
|
|
JToken data = JToken.Parse(message.String);
|
|
if (data["for"] != null)
|
|
{
|
|
if (data["for"].ToString() == "info_request:chatroom_messages")
|
|
{
|
|
var userId = BazookaManager.Instance.GetAccountID();
|
|
foreach (Transform item in content.transform)
|
|
{
|
|
if (!item.gameObject.activeSelf) continue;
|
|
Destroy(item.gameObject);
|
|
break;
|
|
}
|
|
foreach (var chatMessage in data["data"].ToObject<ChatroomMessage[]>())
|
|
{
|
|
InsertMessage(chatMessage, userId);
|
|
}
|
|
statusText.text = "";
|
|
StartCoroutine(ScrollToBottom());
|
|
CustomIconLoader.Init(FindObjectsByType<WaitingForCustomIcon>(FindObjectsSortMode.None));
|
|
}
|
|
else if (data["for"].ToString() == "upload:chatroom_message")
|
|
{
|
|
var userId = BazookaManager.Instance.GetAccountID();
|
|
var chatMessage = data["data"].ToObject<ChatroomMessage>();
|
|
Destroy(content.transform.GetChild(1).gameObject);
|
|
InsertMessage(chatMessage, userId);
|
|
CustomIconLoader.Init(FindObjectsByType<WaitingForCustomIcon>(FindObjectsSortMode.None));
|
|
}
|
|
else if (data["for"].ToString() == "delete:chatroom_message")
|
|
{
|
|
Destroy(content.transform.Find("ChatroomRow_" + data["data"]["id"].ToString() ?? "").gameObject);
|
|
if (data["data"]["fillerMessage"].ToString() != null)
|
|
{
|
|
var userId = BazookaManager.Instance.GetAccountID();
|
|
var chatMessage = data["data"]["fillerMessage"].ToObject<ChatroomMessage>();
|
|
var row = InsertMessage(chatMessage, userId);
|
|
row.transform.SetSiblingIndex(1);
|
|
CustomIconLoader.Init(FindObjectsByType<WaitingForCustomIcon>(FindObjectsSortMode.None));
|
|
}
|
|
}
|
|
else if (data["for"].ToString() == "edit:chatroom_message")
|
|
{
|
|
if (data["data"]["newContent"].ToString() != null)
|
|
{
|
|
content.transform.Find("ChatroomRow_" + data["data"]["id"].ToString()).transform.GetChild(3).GetComponent<TMP_Text>().text = data["data"]["newContent"].ToString();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GameObject InsertMessage(ChatroomMessage message, BigInteger? localUserId)
|
|
{
|
|
var obj = content.transform.Find("ChatroomRow_" + message.ID);
|
|
|
|
var rowInfo = Instantiate(sampleObject, content.transform);
|
|
rowInfo.transform.SetSiblingIndex(content.transform.childCount - 1);
|
|
var bgImg = rowInfo.transform.GetChild(0).GetComponent<Image>();
|
|
var usernameText = rowInfo.transform.GetChild(1).GetComponent<TMP_Text>();
|
|
var playerIcon = rowInfo.transform.GetChild(2).GetComponent<Image>();
|
|
var playerIconButton = rowInfo.transform.GetChild(2).GetComponent<Button>();
|
|
var playerOverlayIcon = playerIcon.transform.GetChild(0).GetComponent<Image>();
|
|
var messageText = rowInfo.transform.GetChild(3).GetComponent<TMP_Text>();
|
|
var optionsButton = rowInfo.transform.GetChild(4).GetComponent<Button>();
|
|
|
|
usernameText.text = message.Username;
|
|
messageText.text = Encoding.UTF8.GetString(Convert.FromBase64String(message.Content));
|
|
if (message.CustomIcon == null)
|
|
{
|
|
playerIcon.sprite = Resources.Load<Sprite>("Icons/Icons/bird_" + message.Icon);
|
|
if (message.Icon == 1) playerIcon.sprite = Tools.GetIconForUser(message.UserID);
|
|
playerOverlayIcon.sprite = Resources.Load<Sprite>("Icons/Overlays/overlay_" + message.Overlay);
|
|
if (message.Overlay != 0) playerOverlayIcon.gameObject.SetActive(true);
|
|
if (message.Overlay == 8) playerOverlayIcon.transform.localPosition = new UnityEngine.Vector2(-16.56f, 14.81f);
|
|
else if (message.Overlay == 11) playerOverlayIcon.transform.localPosition = new UnityEngine.Vector2(-14.74451f, 20.39122f);
|
|
else if (message.Overlay == 13) playerOverlayIcon.transform.localPosition = new UnityEngine.Vector2(-16.54019f, 14.70365f);
|
|
try
|
|
{
|
|
playerIcon.color = new Color(message.BirdColor[0] / 255f, message.BirdColor[1] / 255f, message.BirdColor[2] / 255f);
|
|
playerOverlayIcon.color = new Color(message.OverlayColor[0] / 255f, message.OverlayColor[1] / 255f, message.OverlayColor[2] / 255f);
|
|
}
|
|
catch
|
|
{
|
|
playerIcon.color = Color.white;
|
|
playerOverlayIcon.color = Color.white;
|
|
}
|
|
}
|
|
else playerIcon.gameObject.AddComponent<WaitingForCustomIcon>().ID = message.CustomIcon;
|
|
playerIconButton.onClick.AddListener(async () =>
|
|
{
|
|
var clone = Instantiate(profilePrefab.gameObject, profilePrefab.gameObject.transform.parent);
|
|
clone.SetActive(true);
|
|
await clone.GetComponent<ProfileMenu>().Init(message.UserID);
|
|
});
|
|
optionsButton.onClick.AddListener(() => OptionsButtonClick(message, localUserId ?? 0));
|
|
rowInfo.name = "ChatroomRow_" + message.ID;
|
|
var entryComponet = rowInfo.AddComponent<ChatroomMenuEntry>();
|
|
entryComponet.Init(bgImg, optionsButton);
|
|
rowInfo.SetActive(true);
|
|
return rowInfo;
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
WebsocketHandler.Instance._Connection.StateChanged -= OnStateChanged;
|
|
WebsocketHandler.Instance._Connection.MessageReceived -= OnMessageReceived;
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
reportMessagePanelReportReason.transform.GetChild(0).GetChild(1).GetComponent<TMP_Text>().textWrappingMode = TextWrappingModes.Normal;
|
|
if (BazookaManager.Instance.GetAccountID() == null || BazookaManager.Instance.GetAccountName() == null || BazookaManager.Instance.GetAccountSession() == null)
|
|
{
|
|
sendButton.interactable = false;
|
|
messageInputField.interactable = false;
|
|
}
|
|
sendButton.onClick.AddListener(HandleMessageSubmit);
|
|
downButton.onClick.AddListener(() => StartCoroutine(ScrollToBottom()));
|
|
messageInputField.textComponent.textWrappingMode = TextWrappingModes.Normal;
|
|
messageInputField.onSubmit.AddListener(_ => HandleMessageSubmit());
|
|
|
|
optionsPanelExitButton.onClick.AddListener(() =>
|
|
{
|
|
optionsPanel.SetActive(false);
|
|
selectedMessageForOptions = null;
|
|
});
|
|
optionsPanelDeleteButton.onClick.AddListener(() => { if (selectedMessageForOptions != null) HandleMessageDelete(); });
|
|
optionsPanelDeleteButton.onClick.AddListener(optionsPanelExitButton.onClick.Invoke);
|
|
optionsPanelEditButton.onClick.AddListener(() =>
|
|
{
|
|
var editMessage = Instantiate(editMessagePanelSample, editMessagePanelSample.transform.parent);
|
|
editMessagePanelCurrent = editMessage;
|
|
var editMessageChild = editMessage.transform.GetChild(0);
|
|
var editMessageChildExitButton = editMessageChild.GetChild(0).GetComponent<Button>();
|
|
var editMessageChildSubmitButton = editMessageChild.GetChild(1).GetComponent<Button>();
|
|
var editMessageChildOriginalPreview = editMessageChild.GetChild(2).gameObject;
|
|
var editMessageChildEditedPreview = editMessageChild.GetChild(3).gameObject;
|
|
var editMessageChildNewContentInputBox = editMessageChild.GetChild(4).GetComponent<TMP_InputField>();
|
|
editMessageChildNewContentInputBox.onSelect.AddListener((_) => editMessageChildNewContentInputBox.caretPosition = editMessageChildNewContentInputBox.text.Length);
|
|
editMessageChildNewContentInputBox.text = Encoding.UTF8.GetString(Convert.FromBase64String(selectedMessageForOptions.Content));
|
|
editMessageChildExitButton.onClick.AddListener(() =>
|
|
{
|
|
editMessagePanelCurrent = null;
|
|
Destroy(editMessage);
|
|
optionsPanel.SetActive(true);
|
|
});
|
|
editMessageChildSubmitButton.onClick.AddListener(() =>
|
|
{
|
|
HandleMessageEdit();
|
|
editMessagePanelCurrent = null;
|
|
Destroy(editMessage);
|
|
selectedMessageForOptions = null;
|
|
});
|
|
|
|
var rowInfo = editMessageChild.GetChild(2);
|
|
var usernameText = rowInfo.transform.GetChild(2).GetComponent<TMP_Text>();
|
|
var playerIcon = rowInfo.transform.GetChild(3).GetComponent<Image>();
|
|
var playerOverlayIcon = playerIcon.transform.GetChild(0).GetComponent<Image>();
|
|
var messageText = rowInfo.transform.GetChild(4).GetComponent<TMP_Text>();
|
|
var optionsButton = rowInfo.transform.GetChild(5).GetComponent<Button>();
|
|
|
|
usernameText.text = selectedMessageForOptions.Username;
|
|
messageText.text = Encoding.UTF8.GetString(Convert.FromBase64String(selectedMessageForOptions.Content));
|
|
if (selectedMessageForOptions.CustomIcon == null)
|
|
{
|
|
playerIcon.sprite = Resources.Load<Sprite>("Icons/Icons/bird_" + selectedMessageForOptions.Icon);
|
|
if (selectedMessageForOptions.Icon == 1) playerIcon.sprite = Tools.GetIconForUser(selectedMessageForOptions.UserID);
|
|
playerOverlayIcon.sprite = Resources.Load<Sprite>("Icons/Overlays/overlay_" + selectedMessageForOptions.Overlay);
|
|
if (selectedMessageForOptions.Overlay != 0) playerOverlayIcon.gameObject.SetActive(true);
|
|
if (selectedMessageForOptions.Overlay == 8) playerOverlayIcon.transform.localPosition = new UnityEngine.Vector2(-16.56f, 14.81f);
|
|
else if (selectedMessageForOptions.Overlay == 11) playerOverlayIcon.transform.localPosition = new UnityEngine.Vector2(-14.74451f, 20.39122f);
|
|
else if (selectedMessageForOptions.Overlay == 13) playerOverlayIcon.transform.localPosition = new UnityEngine.Vector2(-16.54019f, 14.70365f);
|
|
try
|
|
{
|
|
playerIcon.color = new Color(selectedMessageForOptions.BirdColor[0] / 255f, selectedMessageForOptions.BirdColor[1] / 255f, selectedMessageForOptions.BirdColor[2] / 255f);
|
|
playerOverlayIcon.color = new Color(selectedMessageForOptions.OverlayColor[0] / 255f, selectedMessageForOptions.OverlayColor[1] / 255f, selectedMessageForOptions.OverlayColor[2] / 255f);
|
|
}
|
|
catch
|
|
{
|
|
playerIcon.color = Color.white;
|
|
playerOverlayIcon.color = Color.white;
|
|
}
|
|
}
|
|
else playerIcon.gameObject.AddComponent<WaitingForCustomIcon>().ID = selectedMessageForOptions.CustomIcon;
|
|
|
|
rowInfo = editMessageChild.GetChild(3);
|
|
usernameText = rowInfo.transform.GetChild(2).GetComponent<TMP_Text>();
|
|
playerIcon = rowInfo.transform.GetChild(3).GetComponent<Image>();
|
|
playerOverlayIcon = playerIcon.transform.GetChild(0).GetComponent<Image>();
|
|
messageText = rowInfo.transform.GetChild(4).GetComponent<TMP_Text>();
|
|
optionsButton = rowInfo.transform.GetChild(5).GetComponent<Button>();
|
|
|
|
usernameText.text = selectedMessageForOptions.Username;
|
|
messageText.text = Encoding.UTF8.GetString(Convert.FromBase64String(selectedMessageForOptions.Content));
|
|
editMessageChildNewContentInputBox.onValueChanged.AddListener((value) => messageText.text = value);
|
|
if (selectedMessageForOptions.CustomIcon == null)
|
|
{
|
|
playerIcon.sprite = Resources.Load<Sprite>("Icons/Icons/bird_" + selectedMessageForOptions.Icon);
|
|
if (selectedMessageForOptions.Icon == 1) playerIcon.sprite = Tools.GetIconForUser(selectedMessageForOptions.UserID);
|
|
playerOverlayIcon.sprite = Resources.Load<Sprite>("Icons/Overlays/overlay_" + selectedMessageForOptions.Overlay);
|
|
if (selectedMessageForOptions.Overlay != 0) playerOverlayIcon.gameObject.SetActive(true);
|
|
if (selectedMessageForOptions.Overlay == 8) playerOverlayIcon.transform.localPosition = new UnityEngine.Vector2(-16.56f, 14.81f);
|
|
else if (selectedMessageForOptions.Overlay == 11) playerOverlayIcon.transform.localPosition = new UnityEngine.Vector2(-14.74451f, 20.39122f);
|
|
else if (selectedMessageForOptions.Overlay == 13) playerOverlayIcon.transform.localPosition = new UnityEngine.Vector2(-16.54019f, 14.70365f);
|
|
try
|
|
{
|
|
playerIcon.color = new Color(selectedMessageForOptions.BirdColor[0] / 255f, selectedMessageForOptions.BirdColor[1] / 255f, selectedMessageForOptions.BirdColor[2] / 255f);
|
|
playerOverlayIcon.color = new Color(selectedMessageForOptions.OverlayColor[0] / 255f, selectedMessageForOptions.OverlayColor[1] / 255f, selectedMessageForOptions.OverlayColor[2] / 255f);
|
|
}
|
|
catch
|
|
{
|
|
playerIcon.color = Color.white;
|
|
playerOverlayIcon.color = Color.white;
|
|
}
|
|
}
|
|
else playerIcon.gameObject.AddComponent<WaitingForCustomIcon>().ID = selectedMessageForOptions.CustomIcon;
|
|
|
|
optionsPanel.SetActive(false);
|
|
editMessage.SetActive(true);
|
|
|
|
CustomIconLoader.Init(FindObjectsByType<WaitingForCustomIcon>(FindObjectsSortMode.None));
|
|
});
|
|
optionsPanelReportButton.onClick.AddListener(() =>
|
|
{
|
|
reportMessagePanelReportReason.text = "";
|
|
optionsPanel.SetActive(false);
|
|
reportMessagePanel.SetActive(true);
|
|
});
|
|
reportMessagePanelExitButton.onClick.AddListener(() =>
|
|
{
|
|
editMessagePanelCurrent = null;
|
|
reportMessagePanel.SetActive(false);
|
|
optionsPanel.SetActive(true);
|
|
});
|
|
reportMessagePanelSubmitButton.onClick.AddListener(async () =>
|
|
{
|
|
reportMessagePanel.SetActive(false);
|
|
await HandleMessageReport();
|
|
editMessagePanelCurrent = null;
|
|
selectedMessageForOptions = null;
|
|
});
|
|
optionsPanelCopyButton.onClick.AddListener(() =>
|
|
{
|
|
if (selectedMessageForOptions != null) GUIUtility.systemCopyBuffer = Encoding.UTF8.GetString(Convert.FromBase64String(selectedMessageForOptions.Content));
|
|
});
|
|
optionsPanelCopyButton.onClick.AddListener(optionsPanelExitButton.onClick.Invoke);
|
|
}
|
|
|
|
void HandleMessageSubmit()
|
|
{
|
|
if (messageInputField.text.Trim() == string.Empty) return;
|
|
sendButton.interactable = false;
|
|
backButton.interactable = false;
|
|
messageInputField.interactable = false;
|
|
UploadMessage msg = new()
|
|
{
|
|
kind = "chatroom_message",
|
|
data = new JObject()
|
|
{
|
|
["content"] = messageInputField.text,
|
|
["auth"] = BazookaManager.Instance.GetAccountSession()
|
|
}
|
|
};
|
|
WebsocketHandler.Instance._Connection.AddOutgoingMessage(JsonConvert.SerializeObject(msg));
|
|
sendButton.interactable = true;
|
|
backButton.interactable = true;
|
|
messageInputField.text = string.Empty;
|
|
messageInputField.interactable = true;
|
|
StartCoroutine(ScrollToBottom());
|
|
}
|
|
|
|
void HandleMessageDelete()
|
|
{
|
|
DeleteMessage msg = new()
|
|
{
|
|
kind = "chatroom_message",
|
|
data = new JObject()
|
|
{
|
|
["id"] = (int)selectedMessageForOptions.ID,
|
|
["auth"] = BazookaManager.Instance.GetAccountSession()
|
|
}
|
|
};
|
|
WebsocketHandler.Instance._Connection.AddOutgoingMessage(JsonConvert.SerializeObject(msg));
|
|
StartCoroutine(ScrollToBottom());
|
|
}
|
|
|
|
void HandleMessageEdit()
|
|
{
|
|
var newContent = editMessagePanelCurrent.transform.GetChild(0).GetChild(4).GetComponent<TMP_InputField>().text;
|
|
selectedMessageForOptions.Content = newContent;
|
|
EditMessage msg = new()
|
|
{
|
|
kind = "chatroom_message",
|
|
data = new JObject()
|
|
{
|
|
["id"] = (int)selectedMessageForOptions.ID,
|
|
["newContent"] = newContent,
|
|
["auth"] = BazookaManager.Instance.GetAccountSession()
|
|
}
|
|
};
|
|
WebsocketHandler.Instance._Connection.AddOutgoingMessage(JsonConvert.SerializeObject(msg));
|
|
StartCoroutine(ScrollToBottom());
|
|
}
|
|
|
|
async Task HandleMessageReport()
|
|
{
|
|
WWWForm dataForm = new();
|
|
dataForm.AddField("id", selectedMessageForOptions.ID.ToString());
|
|
dataForm.AddField("reason", reportMessagePanelReportReason.text);
|
|
using UnityWebRequest request = UnityWebRequest.Post(Endpoints.CHATROOM_REPORT_MESSAGE_ENDPOINT, dataForm);
|
|
request.SetRequestHeader("Authorization", BazookaManager.Instance.GetAccountSession());
|
|
request.SetRequestHeader("Requester", "BerryDashClient");
|
|
request.SetRequestHeader("ClientVersion", Application.version);
|
|
request.SetRequestHeader("ClientPlatform", Application.platform.ToString());
|
|
await request.SendWebRequest();
|
|
StartCoroutine(ScrollToBottom());
|
|
}
|
|
|
|
async void Update()
|
|
{
|
|
var max = content.GetComponent<RectTransform>().sizeDelta.y;
|
|
var current = content.transform.localPosition.y;
|
|
downButton.gameObject.SetActive(Mathf.Abs(max - current) > 0.1f * max);
|
|
if (Keyboard.current.escapeKey.wasPressedThisFrame && FindFirstObjectByType<ProfileMenu>() == null)
|
|
{
|
|
if (optionsPanel.activeSelf) optionsPanelExitButton.onClick.Invoke();
|
|
else if (reportMessagePanel.activeSelf) reportMessagePanelExitButton.onClick.Invoke();
|
|
else if (editMessagePanelCurrent != null) editMessagePanelCurrent.transform.GetChild(0).GetChild(0).GetComponent<Button>().onClick.Invoke();
|
|
else await SceneManager.LoadSceneAsync("MainMenu");
|
|
}
|
|
}
|
|
|
|
IEnumerator ScrollToBottom()
|
|
{
|
|
yield return new WaitForEndOfFrame();
|
|
content.transform.localPosition = new UnityEngine.Vector2(0f, content.GetComponent<RectTransform>().sizeDelta.y);
|
|
}
|
|
|
|
void OptionsButtonClick(ChatroomMessage message, BigInteger localUserId)
|
|
{
|
|
selectedMessageForOptions = message;
|
|
optionsPanelDeleteButton.transform.parent.gameObject.SetActive(localUserId != 0 && message.UserID == localUserId);
|
|
optionsPanelEditButton.transform.parent.gameObject.SetActive(localUserId != 0 && message.UserID == localUserId);
|
|
optionsPanelReportButton.transform.parent.gameObject.SetActive(localUserId != 0 && message.UserID != localUserId);
|
|
optionsPanel.SetActive(true);
|
|
}
|
|
} |