222 lines
6.3 KiB
C#
222 lines
6.3 KiB
C#
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
using gregExtractor.Models;
|
|
using gregExtractor.Services;
|
|
|
|
namespace gregExtractor.GUI.ViewModels;
|
|
|
|
public sealed class CreateViewModel : ObservableObject
|
|
{
|
|
private readonly TemplateService _templateService = new();
|
|
|
|
private int _step = 1;
|
|
private string _modName = "MyDataCenterMod";
|
|
private string _author = "TeamGreg";
|
|
private string _version = "1.0.0";
|
|
private string _description = "Generated by gregExtractor";
|
|
private string _outputPath = Directory.GetCurrentDirectory();
|
|
private TemplateType _selectedTemplateType = TemplateType.HarmonyPatch;
|
|
private string? _selectedCategory;
|
|
private bool _isLoading;
|
|
|
|
public CreateViewModel()
|
|
{
|
|
string groupsPath = Path.Combine(Directory.GetCurrentDirectory(), "hook_groups.json");
|
|
HookClassifier classifier = HookClassifier.LoadFromFile(groupsPath, new Progress<string>(AddLog));
|
|
foreach (string group in classifier.Groups.Keys.OrderBy(x => x, StringComparer.OrdinalIgnoreCase))
|
|
Categories.Add(group);
|
|
|
|
if (!Categories.Contains("Misc", StringComparer.OrdinalIgnoreCase))
|
|
Categories.Add("Misc");
|
|
|
|
TemplateTypes = Enum.GetValues<TemplateType>();
|
|
|
|
NextStepCommand = new RelayCommand(NextStep, () => !IsLoading);
|
|
PreviousStepCommand = new RelayCommand(PreviousStep, () => !IsLoading);
|
|
BrowseOutputPathCommand = new AsyncRelayCommand(BrowseOutputPathAsync);
|
|
GenerateCommand = new AsyncRelayCommand(GenerateAsync, () => !IsLoading && !string.IsNullOrWhiteSpace(ModName));
|
|
OpenOutputCommand = new RelayCommand(OpenOutput, () => Directory.Exists(OutputPath));
|
|
}
|
|
|
|
public Func<string?, Task<string?>>? BrowseFolderHandler { get; set; }
|
|
|
|
public int Step
|
|
{
|
|
get => _step;
|
|
set => SetProperty(ref _step, Math.Clamp(value, 1, 3));
|
|
}
|
|
|
|
public bool IsLoading
|
|
{
|
|
get => _isLoading;
|
|
set
|
|
{
|
|
if (!SetProperty(ref _isLoading, value))
|
|
return;
|
|
|
|
NextStepCommand.NotifyCanExecuteChanged();
|
|
PreviousStepCommand.NotifyCanExecuteChanged();
|
|
GenerateCommand.NotifyCanExecuteChanged();
|
|
}
|
|
}
|
|
|
|
public string ModName
|
|
{
|
|
get => _modName;
|
|
set
|
|
{
|
|
if (!SetProperty(ref _modName, value))
|
|
return;
|
|
|
|
GenerateCommand.NotifyCanExecuteChanged();
|
|
}
|
|
}
|
|
|
|
public string Author
|
|
{
|
|
get => _author;
|
|
set => SetProperty(ref _author, value);
|
|
}
|
|
|
|
public string Version
|
|
{
|
|
get => _version;
|
|
set => SetProperty(ref _version, value);
|
|
}
|
|
|
|
public string Description
|
|
{
|
|
get => _description;
|
|
set => SetProperty(ref _description, value);
|
|
}
|
|
|
|
public string OutputPath
|
|
{
|
|
get => _outputPath;
|
|
set
|
|
{
|
|
if (!SetProperty(ref _outputPath, value))
|
|
return;
|
|
|
|
OpenOutputCommand.NotifyCanExecuteChanged();
|
|
}
|
|
}
|
|
|
|
public TemplateType SelectedTemplateType
|
|
{
|
|
get => _selectedTemplateType;
|
|
set => SetProperty(ref _selectedTemplateType, value);
|
|
}
|
|
|
|
public string? SelectedCategory
|
|
{
|
|
get => _selectedCategory;
|
|
set => SetProperty(ref _selectedCategory, value);
|
|
}
|
|
|
|
public IReadOnlyList<TemplateType> TemplateTypes { get; }
|
|
|
|
public ObservableCollection<string> Categories { get; } = new();
|
|
|
|
public ObservableCollection<string> PreviewTree { get; } = new();
|
|
|
|
public ObservableCollection<string> LogLines { get; } = new();
|
|
|
|
public IRelayCommand NextStepCommand { get; }
|
|
|
|
public IRelayCommand PreviousStepCommand { get; }
|
|
|
|
public IAsyncRelayCommand BrowseOutputPathCommand { get; }
|
|
|
|
public IAsyncRelayCommand GenerateCommand { get; }
|
|
|
|
public IRelayCommand OpenOutputCommand { get; }
|
|
|
|
private void NextStep()
|
|
{
|
|
Step = Math.Min(3, Step + 1);
|
|
if (Step == 3)
|
|
RefreshPreview();
|
|
}
|
|
|
|
private void PreviousStep()
|
|
{
|
|
Step = Math.Max(1, Step - 1);
|
|
}
|
|
|
|
private async Task BrowseOutputPathAsync()
|
|
{
|
|
if (BrowseFolderHandler is null)
|
|
return;
|
|
|
|
string? selected = await BrowseFolderHandler("CreateOutput").ConfigureAwait(false);
|
|
if (!string.IsNullOrWhiteSpace(selected))
|
|
OutputPath = selected;
|
|
}
|
|
|
|
private async Task GenerateAsync()
|
|
{
|
|
IsLoading = true;
|
|
try
|
|
{
|
|
string hooksPath = Path.Combine(Directory.GetCurrentDirectory(), "game_hooks.json");
|
|
TemplateGenerationResult result = await _templateService
|
|
.GenerateModAsync(
|
|
ModName,
|
|
SelectedCategory,
|
|
SelectedTemplateType,
|
|
OutputPath,
|
|
hooksPath,
|
|
new Progress<string>(AddLog),
|
|
CancellationToken.None)
|
|
.ConfigureAwait(false);
|
|
|
|
PreviewTree.Clear();
|
|
PreviewTree.Add(Path.GetFileName(result.ModDirectory) + "/");
|
|
foreach (string file in result.GeneratedFiles.OrderBy(x => x, StringComparer.OrdinalIgnoreCase))
|
|
PreviewTree.Add(" " + Path.GetRelativePath(result.ModDirectory, file).Replace('\\', '/'));
|
|
|
|
AddLog($"✓ Mod erstellt: {result.ModDirectory}");
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
AddLog($"✗ Mod-Erstellung fehlgeschlagen: {exception.Message}");
|
|
}
|
|
finally
|
|
{
|
|
IsLoading = false;
|
|
}
|
|
}
|
|
|
|
private void OpenOutput()
|
|
{
|
|
if (!Directory.Exists(OutputPath))
|
|
return;
|
|
|
|
Process.Start(new ProcessStartInfo
|
|
{
|
|
FileName = OutputPath,
|
|
UseShellExecute = true,
|
|
});
|
|
}
|
|
|
|
private void RefreshPreview()
|
|
{
|
|
PreviewTree.Clear();
|
|
PreviewTree.Add(ModName + "/");
|
|
PreviewTree.Add(" " + ModName + ".csproj");
|
|
PreviewTree.Add(" MainPlugin.cs");
|
|
PreviewTree.Add(" mod.json");
|
|
PreviewTree.Add(" Patches/");
|
|
}
|
|
|
|
private void AddLog(string message)
|
|
{
|
|
string line = $"[{DateTime.Now:HH:mm:ss}] {message}";
|
|
if (LogLines.Count > 1000)
|
|
LogLines.RemoveAt(0);
|
|
|
|
LogLines.Add(line);
|
|
}
|
|
}
|