Files
2026-02-09 23:53:14 +01:00

274 lines
10 KiB
C#

using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Linq;
namespace OctoCore.Inputs
{
/// <summary>
/// Automatically restores OctoActions.cs from backup JSON when package is updated.
/// </summary>
[InitializeOnLoad]
public class OctoActionsPostImport
{
private const string BACKUP_FILE = "Assets/OctoCore/Editor/OctoActions.json";
private static string GetActionsFilePath()
{
// Find OctoInputs.cs to locate the package
string[] guids = AssetDatabase.FindAssets("OctoInputs t:script");
foreach (string guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
if (path.Contains("/Inputs/OctoInputs.cs"))
{
// Found it! Same directory
string directory = Path.GetDirectoryName(path);
return Path.Combine(directory, "OctoActions.cs").Replace("\\", "/");
}
}
// Fallback
return "Assets/OctoCore/Generated/OctoActions.cs";
}
static OctoActionsPostImport()
{
// Restore from backup if needed
EditorApplication.delayCall += RestoreFromBackup;
}
[MenuItem("OctoCore/Input Actions/Restore from Backup")]
public static void ForceRestore()
{
RestoreFromBackup();
}
[MenuItem("OctoCore/Input Actions/Reset to Template")]
public static void ResetToTemplate()
{
if (!EditorUtility.DisplayDialog(
"Reset OctoActions",
"This will reset OctoActions.cs to the template (None = 0).\n\n" +
"The backup JSON will be kept, so you can restore later.\n\n" +
"Are you sure?",
"Reset",
"Cancel"))
{
return;
}
string actionsFile = GetActionsFilePath();
CreateTemplate(actionsFile);
AssetDatabase.Refresh();
Debug.Log("[OctoCore] OctoActions.cs reset to template.");
}
[MenuItem("OctoCore/Input Actions/Delete Backup")]
public static void DeleteBackup()
{
if (!File.Exists(BACKUP_FILE))
{
EditorUtility.DisplayDialog("No Backup", "No backup file found.", "OK");
return;
}
if (!EditorUtility.DisplayDialog(
"Delete Backup",
"This will permanently delete the backup JSON.\n\n" +
"You won't be able to restore your actions after a package update.\n\n" +
"Are you sure?",
"Delete",
"Cancel"))
{
return;
}
File.Delete(BACKUP_FILE);
// Delete meta file too
string metaFile = BACKUP_FILE + ".meta";
if (File.Exists(metaFile))
{
File.Delete(metaFile);
}
AssetDatabase.Refresh();
Debug.Log("[OctoCore] Backup file deleted.");
}
private static void RestoreFromBackup()
{
string actionsFile = GetActionsFilePath();
// Check if backup exists
if (!File.Exists(BACKUP_FILE))
{
Debug.Log("[OctoCore] No backup found. Generate your actions via OctoSettings.");
return;
}
// Check if actions file needs restoration (is it the template?)
if (File.Exists(actionsFile))
{
string currentContent = File.ReadAllText(actionsFile);
// If it contains real actions (not just None), skip restoration
if (currentContent.Contains("_PLACEHOLDER_") || currentContent.Contains("None = 0"))
{
Debug.Log("[OctoCore] Restoring actions from backup...");
RestoreActionsFile(actionsFile);
}
else
{
// File already has real actions, don't overwrite
return;
}
}
else
{
// File doesn't exist, restore it
RestoreActionsFile(actionsFile);
}
}
private static void RestoreActionsFile(string actionsFile)
{
try
{
// Read backup JSON
string json = File.ReadAllText(BACKUP_FILE);
var backup = JsonUtility.FromJson<ActionsBackup>(json);
if (backup == null || backup.Actions == null || backup.Actions.Count == 0)
{
Debug.LogWarning("[OctoCore] Backup file is empty or invalid.");
return;
}
// Generate enum file from backup
StringBuilder sb = new StringBuilder();
sb.AppendLine("// ═══════════════════════════════════════════════════════════════════════════");
sb.AppendLine("// AUTO-GENERATED FILE - DO NOT EDIT MANUALLY");
sb.AppendLine("// ═══════════════════════════════════════════════════════════════════════════");
sb.AppendLine("// Restored from backup by OctoActionsPostImport");
sb.AppendLine($"// Original source: {backup.GeneratedFrom}");
sb.AppendLine($"// Originally generated on: {backup.GeneratedOn}");
sb.AppendLine($"// Restored on: {System.DateTime.Now:yyyy-MM-dd HH:mm:ss}");
sb.AppendLine("// ═══════════════════════════════════════════════════════════════════════════");
sb.AppendLine();
sb.AppendLine("namespace OctoCore.Inputs");
sb.AppendLine("{");
sb.AppendLine(" /// <summary>");
sb.AppendLine(" /// Actions from Unity Input Actions.");
sb.AppendLine($" /// Generated from: {backup.GeneratedFrom}");
sb.AppendLine(" /// Format: ActionMap_ActionName");
sb.AppendLine(" /// Values are stable hashes to prevent serialization issues when regenerating.");
sb.AppendLine(" /// </summary>");
sb.AppendLine(" public enum OctoActions");
sb.AppendLine(" {");
for (int i = 0; i < backup.Actions.Count; i++)
{
var action = backup.Actions[i];
if (i > 0)
sb.AppendLine(",");
sb.AppendLine($" /// <summary>{action.MapName} > {action.ActionName}</summary>");
sb.Append($" {action.Name} = {action.Hash}");
}
sb.AppendLine();
sb.AppendLine(" }");
sb.AppendLine("}");
// Ensure directory exists
string directory = Path.GetDirectoryName(actionsFile);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
// Write restored file
File.WriteAllText(actionsFile, sb.ToString());
AssetDatabase.Refresh();
Debug.Log($"[OctoCore] Actions successfully restored from backup! ({backup.Actions.Count} actions)");
}
catch (System.Exception ex)
{
Debug.LogError($"[OctoCore] Failed to restore actions from backup: {ex.Message}");
}
}
private static void CreateTemplate(string actionsFile)
{
string template =
@"// ═══════════════════════════════════════════════════════════════════════════
// TEMPLATE FILE
// ═══════════════════════════════════════════════════════════════════════════
// This is a template file for OctoActions.
//
// TO GENERATE YOUR REAL ACTIONS:
// 1. Open OctoSettings in the Inspector
// 2. Go to Mapping section
// 3. Assign your Input Action Asset
// 4. Click 'Generate Inputs' button
//
// This template allows the package to compile before actions are generated.
// ═══════════════════════════════════════════════════════════════════════════
namespace OctoCore.Inputs
{
/// <summary>
/// Template enum for input actions.
/// Generate your real actions via OctoSettings > Mapping > Generate Inputs.
/// </summary>
public enum OctoActions
{
/// <summary>
/// Placeholder value.
/// This will be replaced when you generate your input actions.
/// </summary>
None = 0
}
}
";
// Ensure directory exists
string directory = Path.GetDirectoryName(actionsFile);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
// Write template file
File.WriteAllText(actionsFile, template);
}
[System.Serializable]
private class ActionBackupData
{
public string Name;
public int Hash;
public string MapName;
public string ActionName;
}
[System.Serializable]
private class ActionsBackup
{
public string GeneratedFrom;
public string GeneratedOn;
public List<ActionBackupData> Actions;
}
}
}
#endif