Singularity/Assets/Scripts/ModList.cs

343 lines
11 KiB
C#
Raw Normal View History

2024-05-06 14:45:45 -04:00
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class ModList : MonoBehaviour
{
[SerializeField] private string JSONPath;
[SerializeField] private DownloadMod DM;
[SerializeField] private OnlineAccountHandler OAH;
private List<SchakenMods> modList = new();
[Header("\tMod Prefabs")]
[SerializeField] private GameObject ModPrefab;
[SerializeField] private Transform ModPrefabContainer;
[SerializeField] public List<GameObject> ModPrefabList;
[SerializeField] private TMP_InputField SearchText;
public bool AZOrder = true;
public bool DateOrder = true;
// Start is called before the first frame update
public void StartList() {
foreach (GameObject prefab in ModPrefabList) {
DestroyImmediate(prefab);
}
ModPrefabList.Clear();
JSONPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)+@"\Schaken-Mods®\Singularity\Mods\";
if (!Directory.Exists(JSONPath)) {
Directory.CreateDirectory(JSONPath);
}
string[] jsonFiles2 = Directory.GetFiles(JSONPath, "*.json");// Update from 1.1 to 1.11
foreach (string WrongFile in jsonFiles2) {
string newFilePath = Path.ChangeExtension(WrongFile, ".sing");
if (File.Exists(newFilePath)) {
File.Delete(newFilePath);
}
File.Move(WrongFile, newFilePath); // Rename the file
}
string[] jsonFiles = Directory.GetFiles(JSONPath, "*.sing");
foreach (string jsonFile in jsonFiles) {
if (Path.GetFileName(jsonFile) == "0.sing" || Path.GetFileName(jsonFile) == "NM0.sing") {
File.Delete(jsonFile);
} else {
try {
string jsonContent = File.ReadAllText(jsonFile);
jsonContent = "{ \"download\": " + jsonContent + " }";
SchakenMods mod = JsonConvert.DeserializeObject<SchakenMods>(jsonContent);
modList.Add(mod);
} catch (JsonReaderException ex) {
Debug.LogError($"Error deserializing JSON from file {jsonFile}: {ex.Message}");
DM.Con.Alert("Schaken-Mods", $"Error deserializing JSON from file {jsonFile}: {ex.Message}");
Debug.LogError($"Content of {jsonFile}: {File.ReadAllText(jsonFile)}");
}
}
}
for (int i = 0; i < modList.Count; i++) {
AddMod(modList[i]);
}
ResetOrder();
}
public void ResetOrder() {
if (AZOrder) {
OrderAZ();
OAH.Setting.ModListOrder = 0;
OAH.SaveSettings();
return;
}
if (DateOrder) {
OrderDate();
OAH.Setting.ModListOrder = 1;
OAH.SaveSettings();
return;
}
}
public ModListPrefab AddMod(SchakenMods modJSON) {
bool found = false;
ModListPrefab MasterPrefab = new();
for (int i = 0; i < ModPrefabList.Count; i++) {
SchakenMods.Download TempMod = ModPrefabList[i].GetComponent<ModListPrefab>().Mod.Mod;
if ((TempMod.Id == modJSON.Mod.Id) && (TempMod.ModAuthor.Name == modJSON.Mod.ModAuthor.Name)) {
found = true;
MasterPrefab = ModPrefabList[i].GetComponent<ModListPrefab>();
}
}
if (found == false) {
GameObject NewMod = Instantiate(ModPrefab, ModPrefabContainer);
ModPrefabList.Add(NewMod);
NewMod.name = modJSON.Mod.Title;
string Website = modJSON.Mod.Url;
if (modJSON.Mod.Url.Contains("/schaken-mods.com")) {
Website = "Schaken-Mods";
} else if (modJSON.Mod.Url.Contains("/www.nexusmods.com/")) {
Website = "NexusMods";
}
RawImage A = NewMod.GetComponent<ModListPrefab>().FillMe(Website, modJSON, DM);
if (Website == "Schaken-Mods") {
if (modJSON.Mod.PrimaryScreenshotThumb != null) {
if (modJSON.Mod.PrimaryScreenshotThumb.Url != null) {
StartCoroutine(DownloadImage(modJSON.Mod.PrimaryScreenshotThumb.Url, A));
} else {
Debug.LogError($"{modJSON.Mod.Id} is missing its PrimaryScreenshot");
}
} else {
Debug.LogError($"{modJSON.Mod.Id} is missing its PrimaryScreenshot");
}
} else if (Website == "NexusMods") {
StartCoroutine(LoadWebP(modJSON.Mod.PrimaryScreenshotThumb.Url, A));
}
return NewMod.GetComponent<ModListPrefab>();
} else {
return MasterPrefab;
}
}
public void CheckAllForUpdates() {
for (int i = 0; i < ModPrefabList.Count; i++) {
ModListPrefab TempML = ModPrefabList[i].GetComponent<ModListPrefab>();
SchakenMods TempSM = ModPrefabList[i].GetComponent<ModListPrefab>().Mod;
TempML.Spin();
StartCoroutine(CheckForModUpdatesA(TempSM, TempML));
}
}
public void CheckForModUpdates(SchakenMods SM, ModListPrefab MLPrefab) {
StartCoroutine(CheckForModUpdatesA(SM, MLPrefab));
}
IEnumerator CheckForModUpdatesA(SchakenMods SM, ModListPrefab MLPrefab) {
bool UpToDate = true;
if (SM.Mod.Url.ToLower().Contains("schaken-mods.com")) {
using (UnityWebRequest uwr = UnityWebRequest.Get($"https://schaken-mods.com/api/downloads/files/{SM.Mod.Id}")) {
uwr.SetRequestHeader("Authorization", "Bearer " + DM.OAH.BearerID);
yield return uwr.SendWebRequest();
if (uwr.result == UnityWebRequest.Result.ConnectionError) {
Debug.LogError("Error While Sending TEST: " + uwr.error);
DM.Con.Alert("Schaken-Mods", $"Error While Sending: {uwr.error}");
} else {
SchakenMods.Download mod = JsonConvert.DeserializeObject<SchakenMods.Download>(uwr.downloadHandler.text);
if (SM.Mod.Downloaded < mod.Updated) {
UpToDate = false;
}
}
}
} else if (SM.Mod.Url.ToLower().Contains("nexusmods.com")) {
using (UnityWebRequest uwr = UnityWebRequest.Get($"https://api.nexusmods.com/v1/games/{SM.Mod.ModCategory.Name}/mods/{SM.Mod.Id}.sing")) {
uwr.SetRequestHeader("Content-Type", "application/json");
uwr.SetRequestHeader("apikey", DM.OAH.NMKey);
yield return uwr.SendWebRequest();
if (uwr.result == UnityWebRequest.Result.ConnectionError) {
Debug.LogError("Error While Sending TEST: " + uwr.error);
DM.Con.Alert("NexusMods", $"Error While Sending: {uwr.error}");
} else {
// Debug.Log($"Full Report of ({SM.Mod.Id}): {uwr.downloadHandler.text}");
if (uwr.downloadHandler.text.Contains("\"status\":\"wastebinned\"")) {
Debug.LogError($"Mod at {SM.Mod.Id} was removed by Author");
DM.Con.Alert("NexusMods", $"Mod at {SM.Mod.Id} was removed by Author");
yield break;
} else if (uwr.downloadHandler.text.Contains("\"status\":\"hidden\"")) {
Debug.LogError($"Mod at {SM.Mod.Id} was hidden by Author");
DM.Con.Alert("NexusMods", $"Mod at {SM.Mod.Id} was hidden.");
yield break;
} else {
NexusMods.Mod JSON = JsonConvert.DeserializeObject<NexusMods.Mod>(uwr.downloadHandler.text);
if (SM.Mod.Downloaded < JSON.UpdatedTime) {
UpToDate = false;
}
}
}
}
}
// if (!UpToDate) {
MLPrefab.OutOfDate(UpToDate);
// }
MLPrefab.Spin();
}
IEnumerator DownloadImage(string imageUrl, RawImage A, int maxRetries = 3) {
int retryCount = 0;
while (retryCount < maxRetries) {
using (UnityWebRequest www = UnityWebRequestTexture.GetTexture(imageUrl)) {
yield return www.SendWebRequest();
if (www.result != UnityWebRequest.Result.ConnectionError) {
A.texture = DownloadHandlerTexture.GetContent(www);
A.SetNativeSize();
A.SizeToParent();
retryCount = 99;
yield break; // Exit the coroutine if the download is successful
} else {
Debug.LogError("Error downloading image: " + www.error, A.gameObject);
retryCount++;
if (retryCount < maxRetries) {
yield return new WaitForSeconds(1f); // Wait for 1 second before retrying
}
}
}
}
Debug.LogError("Failed to download image after " + maxRetries + " attempts.");
A.gameObject.GetComponent<ModListPrefab>().FailedImage.SetActive(true);
}
private IEnumerator LoadWebP(string url, RawImage rawImage, int maxRetries = 3) {
int retryCount = 0;
while (retryCount < maxRetries) {
using (UnityWebRequest www = UnityWebRequest.Get(url)) {
yield return www.SendWebRequest();
if (www.result != UnityWebRequest.Result.Success) {
Debug.LogError($"Error downloading image ({url}): {www.error}");
retryCount++;
if (retryCount < maxRetries) {
yield return new WaitForSeconds(1f); // Wait for 1 second before retrying
}
} else {
byte[] webPData = www.downloadHandler.data;
if (webPData == null || webPData.Length == 0) {
Debug.LogError("No WebP data received.");
yield break;
}
WebpImporter.ByteWebpTexture2D(webPData, (texture) => {
rawImage.texture = texture;
});
rawImage.SetNativeSize();
rawImage.SizeToParent();
retryCount = 99;
yield break; // Exit the coroutine if the download is successful
}
}
}
Debug.LogError("Failed to download image after " + maxRetries + " attempts.");
}
public void ShowSites(int A) {
if (A == 0) { // ALL
for (int i = 0; i < ModPrefabList.Count; i++) {
ModPrefabList[i].SetActive(true);
}
} else if (A == 1) { // Schaken-Mods
for (int i = 0; i < ModPrefabList.Count; i++) {
ModPrefabList[i].SetActive(ModPrefabList[i].GetComponent<ModListPrefab>().Website.text.Contains("Schaken"));
}
} else if (A == 2) { // NexusMods
for (int i = 0; i < ModPrefabList.Count; i++) {
ModPrefabList[i].SetActive(ModPrefabList[i].GetComponent<ModListPrefab>().Website.text.Contains("Nexus"));
}
}
}
public void OrderAZ() {
ModPrefabList.Sort((a, b) => {
string A = a.name;
string B = b.name;
return string.Compare(A, B);
});
ReOrder(ModPrefabList, AZOrder);
AZOrder = !AZOrder;
DateOrder = true;
OAH.Setting.ModListOrder = 0;
OAH.SaveSettings();
}
public void OrderDate() {
ModPrefabList.Sort((a, b) => {
ModListPrefab modInfoA = a.GetComponent<ModListPrefab>();
ModListPrefab modInfoB = b.GetComponent<ModListPrefab>();
// Extract the date part of the string
string dateStringA = modInfoA.Downloaded.text.Split(S("Downloaded:"))[1].Trim();
string dateStringB = modInfoB.Downloaded.text.Split(S("Downloaded:"))[1].Trim();
// Parse the string into DateTime objects
DateTime dateA = DateTime.Parse(dateStringA);
DateTime dateB = DateTime.Parse(dateStringB);
// Compare the DateTime objects
return DateTime.Compare(dateB, dateA); // Sort from newest to oldest
});
ReOrder(ModPrefabList, DateOrder);
DateOrder = !DateOrder;
AZOrder = true;
OAH.Setting.ModListOrder = 1;
OAH.SaveSettings();
}
public void Search() {
StartCoroutine(SearchA());
}
IEnumerator SearchA() {
string SavedText = SearchText.text;
SearchText.text = "Searching.....";
yield return new WaitForSeconds(0.1f);
for (int i = 0; i < ModPrefabList.Count; i++) {
ModPrefabList[i].SetActive(ModPrefabList[i].name.ToLower().Contains(SavedText.ToLower()));
}
SearchText.text = SavedText;
}
public void CloseSearch() {
for (int i = 0; i < ModPrefabList.Count; i++) {
ModPrefabList[i].SetActive(true);
}
SearchText.text = "";
}
private string S(string A) {
return A;
}
private void ReOrder(List<GameObject> list, bool order = true) {
if (order) {
for (int i = 0; i < list.Count; i++) {
list[i].transform.SetSiblingIndex(i);
}
} else {
list[0].transform.SetSiblingIndex(list.Count - 1);
for (int i = 0; i < list.Count; i++) {
list[i].transform.SetSiblingIndex(list.Count-i-1);
}
}
}
}