Make user search, chatroom, leaderboards and icon marketplace into a popup

This commit is contained in:
Lncvrt committed 2026-03-16 21:43:00 -07:00
1 parent 70687c2856
commit 06ba845790
52 files changed
+30178 -31455

No files matched your search

@@ -0,0 +1,371 @@
using System.Collections;
using System.Numerics;
using System.Threading.Tasks;
using MikeSchweitzer.WebSocket;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Networking;
using UnityEngine.UI;
public class ChatroomPrefab : 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 ProfilePrefab 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) {
var rowInfo = content.transform.Find("ChatroomRow_" + data["data"]["id"].ToString());
var usernameText = rowInfo.transform.GetChild(0).GetComponent<TMP_Text>();
if (!usernameText.text.EndsWith(">(edited)</color>")) {
var color = BazookaManager.Instance.GetColorSettingText();
string hex = new Color((((float)color[0]) - 100f) / 255f, (((float)color[1]) - 100f) / 255f, (((float)color[2]) - 100f) / 255f).ToHexString();
rowInfo.transform.GetChild(0).GetComponent<TMP_Text>().text += $" <color=#{hex}>(edited)</color>";
}
rowInfo.transform.GetChild(2).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 usernameText = rowInfo.transform.GetChild(0).GetComponent<TMP_Text>();
var playerIcon = rowInfo.transform.GetChild(1).GetComponent<Image>();
var playerOverlayIcon = playerIcon.transform.GetChild(0).GetComponent<Image>();
var playerIconButton = rowInfo.transform.GetChild(1).GetComponent<Button>();
var messageText = rowInfo.transform.GetChild(2).GetComponent<TMP_Text>();
var optionsButton = rowInfo.transform.GetChild(3).GetComponent<Button>();
var color = BazookaManager.Instance.GetColorSettingText();
string hex1 = new Color((((float)color[0]) - 50f) / 255f, (((float)color[1]) - 50f) / 255f, (((float)color[2]) - 50f) / 255f).ToHexString();
string hex2 = new Color((((float)color[0]) - 100f) / 255f, (((float)color[1]) - 100f) / 255f, (((float)color[2]) - 100f) / 255f).ToHexString();
usernameText.text = $"{message.Username} <color=#{hex1}>{Tools.FormatHumanTime(message.Timestamp)}</color>" + (message.EditedAt != 0 ? $" <color=#{hex2}>(edited)</color>" : null);
messageText.text = 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<ProfilePrefab>().Init(message.UserID);
});
optionsButton.onClick.AddListener(() => OptionsButtonClick(message, localUserId ?? 0));
rowInfo.name = "ChatroomRow_" + message.ID;
var entryComponet = rowInfo.AddComponent<ChatroomMenuEntry>();
entryComponet.Init(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 = 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(1).GetComponent<TMP_Text>();
var playerIcon = rowInfo.transform.GetChild(2).GetComponent<Image>();
var playerOverlayIcon = playerIcon.transform.GetChild(0).GetComponent<Image>();
var messageText = rowInfo.transform.GetChild(3).GetComponent<TMP_Text>();
usernameText.text = selectedMessageForOptions.Username;
messageText.text = 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(1).GetComponent<TMP_Text>();
playerIcon = rowInfo.transform.GetChild(2).GetComponent<Image>();
playerOverlayIcon = playerIcon.transform.GetChild(0).GetComponent<Image>();
messageText = rowInfo.transform.GetChild(3).GetComponent<TMP_Text>();
usernameText.text = selectedMessageForOptions.Username;
messageText.text = 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 = selectedMessageForOptions.Content;
});
optionsPanelCopyButton.onClick.AddListener(optionsPanelExitButton.onClick.Invoke);
backButton.onClick.AddListener(() => Destroy(gameObject));
}
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());
}
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<ProfilePrefab>() == 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 if (backButton.interactable) backButton.onClick.Invoke();
}
}
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);
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0dbd2b8269756e018b7c71d0e878242c
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2857b1f848102f577abc6acc5bd1885f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,283 @@
using System;
using System.Collections;
using System.Linq;
using System.Numerics;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class IconMarketplaceDownloadIcon : MonoBehaviour {
private readonly static WaitForSeconds _waitForSeconds2 = new(2f);
[SerializeField] private IconMarketplaceManager marketplaceManager;
[SerializeField] private TMP_Text statusText;
[SerializeField] private TMP_Text balanceText;
[SerializeField] private Button backButton;
public GameObject content;
[SerializeField] private GameObject sample;
private string statusMessage;
private Coroutine statusRoutine;
public AudioSource iconPurchaseSound;
[SerializeField] internal Button refreshButton;
[SerializeField] private Button optionsButton;
[SerializeField] internal GameObject optionsPanel;
[SerializeField] internal Button optionsPanelSubmitButton;
[SerializeField] private Button optionsPanelResetButton;
public TMP_Dropdown optionsPanelSortByDropdown;
public Toggle optionsPanelPriceRangeToggle;
[SerializeField] private TMP_InputField optionsPanelPriceRangeMinInput;
[SerializeField] private TMP_InputField optionsPanelPriceRangeMaxInput;
internal string priceRangeMin = "10";
internal string priceRangeMax = "250";
public Toggle optionsPanelSearchForToggle;
[SerializeField] private TMP_InputField optionsPanelSearchForInputField;
internal string searchForValue = "";
[SerializeField] private Toggle optionsPanelOnlyShowToggle;
[SerializeField] private TMP_Dropdown optionsPanelOnlyShowDropdown;
internal bool anyChanges = false;
void Awake() {
optionsPanelPriceRangeMinInput.onSelect.AddListener((_) => optionsPanelPriceRangeMinInput.caretPosition = optionsPanelPriceRangeMinInput.text.Length);
optionsPanelPriceRangeMaxInput.onSelect.AddListener((_) => optionsPanelPriceRangeMaxInput.caretPosition = optionsPanelPriceRangeMaxInput.text.Length);
optionsPanelSearchForInputField.onSelect.AddListener((_) => optionsPanelSearchForInputField.caretPosition = optionsPanelSearchForInputField.text.Length);
backButton.onClick.AddListener(() => marketplaceManager.SwitchPanel(0));
refreshButton.onClick.AddListener(GetIcons);
optionsButton.onClick.AddListener(() => optionsPanel.SetActive(true));
optionsPanelSubmitButton.onClick.AddListener(() => {
optionsPanel.SetActive(false);
if (anyChanges) {
anyChanges = false;
GetIcons();
}
});
optionsPanelResetButton.onClick.AddListener(() => {
optionsPanelSortByDropdown.value = 3;
optionsPanelPriceRangeToggle.isOn = false;
optionsPanelSearchForToggle.isOn = false;
optionsPanelOnlyShowToggle.isOn = false;
});
optionsPanelPriceRangeToggle.onValueChanged.AddListener((on) => {
anyChanges = true;
if (!on) {
optionsPanelPriceRangeMinInput.text = "10";
optionsPanelPriceRangeMaxInput.text = "250";
}
optionsPanelPriceRangeMinInput.interactable = on;
optionsPanelPriceRangeMaxInput.interactable = on;
});
optionsPanelSearchForToggle.onValueChanged.AddListener((on) => {
anyChanges = true;
if (!on) optionsPanelSearchForInputField.text = "";
optionsPanelSearchForInputField.interactable = on;
});
optionsPanelOnlyShowToggle.onValueChanged.AddListener((on) => {
anyChanges = true;
if (!on) optionsPanelOnlyShowDropdown.value = 0;
optionsPanelOnlyShowDropdown.interactable = on;
});
optionsPanelSortByDropdown.onValueChanged.AddListener((_) => anyChanges = true);
optionsPanelPriceRangeMinInput.onValueChanged.AddListener((value) => {
anyChanges = true;
priceRangeMin = value;
});
optionsPanelPriceRangeMaxInput.onValueChanged.AddListener((value) => {
anyChanges = true;
priceRangeMax = value;
});
optionsPanelSearchForInputField.onValueChanged.AddListener((value) => {
anyChanges = true;
searchForValue = value;
});
optionsPanelOnlyShowDropdown.onValueChanged.AddListener((_) => anyChanges = true);
}
internal void Load() {
GetIcons();
balanceText.text = Tools.FormatWithCommas(BazookaManager.Instance.GetCustomBirdIconData().Balance);
}
internal async void GetIcons() {
refreshButton.interactable = false;
optionsButton.interactable = false;
backButton.interactable = false;
foreach (Transform item in content.transform) {
if (item.gameObject.activeSelf) {
Destroy(item.gameObject);
}
}
var currentIcons = new JArray();
foreach (var icon in BazookaManager.Instance.GetCustomBirdIconData().Purchased) {
currentIcons.Add(icon);
}
ShowStatus("Loading...");
WWWForm dataForm = new();
dataForm.AddField("sortBy", optionsPanelSortByDropdown.value.ToString());
dataForm.AddField("priceRangeEnabled", optionsPanelPriceRangeToggle.isOn.ToString());
dataForm.AddField("priceRangeMin", priceRangeMin);
dataForm.AddField("priceRangeMax", priceRangeMax);
dataForm.AddField("searchForEnabled", optionsPanelSearchForToggle.isOn.ToString());
dataForm.AddField("searchForValue", searchForValue);
dataForm.AddField("onlyShowEnabled", optionsPanelOnlyShowToggle.isOn.ToString());
dataForm.AddField("onlyShowValue", optionsPanelOnlyShowDropdown.value.ToString());
dataForm.AddField("currentIcons", Convert.ToBase64String(Encoding.UTF8.GetBytes(currentIcons.ToString(Formatting.None))));
using UnityWebRequest request = UnityWebRequest.Post(Endpoints.ICON_MARKETPLACE_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();
if (request.downloadHandler.text == null) {
refreshButton.interactable = true;
optionsButton.interactable = true;
backButton.interactable = true;
ShowStatus("Failed to make HTTP request");
return;
}
ShowStatus(null);
var jsonResponse = JObject.Parse(request.downloadHandler.text);
var icons = JsonConvert.DeserializeObject<MarketplaceTempIcon[]>(jsonResponse["data"].ToString());
var localUserID = BazookaManager.Instance.GetAccountID();
foreach (var entry in icons) {
GameObject newIcon = Instantiate(sample, content.transform);
newIcon.name = "IconEntry";
newIcon.transform.GetChild(0).GetChild(0).gameObject.AddComponent<WaitingForCustomIcon>().ID = entry.ID;
newIcon.transform.GetChild(1).GetComponent<TMP_Text>().text = "Icon Name: " + entry.Name;
newIcon.transform.GetChild(2).GetComponent<TMP_Text>().text = "Price " + Tools.FormatWithCommas(entry.Price) + " coins";
newIcon.transform.GetChild(3).GetComponent<TMP_Text>().text = "Designer Name: " + entry.CreatorUsername;
var BtnGrid = newIcon.transform.GetChild(4);
var buyBtn = BtnGrid.transform.GetChild(0).GetComponent<Button>();
var buyBtnText = buyBtn.transform.GetChild(0).GetComponent<TMP_Text>();
var sellBtn = BtnGrid.transform.GetChild(1).GetComponent<Button>();
var sellBtnText = sellBtn.transform.GetChild(0).GetComponent<TMP_Text>();
sellBtn.onClick.AddListener(() => {
HandleSell(entry, buyBtn, buyBtnText, sellBtn, localUserID);
Tools.RefreshHierarchy(newIcon);
});
buyBtn.onClick.AddListener(() => {
HandlePurchase(entry, buyBtn, sellBtn, localUserID);
Tools.RefreshHierarchy(newIcon);
});
bool alreadyBought = BazookaManager.Instance.GetCustomBirdIconData().Purchased.Any(d => d == entry.ID);
if (alreadyBought) {
buyBtn.interactable = false;
sellBtn.gameObject.SetActive(true);
if (localUserID != entry.CreatorUserID)
buyBtnText.text = "Purchased";
else {
buyBtnText.text = "Claimed";
sellBtnText.text = "Unclaim";
}
} else {
if (localUserID != entry.CreatorUserID) buyBtnText.text = "Purchase";
else buyBtnText.text = "Claim";
}
newIcon.SetActive(true);
Tools.RefreshHierarchy(newIcon);
}
CustomIconLoader.Init(FindObjectsByType<WaitingForCustomIcon>(FindObjectsSortMode.None));
refreshButton.interactable = true;
optionsButton.interactable = true;
backButton.interactable = true;
}
void HandlePurchase(MarketplaceTempIcon data, Button button, Button sellButton, BigInteger? localUserID) {
button.interactable = false;
MarketplaceIconStorageType marketplaceIconStorage = BazookaManager.Instance.GetCustomBirdIconData();
if (localUserID != data.CreatorUserID) {
if (data.Price > marketplaceIconStorage.Balance) {
button.interactable = true;
ShowStatus("You can't afford this icon! You need " + Tools.FormatWithCommas(data.Price - marketplaceIconStorage.Balance) + " more coins");
return;
}
marketplaceIconStorage.Balance -= data.Price;
iconPurchaseSound.Stop();
iconPurchaseSound.Play();
}
marketplaceIconStorage.Purchased.Add(data.ID);
sellButton.gameObject.SetActive(true);
if (localUserID != data.CreatorUserID) {
button.transform.GetChild(0).GetComponent<TMP_Text>().text = "Purchased";
} else {
button.transform.GetChild(0).GetComponent<TMP_Text>().text = "Claimed";
sellButton.transform.GetChild(0).GetComponent<TMP_Text>().text = "Unclaim";
}
balanceText.text = Tools.FormatWithCommas(marketplaceIconStorage.Balance);
BazookaManager.Instance.SetCustomBirdIconData(marketplaceIconStorage);
}
void HandleSell(MarketplaceTempIcon data, Button buyBtn, TMP_Text buyBtnText, Button sellButton, BigInteger? localUserID) {
MarketplaceIconStorageType marketplaceIconStorage = BazookaManager.Instance.GetCustomBirdIconData();
var owned = marketplaceIconStorage.Purchased.Contains(data.ID);
if (owned) {
marketplaceIconStorage.Purchased.Remove(data.ID);
if (data.CreatorUserID != (BazookaManager.Instance.GetAccountID() ?? 0)) {
marketplaceIconStorage.Balance += data.Price;
iconPurchaseSound.Stop();
iconPurchaseSound.Play();
}
if (data.ID == marketplaceIconStorage.Selected) marketplaceIconStorage.Selected = null;
balanceText.text = Tools.FormatWithCommas(marketplaceIconStorage.Balance);
BazookaManager.Instance.SetCustomBirdIconData(marketplaceIconStorage);
if (localUserID != data.CreatorUserID) buyBtnText.text = "Purchase";
else {
buyBtnText.text = "Claim";
buyBtnText.text = "Claim";
}
buyBtn.interactable = true;
sellButton.gameObject.SetActive(false);
}
}
void ShowStatus(string content) {
if (content == null) {
if (statusRoutine != null) StopCoroutine(statusRoutine);
statusText.gameObject.SetActive(false);
statusText.text = "";
}
statusMessage = content;
if (statusRoutine != null) StopCoroutine(statusRoutine);
statusRoutine = StartCoroutine(StatusRoutine());
}
IEnumerator StatusRoutine() {
statusText.gameObject.SetActive(true);
statusText.text = statusMessage;
statusText.color = new Color(statusText.color.r, statusText.color.g, statusText.color.b, 0f);
float t = 0f;
while (t < 0.5f) {
t += Time.deltaTime;
float a = t / 0.5f;
statusText.color = new Color(statusText.color.r, statusText.color.g, statusText.color.b, a);
yield return null;
}
yield return _waitForSeconds2;
t = 0f;
while (t < 0.5f) {
t += Time.deltaTime;
float a = 1f - (t / 0.5f);
statusText.color = new Color(statusText.color.r, statusText.color.g, statusText.color.b, a);
yield return null;
}
statusText.gameObject.SetActive(false);
statusText.text = "";
statusRoutine = null;
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b8133693b9ee6eec098e9cef8b719edf
@@ -0,0 +1,85 @@
using SimpleFileBrowser;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
public class IconMarketplaceManager : MonoBehaviour {
[SerializeField] private GameObject panel;
[SerializeField] private GameObject normalPanel;
[SerializeField] private GameObject downloadPanel;
[SerializeField] private GameObject uploadPanel;
[SerializeField] private IconMarketplaceUploadIcon uploadPanelScript;
[SerializeField] private IconMarketplaceDownloadIcon downloadPanelScript;
[SerializeField] private Button exitButton;
[SerializeField] private Button downloadButton;
[SerializeField] private Button uploadButton;
[SerializeField] private TMP_Text coinText;
void Start() {
downloadPanelScript.iconPurchaseSound.volume = BazookaManager.Instance.GetSettingSFXVolume();
downloadButton.onClick.AddListener(() => SwitchPanel(1));
if (BazookaManager.Instance.GetAccountID() != null && BazookaManager.Instance.GetAccountName() != null && BazookaManager.Instance.GetAccountSession() != null) {
uploadButton.onClick.AddListener(() => SwitchPanel(2));
} else {
uploadButton.interactable = false;
uploadButton.transform.GetChild(0).transform.localPosition = new Vector3(0, 10, 0);
uploadButton.transform.GetChild(1).GetComponent<TMP_Text>().text = "Not logged in to an account";
}
SwitchPanel(0);
exitButton.onClick.AddListener(() => Destroy(gameObject));
}
internal void SwitchPanel(int panelIndex) {
downloadPanelScript.iconPurchaseSound.Stop();
downloadPanelScript.anyChanges = false;
downloadPanelScript.optionsPanelSortByDropdown.value = 3;
downloadPanelScript.optionsPanelPriceRangeToggle.isOn = false;
downloadPanelScript.optionsPanelSearchForToggle.isOn = false;
switch (panelIndex) {
case 0:
panel.SetActive(false);
panel.SetActive(true);
coinText.text = "You have " + Tools.FormatWithCommas(BazookaManager.Instance.GetCustomBirdIconData().Balance) + " coins";
normalPanel.SetActive(true);
downloadPanel.SetActive(false);
uploadPanel.SetActive(false);
if (DiscordRPCHandler.Instance != null) DiscordRPCHandler.Instance.UpdateRPC("Choosing what to do in the icon marketplace", null);
break;
case 1:
panel.SetActive(false);
panel.SetActive(true);
foreach (Transform item in downloadPanelScript.content.transform) {
if (item.gameObject.activeSelf) {
Destroy(item.gameObject);
}
}
normalPanel.SetActive(false);
downloadPanel.SetActive(true);
uploadPanel.SetActive(false);
downloadPanelScript.Load();
if (DiscordRPCHandler.Instance != null) DiscordRPCHandler.Instance.UpdateRPC("Browsing the icon marketplace", "They have " + Tools.FormatWithCommas(BazookaManager.Instance.GetCustomBirdIconData().Balance) + " coins");
break;
case 2:
panel.SetActive(false);
panel.SetActive(true);
uploadPanelScript.Reset();
normalPanel.SetActive(false);
downloadPanel.SetActive(false);
uploadPanel.SetActive(true);
if (DiscordRPCHandler.Instance != null) DiscordRPCHandler.Instance.UpdateRPC("Uploading an icon to the icon marketplace", null);
break;
}
}
void Update() {
if (Keyboard.current.escapeKey.wasPressedThisFrame) {
if (downloadPanelScript.optionsPanel.activeSelf) downloadPanelScript.optionsPanelSubmitButton.onClick.Invoke();
else if (uploadPanel.activeSelf && FileBrowser.IsOpen) return;
else if (downloadPanel.activeSelf || uploadPanel.activeSelf) SwitchPanel(0);
else if (exitButton.interactable) exitButton.onClick.Invoke();
} else if (Keyboard.current.rKey.wasPressedThisFrame && downloadPanel.activeSelf && downloadPanelScript.refreshButton.interactable) downloadPanelScript.GetIcons();
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: dd46bad161f2c81e2a36dd6a25154ad4
@@ -0,0 +1,118 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using SimpleFileBrowser;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class IconMarketplaceUploadIcon : MonoBehaviour {
[SerializeField] private IconMarketplaceManager marketplaceManager;
[SerializeField] private TMP_Text statusText;
[SerializeField] private Button backButton;
[SerializeField] private Button uploadButton;
[SerializeField] private Button selectButton;
[SerializeField] private TMP_InputField verifyCodeInput;
[SerializeField] private TMP_InputField birdPriceInput;
[SerializeField] private TMP_InputField birdNameInput;
[SerializeField] private Image birdImage;
[SerializeField] private GameObject birdImageNone;
private string birdData = null;
void Awake() {
verifyCodeInput.onSelect.AddListener((_) => verifyCodeInput.caretPosition = verifyCodeInput.text.Length);
birdPriceInput.onSelect.AddListener((_) => birdPriceInput.caretPosition = birdPriceInput.text.Length);
birdNameInput.onSelect.AddListener((_) => birdNameInput.caretPosition = birdNameInput.text.Length);
backButton.onClick.AddListener(() => marketplaceManager.SwitchPanel(0));
uploadButton.onClick.AddListener(() => {
if (birdPriceInput.text.Trim() == string.Empty) {
Tools.UpdateStatusText(statusText, "Bird price can't be empty", Color.red);
} else if (birdNameInput.text.Trim() == string.Empty) {
Tools.UpdateStatusText(statusText, "Bird name can't be empty", Color.red);
} else if (birdData == null) {
Tools.UpdateStatusText(statusText, "You must upload an image", Color.red);
} else {
UploadIcon();
}
});
selectButton.onClick.AddListener(async () => {
string path = await OpenFilePicker();
if (path == null) return;
byte[] fileContent;
try {
fileContent = File.ReadAllBytes(path);
if (fileContent.Length > 1024 * 1024) {
Tools.UpdateStatusText(statusText, "File size exceeds 1 MB limit", Color.red);
return;
}
birdData = Convert.ToBase64String(fileContent);
birdImage.sprite = Tools.GetSpriteFromBase64(birdData);
birdImageNone.SetActive(false);
birdImage.gameObject.SetActive(true);
}
catch (Exception e) {
Tools.UpdateStatusText(statusText, "Failed to read file: " + e.Message, Color.red);
return;
}
});
}
async Task<string> OpenFilePicker() {
FileBrowser.SetFilters(true, new FileBrowser.Filter("Images", ".png"));
var tcs = new TaskCompletionSource<string>();
FileBrowser.ShowLoadDialog(
(paths) => tcs.SetResult(paths.Length > 0 ? paths[0] : null),
() => tcs.SetResult(null),
FileBrowser.PickMode.Files,
false
);
return await tcs.Task;
}
async void UploadIcon() {
uploadButton.interactable = false;
backButton.interactable = false;
selectButton.interactable = false;
WWWForm dataForm = new();
dataForm.AddField("verifyCode", verifyCodeInput.text);
dataForm.AddField("price", birdPriceInput.text);
dataForm.AddField("name", birdNameInput.text);
dataForm.AddField("fileContent", birdData);
using UnityWebRequest request = UnityWebRequest.Post(Endpoints.ICON_MARKETPLACE_UPLOAD_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();
if (request.downloadHandler.text == null) {
uploadButton.interactable = true;
backButton.interactable = true;
selectButton.interactable = true;
Tools.UpdateStatusText(statusText, "Failed to make HTTP request", Color.red);
return;
}
var jsonResponse = JObject.Parse(request.downloadHandler.text);
if ((bool)jsonResponse["success"]) Reset();
Tools.UpdateStatusText(statusText, (string)jsonResponse["message"], (bool)jsonResponse["success"] ? Color.green : Color.red);
uploadButton.interactable = true;
backButton.interactable = true;
selectButton.interactable = true;
}
internal void Reset() {
birdImage.sprite = null;
birdImageNone.SetActive(true);
birdImage.gameObject.SetActive(false);
birdData = null;
verifyCodeInput.text = string.Empty;
birdPriceInput.text = string.Empty;
birdNameInput.text = string.Empty;
statusText.text = string.Empty;
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ac25b048bc0f6aded8697b98caef8382
@@ -0,0 +1,233 @@
using System.Linq;
using Newtonsoft.Json.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Networking;
using UnityEngine.UI;
public class LeaderboardsPrefab : MonoBehaviour {
[SerializeField] private TMP_Text statusText;
[SerializeField] private Button mainBackButton;
[SerializeField] private Button berryBackButton;
[SerializeField] private Button refreshButton;
[SerializeField] private ProfilePrefab profilePrefab;
[SerializeField] private GameObject selectionPanel;
[SerializeField] private Button selectionScoreButton;
[SerializeField] private Button selectionBerryButton;
[SerializeField] private Button selectionCoinButton;
[SerializeField] private Button selectionLegacyButton;
[SerializeField] private Button selectionLevelButton;
[SerializeField] private Button selectionTotalXPButton;
[SerializeField] private Button selectionTotalBerriesButton;
[SerializeField] private GameObject scoresPanel;
[SerializeField] private GameObject content;
[SerializeField] private GameObject sampleObject;
[SerializeField] private TMP_Dropdown berryShowTypeDropdown;
private LeaderboardMode mode = LeaderboardMode.None;
private bool changedByCode = false;
void Awake() {
selectionScoreButton.onClick.AddListener(() => { mode = LeaderboardMode.Score; SwitchMenu(1); });
selectionBerryButton.onClick.AddListener(() => { mode = LeaderboardMode.Berry; SwitchMenu(1); });
selectionCoinButton.onClick.AddListener(() => { mode = LeaderboardMode.Coin; SwitchMenu(1); });
selectionLegacyButton.onClick.AddListener(() => { mode = LeaderboardMode.Legacy; SwitchMenu(1); });
selectionLevelButton.onClick.AddListener(() => { mode = LeaderboardMode.Level; SwitchMenu(1); });
selectionTotalXPButton.onClick.AddListener(() => { mode = LeaderboardMode.TotalXP; SwitchMenu(1); });
selectionTotalBerriesButton.onClick.AddListener(() => { mode = LeaderboardMode.TotalBerries; SwitchMenu(1); });
berryShowTypeDropdown.onValueChanged.AddListener(_ => GetTopPlayers());
mainBackButton.onClick.AddListener(() => Destroy(gameObject));
berryBackButton.onClick.AddListener(() => SwitchMenu(0));
refreshButton.onClick.AddListener(GetTopPlayers);
}
void SwitchMenu(int menu) {
UpdateStatus(false, "");
if (!selectionPanel.activeSelf) {
foreach (Transform item in content.transform) {
if (item.gameObject.activeSelf) {
Destroy(item.gameObject);
}
}
}
if (menu == 0) {
mode = LeaderboardMode.None;
selectionPanel.SetActive(true);
scoresPanel.SetActive(false);
} else if (menu == 1) {
berryShowTypeDropdown.gameObject.SetActive(mode == LeaderboardMode.Berry);
changedByCode = true;
berryShowTypeDropdown.value = 0;
changedByCode = false;
selectionPanel.SetActive(false);
scoresPanel.SetActive(true);
GetTopPlayers();
}
}
async void GetTopPlayers() {
if (changedByCode) return;
berryBackButton.interactable = false;
refreshButton.interactable = false;
foreach (Transform item in content.transform) {
if (item.gameObject.activeSelf) {
Destroy(item.gameObject);
}
}
UpdateStatus(true, "Loading...");
using UnityWebRequest request = UnityWebRequest.Get(mode == LeaderboardMode.Score
? Endpoints.LEADERBOARDS_SCORE_ENDPOINT
: mode == LeaderboardMode.Berry
? Endpoints.LEADERBOARDS_BERRY_ENDPOINT + "?berry=" + berryShowTypeDropdown.value
: mode == LeaderboardMode.Coin
? Endpoints.LEADERBOARDS_COIN_ENDPOINT
: mode == LeaderboardMode.Legacy
? Endpoints.LEADERBOARDS_LEGACY_ENDPOINT
: mode == LeaderboardMode.Level || mode == LeaderboardMode.TotalXP
? Endpoints.BD_ACCOUNT_ENDPOINT + "?username="
: Endpoints.LEADERBOARDS_TOTAL_ENDPOINT);
request.SetRequestHeader("Requester", "BerryDashClient");
request.SetRequestHeader("ClientVersion", Application.version);
request.SetRequestHeader("ClientPlatform", Application.platform.ToString());
await request.SendWebRequest();
if (request.downloadHandler.text == null) {
UpdateStatus(true, "Failed to fetch leaderboard stats");
return;
}
UpdateStatus(false);
var jsonResponse = JObject.Parse(request.downloadHandler.text);
if ((bool)jsonResponse["success"]) {
if (mode != LeaderboardMode.Level && mode != LeaderboardMode.TotalXP) {
var entries = jsonResponse["data"].ToObject<LeaderboardEntry[]>();
for (int i = 0; i < entries.Length; i++) {
var entry = entries[i];
var entryInfo = Instantiate(sampleObject, content.transform);
var usernameText = entryInfo.transform.GetChild(0).GetComponent<TMP_Text>();
var playerIcon = usernameText.transform.GetChild(0).GetComponent<Image>();
var playerIconButton = usernameText.transform.GetChild(0).GetComponent<Button>();
var playerOverlay = playerIcon.transform.GetChild(0).GetComponent<Image>();
var scoreText = entryInfo.transform.GetChild(1).GetComponent<TMP_Text>();
usernameText.text = $"{entry.Username} (#{i + 1})";
scoreText.text = (mode == LeaderboardMode.Berry || mode == LeaderboardMode.TotalBerries ? "Berries: " : mode == LeaderboardMode.Coin ? "Coins: " : "Score: ") + Tools.FormatWithCommas(entry.Value);
if (BazookaManager.Instance.GetAccountID() == entry.UserID) {
usernameText.text = $"<color=#7FFFD4>{usernameText.text}</color>";
scoreText.text = $"<color=#7FFFD4>{scoreText.text}</color>";
}
if (entry.CustomIcon == null) {
playerIcon.sprite = Resources.Load<Sprite>("Icons/Icons/bird_" + entry.Icon);
if (entry.Icon == 1) playerIcon.sprite = Tools.GetIconForUser(entry.UserID);
playerOverlay.sprite = Resources.Load<Sprite>("Icons/Overlays/overlay_" + entry.Overlay);
if (entry.Overlay != 0) playerOverlay.gameObject.SetActive(true);
if (entry.Overlay == 8) playerOverlay.transform.localPosition = new Vector2(-16.56f, 14.81f);
else if (entry.Overlay == 11) playerOverlay.transform.localPosition = new Vector2(-14.74451f, 20.39122f);
else if (entry.Overlay == 13) playerOverlay.transform.localPosition = new Vector2(-16.54019f, 14.70365f);
try {
playerIcon.color = new Color(entry.BirdColor[0] / 255f, entry.BirdColor[1] / 255f, entry.BirdColor[2] / 255f);
playerOverlay.color = new Color(entry.BirdColor[0] / 255f, entry.BirdColor[1] / 255f, entry.BirdColor[2] / 255f);
}
catch {
playerIcon.color = Color.white;
playerOverlay.color = Color.white;
}
} else playerIcon.gameObject.AddComponent<WaitingForCustomIcon>().ID = entry.CustomIcon;
playerIconButton.onClick.AddListener(async () => {
var clone = Instantiate(profilePrefab.gameObject, profilePrefab.gameObject.transform.parent);
clone.SetActive(true);
await clone.GetComponent<ProfilePrefab>().Init(entry.UserID);
});
entryInfo.SetActive(true);
}
} else {
var entries = jsonResponse["data"]
.ToObject<Account[]>()
.Select(entry => {
var xp = Tools.CalculateXP(
entry.Stats.TotalNormalBerries,
entry.Stats.TotalPoisonBerries,
entry.Stats.TotalSlowBerries,
entry.Stats.TotalUltraBerries,
entry.Stats.TotalSpeedyBerries,
entry.Stats.TotalCoinBerries,
entry.Stats.TotalRandomBerries,
entry.Stats.TotalAntiBerries,
entry.Stats.TotalGoldenBerries
);
return new {
Account = entry,
XP = xp
};
})
.OrderByDescending(x => x.XP)
.ToList();
for (int i = 0; i < entries.Count; i++) {
var entry = entries[i].Account;
var xp = entries[i].XP;
var entryInfo = Instantiate(sampleObject, content.transform);
var usernameText = entryInfo.transform.GetChild(0).GetComponent<TMP_Text>();
var playerIcon = usernameText.transform.GetChild(0).GetComponent<Image>();
var playerIconButton = usernameText.transform.GetChild(0).GetComponent<Button>();
var playerOverlay = playerIcon.transform.GetChild(0).GetComponent<Image>();
var scoreText = entryInfo.transform.GetChild(1).GetComponent<TMP_Text>();
usernameText.text = $"{entry.Username} (#{i + 1})";
scoreText.text = (mode == LeaderboardMode.Level ? "Level: " : "XP: ") + Tools.FormatWithCommas(mode == LeaderboardMode.Level ? Tools.GetLevelInfo(xp).level.ToString() : xp.ToString());
if (BazookaManager.Instance.GetAccountID() == entry.UserID) {
usernameText.text = $"<color=#7FFFD4>{usernameText.text}</color>";
scoreText.text = $"<color=#7FFFD4>{scoreText.text}</color>";
}
if (entry.CustomIcon == null) {
playerIcon.sprite = Resources.Load<Sprite>("Icons/Icons/bird_" + entry.Icon);
if (entry.Icon == 1) playerIcon.sprite = Tools.GetIconForUser(entry.UserID);
playerOverlay.sprite = Resources.Load<Sprite>("Icons/Overlays/overlay_" + entry.Overlay);
if (entry.Overlay != 0) playerOverlay.gameObject.SetActive(true);
if (entry.Overlay == 8) playerOverlay.transform.localPosition = new Vector2(-16.56f, 14.81f);
else if (entry.Overlay == 11) playerOverlay.transform.localPosition = new Vector2(-14.74451f, 20.39122f);
else if (entry.Overlay == 13) playerOverlay.transform.localPosition = new Vector2(-16.54019f, 14.70365f);
try {
playerIcon.color = new Color(entry.BirdColor[0] / 255f, entry.BirdColor[1] / 255f, entry.BirdColor[2] / 255f);
playerOverlay.color = new Color(entry.BirdColor[0] / 255f, entry.BirdColor[1] / 255f, entry.BirdColor[2] / 255f);
}
catch {
playerIcon.color = Color.white;
playerOverlay.color = Color.white;
}
} else playerIcon.gameObject.AddComponent<WaitingForCustomIcon>().ID = entry.CustomIcon;
playerIconButton.onClick.AddListener(async () => {
var clone = Instantiate(profilePrefab.gameObject, profilePrefab.gameObject.transform.parent);
clone.SetActive(true);
await clone.GetComponent<ProfilePrefab>().Init(entry.UserID);
});
entryInfo.SetActive(true);
}
}
CustomIconLoader.Init(FindObjectsByType<WaitingForCustomIcon>(FindObjectsSortMode.None));
} else {
UpdateStatus(true, (string)jsonResponse["message"]);
}
berryBackButton.interactable = true;
refreshButton.interactable = true;
}
private void UpdateStatus(bool enabled, string message = "") {
statusText.gameObject.SetActive(enabled);
statusText.text = message;
}
void Update() {
if (Keyboard.current.escapeKey.wasPressedThisFrame && FindFirstObjectByType<ProfilePrefab>() == null) {
if (selectionPanel.activeSelf && mainBackButton.interactable) mainBackButton.onClick.Invoke();
else if (scoresPanel.activeSelf && berryBackButton.interactable) berryBackButton.onClick.Invoke();
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: bbefa9dcefcd38444a3b5b3f3d54ef7c
@@ -9,7 +9,7 @@ using UnityEngine.InputSystem;
using UnityEngine.Networking;
using UnityEngine.UI;
public class ProfileMenu : MonoBehaviour {
public class ProfilePrefab : MonoBehaviour {
[SerializeField] private Button exitButton;
[SerializeField] private Button refreshButton;
[SerializeField] private Button postButton;
@@ -39,7 +39,6 @@ public class ProfileMenu : MonoBehaviour {
private GameObject popupObject;
void Awake() {
exitButton.onClick.AddListener(() => Destroy(gameObject));
}
@@ -335,6 +334,11 @@ public class ProfileMenu : MonoBehaviour {
}
void Update() {
if (Keyboard.current.escapeKey.wasPressedThisFrame && exitButton.interactable) exitButton.onClick.Invoke();
if (Keyboard.current.escapeKey.wasPressedThisFrame && exitButton.interactable) {
if (popupObject) {
Destroy(popupObject);
popupObject = null;
} else exitButton.onClick.Invoke();
}
}
}
@@ -0,0 +1,93 @@
using Newtonsoft.Json.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Networking;
using UnityEngine.UI;
public class UserSearchPrefab : MonoBehaviour {
[SerializeField] private GameObject content;
[SerializeField] private GameObject sampleObject;
[SerializeField] private Button backButton;
[SerializeField] private TMP_InputField usernameInput;
[SerializeField] private Button searchButton;
[SerializeField] private TMP_Text statusText;
[SerializeField] private ProfilePrefab profilePrefab;
void Awake() {
backButton.onClick.AddListener(() => Destroy(gameObject));
usernameInput.onSelect.AddListener((_) => usernameInput.caretPosition = usernameInput.text.Length);
searchButton.onClick.AddListener(Search);
Search();
}
async void Search() {
searchButton.interactable = false;
foreach (Transform item in content.transform)
if (item.gameObject.activeSelf)
Destroy(item.gameObject);
using UnityWebRequest request = UnityWebRequest.Get(Endpoints.BD_ACCOUNT_ENDPOINT + "?username=" + usernameInput.text);
request.SetRequestHeader("Requester", "BerryDashClient");
request.SetRequestHeader("ClientVersion", Application.version);
request.SetRequestHeader("ClientPlatform", Application.platform.ToString());
await request.SendWebRequest();
if (request.downloadHandler.text == null) {
searchButton.interactable = true;
UpdateStatus(true, "Failed to get a list of users");
return;
}
UpdateStatus(false);
var jsonResponse = JObject.Parse(request.downloadHandler.text);
if ((bool)jsonResponse["success"]) {
foreach (var entry in jsonResponse["data"].ToObject<Account[]>()) {
if (entry.UserID == BazookaManager.Instance.GetAccountID()) continue;
var entryInfo = Instantiate(sampleObject, content.transform);
var playerIcon = entryInfo.transform.GetChild(0).GetComponent<Image>();
var playerOverlay = playerIcon.transform.GetChild(0).GetComponent<Image>();
var usernameText = entryInfo.transform.GetChild(1).GetComponent<TMP_Text>();
var playerIconButton = playerIcon.GetComponent<Button>();
var highScoreText = entryInfo.transform.GetChild(2).GetComponent<TMP_Text>();
usernameText.text = entry.Username;
highScoreText.text += Tools.FormatWithCommas(entry.Stats.HighScore);
if (entry.CustomIcon == null) {
playerIcon.sprite = Resources.Load<Sprite>("Icons/Icons/bird_" + entry.Icon);
if (entry.Icon == 1) playerIcon.sprite = Tools.GetIconForUser(entry.UserID);
playerOverlay.sprite = Resources.Load<Sprite>("Icons/Overlays/overlay_" + entry.Overlay);
if (entry.Overlay != 0) playerOverlay.gameObject.SetActive(true);
if (entry.Overlay == 8) playerOverlay.transform.localPosition = new Vector2(-16.56f, 14.81f);
else if (entry.Overlay == 11) playerOverlay.transform.localPosition = new Vector2(-14.74451f, 20.39122f);
else if (entry.Overlay == 13) playerOverlay.transform.localPosition = new Vector2(-16.54019f, 14.70365f);
try {
playerIcon.color = new Color(entry.BirdColor[0] / 255f, entry.BirdColor[1] / 255f, entry.BirdColor[2] / 255f);
playerOverlay.color = new Color(entry.BirdColor[0] / 255f, entry.BirdColor[1] / 255f, entry.BirdColor[2] / 255f);
}
catch {
playerIcon.color = Color.white;
playerOverlay.color = Color.white;
}
} else playerIcon.gameObject.AddComponent<WaitingForCustomIcon>().ID = entry.CustomIcon;
playerIconButton.onClick.AddListener(async () => {
var clone = Instantiate(profilePrefab.gameObject, profilePrefab.gameObject.transform.parent);
clone.SetActive(true);
await clone.GetComponent<ProfilePrefab>().Init(entry.UserID);
});
entryInfo.SetActive(true);
}
CustomIconLoader.Init(FindObjectsByType<WaitingForCustomIcon>(FindObjectsSortMode.None));
} else {
UpdateStatus(true, (string)jsonResponse["message"]);
}
searchButton.interactable = true;
}
void Update() {
if (Keyboard.current.escapeKey.wasPressedThisFrame && FindFirstObjectByType<ProfilePrefab>() == null && backButton.interactable) backButton.onClick.Invoke();
}
private void UpdateStatus(bool enabled, string message = "") {
statusText.gameObject.SetActive(enabled);
statusText.text = message;
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8c6d4c7b82c4d401996b55734bbe5b65