feat: Enhance DevConsole functionality and integrate pause menu blocking

This commit is contained in:
Marvin
2026-04-20 05:10:41 +02:00
parent abbd440bf1
commit d454cd8a28
8 changed files with 249 additions and 4 deletions
+78
View File
@@ -0,0 +1,78 @@
name: gregFramework Release
on:
workflow_dispatch:
push:
tags:
- 'v*'
jobs:
build:
runs-on: windows-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Set Version
shell: pwsh
run: |
$buildNum = "${{ github.run_number }}"
$version = "1.0.0.$buildNum-pre"
echo "VERSION=$version" >> $env:GITHUB_ENV
echo "Building gregFramework version $version"
# 1. Build gregCore
# Hinweis: In CI müssen ggf. Stubs für MelonLoader/Il2Cpp vorhanden sein.
- name: Build gregCore
run: |
cd gregCore
if (Test-Path "ci-stubs/create-stubs.sh") { bash ci-stubs/create-stubs.sh }
dotnet build src/gregCore.csproj -c Release -p:Version=${{ env.VERSION }} -p:CI=true
# 2. Build gregExtractor
- name: Publish gregExtractor
run: |
dotnet publish gregExtractor/gregExtractor.csproj -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:Version=${{ env.VERSION }} -o publish/extractor
# 3. Prepare Assets
- name: Prepare Assets
shell: pwsh
run: |
$releaseDir = "release-assets"
New-Item -ItemType Directory -Path $releaseDir -Force
# gregCore
$coreDll = "gregCore/src/bin/Release/net8.0/gregCore.dll"
if (Test-Path $coreDll) {
Copy-Item $coreDll $releaseDir/
Compress-Archive -Path $coreDll, "gregCore/README.md" -DestinationPath "$releaseDir/gregCore-v${{ env.VERSION }}.zip"
}
# gregExtractor
$extractorExe = "publish/extractor/gregExtractor.exe"
if (Test-Path $extractorExe) {
Copy-Item $extractorExe $releaseDir/
Compress-Archive -Path "publish/extractor/*" -DestinationPath "$releaseDir/gregExtractor-v${{ env.VERSION }}.zip"
}
- name: Create Release
uses: softprops/action-gh-release@v2
with:
name: gregFramework v${{ env.VERSION }}
tag_name: v${{ env.VERSION }}
prerelease: true
files: |
release-assets/*.dll
release-assets/*.exe
release-assets/*.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Binary file not shown.
+1 -1
View File
@@ -36,7 +36,7 @@ if (Test-Path $tmpDir) { Remove-Item -Recurse -Force $tmpDir }
New-Item -ItemType Directory -Path $tmpDir | Out-Null
Copy-Item $dllPath -Destination $tmpDir
Copy-Item "$repoRoot\README.md" -Destination $tmpDir
Copy-Item "$repoRoot\CHANGELOG.md" -Destination $tmpDir
Copy-Item "C:\Users\marvi\source\repos\gregFramework\CHANGELOG.md" -Destination $tmpDir
Copy-Item "$repoRoot\assets\greg_hooks.json" -Destination $tmpDir
# Create zip
+10
View File
@@ -25,10 +25,20 @@ public sealed class GregCoreLoader : MelonMod
public override void OnUpdate()
{
if (global::UnityEngine.Input.GetKeyDown(global::UnityEngine.KeyCode.P))
{
global::gregCore.Infrastructure.Performance.GregDevConsole.Instance.Toggle();
}
_container?.Get<gregCore.Infrastructure.Performance.GregPerformanceGovernor>()?.OnUpdate();
_container?.Get<GregEventBus>()?.FlushDeferredEvents();
}
public override void OnGUI()
{
global::gregCore.Infrastructure.Performance.GregDevConsole.Instance.OnGUI();
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName) =>
_container?.GetRequired<IGregEventBus>()
.Publish(HookName.Create("lifecycle", "SceneLoaded").Full,
+3
View File
@@ -21,6 +21,9 @@ internal static class HookIntegration
var harmony = new HarmonyLib.Harmony("com.teamgreg.gregcore");
SafePatch(harmony, typeof(Il2Cpp.Player), nameof(Il2Cpp.Player.UpdateCoin), typeof(gregCore.GameLayer.Patches.Economy.PlayerPatch), nameof(gregCore.GameLayer.Patches.Economy.PlayerPatch.OnCoinUpdated));
// Block Pause-Menu when Console is open
SafePatch(harmony, typeof(global::Il2Cpp.InputController.IUIActions), nameof(global::Il2Cpp.InputController.IUIActions.OnPause), typeof(gregCore.GameLayer.Patches.UI.InputPausePatch), nameof(gregCore.GameLayer.Patches.UI.InputPausePatch.Prefix));
}
internal static void Emit(HookName hook, EventPayload payload)
@@ -0,0 +1,25 @@
/// <file-summary>
/// Schicht: GameLayer
/// Zweck: Blockiert die Pause-Logik des Spiels wenn die Console offen ist.
/// Maintainer: Harmony Patch. Zielt auf die InputSystem-Aktion 'Pause'.
/// </file-summary>
using HarmonyLib;
using gregCore.Infrastructure.Performance;
namespace gregCore.GameLayer.Patches.UI;
[HarmonyPatch(typeof(global::Il2Cpp.InputController.IUIActions), nameof(global::Il2Cpp.InputController.IUIActions.OnPause))]
internal static class InputPausePatch
{
[HarmonyPrefix]
internal static bool Prefix()
{
// Wenn die DevConsole offen ist, darf das Pause-Menü nicht aufgehen
if (GregDevConsole.Instance.IsOpen)
{
return false; // Verhindert das Auslösen der Original-Methode
}
return true;
}
}
+129
View File
@@ -0,0 +1,129 @@
/// <file-summary>
/// Schicht: Infrastructure
/// Zweck: In-Game DevConsole Overlay mittels Unity IMGUI.
/// Maintainer: Läuft im Unity Main Thread. Nutzt UnityEngine.GUI.
/// </file-summary>
using UnityEngine;
using System.Collections.Generic;
namespace gregCore.Infrastructure.Performance; // Integration in den Performance-Gedanken (Overlay-Last)
internal sealed class GregDevConsole
{
private static GregDevConsole? _instance;
public static GregDevConsole Instance => _instance ??= new GregDevConsole();
public bool IsOpen { get; private set; }
private string _input = "";
private readonly List<string> _logs = new();
private readonly Dictionary<string, Action<string[]>> _commands = new();
private Vector2 _scroll;
private GUIStyle? _boxStyle;
private GregDevConsole()
{
RegisterCommand("help", _ => Log("Verfügbare Befehle: " + string.Join(", ", _commands.Keys)));
RegisterCommand("clear", _ => _logs.Clear());
RegisterCommand("exit", _ => Toggle());
Log("gregCore DevConsole initialisiert. Tippe 'help' für Befehle.");
}
public void RegisterCommand(string name, Action<string[]> action)
{
_commands[name.ToLower()] = action;
}
public void Toggle()
{
IsOpen = !IsOpen;
if (IsOpen)
{
_input = "";
// Cursor-Locking wird über Patches/Input blockiert
}
}
public void Log(string message)
{
_logs.Add($"[{DateTime.Now:HH:mm:ss}] {message}");
if (_logs.Count > 100) _logs.RemoveAt(0);
_scroll.y = float.MaxValue;
}
public void OnGUI()
{
if (!IsOpen) return;
// Simple IMGUI Style
if (_boxStyle == null)
{
_boxStyle = new GUIStyle(GUI.skin.box);
_boxStyle.normal.background = MakeTex(2, 2, new Color(0, 0, 0, 0.8f));
}
float width = Screen.width * 0.8f;
float height = Screen.height * 0.4f;
float x = (Screen.width - width) / 2;
GUI.Box(new Rect(x, 10, width, height), "<b>gregCore DevConsole</b>", _boxStyle);
// Logs
GUILayout.BeginArea(new Rect(x + 10, 40, width - 20, height - 80));
_scroll = GUILayout.BeginScrollView(_scroll);
foreach (var log in _logs)
{
GUILayout.Label(log);
}
GUILayout.EndScrollView();
GUILayout.EndArea();
// Input
GUI.SetNextControlName("GregConsoleInput");
_input = GUI.TextField(new Rect(x + 10, height - 30, width - 120, 25), _input);
if (GUI.Button(new Rect(x + width - 100, height - 30, 90, 25), "Run") ||
(Event.current.isKey && Event.current.keyCode == KeyCode.Return && GUI.GetNameOfFocusedControl() == "GregConsoleInput"))
{
if (!string.IsNullOrWhiteSpace(_input))
{
Execute(_input);
_input = "";
}
GUI.FocusControl("GregConsoleInput");
}
GUI.FocusControl("GregConsoleInput");
}
private void Execute(string input)
{
Log($"> {input}");
var parts = input.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 0) return;
var cmd = parts[0].ToLower();
var args = parts.Length > 1 ? parts[1..] : Array.Empty<string>();
if (_commands.TryGetValue(cmd, out var action))
{
try { action(args); }
catch (Exception ex) { Log($"<color=red>Fehler: {ex.Message}</color>"); }
}
else
{
Log($"<color=yellow>Unbekannter Befehl: {cmd}</color>");
}
}
private Texture2D MakeTex(int width, int height, Color col)
{
Color[] pix = new Color[width * height];
for (int i = 0; i < pix.Length; ++i) pix[i] = col;
Texture2D result = new Texture2D(width, height);
result.SetPixels(pix);
result.Apply();
return result;
}
}
+3 -3
View File
@@ -1,14 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>10.0</LangVersion>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>12.0</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AssemblyName>gregCore</AssemblyName>
<RootNamespace>gregCore</RootNamespace>
<Version>1.0.0.32-pre</Version>
<Version>1.0.0.33-pre</Version>
<Authors>TeamGreg</Authors>
<Description>gregCore Modding Framework für Data Center</Description>