You've already forked FateViewer
Removed external texture loading.
Added Discord link. Minimal cleanup.
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 055f725890d872b4bb22fa493ed06356
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de9592c4ae9713d41ae7a9ae40d1b549
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 854d5bb72ea5cbc4f976cc4e06f28968
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user