diff --git a/src/Watson.CLI/Program.cs b/src/Watson.CLI/Program.cs
index 83bda62..fa80439 100644
--- a/src/Watson.CLI/Program.cs
+++ b/src/Watson.CLI/Program.cs
@@ -1,5 +1,7 @@
-using Spectre.Console;
+using AssetsTools.NET.Extra;
+using Spectre.Console;
using Watson.Lib.Game.AI_TheSomniumFiles2.Enums;
+using Watson.Lib.IO;
using Watson.Program.Utils;
AnsiConsole.Markup("[purple]Welcome to Watson![/] - [yellow]v1.1.0[/]\n");
@@ -9,11 +11,11 @@
{
case HandlerArgs.Mode.SVS:
AnsiConsole.Progress()
- .Start(ctx =>
+ .Start(ctx =>
{
var svs = new Watson.Lib.Game.neptunia_sisters_vs_sisters.Game(arg.GamePath, ctx);
svs.Proccess();
-
+
// Extract to Po
if (arg.extract)
{
@@ -25,15 +27,15 @@
AnsiConsole.MarkupLine("[green]Juego - AI: The Somnium Files - Nirvana Initiative[/]");
AnsiConsole.Status()
.AutoRefresh(true)
- .Start("Iniciando...", ctx =>
+ .Start("Iniciando...", ctx =>
{
// Simulate some work
ctx.Status("Leyendo carpeta del juego...");
ctx.Spinner(Spinner.Known.Circle);
ctx.SpinnerStyle(Style.Parse("yellow"));
var psync2 = new Watson.Lib.Game.AI_TheSomniumFiles2.Game(arg.GamePath, LanguageType.en, ctx);
-
-
+
+
// Update the status and spinner
ctx.Status("Procesando Archivos...");
psync2.Load();
@@ -47,8 +49,39 @@
}
});
break;
+ case HandlerArgs.Mode.Unity3D:
+ AnsiConsole.MarkupLine("[green]Modo - Unity3D[/]");
+ AnsiConsole.Status()
+ .AutoRefresh(true)
+ .Start("Iniciando...", ctx =>
+ {
+ ctx.Status("Leyendo archivo...");
+ ctx.Spinner(Spinner.Known.Circle);
+ ctx.SpinnerStyle(Style.Parse("yellow"));
+ UnityAssetFile.LoadAndExtractUnity3D(arg.filePath);
+ });
+ break;
+ case HandlerArgs.Mode.CocoDrilo:
+ AnsiConsole.MarkupLine("[green]Juego - Later Alligator[/]");
+ AnsiConsole.Status()
+ .AutoRefresh(true)
+ .Start("Iniciando...", ctx =>
+ {
+ ctx.Spinner(Spinner.Known.Circle);
+ ctx.SpinnerStyle(Style.Parse("yellow"));
+ var cocodrilo = new Watson.Lib.Game.LaterAlligator.Game(arg.GamePath, ctx);
+
+ if (arg.extract)
+ {
+ cocodrilo.Proccess();
+ cocodrilo.Export(arg.OutPut);
+ }
+
+ cocodrilo.Import(arg.PoPath);
+ });
+ break;
case HandlerArgs.Mode.Help:
default:
HandlerArgs.PrintInfo();
break;
-}
\ No newline at end of file
+}
diff --git a/src/Watson.CLI/Utils/HandlerArgs.cs b/src/Watson.CLI/Utils/HandlerArgs.cs
index 0b2f1b0..0562eca 100644
--- a/src/Watson.CLI/Utils/HandlerArgs.cs
+++ b/src/Watson.CLI/Utils/HandlerArgs.cs
@@ -11,7 +11,9 @@ public enum Mode
HoloError,
Windose,
SVS,
- Psync2
+ Psync2,
+ CocoDrilo,
+ Unity3D
}
public HandlerArgs(string[] raw_args)
@@ -24,11 +26,15 @@ public HandlerArgs(string[] raw_args)
new( new[] { "--windose" }, () => OperationMode = Mode.Windose),
new( new[] { "--NeptuniaSVS", "-svs" }, () => OperationMode = Mode.SVS),
new( new[] { "--AI2", "-ai2" }, () => OperationMode = Mode.Psync2),
+ new( new[] { "--coco" }, () => OperationMode = Mode.CocoDrilo),
+ new( new[] { "--unity" }, () => OperationMode = Mode.Unity3D),
// Args
new(new[] { "--gamepath" }, x => GamePath = x),
new(new[] { "--output", "-o" }, x => OutPut = x),
- new(new[] { "--extract", "-x" }, () => extract = true)
+ new(new[] { "--extract", "-x" }, () => extract = true),
+ new(new[] { "--import", "-i" }, x => PoPath = x),
+ new(new[] { "--file", "-f" }, x => filePath = x)
};
for (var i = 0; i < raw_args.Length; ++i)
@@ -40,30 +46,22 @@ public HandlerArgs(string[] raw_args)
else
handler.Invoke(handler.RequiresArg ? raw_args[++i] : null!);
}
+
+ if (import && string.IsNullOrEmpty(PoPath))
+ throw new Exception("Import requires a Po file path");
}
public Mode? OperationMode { get; private set; }
public string? GamePath { get; private set; }
+ public string? filePath { get; private set; }
public string? OutPut { get; private set; } = "out";
+ public string? PoPath { get; private set; }
public bool extract { get; private set; }
+ public bool import { get; private set; }
public static void PrintInfo()
{
AnsiConsole.Markup("[purple]Watson.CLI.exe[/] [red](MODE)[/] [yellow](OPTIONS)[/]");
- /*cmdutils.print("Operation Modes:");
- cmdutils.print(" --Hololy Download and decrypt Hololy models.");
- cmdutils.print(" --HoloEarth Download HoloEarths.");
- cmdutils.print(" --HololiveError Decrypt HololiveError bundles.");
- cmdutils.print("General options: ");
- cmdutils.print(" --output, -o Set the output folder.");
- cmdutils.print("Hololive Error options:");
- cmdutils.print(" --input, -i Set the input file to decrypt.");
- cmdutils.print(" --hash Set the hash of the bundle");
- cmdutils.print("Hololy options:");
- cmdutils.print(" --dev Set the dev server");
- cmdutils.print(" --list, -l List the models");
- cmdutils.print(" --download, -d Download the models");
- cmdutils.print(" --model Download the model by name");*/
}
private class Handler
@@ -95,4 +93,4 @@ public void Invoke(string arg)
Fn!();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Watson.CLI/Watson.CLI.csproj b/src/Watson.CLI/Watson.CLI.csproj
index b0e6a3e..7692300 100644
--- a/src/Watson.CLI/Watson.CLI.csproj
+++ b/src/Watson.CLI/Watson.CLI.csproj
@@ -7,6 +7,7 @@
enable
latest
false
+ true
@@ -14,7 +15,7 @@
-
+
diff --git a/src/Watson.Lib/Game/AI_TheSomniumFiles2/Game.cs b/src/Watson.Lib/Game/AI_TheSomniumFiles2/Game.cs
index 4f750b6..34aff5e 100644
--- a/src/Watson.Lib/Game/AI_TheSomniumFiles2/Game.cs
+++ b/src/Watson.Lib/Game/AI_TheSomniumFiles2/Game.cs
@@ -70,7 +70,7 @@ public void Proccess()
foreach (var sprite in m_Sprites) sprite.Load();
}
- public void Import()
+ public void Import(string poPath)
{
throw new NotImplementedException();
}
@@ -148,4 +148,4 @@ public string[] listFonts(string filter = "")
return fonts.ToArray();
}
-}
\ No newline at end of file
+}
diff --git a/src/Watson.Lib/Game/IGame.cs b/src/Watson.Lib/Game/IGame.cs
index d478211..6ac65ff 100644
--- a/src/Watson.Lib/Game/IGame.cs
+++ b/src/Watson.Lib/Game/IGame.cs
@@ -6,7 +6,7 @@ public interface IGame
public void Proccess();
- public void Import();
+ public void Import(string poPath = "");
public void Export(string outpath = "out");
-}
\ No newline at end of file
+}
diff --git a/src/Watson.Lib/Game/LaterAlligator/Game.cs b/src/Watson.Lib/Game/LaterAlligator/Game.cs
new file mode 100644
index 0000000..26be6a6
--- /dev/null
+++ b/src/Watson.Lib/Game/LaterAlligator/Game.cs
@@ -0,0 +1,173 @@
+namespace Watson.Lib.Game.LaterAlligator;
+
+using AssetsTools.NET;
+using AssetsTools.NET.Extra;
+using IO;
+using Spectre.Console;
+using Utils;
+using Yarhl.FileSystem;
+using Yarhl.IO;
+using Yarhl.Media.Text;
+
+public class Game : IGame
+{
+ public string gamepath { get; set; }
+ private string gamedatapath { get; set; }
+ private string assemblyFolder { get; set; }
+ private string ExtractedAssetsFolder { get; set; }
+ private StatusContext ctx { get; set; }
+
+ private Dictionary Say = new Dictionary();
+ private Dictionary InvokeNextLineAsync = new Dictionary();
+
+ public Game(string gamepath, StatusContext ctx)
+ {
+ this.gamepath = gamepath;
+ this.ctx = ctx;
+ Load();
+ }
+
+ public void Load()
+ {
+ gamedatapath = Path.Combine(gamepath, "LaterAlligator_Data");
+ assemblyFolder = Path.Combine(gamedatapath, "Managed");
+ ExtractedAssetsFolder = TempDirectory.CreateTempDirectory();
+ ctx.Status("Extrayendo Archivos...");
+ }
+
+ public void Proccess()
+ {
+ ctx.Status("Leyendo Archivos...");
+ foreach (string filePath in Directory.GetFiles(gamedatapath, "*.bundle", SearchOption.AllDirectories)) {
+ /*if (!filePath.Contains("scenes_scenes_ending-credits.bundle"))
+ continue;*/
+
+ AnsiConsole.MarkupLine("[yellow]Leyendo Archivo:[/] " + Path.GetFileName(filePath));
+ var m_assetfile = new UnityAssetFile(filePath, gamedatapath);
+ List storyTexts = new List();
+ List nextLineAsync = new List();
+ foreach (AssetFileInfo m_monobehaviour in m_assetfile.GetAssetsOfType(AssetClassID.MonoBehaviour)) {
+ var deserialized =
+ m_assetfile.AM.GetBaseField(m_assetfile.Assets, m_monobehaviour);
+ try
+ {
+ if (!deserialized["targetMethod"].IsDummy &&
+ deserialized["targetMethod"].Value.AsString == "NextLineAsync") {
+ foreach (AssetTypeValueField objValue in deserialized["methodParameters.Array"]) {
+ if (objValue["objValue"].IsDummy || objValue["objValue"]["stringValue"].IsDummy)
+ continue;
+ nextLineAsync.Add(objValue["objValue"]["stringValue"].Value.AsString);
+ }
+ }
+
+ if (!deserialized["storyText"].IsDummy)
+ storyTexts.Add(deserialized.Get("storyText").Value.AsString);
+ } catch (Exception e) {
+#if DEBUG
+ AnsiConsole.WriteException(e);
+#endif
+ }
+ }
+
+ if (storyTexts.Count > 0)
+ Say.Add(Path.GetFileName(filePath), storyTexts.ToArray());
+ if (nextLineAsync.Count > 0)
+ InvokeNextLineAsync.Add(Path.GetFileName(filePath), nextLineAsync.ToArray());
+
+ m_assetfile.Close();
+ }
+ }
+
+ public void Import(string poPath)
+ {
+ ctx.Status("Importando Archivos...");
+ foreach (string filePath in Directory.GetFiles(gamedatapath, "*.bundle", SearchOption.AllDirectories)) {
+
+ if (!File.Exists(Path.Combine(poPath, $"{Path.GetFileName(filePath)}.InvokeNextLineAsync.po")) && !File.Exists(Path.Combine(poPath, $"{Path.GetFileName(filePath)}.Say.po")))
+ continue;
+
+ AnsiConsole.MarkupLine("[yellow]Leyendo Archivo:[/] " + Path.GetFileName(filePath));
+ UnityAssetFile m_assetfile = new UnityAssetFile(filePath, gamedatapath);
+
+ if (File.Exists(Path.Combine(poPath, $"{Path.GetFileName(filePath)}.InvokeNextLineAsync.po"))) {
+ using var Po = NodeFactory.FromFile(Path.Combine(poPath, $"{Path.GetFileName(filePath)}.InvokeNextLineAsync.po"), FileOpenMode.Read);
+ Po.TransformWith(new Binary2Po());
+ var po = Po.GetFormatAs();
+ int index = 0;
+ foreach (AssetFileInfo m_monobehaviour in m_assetfile.GetAssetsOfType(AssetClassID.MonoBehaviour)) {
+
+ var deserialized = m_assetfile.AM.GetBaseField(m_assetfile.Assets, m_monobehaviour);
+
+ try {
+ if (!deserialized["targetMethod"].IsDummy &&
+ deserialized["targetMethod"].Value.AsString == "NextLineAsync") {
+ foreach (AssetTypeValueField objValue in deserialized["methodParameters.Array"]) {
+ if (objValue["objValue"].IsDummy || objValue["objValue"]["stringValue"].IsDummy)
+ continue;
+
+ objValue["objValue"]["stringValue"].Value.AsString =
+ !string.IsNullOrEmpty(po.Entries[index].Translated)
+ ? po.Entries[index].Translated.Replace("\n", "\r\n")
+ : po.Entries[index].Original.Replace("\n", "\r\n");
+
+ m_monobehaviour.SetNewData(objValue);
+ index++;
+ }
+ }
+ } catch (Exception e) {
+ // ignored
+ }
+ }
+ }
+
+ if (File.Exists(Path.Combine(poPath, $"{Path.GetFileName(filePath)}.Say.po"))) {
+ using var Po = NodeFactory.FromFile(Path.Combine(poPath, $"{Path.GetFileName(filePath)}.Say.po"), FileOpenMode.Read);
+ Po.TransformWith(new Binary2Po());
+ var po = Po.GetFormatAs();
+ int index = 0;
+ foreach (AssetFileInfo m_monobehaviour in m_assetfile.GetAssetsOfType(AssetClassID.MonoBehaviour)) {
+ try {
+
+ var deserialized = m_assetfile.AM.GetBaseField(m_assetfile.Assets, m_monobehaviour);
+
+ if (!deserialized["storyText"].IsDummy) {
+ deserialized.Get("storyText").Value.AsString =
+ !string.IsNullOrEmpty(po.Entries[index].Translated)
+ ? po.Entries[index].Translated.Replace("\n", "\r\n")
+ : po.Entries[index].Original.Replace("\n", "\r\n");
+ m_monobehaviour.SetNewData(deserialized);
+ index++;
+ }
+
+
+
+ } catch (Exception e) {
+
+ }
+ }
+ }
+
+ // Save the file
+ Utils.Helpers.AssetHelper.Save(m_assetfile);
+ m_assetfile.Close();
+ }
+ }
+
+ public void Export(string outputPath = "out")
+ {
+ ctx.Status("Exportando Archivos...");
+ Directory.CreateDirectory(outputPath);
+ foreach (var (fileName, texts) in Say)
+ {
+ AnsiConsole.MarkupLine($"[yellow]Exportando Archivo:[/] {fileName}");
+ var po = new ArrayString2Po(fileName, "Say").Convert(texts);
+ new Po2Binary().Convert(po).Stream?.WriteTo(Path.Combine(outputPath, $"{fileName}.Say.po"));
+ }
+
+ foreach (var (fileName, texts) in InvokeNextLineAsync) {
+ AnsiConsole.MarkupLine($"[yellow]Exportando Archivo:[/] {fileName}");
+ var po = new ArrayString2Po(fileName, "InvokeNextLineAsync").Convert(texts);
+ new Po2Binary().Convert(po).Stream?.WriteTo(Path.Combine(outputPath, $"{fileName}.InvokeNextLineAsync.po"));
+ }
+ }
+}
diff --git a/src/Watson.Lib/Game/Windose/Game.cs b/src/Watson.Lib/Game/Windose/Game.cs
index 26617fa..9c411ce 100644
--- a/src/Watson.Lib/Game/Windose/Game.cs
+++ b/src/Watson.Lib/Game/Windose/Game.cs
@@ -461,7 +461,7 @@ public void Proccess()
}
}
- public void Import()
+ public void Import(string poPath = "")
{
throw new NotImplementedException();
}
@@ -1127,4 +1127,4 @@ public Po Convert(yakujoMaster.Param[] source)
}
#endregion
-}
\ No newline at end of file
+}
diff --git a/src/Watson.Lib/Game/neptunia-sisters-vs-sisters/Game.cs b/src/Watson.Lib/Game/neptunia-sisters-vs-sisters/Game.cs
index 5f6bff4..c1da94f 100644
--- a/src/Watson.Lib/Game/neptunia-sisters-vs-sisters/Game.cs
+++ b/src/Watson.Lib/Game/neptunia-sisters-vs-sisters/Game.cs
@@ -39,7 +39,7 @@ public void Load()
AnsiConsole.Markup("[yellow]Neptunia: Sisters VS Sisters mode![/]\n");
var task = ctx?.AddTask("[green]Searching assets[/]");
gamedatapath = Path.Combine(gamepath, $"{gamename}_Data");
-
+
foreach (var files in Directory.GetFiles(gamedatapath, "*.*", SearchOption.AllDirectories)
.Where(file => Regex.IsMatch(file, CSV_REGEX)))
csvassets.Add(files);
@@ -48,13 +48,13 @@ public void Load()
public void Proccess()
{
-
+
var task = ctx?.AddTask("[green]Processing assets[/]");
float proInc = 100.0f / (csvassets.Count -1);
foreach (var file in csvassets)
{
var am = new UnityAssetFile(file, gamedatapath);
-
+
// CSV
var text = new TextAsset(am);
text.Load();
@@ -125,15 +125,15 @@ public void Proccess()
csventry.unk_4 = entrys[14];
csvs.Add(csventry);
}
-
+
var arr = csvs.ToArray();
if (arr.Length <= 0)
continue;
csvfiles.Add(csv.Value.Item2["m_Name"].AsString, arr);
}
-
+
// String DB
-
+
var dbobject = new DbStringObject(am);
dbobject.Load();
@@ -156,23 +156,23 @@ public void Proccess()
s.krText_ = test["krText_"].AsString;
s.tag_ = test["tag_"].AsString;
s.extend_ = new DbExtendString(test["extend_"]["Comment_"].AsString);
-
+
list.Add(s);
}
}
}
-
+
var arr = list.ToArray();
if (arr.Length <= 0)
continue;
dbstrings.Add(dbobjets.Value.Item2["m_Name"].AsString, arr);
}
-
+
task?.Increment(proInc);
}
}
- public void Import()
+ public void Import(string poPath = "")
{
throw new NotImplementedException();
}
@@ -180,9 +180,9 @@ public void Import()
public void Export(string outpath = "out")
{
var task = ctx?.AddTask("[green]Converting to po[/]");
-
+
float proInc = 100.0f / (csvfiles.Count + dbstrings.Count);
-
+
if (!Directory.Exists(outpath))
Directory.CreateDirectory(outpath);
@@ -265,4 +265,4 @@ public Po Convert((string, DbStringMake[]) source)
return po;
}
-}
\ No newline at end of file
+}
diff --git a/src/Watson.Lib/IO/ArrayString2Po.cs b/src/Watson.Lib/IO/ArrayString2Po.cs
new file mode 100644
index 0000000..dae078c
--- /dev/null
+++ b/src/Watson.Lib/IO/ArrayString2Po.cs
@@ -0,0 +1,42 @@
+namespace Watson.Lib.IO;
+
+using Yarhl.FileFormat;
+using Yarhl.Media.Text;
+
+public class ArrayString2Po : IConverter
+{
+ private string preContext { get; set; }
+ private string Name { get; set; }
+
+ public ArrayString2Po(string Name, string preContext = "")
+ {
+ this.Name = Name;
+ this.preContext = preContext;
+
+ if (preContext == string.Empty)
+ preContext = "NoPreContext";
+ }
+
+ public Po Convert(string[] source)
+ {
+ var currentCulture = Thread.CurrentThread.CurrentCulture;
+ var po = new Po
+ {
+ Header = new PoHeader("Watson", "d3fau4@not-d3fau4.com", currentCulture.Name)
+ {
+ LanguageTeam = "Any"
+ }
+ };
+
+ for (int i = 0; i < source.Length; i++) {
+ var txt = !source[i].Equals(string.Empty) ? source[i] : "{EMPTY}";
+ po.Add(new PoEntry
+ {
+ Original = txt.Replace("\r\n", "\n"),
+ Context = $"{Name}.{preContext}.{i}"
+ });
+ }
+
+ return po;
+ }
+}
diff --git a/src/Watson.Lib/IO/UnityAssetFile.cs b/src/Watson.Lib/IO/UnityAssetFile.cs
index f8011c9..762e238 100644
--- a/src/Watson.Lib/IO/UnityAssetFile.cs
+++ b/src/Watson.Lib/IO/UnityAssetFile.cs
@@ -4,6 +4,8 @@
namespace Watson.Lib.IO;
+using Spectre.Console;
+
public class UnityAssetFile
{
public AssetsManager AM;
@@ -30,7 +32,7 @@ public UnityAssetFile(string file)
}
catch (Exception ex)
{
- // Si recibe un error de que el archivo es muy pequeño intentar abrir como AssetBundle.
+ // Si recibe un error de que el archivo es muy pequeño intentar abrir como AssetBundle.
if (ex.Message.Contains("too small") || ex.Message.Contains("Unable to read beyond the end"))
{
// Descargar lo que haya conseguido cargar.
@@ -61,7 +63,7 @@ public UnityAssetFile(string file, string DataFolder)
}
catch (Exception ex)
{
- // Si recibe un error de que el archivo es muy pequeño intentar abrir como AssetBundle.
+ // Si recibe un error de que el archivo es muy pequeño intentar abrir como AssetBundle.
if (ex.Message.Contains("too small") || ex.Message.Contains("Unable to read beyond the end"))
{
// Descargar lo que haya conseguido cargar.
@@ -70,10 +72,15 @@ public UnityAssetFile(string file, string DataFolder)
Bundle = AM.LoadBundleFile(file);
// Siempre index 0 ya que es el que contiene todos los archivos
- Assets = AM.LoadAssetsFileFromBundle(Bundle, 0, true);
+ foreach (string fileName in Bundle.file.GetAllFileNames()) {
+ if (!fileName.Contains(".sharedAssets") && Bundle.file.BlockAndDirInfo.DirectoryInfos[Bundle.file.GetFileIndex(fileName)].Flags == 4) {
+ Assets = AM.LoadAssetsFileFromBundle(Bundle, Bundle.file.GetFileIndex(fileName), true);
+ break;
+ }
+ }
AM.LoadClassPackage(new MemoryStream(Resources.Resources.classdata));
- AM.LoadClassDatabaseFromPackage(Assets.file.Metadata.UnityVersion);
+ AM.LoadClassDatabaseFromPackage(Bundle.file.Header.EngineVersion);
IsBundle = true;
}
}
@@ -84,6 +91,40 @@ public UnityAssetFile(string file, string DataFolder)
}
}
+ public static void LoadAndExtractUnity3D(string path, string OutPut = "out")
+ {
+ var AM = new AssetsManager();
+ var a = AM.LoadBundleFile(path, true);
+ try
+ {
+ Directory.CreateDirectory(OutPut);
+ for (int i = 0; i < 10000; i++)
+ {
+ AM.LoadAssetsFileFromBundle(a, i, false);
+ foreach (AssetsFileInstance assetsFileInstance in a.loadedAssetsFiles)
+ {
+ var filePath = Path.Combine(OutPut, assetsFileInstance.name);
+ if (File.Exists(filePath)) continue;
+ AnsiConsole.MarkupLine($"[yellow]Extrayendo archivo: [/] {assetsFileInstance.name}");
+ using (var fileStream = File.Create(filePath))
+ {
+ if (assetsFileInstance.AssetsStream.CanSeek)
+ {
+ assetsFileInstance.AssetsStream.Position = 0;
+ }
+ assetsFileInstance.AssetsStream.CopyTo(fileStream);
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ AnsiConsole.MarkupLine($"[red]Error: [/] {e.Message}");
+#endif
+ }
+ }
+
public void Close()
{
AM.UnloadAll();
@@ -95,4 +136,4 @@ public List GetAssetsOfType(AssetClassID ID)
foreach (var inf in Assets.file.GetAssetsOfType((int)ID)) list.Add(inf);
return list;
}
-}
\ No newline at end of file
+}
diff --git a/src/Watson.Lib/Resources/classdata.tpk b/src/Watson.Lib/Resources/classdata.tpk
index 34add0f..ce5359d 100644
Binary files a/src/Watson.Lib/Resources/classdata.tpk and b/src/Watson.Lib/Resources/classdata.tpk differ
diff --git a/src/Watson.Lib/Utils/Helpers.cs b/src/Watson.Lib/Utils/Helpers.cs
index 3bbd623..fa3ecd6 100644
--- a/src/Watson.Lib/Utils/Helpers.cs
+++ b/src/Watson.Lib/Utils/Helpers.cs
@@ -19,13 +19,18 @@ public static void Save(UnityAssetFile assetFile,
if (assetFile.IsBundle)
{
- assetFile.Bundle.file.BlockAndDirInfo.DirectoryInfos[0].SetNewData(assetFile.Assets.file);
+ assetFile.Bundle.file.BlockAndDirInfo.DirectoryInfos[assetFile.Bundle.file.GetFileIndex(assetFile.Assets.name)].SetNewData(assetFile.Assets.file);
using (AssetsFileWriter writer = new AssetsFileWriter("TMP.unity3d"))
{
assetFile.Bundle.file.Write(writer);
}
assetFile.AM.UnloadAll(true);
- File.Move("TMP.unity3d", assetFile.AssetName, true);
+
+ //Create directory output
+ if (!Directory.Exists("out_assets"))
+ Directory.CreateDirectory("out_assets");
+
+ File.Move("TMP.unity3d", Path.Combine("out_assets", assetFile.AssetName), true);
}
else
{
@@ -84,4 +89,4 @@ public static class TextureHelper
return texFile.pictureData;
}
-}
\ No newline at end of file
+}
diff --git a/src/Watson.Lib/Utils/TempDirectory.cs b/src/Watson.Lib/Utils/TempDirectory.cs
new file mode 100644
index 0000000..725e7b3
--- /dev/null
+++ b/src/Watson.Lib/Utils/TempDirectory.cs
@@ -0,0 +1,24 @@
+namespace Watson.Lib.Utils;
+
+using System;
+using System.IO;
+
+public class TempDirectory
+{
+ public static string CreateTempDirectory()
+ {
+ // Obtener la ruta del directorio temporal del sistema
+ string tempPath = Path.GetTempPath();
+
+ // Generar un nombre único para la nueva carpeta temporal
+ string tempDirectoryName = Guid.NewGuid().ToString();
+
+ // Combinar la ruta del directorio temporal con el nuevo nombre de carpeta
+ string tempDirectoryFullPath = Path.Combine(tempPath, tempDirectoryName);
+
+ // Crear la carpeta
+ Directory.CreateDirectory(tempDirectoryFullPath);
+
+ return tempDirectoryFullPath;
+ }
+}
diff --git a/src/Watson.Lib/Watson.Lib.csproj b/src/Watson.Lib/Watson.Lib.csproj
index b1f836f..9f4a458 100644
--- a/src/Watson.Lib/Watson.Lib.csproj
+++ b/src/Watson.Lib/Watson.Lib.csproj
@@ -6,6 +6,7 @@
latest
true
net8.0
+ true
@@ -13,12 +14,12 @@
-
-
+
+
-
-
+
+
diff --git a/src/Watson.Test/Watson.Test.csproj b/src/Watson.Test/Watson.Test.csproj
index 89acb0c..e8761c9 100644
--- a/src/Watson.Test/Watson.Test.csproj
+++ b/src/Watson.Test/Watson.Test.csproj
@@ -10,10 +10,13 @@
-
-
-
-
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+