Removed external texture loading.

Added Discord link.
Minimal cleanup.
This commit is contained in:
2023-10-09 00:11:02 +02:00
parent 51cc9df14f
commit 17862fa5c3
48 changed files with 505 additions and 848 deletions

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 055f725890d872b4bb22fa493ed06356
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,281 +0,0 @@
/* HaRepacker - WZ extractor and repacker
* Copyright (C) 2009, 2010 haha01haha01
* This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
* This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.*/
namespace SharpApng
{
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using uGIF;
using UnityEngine;
public class Frame : IDisposable
{
#region Fields
private Image m_bmp;
private int m_den;
private int m_num;
#endregion Fields
#region Constructors
public Frame(Image bmp, int num, int den)
{
this.m_num = num;
this.m_den = den;
this.m_bmp = bmp;
}
#endregion Constructors
#region Properties
public Image Bitmap
{
get
{
return m_bmp;
}
set
{
m_bmp = value;
}
}
public int DelayDen
{
get
{
return m_den;
}
set
{
m_den = value;
}
}
public int DelayNum
{
get
{
return m_num;
}
set
{
m_num = value;
}
}
#endregion Properties
#region Methods
public void Dispose()
{
}
#endregion Methods
}
internal class Apng : IDisposable
{
#region Fields
private List<Frame> m_frames = new List<Frame>();
#endregion Fields
#region Constructors
public Apng()
{
}
#endregion Constructors
#region Indexers
public Frame this[int index]
{
get
{
if (index < m_frames.Count) return m_frames[index];
else return null;
}
set
{
if (index < m_frames.Count) m_frames[index] = value;
}
}
#endregion Indexers
#region Methods
public void AddFrame(Frame frame)
{
m_frames.Add(frame);
}
public void AddFrame(Image bmp, int num, int den)
{
m_frames.Add(new Frame(bmp, num, den));
}
public void Dispose()
{
foreach (Frame frame in m_frames)
frame.Dispose();
m_frames.Clear();
}
public void WriteApng(string path, bool firstFrameHidden, bool disposeAfter)
{
Size maxSize = new Size(m_frames.Max(f => f.Bitmap.width), m_frames.Max(f => f.Bitmap.height));
for (int i = 0; i < m_frames.Count; i++)
{
Frame frame = m_frames[i];
//if (frame.Bitmap.Width != maxSize.Width || frame.Bitmap.Height != maxSize.Height)
//frame.Bitmap = ExtendImage(frame.Bitmap, maxSize);
ApngBasicWrapper.CreateFrameManaged(frame.Bitmap, frame.DelayNum, frame.DelayDen, i);
}
ApngBasicWrapper.SaveApngManaged(path, m_frames.Count, maxSize.Width, maxSize.Height, firstFrameHidden);
if (disposeAfter) Dispose();
}
private static Image ExtendImage(Image source, Size newSize)
{
Image result = new Image(newSize.Width, newSize.Height);
//using (Graphics g = Graphics.FromImage(result))
//{
// g.DrawImageUnscaled(source, 0, 0);
//}
return result;
}
#endregion Methods
}
internal static class ApngBasicWrapper
{
#region Fields
private const string apngdll = "apng64.dll";
private const int PIXEL_DEPTH = 4;
#endregion Fields
#region Methods
internal static void CreateFrameManaged(Image source, int num, int den, int i)
{
IntPtr ptr = MarshalByteArray(TranslateImage(source));
CreateFrame(ptr, num, den, i, source.width * source.height * PIXEL_DEPTH);
ReleaseData(ptr);
}
internal static void SaveApngManaged(string path, int frameCount, int width, int height, bool firstFrameHidden)
{
IntPtr pathPtr = MarshalString(path);
byte firstFrame = firstFrameHidden ? (byte)1 : (byte)0;
SaveAPNG(pathPtr, frameCount, width, height, PIXEL_DEPTH, firstFrame);
var bufferSize = GetBufferSize();
//Call and return the pointer
IntPtr returnedPtr = GetBufferContent();
//Create new Variable to Store the result
byte[] returnedResult = new byte[bufferSize];
//Copy from result pointer to the C# variable
Marshal.Copy(returnedPtr, returnedResult, 0, bufferSize);
File.WriteAllBytes(path, returnedResult);
Debug.Log("saved");
ReleaseData(pathPtr);
}
[DllImport(apngdll, CallingConvention = CallingConvention.StdCall)]
private static extern void CreateFrame(IntPtr pdata, int num, int den, int i, int len);
[DllImport(apngdll)]
private static extern void SaveAPNG(IntPtr path, int frameCount, int width, int height, int bytesPerPixel, byte firstFrameHidden);
[DllImport(apngdll)]
private static extern int GetBufferSize();
[DllImport(apngdll)]
private static extern IntPtr GetBufferContent();
private static IntPtr MarshalByteArray(byte[] source)
{
int size = Marshal.SizeOf(source[0]) * source.Length;
IntPtr pnt = Marshal.AllocHGlobal(size);
Marshal.Copy(source, 0, pnt, source.Length);
return pnt;
}
private static IntPtr MarshalString(string source)
{
byte[] toMarshal = Encoding.ASCII.GetBytes(source);
int size = Marshal.SizeOf(source[0]) * source.Length;
IntPtr pnt = Marshal.AllocHGlobal(size + Marshal.SizeOf(source[0]));
Marshal.Copy(toMarshal, 0, pnt, source.Length);
//Marshal.Copy(new byte[] { 0 }, 0, new IntPtr(pnt.ToInt32() + size), 1);
return pnt;
}
private static void ReleaseData(IntPtr ptr)
{
Marshal.FreeHGlobal(ptr);
}
static byte[] TranslateImage(Image texture)
{
int width = texture.width, height = texture.height;
Color32[] original = new Color32[texture.pixels.Length];
texture.pixels.CopyTo(original, 0);
byte[] result = new byte[texture.width * texture.height * PIXEL_DEPTH];
int p = 0;
Debug.Log("1");
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int index = (y * width + x);
int index2 = ((height-y-1) * width + x);
result[index * PIXEL_DEPTH] = original[index2].b;
result[index * PIXEL_DEPTH + 1] = original[index2].g;
result[index * PIXEL_DEPTH + 2] = original[index2].r;
result[index * PIXEL_DEPTH + 3] = original[index2].a;
}
p += 1;
}
Debug.Log("2");
return result;
}
#endregion Methods
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: de9592c4ae9713d41ae7a9ae40d1b549
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,11 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Collections;
using System.Linq;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class FateModelBuilder : MonoBehaviour
@@ -52,40 +47,25 @@ public class FateModelBuilder : MonoBehaviour
var lcButt = UIController.Instance.LoadedCharaButton;
lcButt.GetComponentInChildren<TMPro.TextMeshProUGUI>().text = servant.name + " - AA database";
lcButt.GetComponentInChildren<Button>().onClick.RemoveAllListeners();
lcButt.GetComponentInChildren<Button>().onClick.AddListener(() => Application.OpenURL("https://apps.atlasacademy.io/db/JP/servant/" + servant.collectionNo));
lcButt.GetComponentInChildren<Button>().onClick.AddListener(() => UIController.Instance.OpenUrl("https://apps.atlasacademy.io/db/JP/servant/" + servant.collectionNo));
}
AssetBundle assetBundle = null;
string url = $"{urlBase}/manifest.json";
Manifest manifest = null;
yield return FateAssetManager.DownloadText(url, (txt) =>
{
if (string.IsNullOrEmpty(txt)) return;
txt = $"{{\"Entries\": {txt} }}";
manifest = (Manifest)JsonUtility.FromJson(txt, typeof(Manifest));
});
string url = $"{urlBase}/{idNum}";
if (manifest == null)
{
Error.Log(Color.red, "Failed to download manifest from " + url);
LoadingInProgress = false;
yield break;
}
Error.Log(Color.green, "Loading character id " + id);
url = $"{urlBase}/{manifest.GetFilePath(idNum.ToString())}";
yield return FateAssetManager.DownloadBundle(url, (cb) =>
{
assetBundle = cb;
});
if (assetBundle == null)
{
Error.Log(Color.red, "Loading assetbundle failed!");
LoadingInProgress = false;
yield break;
}
StartCoroutine(BuildModel(assetBundle, manifest, urlBase));
StartCoroutine(BuildModel(assetBundle, urlBase));
}
public void ReplaceTexture()
@@ -124,7 +104,7 @@ public class FateModelBuilder : MonoBehaviour
UIController.Instance.ReactivateTextureLoad();
}
public IEnumerator BuildModel(AssetBundle assetBundle, Manifest manifest, string modelUrl)
public IEnumerator BuildModel(AssetBundle assetBundle, string modelUrl)
{
if (assetBundle == null)
{
@@ -151,16 +131,7 @@ public class FateModelBuilder : MonoBehaviour
else if (asset.GetType() == typeof(Texture2D))
{
Texture2D tex = asset as Texture2D;
yield return FateAssetManager.DownloadTexture(modelUrl + "/" + manifest.GetFilePath(tex.name + ".png"), (tex2) =>
{
if(tex2 == null)
{
Error.Log(Color.red, "Downloading " + tex.name + " failed");
return;
}
tex2.name = tex.name;
servant.Textures.Add(tex2);
});
servant.Textures.Add(tex);
}
else if (asset.GetType() == typeof(Material))
{

View File

@@ -1,28 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
[Serializable]
public class Manifest
{
public List<ManifestEntry> Entries = new List<ManifestEntry>();
public string GetFilePath(string input)
{
try { return Entries.FirstOrDefault(e => Path.GetFileName(e.path).ToLower() == input.ToLower()).path; }
catch { Error.Log(UnityEngine.Color.red, input + " not found in Manifest"); return null; }
}
[Serializable]
public class ManifestEntry
{
public string path;
public string type;
}
}
[Serializable]
public class BasicServant
{

View File

@@ -1,9 +1,5 @@
using SharpApng;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using uGIF;
using UnityEngine;

View File

@@ -1,71 +0,0 @@
// This was made by aaro4130 on the Unity forums. Thanks boss!
// It's been optimized and slimmed down for the purpose of loading Quake 3 TGA textures from memory streams.
using System;
using System.IO;
using UnityEngine;
public static class TGALoader
{
public static Texture2D LoadTGA(string fileName)
{
using (var imageFile = File.OpenRead(fileName))
{
return LoadTGA(imageFile);
}
}
public static Texture2D LoadTGA(Stream TGAStream)
{
using (BinaryReader r = new BinaryReader(TGAStream))
{
// Skip some header info we don't care about.
// Even if we did care, we have to move the stream seek point to the beginning,
// as the previous method in the workflow left it at the end.
r.BaseStream.Seek(12, SeekOrigin.Begin);
short width = r.ReadInt16();
short height = r.ReadInt16();
int bitDepth = r.ReadByte();
// Skip a byte of header information we don't care about.
r.BaseStream.Seek(1, SeekOrigin.Current);
Texture2D tex = new Texture2D(width, height);
Color32[] pulledColors = new Color32[width * height];
if (bitDepth == 32)
{
for (int i = 0; i < width * height; i++)
{
byte red = r.ReadByte();
byte green = r.ReadByte();
byte blue = r.ReadByte();
byte alpha = r.ReadByte();
pulledColors [i] = new Color32(blue, green, red, alpha);
}
} else if (bitDepth == 24)
{
for (int i = 0; i < width * height; i++)
{
byte red = r.ReadByte();
byte green = r.ReadByte();
byte blue = r.ReadByte();
pulledColors [i] = new Color32(blue, green, red, 1);
}
} else
{
throw new Exception("TGA texture had non 32/24 bit depth.");
}
tex.SetPixels32(pulledColors);
tex.Apply();
return tex;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 854d5bb72ea5cbc4f976cc4e06f28968
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -99,7 +99,7 @@ public class UIController : MonoBehaviour
GameObject go = Instantiate(databaseContainer, ServantCostumeList.content);
go.transform.Find("Button").GetComponent<Button>().onClick.AddListener(() => {
Application.OpenURL("https://apps.atlasacademy.io/db/JP/servant/" + servant.collectionNo);
OpenUrl("https://apps.atlasacademy.io/db/JP/servant/" + servant.collectionNo);
});
foreach (var cos in servant.costumes)
@@ -126,7 +126,6 @@ public class UIController : MonoBehaviour
go.transform.Find("Name").GetComponent<TMPro.TextMeshProUGUI>().text = !string.IsNullOrEmpty(cos.shortName)? cos.shortName : cos.name;
go.transform.Find("Button").GetComponent<Button>().onClick.AddListener(() => {
StartCoroutine(FateModelBuilder.Instance.ReplaceServant(cos.battleCharaId.ToString()));
//Application.OpenURL($"https://katboi01.github.io/FateViewer/?id={cos.battleCharaId}{(FateViewerMain.Instance.Region != "JP"? $"?region={FateViewerMain.Instance.Region}" : "")}");
});
}
}
@@ -142,11 +141,6 @@ public class UIController : MonoBehaviour
}
EnemyCostumeList.gameObject.SetActive(true);
//GameObject go = Instantiate(databaseContainer, EnemyCostumeList.Content);
//go.transform.Find("Button").GetComponent<Button>().onClick.AddListener(() => {
// Application.OpenURL("https://apps.atlasacademy.io/db/JP/servant/" + servant[0].collectionNo);
//});
foreach (var cos in enemy)
{
GameObject go = Instantiate(costumeContainer, EnemyCostumeList.content);
@@ -160,6 +154,11 @@ public class UIController : MonoBehaviour
}
}
public void OpenUrl(string url)
{
Application.OpenURL(url);
}
public void ReactivateTextureLoad()
{
ReloadTextureButton.interactable = true;