343 lines
11 KiB
C#
343 lines
11 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
} |