Skip to content

Commit

Permalink
feat: cli support
Browse files Browse the repository at this point in the history
del: targetframework

add: publish-cli-folderexport workflow

+ logging

single file publish

single file workflow
  • Loading branch information
dapexyz committed Nov 14, 2024
1 parent dbebde3 commit 83bd9e3
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 2 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/publish-cli-folderexport.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Publish-CLI-FolderExport

on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:

jobs:
publish:
runs-on: ${{ matrix.config.os }}

strategy:
matrix:
config:
- { name: win_x64, os: windows-latest, runtime: win-x64, executable: AssetRipper.CLI.FolderExport.exe }
- { name: win_arm64, os: windows-latest, runtime: win-arm64, executable: AssetRipper.CLI.FolderExport.exe }
- { name: linux_x64, os: ubuntu-latest, runtime: linux-x64, executable: AssetRipper.CLI.FolderExport }
- { name: mac_x64, os: macos-latest, runtime: osx-x64, executable: AssetRipper.CLI.FolderExport }
- { name: mac_arm64, os: macos-latest, runtime: osx-arm64, executable: AssetRipper.CLI.FolderExport }

steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.x

- name: Publish
run: dotnet publish -c Release -r ${{ matrix.config.runtime }} --self-contained
working-directory: ./Source/AssetRipper.CLI.FolderExport/

- name: Upload
uses: actions/upload-artifact@v4
with:
name: AssetRipper_CLI_FolderExport_${{ matrix.config.name }}
path: ./Source/AssetRipper.CLI.FolderExport/bin/Release/${{ matrix.config.runtime }}/publish/${{ matrix.config.executable }}
if-no-files-found: error
8 changes: 7 additions & 1 deletion AssetRipper.sln
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetRipper.GUI.Web", "Sour
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetRipper.Export.Modules.Models", "Source\AssetRipper.Export.Modules.Models\AssetRipper.Export.Modules.Models.csproj", "{B827502A-EA76-4C16-B246-0E625A7ED80E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetRipper.GUI.Web.Tests", "Source\AssetRipper.GUI.Web.Tests\AssetRipper.GUI.Web.Tests.csproj", "{9EDD3621-6E2B-41AD-8F6A-F8C4CD113566}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetRipper.GUI.Web.Tests", "Source\AssetRipper.GUI.Web.Tests\AssetRipper.GUI.Web.Tests.csproj", "{9EDD3621-6E2B-41AD-8F6A-F8C4CD113566}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetRipper.CLI.FolderExport", "Source\AssetRipper.CLI.FolderExport\AssetRipper.CLI.FolderExport.csproj", "{445709B2-09C3-47E9-B48D-15FE423489F2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -344,6 +346,10 @@ Global
{9EDD3621-6E2B-41AD-8F6A-F8C4CD113566}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9EDD3621-6E2B-41AD-8F6A-F8C4CD113566}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9EDD3621-6E2B-41AD-8F6A-F8C4CD113566}.Release|Any CPU.Build.0 = Release|Any CPU
{445709B2-09C3-47E9-B48D-15FE423489F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{445709B2-09C3-47E9-B48D-15FE423489F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{445709B2-09C3-47E9-B48D-15FE423489F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{445709B2-09C3-47E9-B48D-15FE423489F2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
12 changes: 11 additions & 1 deletion Source/AssetRipper.Assets/Bundles/GameBundle.FromPaths.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,25 @@ public static GameBundle FromPaths(IEnumerable<string> paths, AssetFactoryBase a
initializer?.OnCreated(gameBundle, assetFactory);
gameBundle.InitializeFromPaths(paths, assetFactory, initializer);
initializer?.OnPathsLoaded(gameBundle, assetFactory);
Console.WriteLine("Initializing dependency lists...");
gameBundle.InitializeAllDependencyLists(initializer?.DependencyProvider);
initializer?.OnDependenciesInitialized(gameBundle, assetFactory);
return gameBundle;
}

private void InitializeFromPaths(IEnumerable<string> paths, AssetFactoryBase assetFactory, IGameInitializer? initializer)
{
ResourceProvider = initializer?.ResourceProvider;
List<FileBase> fileStack = LoadFilesAndDependencies(paths, initializer?.DependencyProvider);
int totalFiles = fileStack.Count;
int processedFiles = 0;
UnityVersion defaultVersion = initializer is null ? default : initializer.DefaultVersion;

while (fileStack.Count > 0)
{
if(processedFiles % 100 == 0)
Console.WriteLine($"Bundling file... {processedFiles}/{totalFiles} ({(processedFiles * 100 / totalFiles)}%)");

switch (RemoveLastItem(fileStack))
{
case SerializedFile serializedFile:
Expand All @@ -53,7 +59,11 @@ private void InitializeFromPaths(IEnumerable<string> paths, AssetFactoryBase ass
AddFailed(failedFile);
break;
}

processedFiles++;
}

Console.WriteLine($"Bundling file... {processedFiles}/{totalFiles} [100%]");
}

private static FileBase RemoveLastItem(List<FileBase> list)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\AssetRipper.Export.UnityProjects\AssetRipper.Export.UnityProjects.csproj" />
</ItemGroup>

</Project>
106 changes: 106 additions & 0 deletions Source/AssetRipper.CLI.FolderExport/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using AssetRipper.Export.UnityProjects;
using AssetRipper.Export.UnityProjects.Configuration;
using AssetRipper.Import.Configuration;
using AssetRipper.Primitives;
using AssetRipper.Processing;
using AssetRipper.Processing.Configuration;
using System.CommandLine;
using System.Diagnostics;

public class Program
{
private static readonly string DefaultUnityVersion = "2022.3.22f1";

public static void Main(string[] args)
{
Console.WriteLine(Launch(args) ? "Files exported successfully." : "There was an error exporting the files.");
}

public static bool Launch(string[] args)
{
RootCommand rootCommand = [];

Option<string> folderOption = new(
"--folder",
"Path to the input folder")
{
IsRequired = true
};
rootCommand.AddOption(folderOption);

Option<string> outputOption = new(
"--output",
"Path to the output folder")
{
IsRequired = true
};
rootCommand.AddOption(outputOption);

Option<string> unityVersionOption = new(
"--unity-version",
() => DefaultUnityVersion,
$"Unity version to use (default is {DefaultUnityVersion})");
rootCommand.AddOption(unityVersionOption);

bool result = false;

rootCommand.SetHandler((string folderPath, string outputPath, string unityVersion) =>
{
Stopwatch stopwatch = new();
stopwatch.Start();
DirectoryInfo folder = new(folderPath);
DirectoryInfo output = new(outputPath);

if (!folder.Exists)
{
Console.WriteLine($"The specified input folder '{folder.FullName}' does not exist.");
return;
}

if (!output.Exists)
{
Console.WriteLine($"The specified output folder '{output.FullName}' does not exist.");
return;
}

Console.WriteLine($"Input folder: {folder.FullName}");
Console.WriteLine($"Output folder: {output.FullName}");
Console.WriteLine($"Unity version: {unityVersion}");
Console.WriteLine("Initializing...");

LibraryConfiguration settings = new();
settings.LoadFromDefaultPath();
ExportHandler exportHandler = new(LoadSettings(unityVersion));

GameData gameData = exportHandler.LoadAndProcess(new string[] { folder.FullName });

exportHandler.Export(gameData, output.FullName);

stopwatch.Stop();
TimeSpan ts = stopwatch.Elapsed;

string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);

Console.WriteLine($"Process finished in {elapsedTime}");

result = true;

}, folderOption, outputOption, unityVersionOption);

rootCommand.Invoke(args);

return result;
}

private static LibraryConfiguration LoadSettings(string unityVersion)
{
LibraryConfiguration settings = new();
settings.LoadFromDefaultPath();
settings.ProcessingSettings.BundledAssetsExportMode = BundledAssetsExportMode.GroupByBundleName;
settings.ImportSettings.DefaultVersion = UnityVersion.Parse(unityVersion);
settings.ImportSettings.TargetVersion = UnityVersion.Parse(unityVersion);
return settings;
}
}
4 changes: 4 additions & 0 deletions Source/AssetRipper.Export.UnityProjects/ExportHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public GameData Load(IReadOnlyList<string> paths)
}

GameStructure gameStructure = GameStructure.Load(paths, Settings);
Console.WriteLine("Finished Loading game structure");
GameData gameData = GameData.FromGameStructure(gameStructure);
Logger.Info(LogCategory.Import, "Finished reading files");
return gameData;
Expand Down Expand Up @@ -78,6 +79,7 @@ protected virtual IEnumerable<IAssetProcessor> GetProcessors()

public void Export(GameData gameData, string outputPath)
{
Console.WriteLine("Starting export...");
Logger.Info(LogCategory.Export, "Starting export");
Logger.Info(LogCategory.Export, $"Attempting to export assets to {outputPath}...");
Logger.Info(LogCategory.Export, $"Game files have these Unity versions:{GetListOfVersions(gameData.GameBundle)}");
Expand Down Expand Up @@ -124,7 +126,9 @@ protected virtual IEnumerable<IPostExporter> GetPostExporters()

public GameData LoadAndProcess(IReadOnlyList<string> paths)
{
Console.WriteLine($"Loading game data from paths [{string.Join(", ", paths)}]...");
GameData gameData = Load(paths);
Console.WriteLine("Processing game data...");
Process(gameData);
return gameData;
}
Expand Down
6 changes: 6 additions & 0 deletions Source/AssetRipper.Export.UnityProjects/ProjectExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,18 @@ public void Export(GameBundle fileCollection, CoreConfiguration options)

EventExportStarted?.Invoke();
ProjectAssetContainer container = new ProjectAssetContainer(this, options, fileCollection.FetchAssets(), collections);
int totalExportable = collections.FindAll(col => col.Exportable).Count();
int exportedCount = 0;
for (int i = 0; i < collections.Count; i++)
{
IExportCollection collection = collections[i];
container.CurrentCollection = collection;
if (collection.Exportable)
{
Logger.Info(LogCategory.ExportProgress, $"Exporting '{collection.Name}'");
if(exportedCount % 100 == 0)
Console.WriteLine($"Exporting... {exportedCount}/{totalExportable} ({exportedCount * 100 / totalExportable}%)");
exportedCount++;
bool exportedSuccessfully = collection.Export(container, options.ProjectRootPath);
if (!exportedSuccessfully)
{
Expand All @@ -101,6 +106,7 @@ public void Export(GameBundle fileCollection, CoreConfiguration options)
}
EventExportProgressUpdated?.Invoke(i, collections.Count);
}
Console.WriteLine($"Exporting... {totalExportable}/{totalExportable} (100%)");
EventExportFinished?.Invoke();
}

Expand Down

0 comments on commit 83bd9e3

Please sign in to comment.