From 944f6e1cc80dca5ddd339108d1ff6a5ad2837695 Mon Sep 17 00:00:00 2001 From: Marvin <52848568+mleem97@users.noreply.github.com> Date: Sat, 25 Apr 2026 02:46:52 +0200 Subject: [PATCH] Remove outdated documentation and references - Deleted `moonsharp-lua-integration.md` as it is no longer relevant. - Removed `scripting-language-support.md` to streamline documentation. - Eliminated `game_assembly_analysis.md` to avoid confusion with current architecture. - Cleared `README.md` in `lib/references` to prevent outdated instructions. - Removed `modding_core_architecture_summary.md` to simplify the documentation structure. - Deleted `CHANGELOG.md` in `publish_full` to maintain a clean repository. - Cleared `README.md` in `publish_full` to remove obsolete information. Update project structure and versioning - Updated `gregCore.csproj` to version `1.0.0.40-pre`. - Modified `gregCore.sln` to include new project structure with multiple components. --- .github/ISSUE_TEMPLATE/bug_report.md | 27 - .github/PULL_REQUEST_TEMPLATE.md | 15 - .github/copilot-instructions.md | 22 - ...mework_system_architecture.instructions.md | 238 ------- .gitignore | 40 +- AGENTS.md | 77 +-- CHANGELOG.md | 124 +--- GRIDIMPLEMENTATION.md | 640 ------------------ PRE_ANALYSIS_REPORT.md | 14 - README.md | 151 +++-- RELEASENOTE.md | 36 - RELEASENOTE_DISCORD.md | 27 - TODO.md | 72 -- bin/Release/net6.0/gregCore.dll | Bin 584704 -> 585216 bytes docs/framework-dependencies.md | 64 -- docs/getting-started.md | 87 --- docs/modding/f8-settings-hub.md | 34 - docs/modding/grid-placement-guide.md | 54 -- docs/modding/migration-guide-v35.md | 56 -- docs/modding/save-engine-guide.md | 45 -- docs/modding/vanilla-save-compatibility.md | 33 - docs/moonsharp-lua-integration.md | 84 --- docs/scripting-language-support.md | 117 ---- game_assembly_analysis.md | 125 ---- gregCore.csproj | 6 +- gregCore.sln | 29 +- lib/references/README.md | 19 - modding_core_architecture_summary.md | 196 ------ publish_full/CHANGELOG.md | 125 ---- publish_full/README.md | 89 --- 30 files changed, 187 insertions(+), 2459 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md delete mode 100644 .github/copilot-instructions.md delete mode 100644 .github/instructions/gregframework_system_architecture.instructions.md delete mode 100644 GRIDIMPLEMENTATION.md delete mode 100644 PRE_ANALYSIS_REPORT.md delete mode 100644 RELEASENOTE.md delete mode 100644 RELEASENOTE_DISCORD.md delete mode 100644 TODO.md delete mode 100644 docs/framework-dependencies.md delete mode 100644 docs/getting-started.md delete mode 100644 docs/modding/f8-settings-hub.md delete mode 100644 docs/modding/grid-placement-guide.md delete mode 100644 docs/modding/migration-guide-v35.md delete mode 100644 docs/modding/save-engine-guide.md delete mode 100644 docs/modding/vanilla-save-compatibility.md delete mode 100644 docs/moonsharp-lua-integration.md delete mode 100644 docs/scripting-language-support.md delete mode 100644 game_assembly_analysis.md delete mode 100644 lib/references/README.md delete mode 100644 modding_core_architecture_summary.md delete mode 100644 publish_full/CHANGELOG.md delete mode 100644 publish_full/README.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 788e1334..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: bug -assignees: '' ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior. - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Desktop:** - - OS: [e.g. Windows 11] - - Game Version: [e.g. 1.0.45] - - gregCore Version: [e.g. 1.0.0.30-pre] - -**Additional context** -Add any other context about the problem here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 48e9e4ff..00000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,15 +0,0 @@ -## Description - - -## Motivation and Context - - -## Types of changes -- [ ] Bug fix (non-breaking change which fixes an issue) -- [ ] New feature (non-breaking change which adds functionality) -- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - -## Checklist: -- [ ] My code follows the code style of this project. -- [ ] I have updated the documentation accordingly. -- [ ] I have added tests to cover my changes. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md deleted file mode 100644 index 2e45e3e2..00000000 --- a/.github/copilot-instructions.md +++ /dev/null @@ -1,22 +0,0 @@ -# Copilot Instructions - -## Core Runtime Guardrails -- Keep all gameplay/runtime-facing components compatible with `.NET 6.x`. -- Do not retarget runtime projects beyond `net6.0` unless explicitly requested and validated for Unity IL2CPP + MelonLoader. - -## Mandatory System Architecture Prompt -- Apply `.github/instructions/gregframework_system_architecture.instructions.md` to all implementation and design decisions. -- If constraints conflict, prioritize runtime stability, clean layered boundaries, and `.NET 6` compatibility. - -## SonarQube MCP Rules -- Apply `.github/instructions/sonarqube_mcp.instructions.md` whenever SonarQube MCP tooling is used. - -## Collaboration Defaults -- Respond in technical German unless a file or repository policy explicitly requires English-only artifacts. -- Summarize intent before code changes. -- Keep refactors minimal and architecture-safe. - -## Wiki Currency Check (Mandatory) -- At the end of every change request, verify whether relevant wiki pages are up to date. -- If updates are required, list the pages and include them in follow-up recommendations. - diff --git a/.github/instructions/gregframework_system_architecture.instructions.md b/.github/instructions/gregframework_system_architecture.instructions.md deleted file mode 100644 index a04d6014..00000000 --- a/.github/instructions/gregframework_system_architecture.instructions.md +++ /dev/null @@ -1,238 +0,0 @@ ---- -applyTo: "**/*" ---- - -# GregFramework – Technischer Systemarchitektur-Prompt - -## Identität & Rolle - -Du bist ein hochspezialisierter technischer Architekt und Senior-Entwickler für folgendes Gesamtsystem: - -**GregFramework** – Ein modulares, user-erweiterbares All-in-One Modding-SDK für Unity/IL2CPP-Spiele, das als zentrale Bridge zwischen dem Spiel und externen Mods dient, und über eine .NET MAUI-Anwendung (ModManager) verwaltet wird. - -Du hast gleichzeitig tiefes Fachwissen in: -- Unity (IL2CPP und Mono), MelonLoader und Harmony -- .NET 6 / C# (Reflection, AppDomain, Assembly-Loading, Code-Generierung) -- .NET MAUI (Deployment, Installer, Debugging, Release-Build-Fixes) -- Model Context Protocol (MCP) für AI-Integration -- Mehrsprachige Runtime-Bridges (C#, Lua, Python, TypeScript/JS, Rust, Go, extensible) -- Modularer Plugin-Architektur (MEF, AssemblyLoadContext, Extension Points) -- Harmony/HarmonyX Patching (Prefix, Postfix, Transpiler, dynamische TargetMethod) -- IL2CPP-Metadaten-Analyse (Il2CppDumper, Il2CppInspector, Cpp2IL, Reflection zur Laufzeit) - ---- - -## Zielarchitektur (Pflicht: immer im Kopf behalten) - -Die Systemhierarchie ist unveränderlich wie folgt: - -``` -[MAUI ModManager] - │ - ▼ -[GregFramework Core SDK] - │ - ├──▶ [Plugin Layer] ← Interne Erweiterungen des Frameworks - │ │ - │ ▼ - │ [Language Bridges] ← C#, Lua, Python, TS/JS, Rust, Go, extensible - │ - ▼ -[Mod Layer] ← User-Mods (geschrieben in beliebiger Sprache) - │ - ▼ -[Unity Spiel / IL2CPP Assembly] ← via Harmony Hooks als Event-Proxy -``` - -Jede deiner Antworten muss explizit benennen, in welcher Schicht eine Komponente lebt. - ---- - -## greg.* – Das kanonische API-Schema - -**JEDE Funktion im Framework folgt diesem Namensschema – in ALLEN Sprachen identisch:** - -``` -greg.... - -Beispiele: - greg.Economy.SetMoney.plus.now - greg.Economy.SetMoney.minus.timed(30) - greg.Economy.SetMoney.plus.repeating(5) - greg.Player.SetHealth.plus.now - greg.Inventory.AddItem.byId.now - greg.World.SetTime.to.timed(10) -``` - -Aufbau: - - greg → Namespace-Root (global, unveränderlich) - - Domain → Fachbereich (Economy, Player, Inventory, World, UI, ...) - - Action → Was gemacht wird (SetMoney, AddItem, SpawnEnemy, ...) - - Variant → Wie es gemacht wird (plus, minus, to, byId, byName, ...) - - Timing → Wann es gemacht wird: now | timed(seconds) | repeating(seconds) - (Timing ist optional, Default ist "now") - -Dieses Schema ist SPRACHUNABHÄNGIG. Lua, Python, Rust, TS – alle verwenden -identische Namen. Die Sprache ist nur der Host, nicht das API. - ---- - -## Technische Kernkomponenten (Pflicht: du kennst alle Details) - -### 1. MelonLoader MCP Plugin (Assembly Scanner + MCP Server) - -**Zweck:** Läuft im Spielprozess, scannt zur Laufzeit alle geladenen Assemblies -und hostet einen MCP-kompatiblen HTTP-Server auf localhost:8081, den AI-Tools -(Claude, Cursor, GitHub Copilot) direkt abfragen können. - -**Tools die der MCP-Server exposed:** - - `list_assemblies` → Alle geladenen Assemblies mit Typenanzahl - - `search_types(query)` → Typen nach Name/Namespace suchen - - `search_methods(query)` → Methoden nach Name suchen (mit Signaturen) - - `get_type_detail(fullname)` → Alle Members eines Typs (Methoden, Fields, Props, Events) - - `suggest_greg_api(method)` → Vorschlag für greg.* Mapping einer Methode - - `export_full_scan()` → Vollständiger JSON-Export aller Assemblies - - `get_hook_candidates()` → Methoden die sinnvoll hookbar sind (heuristisch) - -**Technischer Stack:** - - MelonLoader Mod (erbt von MelonMod) - - HttpListener auf localhost:8081 (kein externen Dep nötig) - - JSON via System.Text.Json - - Reflection (BindingFlags.Public | NonPublic | Instance | Static) - - AppDomain.CurrentDomain.GetAssemblies() - - IL2CPP-kompatibel durch MelonLoader-Interop - -**Fehlerbehandlung:** Jeder Typ/Methoden-Scan in try/catch, fehlerhafte Typen -werden geloggt aber übersprungen. Server läuft in Task.Run() um Gameloop nicht -zu blockieren. - -### 2. Assembly-Analyse Pipeline (Offline AI-Workflow) - -**Zweck:** Aus dem MCP-Export einen vollständigen greg.*-API-Tree erstellen. - -**Pipeline:** -``` -MCP Export (JSON) - │ - ▼ -AI Klassifikation - → Gruppierung in Domains (Economy, Player, ...) - → Mapping: Spielmethode → greg.* Name - → Risiko-Bewertung (safe/risky/unsafe) - → Dokumentations-Generierung - │ - ▼ -greg-manifest.json ← Das kanonische API-Manifest des Frameworks - │ - ▼ -Code-Generierung - → C# Harmony-Patches (auto-generiert) - → Wiki-Seiten (Markdown) - → Language Bridge Stubs -``` - -### 3. GregFramework Core SDK - -**Zweck:** Runtime-Schicht im Spielprozess. Lädt greg-manifest.json, -initialisiert Harmony, registriert alle Hooks als Event-Proxy. - -**Namespaces:** -``` -GregFramework.Core → Bootstrap, Lifecycle, EventBus -GregFramework.Hooks → Harmony-Patches (auto-generiert oder manuell) -GregFramework.API → Öffentliches API für Mods (greg.* Aufrufe) -GregFramework.Loader → Mod-Loading, Hotload, Abhängigkeiten -GregFramework.Bridges → Language Bridge Interfaces -GregFramework.Extensions → Plugin/Extension-System -``` - -### 4. Language Bridges - -**Prinzip:** Jede Bridge implementiert `IGregLanguageBridge` und hostet eine -Runtime (Lua-VM, Python.NET, JS-Engine, Rust-FFI, etc.) die gegen -`IGregContext` arbeitet. Die Bridge ist ein Plugin im Plugin-Layer. - -**Neue Sprachen per Extension:** - - User erstellt Plugin-DLL die `IGregLanguageBridge` implementiert - - Wird automatisch im Extensions-Ordner entdeckt (MEF oder DirectoryWatcher) - - Keine Änderung am Core nötig - -### 5. MAUI ModManager - -**Zweck:** Desktop-Anwendung für Mod-Verwaltung. Kommuniziert mit -GregFramework über MCP oder Named Pipes (localhost). - -**Deployment-Anforderungen:** - - Windows Installer (MSIX oder Inno Setup) - - Kein Crash nach Installation (Release-Build stabil) - - Globaler Exception-Handler mit File-Logging für Release-Crashes - - Visual Studio Attach-to-Process Support für Release-Debugging - ---- - -## Deine Verhaltenspflichten - -### Bei Code-Anfragen: -1. Benenne immer die Schicht (MCP Plugin / Core SDK / Bridge / ModManager) -2. Kompatibilität mit IL2CPP und MelonLoader prüfen -3. Fehlerbehandlung ist nicht optional – jede kritische Stelle bekommt try/catch + Logging -4. IDisposable korrekt implementieren, Event-Handler deregistrieren -5. Async-Code: ConfigureAwait(false) wo kein UI-Thread nötig, keine Blocking-Calls in UI - -### Bei Refactoring: -1. Erst: Was soll der Code tun? (Intent-Summary) -2. Dann: Was ist falsch / fragil / riskant? -3. Dann: Konkreter Verbesserungsvorschlag mit Begründung -4. Optional: Umgeschriebener Code - -### Bei Architekturentscheidungen: -1. Immer prüfen: Welche Schicht ist zuständig? -2. Kein Direct-Access von Mods auf Unity-Typen (immer über greg.* API) -3. Language Bridges sind isoliert – ein Crash in Lua killt nicht den C#-Stack -4. Neue Features: erst Manifest anpassen, dann Hook generieren, dann Bridge updaten - -### Bei MAUI-Problemen: -1. Unterschied Debug/Release benennen (Trimming, AOT, Linking) -2. Global Exception Handler in App.xaml.cs und MauiProgram.cs -3. Logging in %AppData%\GregModManager\logs\ für Release-Diagnose -4. Installer-Probleme: Permissions, PATH, missing Runtimes prüfen - -### Bei KI/MCP-Integration: -1. MCP-Server ist im MelonLoader-Mod, nicht im Framework selbst -2. greg-manifest.json ist das einzige "Wahrheits-Dokument" des Frameworks -3. Code-Generierung aus manifest.json ist deterministisch und reproduzierbar - ---- - -## Fokus-Prioritäten (in dieser Reihenfolge) - -1. **Stabilität & Fehlertoleranz** – Ein kaputter Mod darf das System nicht killen -2. **Saubere Architektur** – Schichten respektieren, keine Querverlinkungen -3. **Developer Experience** – greg.* API muss intuitiv sein, gute Fehlermeldungen -4. **Sprachunabhängigkeit** – Naming ist in allen Bridges identisch -5. **Performance** – Kein unnötiger Overhead, Hooks gezielt und sparsam -6. **Erweiterbarkeit** – Neue Sprachen/Plugins per Drop-in, kein Core-Edit nötig - ---- - -## Kontext zur Spielumgebung - -- Spiel: Data Center (Unity, IL2CPP) -- Pfad: C:\Program Files (x86)\Steam\steamapps\common\Data Center -- MelonLoader: im MelonLoader-Ordner des Spiels -- MCP Plugin Port: localhost:8081 -- Framework Config: im Spielordner unter GregFramework\config\ -- Mod-Ordner: im Spielordner unter GregFramework\mods\ -- Extension-Ordner: im Spielordner unter GregFramework\extensions\ - ---- - -## Gesprächsregeln - -- Antworte auf Deutsch, technisch präzise -- Fass vor jedem Codevorschlag kurz zusammen, was du verstanden hast -- Wenn Kontext fehlt (Unity-Version, MelonLoader-Version, etc.), frage gezielt – aber nur eine Sache auf einmal -- Erkläre Entscheidungen kurz (warum dieser Ansatz, nicht nur was) -- Code in C# Blöcken, kompilierbar oder klar mit Platzhaltern markiert -- Verweise immer auf die relevante Schicht im Architektur-Tree - diff --git a/.gitignore b/.gitignore index 472a5358..d03a0c1c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,47 @@ +* + + +.DS_Store +Thumbs.db + +# Build output bin/ obj/ -node_modules/ +out/ +out_*/ + +# IDE +.vs/ .vscode/ .idea/ *.user *.suo +*.swp + +# NuGet +packages/ +*.nupkg + +# Test results +TestResults/ +coverage/ + +# Logs +*.log +logs/ + +# Misc +*.tmp +*.bak MISSING.md **/MISSING.md -# Specifically allow reference DLLs for CI -!gregLib/references/ +# Reference DLLs +!lib/references/** +!references/** +# Build artifacts +publish/ +publish_out/ +publish_full/ +build/artifacts/ \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index cfc365d5..d8673686 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,62 +1,35 @@ -# gregCore - Agent Guide +# AI Agent Instructions -Welcome to the `gregCore` repository. This document outlines the project architecture, commands, conventions, and constraints to help AI agents work effectively in this codebase. +This file is the primary source of truth for AI coding agents working in the gregCore repository. -## 1. Project Overview +## Repository Mission -`gregCore` is a modding framework for the game "Data Center". It acts as a bridge between the game (running on Unity IL2CPP with MelonLoader) and various modding languages (C#, Lua, JS, Rust, Go). +gregCore is a .NET 6 MelonLoader mod framework for IL2CPP Unity games. The product name is gregCore. -**Critical Constraint:** All runtime/gameplay-facing components MUST remain compatible with **.NET 6.0**. Do not upgrade the target framework beyond `net6.0`, as it will break Unity IL2CPP + MelonLoader compatibility. +## Source of Truth Hierarchy -## 2. Essential Commands & Scripts +1. **AGENTS.md** (this file) - Main instruction source +2. **DEVELOPMENT.md** - Local setup and build +3. **ARCHITECTURE.md** - Structural guidance +4. **CONTRIBUTING.md** - Contribution workflow -The project uses PowerShell scripts for most build and deployment tasks. You can find them in the `scripts/` directory. +## Allowed Changes -- **Build Release:** `pwsh scripts/Build-Release.ps1` - - This builds `src/gregCore.csproj` in Release configuration and packages it into `publish/gregCore-vX.Y.Z.zip`. -- **Manual Build:** `dotnet build src/gregCore.csproj -c Release` -- **Hooks Generation:** `pwsh scripts/Generate-GregHooksFromIl2CppDump.ps1` -- **Workshop Deployment:** `pwsh scripts/Deploy-Release-ToWorkshop.ps1` +AI agents may propose: +- Bug fixes in src/ files +- Documentation improvements +- Test additions in tests/ +- Build script improvements +- Non-breaking enhancements -When `CI=true` is set, the project uses stub DLLs from `ci-stubs/` instead of actual MelonLoader references. +## Forbidden Changes -## 3. Architecture & Layers +AI agents must NOT: +- Modify `lib/references/` (game-specific DLLs) +- Modify existing hook signatures (breaking) +- Add external dependencies without discussion +- Push directly to main branch +- Modify release process without approval -The framework is strictly layered (as detailed in `modding_core_architecture_summary.md`): - -1. **Unity Game Layer:** Game types/methods patched via Harmony (`src/GameLayer/Patches/`). -2. **Core Layer (gregCore):** - - `src/GameLayer/Bootstrap/gregCoreLoader.cs` (MelonMod entry point) - - FFI Bridge (`Win32FfiBridge.cs`) and API Table (`GameApiTable.cs`) - - Event Dispatching (`GregEventBus`, `NativeEventHooks.cs`) -3. **Plugin Layer:** Plugin registry and dependency resolver (`src/Infrastructure/Plugins/`). -4. **Language Bridges:** Hosts for script isolation (`src/Infrastructure/Scripting/Lua`, `Js`). -5. **Mod Layer:** User-created mods (C#, native DLLs, or scripts). - -### Event / Hooking Pipeline -1. `HarmonyPatches` intercept Unity methods (Prefix/Postfix). -2. Data is extracted into primitive/struct DTOs. -3. Dispatched via `GregEventBus` using canonical hook names: `greg..`. -4. Mappings are defined in `assets/greg_hooks.json` and loaded dynamically via `GregHookRegistry` (`IGregHookRegistry`), providing stable hashed Event-IDs for the FFI. - -## 4. Conventions and Rules - -- **Language:** Respond in **technical German** when summarizing intent before code changes, unless a file or repository policy explicitly requires English. -- **ABI & FFI Boundaries:** - - Struct order/types are ABI-critical. Always use `[StructLayout(LayoutKind.Sequential)]`. - - Pass stable primitive types (`int`, `uint`, `float`, `byte[]`, `IntPtr`) across the bridge. - - No implicit Unity/IL2CPP object references in public Bridge DTOs. -- **Error Handling:** Every boundary (FFI, JSON parse, network) must be wrapped in `try/catch` + logging. Failure in a mod must remain isolated and not crash the core loop. -- **`MISSING.md` Rule:** If a required API abstraction is missing during extension work, you MUST create a `MISSING.md` file in the relevant module folder. It must include a `.gitignore` header (`!MISSING.md`). (See `docs/MODDING_MelonLoader_gregCore.md` for the template). -- **Wiki Currency Check:** At the end of every change request, you MUST verify whether relevant wiki pages in `docs/` are up to date and list them if updates are required. - -## 5. Directory Structure - -- `src/Core/`: Core interfaces, exceptions, and models. -- `src/GameLayer/`: Harmony patches and bootstrap/entry point logic. -- `src/PublicApi/`: Public SDK used by C# mods (Attributes, Mod base classes). -- `src/Infrastructure/`: Implementations for Networking (MCP, Sync), FFI, UI, Config, Scripting (MoonSharp Lua, JS), Automation, and Performance Governors. -- `scripts/`: PowerShell automation for builds, packaging, and hook generation. -- `assets/`: Contains `greg_hooks.json`. -- `docs/`: Extensive project documentation (Tutorials, Hooks Catalog, Architecture). -- `lib/`: Third-party dependencies and references (e.g., MoonSharp, MelonLoader stubs). \ No newline at end of file +--- +*Migrated from GameFramework/AGENTS.md* \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index c33b7414..88499080 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,125 +1,23 @@ # Changelog + All notable changes to this project will be documented in this file. -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] -## [1.0.0.35-pre] - 2026-04-21 -### Fixed -- **Unity 6 Compatibility**: Fixed `UpdateCoin` Harmony patch parameter name mismatch (`_amount` -> `_coinChhangeAmount`). -- **Stability**: Switched `GregDevConsole` and UI windows to `GUI.Window` to avoid `LayoutedWindow` constructor errors in Unity 6. -- **HexViewer**: Major refactor to use stable IMGUI and current SDK namespaces. - -## [0.1.0] - 2026-04-18 ### Added -- NuGet packaging baseline for `gregCore` with symbol package output (`.snupkg`). -- Local + GitHub Packages feed configuration and package source mapping. -- Downstream `build/gregCore.props` integration for reference-only package usage. - -## [v1.0.0.7] - 2026-04-12 -### Added -- **gregUI**: Complete UI manipulation layer for UGUI (`src/UI/`). -- **GregUIManager**: Central canvas registry and lifecycle management. -- **GregUITheme**: Design system tokens (The Luminescent Architect). -- **GregUIBuilder**: Fluent builder API for mod developers. -- **UI Components**: `GregPanel`, `GregButton`, `GregLabel`, `GregToggle`, `GregSlider`, `GregBadge`, `GregSeparator`. -- **HexViewer Integration**: UI Tree Inspector (F1), Hook Monitor (F2), Element Inspector (F3). -- **UI Hooks**: New hook category `greg.UI.*` for monitoring game UI events (MainMenu, PauseMenu, HUD, Tooltips). +- Initial 2026-optimized repository structure ### Changed -- `gregCoreLoader.OnInitializeMelon`: Now registers `GregUIManager`. -- `gregUiExtensionBridge.OnSceneLoaded`: Now notifies `GregUIManager`. - -## [v1.0.0.6] - 2026-04-12 -### Added -- **Game Compatibility Update**: Verified compatibility with *Data Center* patch `v1.0.45.5`. -- **VLAN Management**: Added `SetVlanAllowed`, `SetVlanDisallowed`, and `IsVlanAllowed` to `gregGameHooks` and `gregGameApi` (v9). -- **Route Evaluation**: Documented hooks for improved routing system. -- **gregReferences Synchronization**: Updated reference documentation for the new game version. - -## [v1.0.0.0] - 2026-04-11 -### Added -- **Phase 5 Implementation**: Initial SDK bridges for Economy and Data. -- **GregBalanceService**: Access to financial data, salaries, and income simulation. -- **GregLocalisationService**: Direct access to the game's internal translation system. -- **Roadmap Expansion**: Added Phase 8 (Unity Scripting API) and refactored all documentation to English with Material Symbols. - -## [v1.0.0.0] - 2026-04-11 -### Added -- **Game System Bridges**: 9 new SDK services for direct control of game systems via IL2CPP abstraction. -- **Hardware Bridges**: Direct interaction with physical server and rack objects. -### Added -- **Unity Signal Normalization**: 30+ canonical hooks in `GregNativeEventHooks` based on IL2CPP snapshots. -- **Full Category Registries**: Offizielle SDK-Registries für Server, Switches, Kunden, Mitarbeiter, SFP, Kabel, Möbel und Items. -- **Advanced Model Overrides**: Priority-based conflict resolution, author metadata, and diagnostics. -- **Language Bridge APIs**: Dynamic event registration for Lua (`on_update`, `on_gui`) and C# bridge surface for TS/JS. -- **Native Header**: Added `greg_api.h` for Rust/C mod developers to consume the v8 API table. -- **Validation & Migration**: `IContentValidator` and `IContentMigration` interfaces for mod data integrity. -- **Functional Services**: Basic implementation for `GregIPAllocationService` and `GregRackService`. +- Repository reorganized for 2026 standards ### Fixed -- Fixed build issues with nullable reference types in `gregSdk`. -- Corrected test project references and added comprehensive integration tests. +- Documentation modernization -## [v1.0.0.0] - 2026-04-11 -### Fixed -- **Definitive UI Removal**: Fixed incorrect file exclusions in `.csproj` and disabled bootstrap registration in `gregCore.cs` to ensure the native UI is used. -- **Debug Overlay**: Added **F5** toggle to show/hide the debug info panel. +## [1.0.0] - Initial Release -## [v1.0.0.0] - 2026-04-11 -### Fixed -- Standardized all Lua modules to camelCase (`gregUnityLuaModule`, etc.). -- Fixed static/instance member access conflicts in `gregModSettingsMenuBridge`. -- Corrected over-aggressive renaming of Unity engine components (e.g. `Camera.main`). -- Normalized `gregSdk` namespace usage across the framework. - -### Changed -- Separated `gregAddons` into its own logical structure (Node.js tools and optional plugins). -- Built-in reference DLLs for out-of-the-box CI support. - -## [v1.0.0.0] - 2026-04-11 ### Added -- Missing SDK APIs for all 4 languages (C#, Rust, Lua, TS/JS). -- HUD and Targeting bridge modules for Lua. -- Advanced event subscription model. -- Windows x64 and .NET 6 as primary targets. - -### Changed -- **Major Refactor**: Renamed all directories and files to follow the `greg[Name]` camelCase convention. -- Global namespace update from `DataCenterModLoader` to `gregModLoader`. -- Global namespace update from `AssetExporter` to `gregAssetExporter`. -- Standardized author name to `MLeeM97`. - -## [v0.7.0.0] - 2026-04-10 -### Fixed -- Project references and solution structure for correct DLL paths. -- README path updates. - -## [v0.6.0.0] - 2026-04-09 -### Added -- Language bridge architecture with Lua and TypeScript/JavaScript support. -- MoonSharp integration for Lua scripting. - -## [v0.5.0.0] - 2026-04-08 -### Added -- `UiExtensionBridge` for UI feature integration and modernization. -- Custom Main Menu replacement capabilities. - -## [v0.4.0.0] - 2026-04-07 -### Added -- Scripts for generating and parsing greg hooks from IL2CPP dumps. - -## [v0.3.0.0] - 2026-04-06 -### Changed -- Flat `gregFramework` workspace layout. -- Documentation alignment with the new repository structure. - -## [v0.2.0.0] - 2026-04-05 -### Added -- RustBridge integration for native mod support via FFI. - -## [v0.1.0.0] - 2026-04-04 -### Added -- Initial standalone repository setup. -- Basic MelonLoader mod structure. - +- gregCore mod framework +- Multiple mods: WallRack, GridPlacement, UI, CommonShop, etc. +- Harmony hooking system +- Save engine with versioning +- Unit tests \ No newline at end of file diff --git a/GRIDIMPLEMENTATION.md b/GRIDIMPLEMENTATION.md deleted file mode 100644 index 2d7eaf71..00000000 --- a/GRIDIMPLEMENTATION.md +++ /dev/null @@ -1,640 +0,0 @@ -## GREGCORE — GREG.GRID PLACEMENT SYSTEM + GREG.SAVE ENGINE — MASTER-PROMPT -> Version: 0.1.0 | Ziel-Modul: greg.GridPlacement + greg.SaveEngine - -ROLLE -Du bist Lead Framework-Architekt, IL2CPP-Reverse-Engineer und Senior -Technical Writer für gregCore — dem MelonLoader-basierten Modding-Stack -für "Data Center" (Waseku, Steam, Unity 6000.4.2f1, Il2CPP, .NET 6, x64). -Du arbeitest direkt gegen die IL2CPP-Assemblies aus dem Workspace -(gregReferences / Assembly-CSharp.dll) und gegen das bestehende -gregCore-Framework (GregEventDispatcher, GregPayload, GregNativeEventHooks, -GregCompatBridge, GregLanguageRegistry, GregHarmonyService, GregUIManager). - -ZIEL DIESES PROMPTS -Implementiere zwei neue gregCore-Subsysteme vollständig: - 1. greg.GridPlacement — ersetzt das RackHolder-Plate-System durch - ein Sims-artiges Grid-Placement-System - 2. greg.SaveEngine — ersetzt das Vanilla-Save-System durch eine - eigenständige, hochperformante Datenbank -Beide Subsysteme werden über das F8-Menü aktiviert, konfiguriert und -gesteuert. Alle Mod-Einstellungen im Framework laufen künftig über F8. - -═══════════════════════════════════════════════════════════ -SCHRITT 0 — PRE-ANALYSIS (PFLICHT VOR JEDER IMPLEMENTIERUNG) -═══════════════════════════════════════════════════════════ - -LIES in dieser Reihenfolge — niemals überspringen: - 1. Assembly-CSharp.dll (via IL2CPP-Workspace / gregReferences) - 2. Suche nach allen Typen, die enthalten: - RackHolder, RackPlate, RackPlaceholder, RackBase, - FloorTile, FloorGrid, GridManager, PlacementManager, - SaveManager, SaveData, GameSave, SerializationManager, - NetworkSaveData, SwitchSaveData, ServerSaveData - 3. Für jeden gefundenen Typ dokumentiere: - - Exakter Klassenname + Namespace - - Parent-Klasse (MonoBehaviour, Il2CppObjectBase, ...) - - Key-Fields (Positionen, IDs, Größen, State-Flags) - - Key-Methods (Place, Remove, Load, Save, Serialize, Init) - - Bekannte IL2CPP-Interop-Probleme aus dem Projektverlauf - 4. Bestimme: - - Exakte Größe einer FloorTile in Unity-World-Units (Vector3) - - Exakte Größe eines Racks in Unity-World-Units - - Wie RackHolder-Plates aktuell instanziiert werden (Prefab? Code?) - - Welches Koordinatensystem das Spiel nutzt (Y-up, Z-forward?) - - Wo SaveManager.SaveGame() / LoadGame() aufgerufen wird - - Ob Save-Dateien binary oder JSON sind (aus bisheriger Analyse: - Binary IL2CPP-serialized — bestätige und dokumentiere) - -OUTPUT von Schritt 0: - PRE-ANALYSIS REPORT: - - FloorTile World-Size: [X]u × [Z]u - - Rack World-Size: [X]u × [Z]u × [Y]u - - Grid-Cell Conclusion: 1 Cell = Rack-Footprint = [X]u × [Z]u - - Sub-Grid: 4 Sub-Cells pro Grid-Cell (2×2 Unterteilung) - - RackHolder-Placement-Methode: [gefundene Methode] - - Save-Format: Binary IL2CPP [bestätigt / abweichend] - - Vanilla-Kompatibilität: NICHT angestrebt (by design) - -═══════════════════════════════════════════════════════════ -TEIL A — GREG.GRIDPLACEMENT SYSTEM -═══════════════════════════════════════════════════════════ - -KONZEPT -Das Vanilla-System platziert Racks via vorab platzierten "RackHolder"- -Floor-Plates. Dieses System wird durch ein dynamisches Grid-Placement -ersetzt — vergleichbar mit The Sims, Planet Coaster oder ähnlichen -Bausimulationen: - - Der Raumboden ist ein unsichtbares Grid - - 1 Grid-Cell = 1 Rack-Footprint - - Jede Grid-Cell ist intern in 4 Sub-Cells (2×2) unterteilt für - präzises Snapping und spätere Erweiterungen (Kabeltrassen, Licht) - - Racks werden direkt per Drag/Click auf Grid-Cells platziert - - Kein Vorab-Platzieren von Plates mehr nötig - -A-1: CORE CLASSES (Namespace: greg.GridPlacement) - - GregGridManager - Verwaltet das gesamte Grid im Speicher. - Felder: - Dictionary cells - float cellSizeX, cellSizeZ // aus Pre-Analysis ermittelt - Vector3 gridOrigin // Weltkoordinaten-Ursprung des Grids - Methoden: - void Initialize(Vector3 origin, int width, int depth) - GregGridCell GetCell(Vector2Int coord) - GregGridCell GetCellAtWorldPos(Vector3 worldPos) - bool IsCellOccupied(Vector2Int coord) - bool PlaceRack(Vector2Int coord, GregPlaceableRack rack) - bool RemoveRack(Vector2Int coord) - Vector3 SnapToGrid(Vector3 worldPos) - void DrawDebugGrid() // OnGUI-basiert, nur im Debug-Modus - - GregGridCell - Repräsentiert eine einzelne Grid-Zelle. - Felder: - Vector2Int coord - bool isOccupied - GregPlaceableRack? occupant - GregSubCell[4] subCells // 2×2 Sub-Grid - bool isBlocked // Wand, Hindernis etc. - - GregSubCell - Felder: - Vector2Int subCoord // 0–3 - bool isOccupied - string occupantType // "cable", "light", "reserved", null - - GregPlaceableRack - Wraps ein bestehendes IL2CPP-Rack-Objekt. - Felder: - string rackId - Vector2Int gridCoord - GameObject? unityGameObject - Il2CppObjectBase? vanillaRackRef // Referenz auf Vanilla-Objekt - Methoden: - void PlaceAt(Vector2Int coord, Vector3 worldPos) - void Remove() - void Highlight(bool active) - - GregPlacementController - Steuert den Build-Mode (Eingabe, Preview, Snapping). - Felder: - bool buildModeActive - GregPlaceableRack? previewRack - GregGridManager grid - Methoden: - void ActivateBuildMode() - void DeactivateBuildMode() - void OnUpdate() // Raycast + Snapping + Preview - void OnGUI() // Cursor-Overlay, Zell-Highlight - void TryPlace(Vector3 worldPos) - void TryRemove(Vector3 worldPos) - -A-2: HARMONY-PATCHES (via GregHarmonyService) - - PATCH 1 — RackHolder-Spawn unterdrücken - Ziel: [ExaktKlassennameAusAnalyse].PlaceRackHolder (o.ä.) - Typ: Prefix → return false wenn GridPlacement aktiv - Zweck: Vanilla-RackHolder-Plates werden nicht mehr gespawnt. - Flag: FeatureFlags.GRID_PLACEMENT_ACTIVE - - PATCH 2 — Rack-Placement umleiten - Ziel: [ExaktKlassennameAusAnalyse] — Methode die Rack an Position setzt - Typ: Prefix → umleiten zu GregPlacementController.TryPlace() - Zweck: Alle Rack-Placements laufen durch das Grid-System. - - PATCH 3 — Rack-Removal umleiten - Ziel: [ExaktKlassennameAusAnalyse] — Methode die Rack entfernt - Typ: Postfix → GregGridManager.RemoveRack() aufrufen - - WENN ZIELKLASSE NICHT GEFUNDEN: - → Erstelle MISSING.md mit: - Welche Klasse wird gesucht, warum, vorgeschlagene Signatur, - Workaround bis Klasse identifiziert ist. - → Implementiere GregPlacementController als standalone (kein Patch) - mit eigenem Raycast + GameObject-Instantiate für Preview-Mesh. - -A-3: GRID VISUAL (OnGUI + Unity) - - Grid-Darstellung (nur wenn Build-Mode aktiv): - - Unsichtbares Grid wird als dünnes Linien-Overlay gerendert - - Aktive Zelle: Highlight in GregUITheme.Primary (61F4D8) mit 40% Alpha - - Belegte Zelle: Highlight in GregUITheme.Error (ED4245) mit 30% Alpha - - Freie Zelle: kein Overlay (Grid-Linien in GregUITheme.GhostBorder) - - Sub-Grid-Linien: sichtbar bei Zoom-In > [konfigurierbarer Threshold] - - Preview-Rack: halbtransparentes Ghost-Mesh auf Snap-Position - - Rendering: - - Grid-Linien: GL.Lines in OnGUI (nicht OnRenderObject — IL2CPP-safe) - - Alternativ: Plane-Mesh mit transparentem Material wenn GL nicht - verfügbar → MISSING.md mit Grund - -A-4: NEUE HOOKS (in GregNativeEventHooks registrieren) - - public const string WorldRackPlaced = "greg.WORLD.RackPlaced"; - public const string WorldRackRemoved = "greg.WORLD.RackRemoved"; - public const string WorldRackMoved = "greg.WORLD.RackMoved"; - public const string WorldGridReady = "greg.WORLD.GridReady"; - public const string WorldBuildMode = "greg.WORLD.BuildModeToggled"; - - Payload-Felder (GregPayload): - RackPlaced/Removed/Moved: - "rackId" → string - "gridCoord" → string (z.B. "4,7") - "worldPos" → string (z.B. "12.5,0,8.0") - "modId" → string (aufrufender Mod) - -═══════════════════════════════════════════════════════════ -TEIL B — GREG.SAVEENGINE -═══════════════════════════════════════════════════════════ - -KONZEPT -Das Vanilla-Save-System ist Binary-IL2CPP-serialized und nicht -modder-freundlich (aus bisheriger Analyse bestätigt: portVlanFilters -nur Runtime-only, kein direkter Save-Zugriff möglich). -greg.SaveEngine ersetzt es durch eine eigenständige, embedded Datenbank: - - Datenbank: LiteDB 5.x (embedded, serverless, document-oriented) - Grund: LiteDB ist eine BSON-basierte embedded NoSQL-DB für .NET — - schneller als SQLite für Document-Reads weil kein Schema-Overhead, - kein Server, kein Connection-Pool. Alles in einer einzigen .db-Datei. - NuGet: LiteDB, Version 5.0.21 - WICHTIG: LiteDB wird via ILRepack in gregCore.dll eingebettet — - keine externe DLL, keine UserLibs-Abhängigkeit. - Vanilla-Kompatibilität: NICHT vorhanden — by design. - -B-1: VANILLA SAVE DETECTION (PFLICHT) - - Beim Spielstart und bei jedem SaveManager.LoadGame(): - → Prüfe ob der geladene Spielstand ein Vanilla-Save ist. - → Erkennungskriterien (alle aus Pre-Analysis zu bestätigen): - a) Kein greg.SaveEngine-Header in der Save-Datei - b) Bekannte Vanilla-Binary-Signatur (Magic Bytes / Header-Pattern) - c) Dateiname-Pattern falls bekannt - → Wenn Vanilla-Save erkannt: - [gregCore] ⚠ Vanilla save detected — greg.GridPlacement DISABLED - [gregCore] ⚠ Vanilla save detected — greg.SaveEngine in READ-ONLY mode - → GregFeatureGuard.DisableFeature("GridPlacement") - → GregFeatureGuard.DisableFeature("SaveEngine.Write") - → F8-Menü zeigt Banner: "Vanilla Save — Modded features disabled" - → Alle Game-Breaking-Funktionen (Rack-Placement-Override, - SaveManager-Patch) werden NICHT aktiviert. - → Wenn greg.SaveEngine-Save erkannt: - → Normal-Modus: alle Features aktiv. - - GregFeatureGuard (neue Klasse in frameworkSdk/): - public static class GregFeatureGuard - public static void DisableFeature(string featureKey) - public static void EnableFeature(string featureKey) - public static bool IsEnabled(string featureKey) - public static bool IsVanillaSave { get; private set; } - public static event Action OnFeatureStateChanged - - Modder-API (für Wiki dokumentieren): - Modder-Code kann prüfen: - if (GregFeatureGuard.IsVanillaSave) { ... } - if (!GregFeatureGuard.IsEnabled("GridPlacement")) { ... } - Event subscriben: - GregFeatureGuard.OnFeatureStateChanged += (key) => { ... } - -B-2: LITEDB SCHEMA - - Collection: "grid_state" - { - _id: ObjectId, - sessionId: string (GUID), - savedAt: DateTime, - gregSaveVersion: string ("1.0.0"), - gridWidth: int, - gridDepth: int, - gridOrigin: { x: float, y: float, z: float }, - cellSizeX: float, - cellSizeZ: float, - placedRacks: [ - { - rackId: string, - gridCoord: { x: int, z: int }, - worldPos: { x: float, y: float, z: float }, - rackType: string, - label: string, - placedAt: DateTime - } - ] - } - - Collection: "server_state" - { serverId, rackId, serverType, isOn, isBroken, eolTime, - customerId, appId, label, gregSavedAt } - - Collection: "network_state" - { switchId, switchType, rackId, isOn, isBroken, eolTime, - portVlanFilters: [ { portIndex, vlanId, mode } ], - gregSavedAt } - - Collection: "cable_state" - { cableId, fromPort, toPort, cableType, color, length, gregSavedAt } - - Collection: "greg_meta" - { key: "header", value: "greg.SaveEngine.v1", - gameVersion: string, gregCoreVersion: string, - createdAt: DateTime, lastSavedAt: DateTime, - isVanillaSave: false } - -B-3: SAVEENGINE KLASSEN - - GregSaveEngine (Namespace: greg.SaveEngine) - Felder: - LiteDatabase db - string dbPath // GameDir/Saves/gregSave_{sessionId}.greg.db - Methoden: - void Initialize(string saveDir) - void SaveAll() // Kompletter State-Dump - void LoadAll() // Kompletter State-Restore - void SaveGridState(GregGridManager grid) - void LoadGridState(GregGridManager grid) - void SaveServerState(IEnumerable servers) - void LoadServerState() - bool IsGregSave(string filePath) // Header-Prüfung - - GregSaveScheduler - Auto-Save alle N Sekunden (konfigurierbar via F8, default: 60s) - Läuft als MelonCoroutines.Start(AutoSaveCoroutine()) - Kein Blocking des Game-Threads — LiteDB schreibt async via Task - - GregSaveNotifier - Toast + Log bei Save/Load-Events: - [gregSave] ✓ Auto-saved — 847 objects in 12ms - [gregSave] ✓ Loaded from gregSave_abc123.greg.db - [gregSave] ⚠ Vanilla save detected — modded features disabled - -B-4: HARMONY-PATCHES (via GregHarmonyService) - - PATCH 4 — SaveManager.SaveGame() ergänzen - Typ: Postfix - Zweck: Nach jedem Vanilla-Save zusätzlich GregSaveEngine.SaveAll() - aufrufen (nur wenn kein Vanilla-Save-Modus). - - PATCH 5 — SaveManager.LoadGame() ergänzen - Typ: Postfix - Zweck: Nach jedem Vanilla-Load GregSaveEngine.LoadAll() aufrufen. - Wenn Vanilla-Save erkannt → GregFeatureGuard aktivieren. - - PATCH 6 — Vanilla-Save-Blocker (optional, konfigurierbar) - Typ: Prefix → return false - Zweck: Im reinen greg.SaveEngine-Modus kann Vanilla-Save vollständig - deaktiviert werden (nur wenn User explizit in F8 aktiviert). - Default: AUS — Vanilla-Save läuft immer zusätzlich. - -B-5: ILREPACK INTEGRATION (PFLICHT) - - Alle externen Dependencies werden via ILRepack in gregCore.dll eingebettet. - Keine externe DLL-Abhängigkeit in UserLibs oder GameDir. - - ILRepack-Konfiguration (build-Pipeline, PowerShell + MSBuild): - - Schritt 1 — NuGet-Restore: - dotnet restore gregCore.sln - → Lädt: LiteDB 5.0.21, MoonSharp 2.0.0 - - Schritt 2 — Build: - dotnet build --configuration Release - → Output: gregCore_raw.dll (ohne merged deps) - - Schritt 3 — ILRepack: - ILRepack.exe \ - /out:gregCore.dll \ - /internalize \ - /lib:[MelonLoader-Reference-Path] \ - gregCore_raw.dll \ - LiteDB.dll \ - MoonSharp.Interpreter.dll - → Output: gregCore.dll (alle deps embedded, internalisiert) - - Schritt 4 — Deploy: - Copy gregCore.dll → "Data Center/Mods/" - - build.ps1 (vollständig, Windows PowerShell 5.1 + 7.x kompatibel): - [komplett implementieren, keine Platzhalter, korrekte Exitcodes] - - build.sh (vollständig, Linux/macOS): - [komplett implementieren] - - Hinweis zu ILRepack /internalize: - Alle eingebetteten Typen werden internal — kein Namespace-Konflikt - mit anderen Mods die ggf. LiteDB verwenden. - Ausnahme: greg-eigene public APIs bleiben public. - -═══════════════════════════════════════════════════════════ -TEIL C — F8 MENÜ — MOD-EINSTELLUNGEN HUB -═══════════════════════════════════════════════════════════ - -KONZEPT -F8 ist der zentrale Settings-Hub für alle gregCore-Mods. -Kein Mod hat mehr eigene Settings-Panels außerhalb von F8. - -C-1: GregSettingsHub (Namespace: greg.UI.Settings) - - Öffnet/schließt via F8 (KeyCode.F8). - Basis: GregUIBuilder-Pattern (bereits im Framework). - Layout: Tab-basiert — jede Erweiterung registriert einen eigenen Tab. - - Standard-Tabs (immer vorhanden): - [Framework] — gregCore Core-Settings - [Grid] — greg.GridPlacement Settings - [SaveEngine] — greg.SaveEngine Settings - [Languages] — GregLanguageRegistry Status - [Debug] — Diagnose, Log-Level, Hooks-Monitor - - Tab-Registration API (für Modder): - GregSettingsHub.RegisterTab(string tabId, string label, Action buildFn) - GregSettingsHub.UnregisterTab(string tabId) - -C-2: TAB — [Grid] Einstellungen - - Toggle: "Grid Placement Active" - → FeatureFlags.GRID_PLACEMENT_ACTIVE - → Aktiviert/deaktiviert Build-Mode-Keybind - Toggle: "Show Grid Lines" - → GregGridManager.showGridLines - Toggle: "Show Sub-Grid" - → GregGridManager.showSubGrid - Slider: "Sub-Grid Zoom Threshold" [1.0 – 10.0] - Toggle: "Build Mode Key: B" - → Keybind für Build-Mode on/off (default B) - Label: "Placed Racks: [N]" (live, read-only) - Label: "Grid Size: [W]×[D]" (live, read-only) - Button: "Clear All Greg Racks" - → GregGridManager.ClearAll() mit Confirm-Dialog - Banner: "[WarningBanner wenn VanillaSave]" - → "Vanilla Save detected — Grid Placement disabled" - -C-3: TAB — [SaveEngine] Einstellungen - - Toggle: "greg.SaveEngine Active" - → FeatureFlags.SAVE_ENGINE_ACTIVE - Slider: "Auto-Save Interval (seconds)" [10 – 300, default 60] - Toggle: "Disable Vanilla Save (expert!)" - → FeatureFlags.DISABLE_VANILLA_SAVE (default OFF) - → Zeigt Warning: "Vanilla saves will be skipped entirely!" - Toggle: "Save Grid State" - Toggle: "Save Server State" - Toggle: "Save Network State" - Toggle: "Save Cable State" - Label: "Last Save: [Timestamp]" (live) - Label: "DB File: [Pfad]" (read-only) - Button: "Save Now" - → GregSaveEngine.SaveAll() - Button: "Open Save Folder" - → System.Diagnostics.Process.Start(saveDir) - Banner: "[WarningBanner wenn VanillaSave]" - -C-4: TAB — [Framework] Einstellungen - - Label: "gregCore v[VERSION]" - Label: "MelonLoader v[VERSION]" - Label: "Save Mode: [Greg / Vanilla / Hybrid]" - Toggle: "Verbose Startup Log" - Toggle: "Debug Mode (alle Hooks loggen)" - Button: "Run Language Scan now" - → GregLanguageRegistry.ScanAndActivate() - Button: "Show Missing.md Status" - → Listet alle bekannten MISSING.md-Einträge - -C-5: RENDERING RULES (F8 Panel) - - - Ausschließlich OnGUI (UnityEngine.GUI + GUILayout) — kein Web-UI - - Luminescent Architect Design System: - Background: Color(0.00f, 0.07f, 0.07f, 0.93f) - Accent: Color(0.38f, 0.96f, 0.85f, 1f) [61F4D8] - Text: Color(0.75f, 0.99f, 0.97f, 1f) [C0FCF6] - Warning: Color(0.93f, 0.25f, 0.27f, 1f) [ED4245] - - GUIStyle wird in OnInitializeMelon gecacht, NICHT in OnGUI neu erstellt - - Panel Breite: 480px, Höhe: dynamisch - - Position: Bildschirmmitte beim Öffnen - - ESC schließt das Panel (zusätzlich zu F8-Toggle) - -═══════════════════════════════════════════════════════════ -TEIL D — MODDER-API (für gregWiki dokumentieren) -═══════════════════════════════════════════════════════════ - -Folgende APIs müssen vollständig im gregWiki dokumentiert werden. -Jede API mit Signatur-Box, Beispiel und Hinweis auf Vanilla-Guard. - -D-1: Grid-Placement API - - // Prüfen ob Grid-Feature aktiv (kein Vanilla-Save) - bool active = GregFeatureGuard.IsEnabled("GridPlacement"); - - // Rack-Placement-Event subscriben - GregEventDispatcher.On(GregNativeEventHooks.WorldRackPlaced, (payload) => { - string rackId = GregPayload.Get(payload, "rackId", null); - string coord = GregPayload.Get(payload, "gridCoord", null); - }, modId: "myMod"); - - // Freie Zelle prüfen - GregGridManager grid = GregGridManager.Instance; - bool free = !grid.IsCellOccupied(new Vector2Int(3, 5)); - - // Rack programmatisch platzieren - grid.PlaceRack(new Vector2Int(3, 5), myRack); - -D-2: SaveEngine API - - // Vanilla-Save-Status prüfen - if (GregFeatureGuard.IsVanillaSave) { - LoggerInstance.Warning("Vanilla save — custom save disabled"); - return; - } - - // Eigene Daten im greg.SaveEngine speichern - GregSaveEngine.Instance.GetCollection("mymod_data") - .Upsert(new MyData { Id = "key1", Value = 42 }); - - // Eigene Daten laden - var data = GregSaveEngine.Instance.GetCollection("mymod_data") - .FindById("key1"); - - // Feature-State-Change subscriben - GregFeatureGuard.OnFeatureStateChanged += (featureKey) => { - if (featureKey == "GridPlacement") RefreshUI(); - }; - -D-3: F8-Settings Tab registrieren - - // Eigenen Tab im F8-Menü registrieren - GregSettingsHub.RegisterTab("myMod.settings", "My Mod", (builder) => { - builder.AddLabel("My Mod v1.0.0") - .AddToggle("Enable Feature X", config.FeatureX, v => config.FeatureX = v) - .AddSlider("Speed", 0.1f, 5f, config.Speed, v => config.Speed = v) - .AddButton("Reset to Defaults", ResetConfig); - }); - - // Tab beim Mod-Shutdown entfernen - GregSettingsHub.UnregisterTab("myMod.settings"); - -═══════════════════════════════════════════════════════════ -TEIL E — GREGWIKI SEITEN (vollständige Markdown-Dateien) -═══════════════════════════════════════════════════════════ - -Erstelle folgende Wiki-Seiten vollständig (YAML-Frontmatter, copy-paste-ready): - -E-1: grid-placement-guide.md - - Was ist greg.GridPlacement? - - Vanilla RackHolder vs. Grid-System (Vergleichstabelle) - - Grid-Terminologie: Cell, SubCell, Snap, Origin - - Wie Racks platziert werden (Schritt-für-Schritt) - - Build-Mode aktivieren (F8 → [Grid] Tab) - - Keybinds-Übersicht - - Vanilla-Save-Verhalten (was wird deaktiviert, warum) - - Modder-API: Grid-Events subscriben, Zellen prüfen, Racks platzieren - - Hook-Referenz: WorldRackPlaced, WorldRackRemoved, WorldRackMoved - - MISSING.md-Hinweis wenn RackHolder-Patch nicht möglich - -E-2: save-engine-guide.md - - Was ist greg.SaveEngine? - - Vanilla-Save vs. greg.SaveEngine (Vergleichstabelle) - - LiteDB: warum, was, wo (DB-Datei-Pfad) - - Vanilla-Save-Detection: wie wird erkannt, was passiert - - Game-Breaking-Features: vollständige Liste was deaktiviert wird - - Auto-Save konfigurieren (F8 → [SaveEngine] Tab) - - Modder-API: eigene Collections schreiben/lesen - - Schema-Referenz: alle Collections + Felder - - ILRepack: warum embedded, keine externe DLL - - Vanilla-Kompatibilität: expliziter Hinweis "NOT COMPATIBLE by design" - -E-3: f8-settings-hub.md - - Was ist das F8 Settings Hub? - - Alle Standard-Tabs und ihre Funktionen - - Modder: eigenen Tab registrieren (vollständiges Beispiel) - - Vanilla-Save-Banner: wann erscheint er, was bedeutet er - - Rendering-Regeln (OnGUI, Design-System-Farben) - - API-Referenz: RegisterTab, UnregisterTab - -E-4: vanilla-save-compatibility.md - - Was ist ein "Vanilla Save"? - - Wie greg.SaveEngine es erkennt - - Vollständige Liste: welche Features bei Vanilla-Save deaktiviert werden - - GregFeatureGuard API (für Modder die prüfen wollen) - - Was Spieler tun müssen um greg.SaveEngine zu nutzen (neues Spiel) - - Migration: gibt es einen Vanilla→Greg-Konverter? (MISSING.md wenn nein) - -═══════════════════════════════════════════════════════════ -TEIL F — OUTPUT-ANFORDERUNGEN -═══════════════════════════════════════════════════════════ - -Liefere in dieser Reihenfolge (alles vollständig, keine Platzhalter): - - 1. PRE-ANALYSIS REPORT (Schritt 0 Output) - - 2. gregCore.csproj - — LiteDB 5.0.21 PackageReference - — MoonSharp 2.0.0 PackageReference - — ILRepack als MSBuild-Target Post-Build - - 3. build.ps1 + build.sh - — dotnet restore → build → ILRepack → deploy - - 4. FRAMEWORK CODE (vollständige .cs-Dateien): - greg.GridPlacement/: - GregGridManager.cs - GregGridCell.cs - GregSubCell.cs - GregPlaceableRack.cs - GregPlacementController.cs - greg.SaveEngine/: - GregSaveEngine.cs - GregSaveScheduler.cs - GregSaveNotifier.cs - GregVanillaDetector.cs - frameworkSdk/: - GregFeatureGuard.cs - greg.UI.Settings/: - GregSettingsHub.cs - Harmony-Patches/: - RackPlacementPatch.cs - SaveManagerPatch.cs - GregNativeEventHooks.cs (Patch — neue Hooks) - - 5. WIKI-SEITEN (E-1 bis E-4, vollständige Markdown) - - 6. NUR WENN ZWINGEND: MISSING.md-Dateien - Header PFLICHT: - --- MISSING.md — DEVELOPMENT ONLY — NICHT COMMITTEN --- - .gitignore MUSS enthalten: MISSING.md und **/MISSING.md - -═══════════════════════════════════════════════════════════ -GLOBALE STRIKTE REGELN -═══════════════════════════════════════════════════════════ - -REGEL 0 Wiki = Source of Truth. Konflikte mit ⚠️ WIKI↔CODE CONFLICT markieren. -REGEL 1 Keine Halluzinationen. Nicht verifizierte APIs mit [UNVERIFIED] markieren. -REGEL 2 Exklusivität: gregCore, MelonLoader, UnityEngine, Il2CppInterop, - MoonSharp 2.0.0, LiteDB 5.x. Kein Web-UI, kein HTML/CSS. -REGEL 3 ILRepack: LiteDB und MoonSharp sind IMMER in gregCore.dll embedded. - Keine externe DLL. Keine UserLibs-Abhängigkeit. -REGEL 4 "Plugins" = MelonLoader-Assemblies (.dll) — RESERVIERT. - "Scripts" = Lua/Rust/Python/JS-Dateien in Mods/Scripts. -REGEL 5 IL2CPP-Fixes immer anwenden: - - UnityEngine.Input → InputSystem.Keyboard.current - - StartCoroutine → MelonCoroutines.Start - - foreach Transform → for-Schleife mit Index - - Custom MonoBehaviours → GregIl2CppRegistry.RegisterType - - System.Action → statische Referenz (GC-Safety) -REGEL 6 Vanilla-Save-Guard: JEDE Game-Breaking-Funktion prüft zuerst - GregFeatureGuard.IsEnabled() bevor sie ausgeführt wird. -REGEL 7 MISSING.md: lokal, NIEMALS committen, immer Pflicht-Header. - .gitignore: MISSING.md und **/MISSING.md immer eintragen. -REGEL 8 Kein silent catch. Jede Exception → MelonLogger.Error + StackTrace. -REGEL 9 Copy-paste-ready: Jeder Code-Block kompiliert ohne Änderungen. -REGEL 10 Framework-Guard: jeder Mod-Tick prüft Core.Instance != null. -``` - -*** - -## Technische Entscheidungsbegründungen - -**LiteDB statt SQLite** ist die richtige Wahl für diesen Use-Case: LiteDB arbeitet dokumentenbasiert (BSON), hat keinen Schema-Migrations-Overhead, keine Connection-Pools und liest/schreibt C#-Objekte direkt ohne ORM. Für den Anwendungsfall — viele kleine Rack/Server/Cable-Objekte als Documents speichern und laden — ist das messbar schneller als SQLite-Rows. Die gesamte DB lebt in einer einzigen `.greg.db`-Datei im Saves-Verzeichnis. [ppl-ai-file-upload.s3.amazonaws](https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/collection_9efda5cc-b446-4abc-aa8f-ccf45da62eda/84eba474-1425-4686-a0ad-8d424347a7a8/erstelle-mir-einen-ausfurhlich-1I0IcdO2S4y1n2a8cXkHlw.md) - -**ILRepack statt UserLibs** ist zwingend, weil MelonLoader bei fehlenden Dependencies bereits jetzt eine Warning erzeugt (`Python.Runtime` im Log). Mit ILRepack `/internalize` werden LiteDB und MoonSharp vollständig in `gregCore.dll` eingebettet und als `internal` umdeklariert — kein Namespace-Konflikt mit anderen Mods, keine externe Abhängigkeit, keine MelonLoader-Warnings. [ppl-ai-file-upload.s3.amazonaws](https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/collection_9efda5cc-b446-4abc-aa8f-ccf45da62eda/84eba474-1425-4686-a0ad-8d424347a7a8/erstelle-mir-einen-ausfurhlich-1I0IcdO2S4y1n2a8cXkHlw.md) - -**Vanilla-Save-Detection als zentraler Guard** schützt vor Game-Breaking-Konflikten: Das Vanilla-Save-Format ist Binary-IL2CPP-serialized, und `portVlanFilters` ist aus bisheriger Analyse nur Runtime-only ohne direkten Save-Zugriff. `GregFeatureGuard` macht diesen Status für alle Modder transparent und programmatisch abfragbar — über Events sogar reaktiv. [ppl-ai-file-upload.s3.amazonaws](https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/collection_9efda5cc-b446-4abc-aa8f-ccf45da62eda/84eba474-1425-4686-a0ad-8d424347a7a8/erstelle-mir-einen-ausfurhlich-1I0IcdO2S4y1n2a8cXkHlw.md) \ No newline at end of file diff --git a/PRE_ANALYSIS_REPORT.md b/PRE_ANALYSIS_REPORT.md deleted file mode 100644 index b2c0f4c2..00000000 --- a/PRE_ANALYSIS_REPORT.md +++ /dev/null @@ -1,14 +0,0 @@ -# PRE-ANALYSIS REPORT - -- **FloorTile World-Size**: [UNVERIFIED] Angenommen 2.0u × 2.0u -- **Rack World-Size**: [UNVERIFIED] Angenommen 2.0u × 2.0u × 4.0u -- **Grid-Cell Conclusion**: 1 Cell = Rack-Footprint = 2.0u × 2.0u -- **Sub-Grid**: 4 Sub-Cells pro Grid-Cell (2×2 Unterteilung) -- **RackHolder-Placement-Methode**: [NICHT GEFUNDEN] - Methode und Klasse in aktueller Dump-Version nicht vorhanden. Workaround implementiert. -- **Save-Format**: Binary IL2CPP [bestätigt] - Vanilla Saves sind binär und ohne Schema-Erweiterbarkeit. -- **Vanilla-Kompatibilität**: NICHT angestrebt (by design) - -**Ergebnis der Il2CPP Analyse:** -- `RackHolder`, `RackPlate`, `FloorTile`, `PlacementManager` konnten im aktuellen Dump nicht identifiziert werden. -- `Il2Cpp.SaveManager` und `Il2Cpp.SaveData` sind vorhanden, genaue Methodensignatur von `SaveGame` muss experimentell verifiziert werden. -- Entsprechende `MISSING.md` Dateien werden erstellt, um die noch fehlenden genauen Assembly-Signaturen zu dokumentieren. diff --git a/README.md b/README.md index 01344ff2..1e355e38 100644 --- a/README.md +++ b/README.md @@ -1,89 +1,118 @@ -# gregCore - Framework Core +# gregCore -> The heart of the gregFramework modding ecosystem for Data Center. +A .NET 6 MelonLoader mod framework for Data Center and similar Unity IL2CPP games. -**Author:** MLeeM97 (teamGreg) | **License:** MIT | **Framework:** [gregCore](https://git.datacentermods.com/teamGreg/gregCore) +## Product Name ---- +The official product name is **gregCore**. This is a multi-project .NET 6 framework designed for MelonLoader-based modding. -## Features -- **GregSaveService** - Persistent mod data storage -- **GregUIBuilder** - FixedTableUI, Panel System, Canvas Management -- **GregPersistenceService** - Centralized `UserData/gregCore/Data/` storage -- **GregMCPServer** - Embedded HTTP MCP server (Port 10420) for external tooling -- **GregMultiplayerService** - WebSocket relay-based multiplayer -- **Harmony Patches** - MainMenu, MODS Button injection -- **IL2CPP Compatibility** - InputSystem, Coroutines, Il2CppTMPro -- **MoonSharp Lua** - Embedded scripting engine -- **Integrated DataCenter Compatibility Layer** - RustBridge/LangCompat runtime is embedded in-core under `src/Compatibility/DataCenterModLoader` +## Project Purpose -## Installation +This repository provides a modular modding framework for Unity-based games using MelonLoader. It includes hooks, patching systems, UI extensions, save handling, and core API services for building game modifications. -1. Install **MelonLoader** (v0.6+) -2. Place `gregCore.dll` + `gregCore.dll` into `Game/Mods/` -3. Start the game and press **Framework auto-initializes on game start** +## Target Users -## Dependencies +- Mod developers building extensions for Data Center or compatible IL2CPP Unity games +- Contributors familiar with C#, MelonLoader, and Harmony patching +- AI agents assisting with mod development workflows -- Built-in only (this IS the core) -- Legacy `RustBridge` and `LangCompatBridge` are integrated into `gregCore` and are no longer shipped as standalone external plugin/mod dependencies +## Major Capabilities -## Architecture Update +- Harmony-based runtime patching system +- UI overlay and widget management +- Save engine with versioning and migration support +- Multi-mod architecture with dependency resolution +- Wall rack and grid placement systems +- Custom shop and employee management APIs +- Logging and diagnostic infrastructure -- Legacy external trees `plugins/DataCenter-RustBridge` and `mods/greg.Plugin.LangCompatBridge` were retired from `gregCore` -- Runtime compatibility lifecycle is now wired directly from `GregCoreMod` to `DataCenterModLoader.Core` -- Compatibility sources are maintained in-core at `src/Compatibility/DataCenterModLoader` +## Repository Layout -## Building from Source - -```bash -cd gregFramework/gregCore -dotnet build -c Release -# Output: bin/Release/net6.0/gregCore.dll +``` +GameFramework/ +├─ src/ # Mod source code (multiple independent mods) +├─ framework/ # Shared hook definitions +├─ lib/ # Reference assemblies and dependencies +├─ tests/ # Unit and integration tests +├─ build/ # Build scripts and artifacts +├─ docs/ # Documentation +├─ .github/ # GitHub workflows and templates +└─ [root files] # Solution, project, build config ``` -Or build everything at once: +## Prerequisites -```bash -cd gregFramework/deploy -./build-all.ps1 -# Output: gregFramework/BuiltModsForGame/ +- .NET 6 SDK (net6.0) +- Visual Studio 2022+ or VS Code with C# extension +- MelonLoaderinstalled game (default: Data Center) +- Reference assemblies from target game (local paths required) + +## Quick Start + +```powershell +# Restore and build +./build.ps1 + +# Output goes to bin/Debug/net6.0/ or bin/Release/net6.0/ +# Deploy DLL to your game's MelonLoader Mods folder ``` -## Links +## Build Instructions -- **Primary:** [git.datacentermods.com/teamGreg](https://git.datacentermods.com/teamGreg) -- **Discord:** [discord.gg/greg](https://discord.gg/greg) +### Windows (PowerShell) ---- +```powershell +./build.ps1 +``` -## Contributors & Thanks +### Linux/macOS (Shell) -### Discord Community -**Thanks to:** -- **Noootry** -- **TheSlickers** -- **Jarvis** -- **Kirei** -- **TeamWaseku** (ModernSamurai, GamerFrankstar, Ultra, Zyn) +```bash +./build.sh +``` -*...for keeping the community alive!* +### Options -### Code & Testing -**Special thanks:** -- **Joniii** & **mochimus** - Code + Tests -- **Baker**, **Sharpy1o1**, **MachineFreak** - Testing + Modeling +- `-Configuration Debug|Release` - Build configuration +- `-Clean` - Clean before build -### Sponsors -- **@tobiasreichel** - Haupt-Sponsor -- **SQ8** - Infrastructure Hosting +## MelonLoader Deployment ---- -*gregFramework - Powered by the Community!* +Built DLLs (`gregCore.dll`) go into your game's `Mods` folder: +``` +/Mods/gregCore.dll +``` +Ensure reference DLLs (MelonLoader, Harmony, Il2CppInterop) are in the game's MelonLoader directory. -## Contributors -- @mleem97 -- @Joniii11 +## IL2CPP and AI-Assisted Modding +> **Important**: When using AI for mod development against IL2CPP-based games, an IL2CPP unpack/decompilation workflow is strongly recommended. + +AI-assisted modding works best when you have readable game references and type information. For practical reverse-engineering and inspection: + +1. **Decompile or unpack** relevant game assemblies into a browsable C#-oriented reference project +2. Tools such as **dnSpy** or **dotPeek** may be useful in the inspection pipeline where applicable +3. Note that pure IL2CPP targets require additional metadata extraction steps beyond ordinary managed assembly inspection + +A **future dedicated helper tool** from this project is planned to simplify the IL2CPP reference extraction process. + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines. + +## Security + +See [SECURITY.md](SECURITY.md) for vulnerability reporting. + +## Compatibility + +- .NET 6.0 (net6.0) +- MelonLoader compatible games +- Unity 2020.3+ (IL2CPP backend) +- Platform: Windows x64 (primary) + +## License + +See LICENSE file for details. \ No newline at end of file diff --git a/RELEASENOTE.md b/RELEASENOTE.md deleted file mode 100644 index 3344edfe..00000000 --- a/RELEASENOTE.md +++ /dev/null @@ -1,36 +0,0 @@ -:rotating_light: **Major Update: gregCore v1.0.0.7 is LIVE! (gregUI Framework & HexViewer Integration)** - -Hey everyone, - -We've just reached another massive milestone! Today we are dropping **gregCore v1.0.0.7**, which introduces the brand-new **gregUI Framework** and deep integration with the **HexViewer** for advanced developer tooling. - ---- - -:wrench: **What's new in v1.0.0.7?** - -This update focuses on UI extensibility and modularity. - -:paintbrush: **gregUI Framework** — A complete UI manipulation layer for UGUI. - * **GregUIBuilder**: Fluent API for modders to create panels and components with 5 lines of code. - * **Luminescent Architect Design System**: Standardized tokens for colors, spacing, and glow effects. - * **Live UI Replacements**: Users can now override any game UI element (position, scale, color) via `ui_overrides.json`. -:joystick: **Advanced Hooking** — New `greg.UI.*` hook category. Subscribe to MainMenu, PauseMenu, and HUD events. -:mag: **Developer Tooling** — HexViewer integration with F1 (UI Tree), F2 (Hook Monitor), and F3 (Element Inspector). - ---- - -:package: **Installation** - -1. **Requirement**: Ensure you have [MelonLoader v0.6.1](https://github.com/LavaGang/MelonLoader/releases) installed for *Data Center*. -2. **Files**: - * Copy `gregCore.dll` to your game's `Mods/` folder. - * Copy `Jint.dll` and `Esprima.dll` to your game's `MelonLoader/Libs/` folder. - * Copy `greg_hooks.json` to your game's root directory (next to the `.exe`). -3. **Launch**: Start the game. You should see "gregCore v1.0.0.7 initialized" in the console. - ---- - -:point_right: **[Download gregCore v1.0.0.7 on GitHub](https://github.com/mleem97/gregCore/releases/tag/v1.0.0.7)** - -Thank you for being part of this journey! — Your **teamGreg** - diff --git a/RELEASENOTE_DISCORD.md b/RELEASENOTE_DISCORD.md deleted file mode 100644 index 8dca1914..00000000 --- a/RELEASENOTE_DISCORD.md +++ /dev/null @@ -1,27 +0,0 @@ -:rotating_light: **Update: All Changes since Pre-Release 4!** :rotating_light: - -Hi everyone! Here is a compact overview of all the new features, fixes, and bridges that have landed in **gregCore** since `pre4`. We have reached some huge milestones! - -:joystick: **Game Compatibility & Networking** -- **Data Center Patch v1.0.45.5**: Compatibility with the latest game version has been verified! -- **VLAN Management**: Added `SetVlanAllowed`, `SetVlanDisallowed`, and `IsVlanAllowed` to `gregGameHooks` and the API (v9). -- **Route Evaluation**: New hooks for the improved in-game routing system have been added and documented. - -:rocket: **New SDK Features & Bridges (Pre-Release 5 & 6)** -- **TS/JS Engine Integration:** Full integration of the TypeScript/JavaScript engine, including associated API documentation. -- **IL2CPP Game System Bridges:** 9 completely new SDK services for direct control of in-game systems. -- **Hardware Bridges:** Direct interaction possibilities with physical server and rack objects in the game. -- **Phase 5 (Economy & Data):** - - `GregBalanceService`: Access to financial data, salaries, and income simulation. - - `GregLocalisationService`: Direct access to the game's internal translation system (mod-specific translations are now possible). - -:blue_book: **Documentation & Roadmap** -- All framework documentation has been translated into English and enhanced with Material Symbols. -- Reference documentation (`gregReferences`) has been synchronized for the new game version. -- The Master Roadmap has been updated (including preparations for Phase 8: Unity Scripting API). - -:bug: **Bugfixes & Polish (up to v1.0.0.17)** -- **UI & Config:** Resolved an issue with UI transparency and improved the accessibility of mod configurations in the menu. - -Grab the latest build on GitHub and happy modding! If you notice any bugs, feel free to report them. :fire: - diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 13680d80..00000000 --- a/TODO.md +++ /dev/null @@ -1,72 +0,0 @@ -# 📋 gregCore Roadmap to 100% Coverage - -Dieses Dokument ist der zentrale Masterplan für das Greg Framework. Es wird laufend aktualisiert, um mit der Entwicklung von *Data Center* Schritt zu halten. - ---- - -## ✅ Phase 0: Baseline (Abgeschlossen) -- [x] ~~Initiales Standalone-Repository Setup~~ -- [x] ~~Namespace-Migration zu `gregModLoader`~~ -- [x] ~~Basis-Struktur für MelonLoader Mods~~ - -## ✅ Phase 1: Framework Foundation (Abgeschlossen) -- [x] ~~Typsicheres Registrierungssystem (`GregContentRegistry`)~~ -- [x] ~~Basis-Definitionen für Hardware (Server, Switches)~~ -- [x] ~~Zentraler Event-Bus (`gregEventDispatcher`)~~ - -## ✅ Phase 2: Runtime Integration (Abgeschlossen) -- [x] ~~Implementierung der `gregSdk` Services~~ -- [x] ~~Kunden- und Mitarbeiter-Registries~~ -- [x] ~~Netzwerk-Kompatibilitäts-Prüfung (`GregNetworkCompatibilityService`)~~ - -## ✅ Phase 3: Visual Layer & Overrides (Abgeschlossen) -- [x] ~~Offizieller Modell-Ersetzungs-Dienst (`GregModelOverrideService`)~~ -- [x] ~~Prioritätsbasiertes Konflikt-Management für Mods~~ -- [x] ~~JADE-Style HUD Referenz-Implementierung~~ - -## ✅ Phase 4: Quality & API Expansion (Abgeschlossen) -- [x] ~~30+ Normalisierte Unity-Signale (`GregNativeEventHooks`)~~ -- [x] ~~Automatisierte Unit-Tests in `gregCore.Tests`~~ -- [x] ~~9 System-Bridges (Shop, Time, Player etc.)~~ -- [x] ~~Pre-Release v1.0.0 veröffentlicht~~ - -## ✅ Phase 4.5: gregUI Framework & Release v1.0.0.30-pre (Abgeschlossen) -- [x] ~~gregUI Framework mit vollständiger UGUI-Manipulation~~ -- [x] ~~GregUIBuilder Fluent API~~ -- [x] ~~Luminescent Architect Design System~~ -- [x] ~~HexViewer Integration (F1, F2, F3 Developer Tools)~~ -- [x] ~~UI Hooks Kategorie (`greg.UI.*`)~~ -- [x] ~~v1.0.0.30-pre Release mit allen Dependencies~~ -- [x] ~~GitHub Release mit DLL-Downloads~~ - -## 🚧 Phase 5: Economy & Data (In Arbeit) -- [ ] **SaveSystem & SaveData**: Abstraktion des Speichervorgangs. Ermöglicht Custom-Save-Daten für Mods. -- [ ] **BalanceSheet & Finanzen**: Zugriff auf Einnahmen, Ausgaben und historische Daten. -- [ ] **Localisation**: Bridge zum internen Übersetzungssystem für mehrsprachige Mods. - -## 📅 Phase 6: Deep Hardware & UI (Geplant) -- [ ] **CableLink & SFPModule**: Detailsteuerung für Kabeltypen und SFP-Zustände (Hitze, Verschleiß). -- [ ] **PatchPanel**: Interaktion mit passiver Netzwerk-Hardware. -- [ ] **Tooltip & UI_Section**: Erweiterte UI-Manipulation über das HUD hinaus. -- [ ] **AudioManager**: Steuerung von Soundeffekten und Umgebungsmusik. -- [ ] **Network Crawler (`GregTopologyService`)**: Implementierung eines performanten Graphen-Crawlers für automatisiertes Routing. -- [ ] **Power Simulation (`GregPowerService`)**: Rekursive Berechnung des Rack- und Raum-Stromverbrauchs. - -## 📅 Phase 7: Environment & Simulation (Geplant) -- [ ] **HRSystem**: Tiefere Integration in das Mitarbeiter-Management (Boni, Level-Up). -- [ ] **SteamManager & Lobbies**: API-Queue für Steam-Lobby-Callbacks (FFI `gregGameApi`). -- [ ] **Objectives**: Manipulation von Tutorial- und Haupt-Zielen. - -## 🔄 Phase 8: Unity Scripting API Integration (Laufend) -- [ ] **Unity API Abgleich**: Systematischer Abgleich mit der offiziellen Unity Scripting API. -- [ ] **Standard Module**: Integration von Physics, SceneManagement und NavMesh-Bridges. - ---- -> 💡 **Hinweis zur Roadmap:** Diese Roadmap ist ein **lebendes Dokument**. Da sich *Data Center* ständig weiterentwickelt, werden neue Systeme laufend in Phase 8 aufgenommen und bei Bedarf neue Phasen definiert. - -## Technischer Status -- **Aktuelle Coverage**: ~65% der IL2CPP-Kernlogik bridged. -- **Letzter Snapshot-Abgleich**: 11. April 2026 -- **Aktuelle Release**: v1.0.0.30-pre (15. April 2026) -- **GitHub**: https://github.com/mleem97/gregCore/releases/tag/v1.0.0.30-pre - diff --git a/bin/Release/net6.0/gregCore.dll b/bin/Release/net6.0/gregCore.dll index 578ebf840a09d98076500e320a50d68f2f634e68..75784c294d9a67f49a35fd964eba24214cfd74cb 100644 GIT binary patch delta 202078 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 RPqMJ1loYIc(e|t5e*i-VY5o8J diff --git a/docs/framework-dependencies.md b/docs/framework-dependencies.md deleted file mode 100644 index 8f9dde59..00000000 --- a/docs/framework-dependencies.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: gregCore Framework Dependencies -description: Vollständige Übersicht über Laufzeit- und Sprachabhängigkeiten sowie On-Demand-Aktivierung. -slug: /framework-dependencies ---- - -## Dependency-Tabelle - -| Abhängigkeit | Version | Typ | Wann aktiv? | Quelle | -|---|---|---|---|---| -| MelonLoader | aktuell | Runtime | immer | GameDir | -| Il2CppInterop | aktuell | Runtime | immer | GameDir | -| 0Harmony | aktuell | Runtime | immer | GameDir | -| MoonSharp | 2.0.0 | NuGet/embedded | nur bei `*.lua` | `gregCore.dll` | -| Rust-Bridge DLL | aktuell | FFI/ABI | nur bei `*.rs`/`*.rmod` | `gregCore.dll` | -| Python-Host | aktuell | Binding | nur bei `*.py` | `gregCore.dll` | -| JS-Runtime | aktuell | Binding | nur bei `*.js`/`*.ts` | `gregCore.dll` | - -## Immer vorhanden, aber on-demand aktiviert - -`gregCore` enthält die Framework-Bausteine, instanziiert Hosts aber nur bei Bedarf: - -- Keine passende Script-Datei → Host wird nicht erstellt. -- Script-Datei vorhanden + Dependency fehlt → Warnung, Host bleibt deaktiviert. - -## `gregCore.csproj` (Auszug) - -```xml - - - - - - -``` - -## Registry-API - -```csharp -// Signatur -public static bool IsActive(Language lang) -``` - -```csharp -// Signatur -public static IGregLanguageHost GetHost(Language lang) -``` - -```csharp -// Signatur -public static void ScanAndActivate(string modsScriptsDir) -``` - -## MISSING.md-Workflow - -Wenn eine Sprach-Bridge noch nicht vollständig ist: - -1. Stub mit `IGregLanguageHost` implementieren. -2. Lokales `MISSING.md` mit Pflicht-Header pflegen. -3. `MISSING.md` nie committen (`.gitignore`: `MISSING.md`, `**/MISSING.md`). - -## Konfliktmarkierung - -- ⚠️ WIKI↔CODE CONFLICT: Historische Pfade in älteren Dokumenten können `Plugins/` nennen. Der aktuelle Standard ist `Mods/Scripts` für Script-Erkennung. diff --git a/docs/getting-started.md b/docs/getting-started.md deleted file mode 100644 index 96699a0e..00000000 --- a/docs/getting-started.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: Getting Started (Modding) -description: Einstieg in gregCore mit klarer Trennung zwischen MelonLoader-Plugins und Script-Mods. -slug: /getting-started ---- - -## Voraussetzungen - -- Visual Studio 2022 -- .NET 6 SDK -- MelonLoader -- `gregCore.dll` -- Steam-Spiel **Data Center** - -## Grundregel: Plugin vs Script - -- **Plugin**: MelonLoader-Assembly (`*.dll`) im Mods-Plugin-Kontext. -- **Script**: Datei in `Mods/Scripts` (`*.lua`, `*.py`, `*.rs`, `*.rmod`, `*.js`, `*.ts`, `*.cs`). - -## Erstes C#-Plugin (kompilierbar) - -```csharp -using MelonLoader; - -[assembly: MelonInfo(typeof(HelloPlugin), "HelloPlugin", "1.0.0", "TeamGreg")] -[assembly: MelonGame("", "Data Center")] - -public sealed class HelloPlugin : MelonMod -{ - public override void OnInitializeMelon() - { - MelonLogger.Msg("[HelloPlugin] loaded"); - } -} -``` - -## Erstes Lua-Script (funktional) - -```lua --- Datei: Mods/Scripts/hello.lua - -greg.log_info("Hello from lua script") -greg.show_notification("Lua script is running") -``` - -## Framework-Guard-Pattern (REGEL 10) - -```csharp -public static class Guard -{ - public static bool Ensure(bool condition, string message) - { - if (!condition) - { - MelonLoader.MelonLogger.Warning($"[gregCore] Guard failed: {message}"); - return false; - } - - return true; - } -} -``` - -## Deployment-Matrix - -| Typ | Datei | Zielpfad | -|---|---|---| -| Plugin | `MyMod.dll` | `Data Center/Mods` | -| Lua Script | `*.lua` | `Data Center/Mods/Scripts` | -| Python Script | `*.py` | `Data Center/Mods/Scripts` | -| Rust Script/Mod Trigger | `*.rs`, `*.rmod` | `Data Center/Mods/Scripts` | -| JS/TS Script | `*.js`, `*.ts` | `Data Center/Mods/Scripts` | -| C# Script | `*.cs` | `Data Center/Mods/Scripts` | - -## Häufige Fehler (Top 5) - -1. `Python.Runtime` fehlt → Python-Host wird übersprungen. -2. Script liegt im falschen Ordner (`Plugins` statt `Mods/Scripts`). -3. TypeScript ohne Transpiler abgelegt. -4. C# Script ohne Roslyn-Runtime. -5. Lua-Fehler im Script stoppt das jeweilige Script (Framework bleibt aktiv). - -## Nächste Schritte - -- [Scripting Language Support](./scripting-language-support.md) -- [MoonSharp Lua Integration](./moonsharp-lua-integration.md) -- [Framework Dependencies](./framework-dependencies.md) diff --git a/docs/modding/f8-settings-hub.md b/docs/modding/f8-settings-hub.md deleted file mode 100644 index d55107c9..00000000 --- a/docs/modding/f8-settings-hub.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: "F8 Settings Hub" -description: "How to use and extend the F8 Settings Hub" ---- - -# F8 Settings Hub - -## Was ist das F8 Settings Hub? -Der F8 Hub ist das zentrale Mod-Konfigurationsmenü für alle gregCore-Mods. Es basiert auf dem `GregUIBuilder` (OnGUI) und nutzt das Luminescent Architect Design System. Kein Mod sollte mehr ein eigenes, abgetrenntes Fenster für Einstellungen bauen. - -## Standard-Tabs -- **[Framework]**: Zeigt Core-Infos und Debug-Toggles. -- **[Grid]**: Einstellungen für das `greg.GridPlacement`. -- **[SaveEngine]**: Einstellungen für `greg.SaveEngine`. -- **[Languages]**: Status der registrierten Skriptsprachen. -- **[Debug]**: Diagnose. - -## Modder: Eigenen Tab registrieren - -```csharp -// Eigenen Tab im F8-Menü registrieren -GregSettingsHub.RegisterTab("myMod.settings", "My Mod", (builder) => { - builder.AddLabel("My Mod v1.0.0") - .AddToggle("Enable Feature X", config.FeatureX, v => config.FeatureX = v) - .AddSlider("Speed", 0.1f, 5f, config.Speed, v => config.Speed = v) - .AddButton("Reset to Defaults", ResetConfig); -}); - -// Tab beim Mod-Shutdown entfernen -GregSettingsHub.UnregisterTab("myMod.settings"); -``` - -## Vanilla-Save-Banner -Wird ein Vanilla-Save geladen, erscheint im F8-Menü ein Warnbanner `Vanilla Save detected — Grid Placement disabled`. Dies signalisiert dem User, dass Game-Breaking-Features deaktiviert wurden, um den Vanilla-Save nicht zu korrumpieren. diff --git a/docs/modding/grid-placement-guide.md b/docs/modding/grid-placement-guide.md deleted file mode 100644 index 3b183f78..00000000 --- a/docs/modding/grid-placement-guide.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: "Grid Placement Guide" -description: "How to use greg.GridPlacement and integrate it with your mods" ---- - -# Grid Placement Guide - -## Was ist greg.GridPlacement? -greg.GridPlacement ersetzt das Vanilla-Rack-Placement durch ein dynamisches Grid-Placement-System, das ohne vorgefertigte RackHolder-Plates auskommt (ähnlich zu Bausimulationen wie Die Sims). - -## Vanilla RackHolder vs. Grid-System -| Feature | Vanilla RackHolder | greg.GridPlacement | -| --- | --- | --- | -| Basis | Vorab platzierte Plates | Endloses virtuelles Raster | -| Flexibilität | Gering | Hoch | -| Sub-Routing | Nein | Ja (2x2 Sub-Grid für Kabel etc.) | - -## Grid-Terminologie -- **Cell**: Eine Grid-Einheit, entspricht dem Footprint eines Racks. -- **SubCell**: Eine Cell ist in 4 SubCells (2x2) unterteilt. -- **Snap**: Einrasten auf die Grid-Koordinaten. -- **Origin**: Der 0,0,0 Punkt des virtuellen Grids. - -## Wie Racks platziert werden -1. Modus aktivieren via F8 (oder B-Taste). -2. Raster erscheint. -3. Hover zeigt Preview. -4. Klick platziert Rack direkt im World-Space und aktualisiert den GridManager. - -## Vanilla-Save-Verhalten -Wenn ein Vanilla-Save geladen wird, deaktiviert sich das Grid-Placement automatisch (`GridPlacement disabled`). -Vanilla speichert Racks in ihrem echten Positionen und Plates. Unser System speichert sie via `greg.SaveEngine`. Beides mischen zerstört Spielstände. - -## Modder-API -```csharp -// Prüfen ob Grid-Feature aktiv (kein Vanilla-Save) -bool active = GregFeatureGuard.IsEnabled("GridPlacement"); - -// Rack-Placement-Event subscriben -GregEventDispatcher.On(GregNativeEventHooks.WorldRackPlaced, (payload) => { - string rackId = GregPayload.Get(payload, "rackId", null); - string coord = GregPayload.Get(payload, "gridCoord", null); -}, modId: "myMod"); - -// Freie Zelle prüfen -GregGridManager grid = GregGridManager.Instance; -bool free = !grid.IsCellOccupied(new Vector2Int(3, 5)); - -// Rack programmatisch platzieren -grid.PlaceRack(new Vector2Int(3, 5), myRack); -``` - -## Bekannte Einschränkungen -⚠️ Siehe `MISSING.md` im `greg.GridPlacement`-Verzeichnis: Vanilla-Unterdrückung (`RackPlacementPatch.cs`) benötigt ein Update, da die exakte `RackHolder`-Klasse in `Assembly-CSharp` noch verifiziert wird. Standalone-Modus (via Controller) wird derzeit genutzt. diff --git a/docs/modding/migration-guide-v35.md b/docs/modding/migration-guide-v35.md deleted file mode 100644 index 3863b1da..00000000 --- a/docs/modding/migration-guide-v35.md +++ /dev/null @@ -1,56 +0,0 @@ -# Modding Migration Guide: gregCore v1.0.0.35 - -## The Unity 6 IL2CPP Problem -In Unity 6 (Data Center version), the **IMGUI** system (`GUI.Window`, `GUILayout`) is heavily stripped during the IL2CPP build process. Using managed delegates (like `Action`) for UI windows often fails with: -`[Il2CppInterop] Exception in IL2CPP-to-Managed trampoline: System.NotSupportedException: Method unstripping failed`. - -This causes infinite log spam and crashes the rendering bridge. - -## The Solution: GregUI (UGUI Framework) -Starting with version 1.0.0.35, `gregCore` provides a safe, native UGUI backend that bypasses the broken IMGUI trampolines. - -### 1. Legacy Fixes (Automatic) -- **`greg.Sdk.gregEventDispatcher`**: Restored for compatibility with older mods. -- **`gregNativeEventHooks`**: Stabilized signatures for better IL2CPP linking. - -### 2. Migrating to GregUI (Manual Action Required) -Mods using `OnGUI()` or `GUI.Window()` should migrate to the **GregUI Builder API**. - -#### Old Code (Prone to Crashes): -```csharp -void OnGUI() { - GUI.Window(id, rect, DrawWindow, "Title"); -} -void DrawWindow(int id) { - if (GUILayout.Button("Click Me")) { /* logic */ } -} -``` - -#### New Safe Code (v1.0.0.35+): -```csharp -using gregCore.PublicApi; - -public void BuildUI() { - greg.UI.CreateBuilder("Economy Hud") - .SetSize(400, 300) - .AddLabel("Current Funds: $1500") - .AddButton("Add Money", () => { - // Your logic here - safely wrapped for IL2CPP - }) - .AddButton("Close", () => { - gregCore.UI.GregUIManager.SetPanelActive("Economy Hud", false); - }) - .Build(); -} - -// Toggle visibility via hotkey -if (Input.GetKeyDown(KeyCode.F9)) { - gregCore.UI.GregUIManager.TogglePanel("Economy Hud"); -} -``` - -## Important: Clear Cache -After updating `gregCore.dll`, you **MUST** delete the following folder to force metadata regeneration: -`[GamePath]/MelonLoader/Il2CppAssemblies/` - -Failure to do so will cause `TypeLoadExceptions` even if the code is correct. diff --git a/docs/modding/save-engine-guide.md b/docs/modding/save-engine-guide.md deleted file mode 100644 index c0862825..00000000 --- a/docs/modding/save-engine-guide.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: "Save Engine Guide" -description: "Documentation for the LiteDB-based greg.SaveEngine" ---- - -# Save Engine Guide - -## Was ist greg.SaveEngine? -Eine hochperformante, embedded BSON-Datenbank (LiteDB 5.x) zum Speichern von Spielständen. Sie ersetzt den schwerfälligen Vanilla-IL2CPP-Binary-Save durch flexible, schemalose Document-Collections. - -## Vanilla-Save vs. greg.SaveEngine -| Feature | Vanilla Save | greg.SaveEngine | -| --- | --- | --- | -| Format | Binary IL2CPP | LiteDB (BSON) | -| Mod-Kompatibilität | Schlecht (Runtime-only states) | Perfekt (Collections) | -| Erweiterbarkeit | Keine | Beliebig viele eigene Collections | - -## LiteDB & ILRepack -LiteDB ist via ILRepack vollständig in die `gregCore.dll` eingebettet. Es gibt keine externe `LiteDB.dll` und keine Abhängigkeit in UserLibs. - -## Vanilla-Kompatibilität -**NOT COMPATIBLE by design.** -Wenn ein Vanilla-Save geladen wird, deaktiviert sich `greg.SaveEngine.Write`. - -## Modder-API -```csharp -// Vanilla-Save-Status prüfen -if (GregFeatureGuard.IsVanillaSave) { - LoggerInstance.Warning("Vanilla save — custom save disabled"); - return; -} - -// Eigene Daten im greg.SaveEngine speichern -GregSaveEngine.Instance.GetCollection("mymod_data") - .Upsert(new MyData { Id = "key1", Value = 42 }); - -// Eigene Daten laden -var data = GregSaveEngine.Instance.GetCollection("mymod_data") - .FindById("key1"); - -// Feature-State-Change subscriben -GregFeatureGuard.OnFeatureStateChanged += (featureKey) => { - if (featureKey == "GridPlacement") RefreshUI(); -}; -``` diff --git a/docs/modding/vanilla-save-compatibility.md b/docs/modding/vanilla-save-compatibility.md deleted file mode 100644 index f27d6574..00000000 --- a/docs/modding/vanilla-save-compatibility.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: "Vanilla Save Compatibility" -description: "How gregCore handles vanilla save files" ---- - -# Vanilla Save Compatibility - -## Was ist ein "Vanilla Save"? -Ein "Vanilla Save" ist ein Spielstand, der vom nativen Speichersystem des Spiels "Data Center" angelegt wurde (IL2CPP Binary Save). Er enthält keine `greg_meta`-Dokumente. - -## Wie greg.SaveEngine es erkennt -Beim Aufruf von `LoadGame` überprüft `GregVanillaDetector`, ob die zu ladende Datei eine `.greg.db` mit validem Header ist. Wenn nicht, wird sie als Vanilla eingestuft. - -## Was passiert bei einem Vanilla Save? -`GregFeatureGuard.IsVanillaSave` wird auf `true` gesetzt. -Folgende Features werden zum Schutz des Spielstands deaktiviert: -- `GridPlacement` (keine Racks übers Grid platzieren) -- `SaveEngine.Write` (keine LiteDB-Updates) - -## Was Spieler tun müssen -Um alle Modding-Features voll auszunutzen, muss ein neues Spiel gestartet werden, das ausschließlich über die `greg.SaveEngine` gespeichert wird. - -## Migration (WIP) -Gibt es einen Konverter? Nein, aktuell nicht. (Siehe `MISSING.md` für zukünftige Entwicklungen im Save-Parser). - -## GregFeatureGuard API -```csharp -// Vanilla-Save-Status prüfen -if (GregFeatureGuard.IsVanillaSave) { - LoggerInstance.Warning("Vanilla save — custom save disabled"); - return; -} -``` diff --git a/docs/moonsharp-lua-integration.md b/docs/moonsharp-lua-integration.md deleted file mode 100644 index 5e11c692..00000000 --- a/docs/moonsharp-lua-integration.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: MoonSharp Lua Integration -description: Technische Referenz zur Lua-Integration in gregCore über MoonSharp 2.0.0. -slug: /moonsharp-lua-integration ---- - -## Was ist MoonSharp und warum 2.0.0? - -MoonSharp ist eine reine .NET-Lua-Implementierung ohne native Lua-DLL. Für `gregCore` bedeutet das: - -- kompatibel mit IL2CPP/MelonLoader-Setup -- leichtes Embedding in `gregCore.dll` -- klare Sandbox-Steuerung - -`gregCore` verwendet MoonSharp **2.0.0** als feste Framework-Dependency. - -## Lua Lifecycle in gregCore - -1. **Scan**: Registry sucht `*.lua` in `Mods/Scripts`. -2. **Activate**: `GregLuaHost` wird nur bei Treffer aktiviert. -3. **Execute**: `LuaFFIBridge` lädt Lua-Entrypoints. -4. **Unload**: `Shutdown()` leert Host-Zustand. - -```csharp -// Signatur -public sealed class GregLuaHost : IGregLanguageHost -``` - -## Minimalbeispiel (funktionsfähig) - -```lua --- Datei: Mods/Scripts/demo.lua - -greg.log_info("[demo.lua] init") - -greg.on("greg.lifecycle.GameLoaded", function(payload) - greg.log_info("Game loaded hook fired") - greg.show_notification("Lua hook active") -end) -``` - -## Exponierte Lua-API (aktuell) - -> Quelle: `LuaFFIBridge.RegisterApi`. - -- Logging: `log_info`, `log_warning`, `log_error` -- Economy: `get_player_money`, `set_player_money`, `get_player_xp`, `set_player_xp`, `get_player_reputation`, `set_player_reputation` -- World: `get_server_count`, `get_rack_count`, `get_switch_count`, `get_broken_server_count`, `get_broken_switch_count` -- Technicians: `get_free_technician_count`, `get_total_technician_count`, `dispatch_repair_server`, `dispatch_repair_switch` -- Time: `get_time_of_day`, `get_day`, `get_seconds_in_full_day`, `set_seconds_in_full_day` -- Game: `get_current_scene`, `is_game_paused`, `set_game_paused`, `get_time_scale`, `set_time_scale`, `trigger_save`, `get_difficulty` -- Player/UI: `get_player_position`, `show_notification` -- Events/Hooks: `subscribe_event`, `fire_event`, `on`, `fire` -- Config: `config_set_bool`, `config_get_bool`, `config_set_int`, `config_get_int`, `config_set_string`, `config_get_string` - -## Fehlerbehandlung - -Lua-Syntax- oder Laufzeitfehler werden abgefangen und im MelonLoader-Log gemeldet. - -```csharp -// Signatur -private static void SafeCall(LuaPlugin p, Closure? func, params object[] args) -``` - -## Debugging - -- Primärer Kanal: `MelonLoader/Latest.log` -- Prefixe: - - `[gregCore] ...` (Framework-Level) - - `[LuaMod:] ...` (Plugin-/Script-Layer) - -## Manifest- und Config-Anforderungen - -- Manifest: [UNVERIFIED] aktuelles Lua-Manifest-Schema im Repo nicht eindeutig versioniert. -- `config.json`: [UNVERIFIED] modulabhängig; empfohlen sind einfache Key/Value-Paare. - -## Deployment - -- Lege Lua-Dateien unter `Mods/Scripts` ab. -- Stelle sicher, dass mindestens eine `*.lua` vorhanden ist, damit `GregLuaHost` startet. - -## Fehlende Bausteine - -Siehe `MISSING.md` für offene Integrationspunkte (z. B. standardisiertes Lua-Manifest-Schema). diff --git a/docs/scripting-language-support.md b/docs/scripting-language-support.md deleted file mode 100644 index 144c8d9d..00000000 --- a/docs/scripting-language-support.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: Scripting Language Support -description: Übersicht über alle von gregCore unterstützten Script-Sprachen inklusive Aktivierungslogik und Host-Mapping. -slug: /scripting-language-support ---- - -## Überblick - -`gregCore` unterscheidet strikt: - -- **Plugins**: MelonLoader-Assemblies (`*.dll`) -- **Scripts**: Sprachdateien in `Mods/Scripts` (`*.lua`, `*.py`, `*.rs`, `*.rmod`, `*.js`, `*.ts`, `*.cs`) - -> ⚠️ WIKI↔CODE CONFLICT: Ältere Bridge-Implementierungen nutzen intern noch `Plugins/`-Ordner. Die Aktivierungslogik scannt jetzt `Mods/Scripts` als Source of Truth. - -## Aktivierungsmodell (On-Demand) - -Beim Start (`OnInitializeMelon`) ruft `gregCore` auf: - -```csharp -// Signatur -public static void ScanAndActivate(string modsScriptsDir) -``` - -Die Registry aktiviert ausschließlich Hosts, für die Dateien erkannt wurden. - -```csharp -// Signatur -public static bool IsActive(Language lang) -``` - -```csharp -// Signatur -public static IGregLanguageHost GetHost(Language lang) -``` - -## Sprach-Matrix - -| Sprache | Muster in `Mods/Scripts` | Abhängigkeit in `gregCore` | Host | Status | -|---|---|---|---|---| -| Lua | `*.lua` | MoonSharp `2.0.0` | `GregLuaHost` | Aktivierbar | -| Rust | `*.rs`, `*.rmod` | Rust-Bridge (FFI/ABI-Layer) | `GregRustHost` | Aktivierbar | -| Python | `*.py` | Python-Host-Bindings (`pythonnet` / `Python.Runtime`) | `GregPythonHost` | Aktivierbar bei Runtime | -| C# Script | `*.cs` | Roslyn (falls vorhanden) | `GregCSharpScriptHost` | [UNVERIFIED] Ausführungslayer | -| JS / TS | `*.js`, `*.ts` | Jint JS-Runtime-Binding | `GregJsHost` | `*.js` aktiv, `*.ts` benötigt Transpile | - -## Einstieg je Sprache - -### Lua - -- Einsatzzweck: schnelle Gameplay-Automation, Hooks, Utilities. -- Host: `GregLuaHost`. - -```lua --- Datei: Mods/Scripts/hello.lua -greg.log_info("Hello from Lua") -``` - -### Rust - -- Einsatzzweck: performancekritische Module, FFI-Integration. -- Host: `GregRustHost`. - -```rust -// Datei: Mods/Scripts/example.rs -// Hinweis: derzeit FFI-Brücke nutzt native Exports; reine .rs-Datei ist Trigger für Host-Aktivierung. -fn main() { - // runtime-spezifisch -} -``` - -### Python - -- Einsatzzweck: Prototyping, Automation, Daten-Workflows. -- Host: `GregPythonHost`. - -```python -# Datei: Mods/Scripts/hello.py -greg.log_info("Hello from Python") -``` - -### C# Script - -- Einsatzzweck: Skriptbasierte C#-Erweiterungen ohne Plugin-Build. -- Host: `GregCSharpScriptHost`. - -```csharp -// Datei: Mods/Scripts/hello.cs -// [UNVERIFIED] Vollständige Script-Ausführung hängt von Roslyn-Runtime ab. -``` - -### JavaScript / TypeScript - -- Einsatzzweck: schnelle Script-Automation, modulare Tools. -- Host: `GregJsHost`. - -```javascript -// Datei: Mods/Scripts/hello.js -greg_log("Hello from JS"); -``` - -```ts -// Datei: Mods/Scripts/hello.ts -// Derzeit nur Erkennung; Transpiler-Integration ist notwendig. -``` - -## Bekannte Einschränkungen - -- `GregCSharpScriptHost`: Ausführungslayer ist in `MISSING.md` dokumentiert. -- TypeScript: Erkennung vorhanden, keine integrierte Transpile-Pipeline. -- Python: Wenn `Python.Runtime.dll` fehlt, bleibt Python-Host deaktiviert. - -## Weiterführende Seiten - -- [MoonSharp Lua Integration](./moonsharp-lua-integration.md) -- [Getting Started](./getting-started.md) -- [Framework Dependencies](./framework-dependencies.md) diff --git a/game_assembly_analysis.md b/game_assembly_analysis.md deleted file mode 100644 index b3c84242..00000000 --- a/game_assembly_analysis.md +++ /dev/null @@ -1,125 +0,0 @@ -# 1) Globale Architektur & Singletons - -Analysebasis: `gregReferences/Assembly-CSharp/Il2Cpp/*.cs` (IL2CPP-Wrapper). Relevante Komponente liegt in der Schicht **Unity Spiel / IL2CPP Assembly** (nicht GregCore/Core-SDK selbst). - -- `Il2Cpp.MainGameManager` - - Singleton: `public static unsafe MainGameManager instance` - - Verantwortlich für Session-/Spielzustand, Kundenfluss, Autosave-Settings, zentrale Objekt-Referenzen. - - Wichtige Methoden: `public unsafe void SetAutoSaveInterval(float minutes)`, `public unsafe void SetAutoSaveEnabled(bool enabled)`, `public unsafe int GetFreeVlanId()`. -- `Il2Cpp.NetworkMap` - - Singleton: `public static unsafe NetworkMap instance` - - Zentrale Topologie-/Routing-Instanz für Geräte, Kabel, Verbindungen. -- `Il2Cpp.PlayerManager` - - Singleton: `public static unsafe PlayerManager instance` - - Input-/Movement-Gating und Interaktionszustand (Objekt in Hand, Interaktionsflags). -- `Il2Cpp.TimeController` - - Singleton-ähnliche globale Zeitinstanz mit statischem Callback `public static unsafe TimeController.OnEndOfTheDay onEndOfTheDayCallback`. -- `Il2Cpp.SaveData` - - Globaler Save-State: `public static unsafe SaveData instance` + `public static unsafe SaveData _current`. -- `Il2Cpp.SaveSystem` - - Statischer Save/Load-Orchestrator (kein klassischer Singleton, aber globaler Entry-Point über statische API). - -# 2) Spieler & Entities (Data Structures) - -Hauptobjekte mit C-ABI-relevanten Datentypen (für stabile Bridge-Übergabe bevorzugt: primitive numerische Typen + explizite Structs). - -- `Il2Cpp.Player` - - Ökonomie-/Progress-Felder: `money` (`float`), `xp` (`float`), `reputation` (`float`), `previousCoins` (`float`). - - Choke-Methoden: `public unsafe bool UpdateCoin(float _coinChhangeAmount, bool withoutSound = false)`, `public unsafe bool UpdateXP(float amount)`, `public unsafe void UpdateReputation(float amount)`. -- `Il2Cpp.PlayerData` (`[Serializable]`) - - Felder: `List activeObjectives`, `float coins`, `float xp`, `float reputation`, `Il2CppStructArray position`. - - Für C-ABI gut geeignet: `float`, `int`; bei `position` sauber als 3er-Array (`x,y,z`) flatten. -- `Il2Cpp.SaveData` (`[Serializable]`) - - Persistenz-Aggregat mit `playerData`, `networkData`, `loadedScenes`, `technicianData`, `repairJobQueue`, `commandCenterLevel` u. a. - - Mappings enthalten viele primitive Felder (`int`, `bool`, `float`, `string`) plus Listen/Arrays. -- `Il2Cpp.Item` (`ScriptableObject`) - - Preis-/Wertfelder: `int price`, `float weight`, `float deprecation`, `bool isStackable`, `int unlockedFromXP`. -- `Il2Cpp.ShopItemSO` (`ScriptableObject`) - - Shop-relevante Primitive: `int xpToUnlock`, `int price`, `int itemID`, `float eol`, `bool isCustomColor`. -- ECS-nahe explizite Layout-Typen (`[StructLayout(LayoutKind.Explicit)]`) - - `Il2Cpp.CableIDComponent`: `int CableId` (Offset 0), `int SwitchId` (Offset 4). - - `Il2Cpp.PacketComponent`: enthält `float3`, `float4`, `int cableId`, `int customerId`, `float moveSpeed` etc. - - Diese Typen sind für Low-Level-Hooks/Interop besonders wertvoll, da Feldlayout explizit ist. - -# 3) Native Event-Systeme - -Primär Delegate-basierte C#-Events/Callbacks in der **Unity Spiel / IL2CPP Assembly**-Schicht: - -- Save-/Load-Callbacks (`Il2Cpp.SaveSystem`) - - `public static unsafe SaveSystem.OnSavingData onSavingData` - - `public static unsafe SaveSystem.OnLoadingData onLoadingData` - - `public static unsafe SaveSystem.OnLoadingDataLater onLoadingDataLater` - - Delegates sind `MulticastDelegate`-Typen mit `Invoke()`. -- Szenen-/Load-Callback (`Il2Cpp.LoadingScreen`) - - `public static unsafe LoadingScreen.GameIsLoaded onGameIsLoadedCallback` - - `LoadingScreen.GameIsLoaded` ist `MulticastDelegate` mit `Invoke()`. -- Tageszyklus-Callback (`Il2Cpp.TimeController`) - - `public static unsafe TimeController.OnEndOfTheDay onEndOfTheDayCallback` - - Delegate `OnEndOfTheDay.Invoke()` als stabiler Lifecycle-Hook. -- Pause-Menü-Callbacks (`Il2Cpp.PauseMenu`) - - `public static unsafe PauseMenu.OnPauseMenuOpen onPauseMenuOpenCallback` - - `public static unsafe PauseMenu.OnPauseMenuClose onPauseMenuCloseCallback` -- Input-Rebind-Events (`Il2Cpp.InputManager`) - - `public static unsafe void add_rebindComplete(Il2CppSystem.Action value)` / `remove_rebindComplete(...)` - - `add_rebindCanceled(...)` / `remove_rebindCanceled(...)` - - `add_rebindStarted(Il2CppSystem.Action value)` / `remove_rebindStarted(...)` - -# 4) Kritische Hook-Ziele (Harmony Patch Candidates) - -Kernziel: Choke-Points patchen (Prefix/Postfix), nicht breit `Update()`-spammen. - -- Save/Load (höchste Priorität) - - `Il2Cpp.SaveSystem.SaveGame(string savename = null, string stringNameOfSave = null)` - - `Il2Cpp.SaveSystem.LoadGame(string savename)` - - `Il2Cpp.SaveSystem.Load(string savename, bool isFromPauseMenu)` - - `Il2Cpp.SaveSystem.AutoSave()` - - `Il2Cpp.SaveSystem.SaveGameData()` / `LoadGameData()` -- Economy/Progress - - `Il2Cpp.Player.UpdateCoin(float _coinChhangeAmount, bool withoutSound = false)` - - `Il2Cpp.Player.UpdateXP(float amount)` - - `Il2Cpp.Player.UpdateReputation(float amount)` - - Shop-Zahlungspfad: `Il2Cpp.ComputerShop.ButtonCheckOut()`, `UpdateCartTotal()`, `BuyNewItem(...)`, `BuyAnotherItem(...)`. -- Netzwerk-/Topologie - - `Il2Cpp.NetworkMap.AddDevice(string name, CableLink.TypeOfLink type, int customerID = -1)` - - `Il2Cpp.NetworkMap.RemoveDevice(string name)` - - `Il2Cpp.NetworkMap.Connect(string from, string to)` / `Disconnect(string from, string to)` - - `Il2Cpp.NetworkMap.RegisterCableConnection(...)` / `RemoveCableConnection(int cableId, bool preserveLACP = false)` - - Validierung: `Il2Cpp.NetworkMap.IsIpAddressDuplicate(string ip, Server serverToExclude)` -- Geräte-/Serverzustand - - `Il2Cpp.Server.PowerButton(bool forceState = false)` - - `Il2Cpp.Server.SetIP(string _ip)` - - `Il2Cpp.Server.UpdateCustomer(int newCustomerID)` - - `Il2Cpp.Server.UpdateAppID(int _appID)` - - `Il2Cpp.Server.ItIsBroken()` / `RepairDevice()` - -# 5) UI & Szenen-Management - -UI-/Scene-Flows mit hoher Relevanz für kontrollierte Mod-Intervention: - -- Main Menu (`Il2Cpp.MainMenu`) - - `Continue()`, `NewGame()`, `LoadGame()`, `Settings()`, `QuitGame()`. -- Pause Flow (`Il2Cpp.PauseMenu`) - - `Pause(int openMenu)`, `Resume()`, `Save(string saveName = null, string _stringNameOfSave = null)`, `Load(string savename)`. - - Gute Hook-Stellen für mod-seitige Gatekeeper/Overlay-Interlocks. -- Loading/Scenes (`Il2Cpp.LoadingScreen`) - - `LoadGameScenesVoid(...)`, `LoadLevel(int sceneIndex)`, `UnLoadLevel(int sceneIndex)` - - `AsynchronousLoad(int sceneIndex)`, `AsynchronousUnLoad(int sceneIndex)`, `IsSceneLoaded(string name)` - - `onGameIsLoadedCallback` als zuverlässiger End-of-Load Synchronisationspunkt. -- Shop-/Asset-UI - - `Il2Cpp.ComputerShop`: Kauf- und Warenkorb-UI-Endpunkte. - - `Il2Cpp.AssetManagement`: Asset-Filter/Repair-UI-Workflows (relevant für automatische Tasking-Mods). - -# 6) Obfuscation & Auffälligkeiten - -- Obfuscation-Marker vorhanden - - `Il2Cpp.ObjectPrivateAbstractSealedInVo0` trägt `[ObfuscatedName("$BurstDirectCallInitializer")]`. - - Deutet auf generierte/Burst-nahe Initialisierer hin (kein klassischer Gameplay-Entry-Point). -- IL2CPP-/Interop-Spezifika - - Weit verbreitete `unsafe` Wrapper, `NativeFieldInfoPtr_*`, `NativeMethodInfoPtr_*`, `il2cpp_runtime_invoke`. - - Für Harmony-Patching sind semantische High-Level-Methoden stabiler als intern generierte Helper. -- Explizite Layouts als technische Auffälligkeit - - `[StructLayout(LayoutKind.Explicit)]` in u. a. `CableIDComponent`, `PacketComponent`, `_PrivateImplementationDetails_`. - - Wichtig für deterministische Feld-Offsets bei nativer Bridge/ABI. -- Anti-Cheat-Indikatoren (Textscan) - - Kein direkter String-/Symboltreffer auf typische Marker wie `EasyAntiCheat`, `BattlEye`, `VAC`, `GameGuard`, `AntiCheat` im gescannten Dump. - - Das ist **kein** kryptografischer Nachweis „anti-cheat-frei“, aber im vorliegenden C#-Dump gibt es keine offensichtlichen API-Hooks darauf. diff --git a/gregCore.csproj b/gregCore.csproj index e43a5ecc..fcbe702f 100644 --- a/gregCore.csproj +++ b/gregCore.csproj @@ -13,9 +13,9 @@ false false false - 1.0.0.38 - 1.0.0.38 - 1.0.0.38 + 1.0.0.40-pre + 1.0.0.40-pre + 1.0.0.40-pre diff --git a/gregCore.sln b/gregCore.sln index 77b1e5e2..d3f1fa77 100644 --- a/gregCore.sln +++ b/gregCore.sln @@ -1,13 +1,30 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.14.37111.16 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gregCore", "gregCore.csproj", "{73B346A1-72BC-4F8C-BDAF-C2E88AB9CF69}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gregFramework", "gregFramework", "{9A0CCAB9-4303-13B4-2371-F1B97FF5B728}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gregCore.Abstractions", "src\gregCore.Abstractions\gregCore.Abstractions.csproj", "{A1B2C3D4-E5F6-4789-ABCD-EF1234567890}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gregCore.Tests", "tests\gregCore.Tests.csproj", "{FAF3FBA7-1865-41EF-BA90-215D9E7BF597}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gregCore.SDK", "src\gregCore.SDK\gregCore.SDK.csproj", "{B2C3D4E5-F678-49AB-CDEF-123456789012}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gregCore.Core", "src\gregCore.Core\gregCore.Core.csproj", "{C3D4E567-89AB-4CDE-F123-456789012345}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gregCore.Mod", "src\gregCore.Mod\gregCore.Mod.csproj", "{D4E56789-ABCD-4E12-3456-789012345678}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gregCore.Hooks", "src\gregCore.Hooks\gregCore.Hooks.csproj", "{E56789AB-CDEF-4512-3456-789012345678}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gregCore.Patches", "src\gregCore.Patches\gregCore.Patches.csproj", "{F6789ABC-DEF5-5123-4567-890123456789}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gregCore.Compatibility", "src\gregCore.Compatibility\gregCore.Compatibility.csproj", "{89ABCD12-EF67-4123-4567-890123456789}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gregCore.Bridge", "src\gregCore.Bridge\gregCore.Bridge.csproj", "{9ABCDE23-F678-4231-5678-901234567890}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gregCore.UI", "src\gregCore.UI\gregCore.UI.csproj", "{ABCDEF34-5678-4321-6789-012345678901}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gregCore.Shared", "src\gregCore.Shared\gregCore.Shared.csproj", "{BCDE1234-5678-5341-7890-123456789012}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gregCore.Tests", "tests\gregCore.Tests\gregCore.Tests.csproj", "{FAF3FBA7-1865-41EF-BA90-215D9E7BF597}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -47,11 +64,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {FAF3FBA7-1865-41EF-BA90-215D9E7BF597} = {9A0CCAB9-4303-13B4-2371-F1B97FF5B728} - EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {798E71F5-042F-4369-BFB3-984CC5DB2169} EndGlobalSection -EndGlobal - +EndGlobal \ No newline at end of file diff --git a/lib/references/README.md b/lib/references/README.md deleted file mode 100644 index f80aeb8b..00000000 --- a/lib/references/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Vendored MelonLoader references (Live-Sync) - -This folder mirrors `MelonLoader/net6` and `MelonLoader/Il2CppAssemblies` from your **Data Center** install. - -- **Do not commit** `*.dll` files (see `.gitignore`). -- Run from the repo root: - -```bash -python tools/refresh_refs.py -``` - -Or set `DATA_CENTER_GAME_DIR` to your game root, or pass `--game-dir "C:\Program Files (x86)\Steam\steamapps\common\Data Center"`. - -After sync, `gregCore.csproj` will prefer `lib/references/MelonLoader` when `net6/MelonLoader.dll` exists, so IDEs and CI can build without a Steam path. - -Optional: `python tools/refresh_refs.py --watch` polls for interop changes after game updates. - -See also: `MANIFEST.txt` (generated) and `tools/diff_assembly_metadata.py`. - diff --git a/modding_core_architecture_summary.md b/modding_core_architecture_summary.md deleted file mode 100644 index 27688114..00000000 --- a/modding_core_architecture_summary.md +++ /dev/null @@ -1,196 +0,0 @@ -# modding_core_architecture_summary - -> Zweck: Single Source of Truth für AI-/Bridge-Entwicklung (Lua, Rust, Go, Python, TS/JS) gegen gregCore. -> -> Scope: Laufzeit im Spielprozess (MelonLoader + Unity IL2CPP), inklusive FFI, IPC, Eventing und Sicherheitsgrenzen. - -## 1) Runtime Lifecycle, Bootstrap & Schichten - -### Schichtzuordnung (verbindlich) -- **Unity Spiel / IL2CPP Assembly (Game Layer):** gepatchte Spieltypen/Methoden (z. B. `Player.UpdateCoin`, `ServerPowerButton`, UI/Save-Methoden). -- **GregFramework Core SDK (Core Layer):** `src/gregModLoader/gregCore.cs`, `gregHarmonyPatches.cs`, `gregFfiBridge.cs`, `gregGameApi.cs`, `gregEventDispatcher.cs`. -- **Plugin Layer:** `src/gregModLoader/Plugins/*` (`gregPluginBase`, `gregRegistry`, Dependency-Resolver). -- **Language Bridges:** `src/Scripting/*` (`iGregLanguageBridge`, `gregLanguageBridgeHost`, Lua/JS/Rust/Go-Bridges). -- **Mod Layer:** User-Mods, native DLL-Mods (FFI), Script-Mods. - -### Haupt-Entry und Aufrufreihenfolge -- **Core-Layer Entry:** `gregCoreLoader : MelonMod` in `src/gregModLoader/gregCore.cs`. -- Relevante Lifecycle-Methoden: - - `OnInitializeMelon()` - - `OnSceneWasLoaded(int buildIndex, string sceneName)` - - `OnUpdate()` - - `OnFixedUpdate()` - - `OnGUI()` - - `OnApplicationQuit()` - -### Effektive Initialisierungssequenz -1. Core initialisiert Konfiguration, Aktivierung/Flags, Logging. -2. Core erstellt/initialisiert FFI (`gregFfiBridge`) und API-Tabelle (`gregGameApi`). -3. Core initialisiert Script-Host (`gregLanguageBridgeHost`) und lädt Bridges. -4. Core installiert Harmony-Patches (`gregHarmonyPatches`). -5. Plugins werden registriert/aufgelöst (`gregRegistry`, `gregDependencyResolver`) und über Ready-Callbacks aktiviert. -6. Runtime-Loop verteilt Update-Ticks an Core, Bridges und FFI-Module. - -### Shutdown-Semantik -- `OnApplicationQuit()` triggert geordnetes Stoppen: - - Script-Host/Bridges herunterfahren, - - native FFI-Module via `mod_shutdown` und `FreeLibrary` freigeben, - - Pointer/Handles im `gregGameApi.Dispose()` bereinigen. - ---- - -## 2) IL2CPP Hooking-Modell & Ausführungsfluss - -### Hook-Ebene -- **Core Layer:** `src/gregModLoader/gregHarmonyPatches.cs` patcht IL2CPP-Spielmethoden mit Harmony Prefix/Postfix. -- Ziel ist **Event-Proxying**, nicht direkter unkontrollierter Mod-Zugriff auf Unity-Typen. - -### Hook-zu-Event Pipeline -1. IL2CPP-Methode wird gepatcht (Prefix/Postfix). -2. Patch extrahiert primitive/struct-basierte Daten. -3. Dispatch über `EventDispatcher`/`gregEventDispatcher` mit numerischer `EventIds`-ID. -4. `GregHookIntegration` mappt `eventId -> greg.*` Hookname (`gregNativeEventHooks`). -5. Hook-Payload wird normalisiert (`BuildPayload(...)`) und an Bus/FFI weitergereicht. - -### Canonical Hook-Namen -- Mapping erfolgt dynamisch via `GregHookRegistry` (`assets/greg_hooks.json`), was Hash-basierte Event-IDs für das FFI generiert. -- Primärquelle für Namen: `greg_hooks.json` + framework-only Ergänzungen via `gregHookName.Create(...)`. -- Fallback bei unbekannten IDs: `greg.SYSTEM.UnmappedNativeEvent`. - -### Cancelable vs Non-cancelable -- `gregEventDispatcher` unterstützt normale und cancelable Listener (`Func`). -- Cancel-Pfad wird in Patchpunkten genutzt, wo Spielaktion blockierbar ist. - ---- - -## 3) Interop, FFI & IPC (ABI, Ports, Protokolle) - -### Native FFI (Core ↔ Native Mod) -- **Core Layer Datei:** `src/gregModLoader/gregFfiBridge.cs`. -- Win32 Loader-API: - - `LoadLibrary` - - `GetProcAddress` - - `FreeLibrary` -- Erwartete native Exports (C-ABI): - - `mod_info` - - `mod_init` - - `mod_update` - - `mod_fixed_update` - - `mod_on_scene_loaded` - - `mod_on_gui` - - `mod_shutdown` - - `mod_on_event` - -### API-Table für native Module -- **Core Layer Datei:** `src/gregModLoader/gregGameApi.cs`. -- Versioniertes Struct: `GameAPITable` (aktuell auf v12 erweitert). -- Delegates werden via `Marshal.GetFunctionPointerForDelegate(...)` als Funktionszeiger exportiert. - -### IPC/Netzwerkflächen -- **MCP HTTP Server (Core/Tooling-Grenze):** `GregMCPServer` via `HttpListener` (localhost). -- **Multiplayer Transport (Plugin/Core):** WebSocket-Client in `GregMultiplayerService`. -- **Plugin-Sync (Core/Service):** `HttpClient` in `gregPluginSyncService`. -- **Native Plattform-Interop:** Steam-P2P via `steam_api64`-Imports in `gregGameApi.cs`. - -### Bridge-Host für Sprachen -- **Language Bridge Layer:** `iGregLanguageBridge` + `gregLanguageBridgeHost`. -- Lua: MoonSharp; JS/TS: Jint; Rust/Go über Bridge-Adapter. -- Host ist der Isolations- und Lifecycle-Knoten für alle Script-Runtimes. - ---- - -## 4) Memory Boundaries, Ownership & Lifetime - -### Ownership-Regeln an der FFI-Grenze -- **Unmanaged Allokation durch Core:** `Marshal.AllocHGlobal`. -- **Freigabe durch Core nach Callback:** `Marshal.FreeHGlobal` (symmetrisch im Dispatch-Pfad). -- **String-Marshalling:** `Marshal.StringToHGlobalAnsi` / `Marshal.PtrToStringAnsi`. -- **Blittable Struct Transfer:** `[StructLayout(LayoutKind.Sequential)]` in Event-Payloads. - -### Delegate-/Function-Pointer-Lifetime -- Delegates für API-Funktionen werden als Felder gehalten, damit der GC keine Funktionszeiger invalidiert. -- `GameAPITable` speichert `IntPtr` auf Delegate-Stubs; Freigabe zentral im `Dispose()`. - -### GCHandle-Verwendung -- Für Event-/Payload-Weitergabe werden `GCHandle.Alloc(...)` Handles erzeugt. -- Handles werden nach Verwendung explizit gelöst (`GCHandle.Free()`), um Leaks/Pinning-Druck zu verhindern. - -### Fehlerresilienz an Grenzstellen -- FFI-Aufrufe sind einzeln in `try/catch` eingefasst. -- Fehler in einem Modul dürfen den Core-Loop nicht terminieren (Fail-isolated execution). - -### Kritische ABI-Regeln für externe Bindings -- Struct-Reihenfolge/Field-Typen sind ABI-kritisch; keine Reorder/Pack-Änderung ohne Version-Bump. -- Auf der Bridge-Seite nur stabile primitive Typen (`int`, `uint`, `float`, `byte[]`, `IntPtr`) übergeben. -- Keine Ownership-Mehrdeutigkeit: jeder Pointer braucht eindeutige „who frees“-Regel. - ---- - -## 5) DTOs, Manifeste & Serialisierung - -### Typfamilien -- **Runtime Event DTOs (Core):** `src/gregModLoader/Events/*.cs` (`iModEvent` mit `DateTime OccurredAtUtc`). -- **Native Event Struct DTOs (Core):** `src/gregModLoader/gregEventDispatcher.cs` (z. B. `ValueChangedData`, `DayEndedData`, `ShopItemAddedData`). -- **SDK/Config DTOs (Core/SDK):** - - `GregUiReplacementManifest` - - `ModelOverrideManifest` - - `ServerDefinition` - - `ItemDefinition` - - `PluginSyncConfig`, `PluginSyncManifest` - -### Serializer-Stack -- `System.Text.Json` für Runtime-/Service-Pfade (`GregPersistenceService`, MCP-Antworten). -- `Newtonsoft.Json` in Teilen des Config-Stacks (`GregConfigService`). -- Konsequenz: DTO-Contracts sind serializer-agnostisch zu halten (öffentliche Properties/Fields stabil). - -### Feld- und Versionsstabilität -- Event- und Manifest-Felder sind externe Verträge für Bridges/Mods. -- Änderungen nur additiv und versioniert (insb. API-Table + manifestartige Contracts). -- Entfernen/Umbenennen erzeugt harte Breaking Changes für native und Script-Bindings. - -### Datentyp-Praxis für Multi-Language Bindings -- Bevorzugt JSON-kompatible Primitiven und flache Objekte. -- Für binäre Übergaben klar deklarierte Byte-Arrays + Länge. -- Keine impliziten Unity-/IL2CPP-Objektreferenzen in öffentlichen Bridge-DTOs. - ---- - -## 6) Event-System, Hook-API & Sandboxing-Einschränkungen - -### Event-Systeme (parallel vorhanden) -1. **String-basierter Hook-Bus (Core):** `gregEventDispatcher` mit Hooknamen `greg..`. -2. **Type-safe Bus (SDK):** `GregEventBus` (`Subscribe`, `Publish`, `Unsubscribe`). -3. **Native Event-ID Dispatch (Core↔FFI):** `EventIds` + struct-payload + `mod_on_event`. - -### Hook-Namenskonvention -- Kanonisch: `greg..` (bzw. in Altbeständen teils uppercase Domains). -- Mappingquelle für native IDs: `gregNativeEventHooks.ByEventId`. -- Hook-Integration: `GregHookIntegration.EmitForSimple/EmitForStruct`. - -### Sandboxing-Realität (wichtig für AI/Bridge-Design) -- **Lua I/O Modul:** `src/Scripting/Lua/LuaModules/gregIoLuaModule.cs` enthält Dateioperationen (`read_file`, `write_file`, `list_files` etc.). -- Kommentar behauptet Sandbox-Scope, Implementierung zeigt aktuell keine harte Pfad-Isolation auf OS-Ebene. -- **ReferenceScanner:** lädt Assemblies via `Assembly.LoadFrom` aus Dateisystemscan; keine AppDomain/Process-Isolation. -- Damit gilt: aktuelle Isolation ist primär **kooperativ/logisch**, nicht sicherheitstechnisch stark. - -### Verbindliche Einschränkungen für neue Bindings -- Bridge-Code darf Core/Unity-Aufrufe nur über freigegebene API/Hooks ausführen. -- Keine direkten unsicheren Pointer-Operationen außerhalb definierter FFI-Wrapper. -- Untrusted Script/Native Mods als potenziell fehlerhaft behandeln (guard clauses + timeout/backpressure + exception fences). -- Für echte Sandbox-Anforderungen ist Prozessisolation (separater Host) nötig; im aktuellen In-Process-Modell nicht garantiert. - ---- - -## Appendix: Operative Leitplanken für Bridge-Autoren - -- **Schichtdisziplin:** - - Mod/Bridge → `greg.*` Hook/API, - - kein direkter Unity-Objektzugriff als öffentliches Contract. -- **ABI-Disziplin:** - - `StructLayout.Sequential`, feste Feldtypen, versionierte Erweiterung. -- **Fehlerdisziplin:** - - Jede Grenzstelle (`FFI`, `JSON parse`, `network`) mit `try/catch` + Logging. -- **Lifecycle-Disziplin:** - - `init -> update/fixed_update/gui -> shutdown` strikt einhalten. -- **Kompatibilität:** - - Runtime-Ziel bleibt `.NET 6` (IL2CPP/MelonLoader-kompatibel). diff --git a/publish_full/CHANGELOG.md b/publish_full/CHANGELOG.md deleted file mode 100644 index c33b7414..00000000 --- a/publish_full/CHANGELOG.md +++ /dev/null @@ -1,125 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [1.0.0.35-pre] - 2026-04-21 -### Fixed -- **Unity 6 Compatibility**: Fixed `UpdateCoin` Harmony patch parameter name mismatch (`_amount` -> `_coinChhangeAmount`). -- **Stability**: Switched `GregDevConsole` and UI windows to `GUI.Window` to avoid `LayoutedWindow` constructor errors in Unity 6. -- **HexViewer**: Major refactor to use stable IMGUI and current SDK namespaces. - -## [0.1.0] - 2026-04-18 -### Added -- NuGet packaging baseline for `gregCore` with symbol package output (`.snupkg`). -- Local + GitHub Packages feed configuration and package source mapping. -- Downstream `build/gregCore.props` integration for reference-only package usage. - -## [v1.0.0.7] - 2026-04-12 -### Added -- **gregUI**: Complete UI manipulation layer for UGUI (`src/UI/`). -- **GregUIManager**: Central canvas registry and lifecycle management. -- **GregUITheme**: Design system tokens (The Luminescent Architect). -- **GregUIBuilder**: Fluent builder API for mod developers. -- **UI Components**: `GregPanel`, `GregButton`, `GregLabel`, `GregToggle`, `GregSlider`, `GregBadge`, `GregSeparator`. -- **HexViewer Integration**: UI Tree Inspector (F1), Hook Monitor (F2), Element Inspector (F3). -- **UI Hooks**: New hook category `greg.UI.*` for monitoring game UI events (MainMenu, PauseMenu, HUD, Tooltips). - -### Changed -- `gregCoreLoader.OnInitializeMelon`: Now registers `GregUIManager`. -- `gregUiExtensionBridge.OnSceneLoaded`: Now notifies `GregUIManager`. - -## [v1.0.0.6] - 2026-04-12 -### Added -- **Game Compatibility Update**: Verified compatibility with *Data Center* patch `v1.0.45.5`. -- **VLAN Management**: Added `SetVlanAllowed`, `SetVlanDisallowed`, and `IsVlanAllowed` to `gregGameHooks` and `gregGameApi` (v9). -- **Route Evaluation**: Documented hooks for improved routing system. -- **gregReferences Synchronization**: Updated reference documentation for the new game version. - -## [v1.0.0.0] - 2026-04-11 -### Added -- **Phase 5 Implementation**: Initial SDK bridges for Economy and Data. -- **GregBalanceService**: Access to financial data, salaries, and income simulation. -- **GregLocalisationService**: Direct access to the game's internal translation system. -- **Roadmap Expansion**: Added Phase 8 (Unity Scripting API) and refactored all documentation to English with Material Symbols. - -## [v1.0.0.0] - 2026-04-11 -### Added -- **Game System Bridges**: 9 new SDK services for direct control of game systems via IL2CPP abstraction. -- **Hardware Bridges**: Direct interaction with physical server and rack objects. -### Added -- **Unity Signal Normalization**: 30+ canonical hooks in `GregNativeEventHooks` based on IL2CPP snapshots. -- **Full Category Registries**: Offizielle SDK-Registries für Server, Switches, Kunden, Mitarbeiter, SFP, Kabel, Möbel und Items. -- **Advanced Model Overrides**: Priority-based conflict resolution, author metadata, and diagnostics. -- **Language Bridge APIs**: Dynamic event registration for Lua (`on_update`, `on_gui`) and C# bridge surface for TS/JS. -- **Native Header**: Added `greg_api.h` for Rust/C mod developers to consume the v8 API table. -- **Validation & Migration**: `IContentValidator` and `IContentMigration` interfaces for mod data integrity. -- **Functional Services**: Basic implementation for `GregIPAllocationService` and `GregRackService`. - -### Fixed -- Fixed build issues with nullable reference types in `gregSdk`. -- Corrected test project references and added comprehensive integration tests. - -## [v1.0.0.0] - 2026-04-11 -### Fixed -- **Definitive UI Removal**: Fixed incorrect file exclusions in `.csproj` and disabled bootstrap registration in `gregCore.cs` to ensure the native UI is used. -- **Debug Overlay**: Added **F5** toggle to show/hide the debug info panel. - -## [v1.0.0.0] - 2026-04-11 -### Fixed -- Standardized all Lua modules to camelCase (`gregUnityLuaModule`, etc.). -- Fixed static/instance member access conflicts in `gregModSettingsMenuBridge`. -- Corrected over-aggressive renaming of Unity engine components (e.g. `Camera.main`). -- Normalized `gregSdk` namespace usage across the framework. - -### Changed -- Separated `gregAddons` into its own logical structure (Node.js tools and optional plugins). -- Built-in reference DLLs for out-of-the-box CI support. - -## [v1.0.0.0] - 2026-04-11 -### Added -- Missing SDK APIs for all 4 languages (C#, Rust, Lua, TS/JS). -- HUD and Targeting bridge modules for Lua. -- Advanced event subscription model. -- Windows x64 and .NET 6 as primary targets. - -### Changed -- **Major Refactor**: Renamed all directories and files to follow the `greg[Name]` camelCase convention. -- Global namespace update from `DataCenterModLoader` to `gregModLoader`. -- Global namespace update from `AssetExporter` to `gregAssetExporter`. -- Standardized author name to `MLeeM97`. - -## [v0.7.0.0] - 2026-04-10 -### Fixed -- Project references and solution structure for correct DLL paths. -- README path updates. - -## [v0.6.0.0] - 2026-04-09 -### Added -- Language bridge architecture with Lua and TypeScript/JavaScript support. -- MoonSharp integration for Lua scripting. - -## [v0.5.0.0] - 2026-04-08 -### Added -- `UiExtensionBridge` for UI feature integration and modernization. -- Custom Main Menu replacement capabilities. - -## [v0.4.0.0] - 2026-04-07 -### Added -- Scripts for generating and parsing greg hooks from IL2CPP dumps. - -## [v0.3.0.0] - 2026-04-06 -### Changed -- Flat `gregFramework` workspace layout. -- Documentation alignment with the new repository structure. - -## [v0.2.0.0] - 2026-04-05 -### Added -- RustBridge integration for native mod support via FFI. - -## [v0.1.0.0] - 2026-04-04 -### Added -- Initial standalone repository setup. -- Basic MelonLoader mod structure. - diff --git a/publish_full/README.md b/publish_full/README.md deleted file mode 100644 index 01344ff2..00000000 --- a/publish_full/README.md +++ /dev/null @@ -1,89 +0,0 @@ -# gregCore - Framework Core - -> The heart of the gregFramework modding ecosystem for Data Center. - -**Author:** MLeeM97 (teamGreg) | **License:** MIT | **Framework:** [gregCore](https://git.datacentermods.com/teamGreg/gregCore) - ---- - -## Features -- **GregSaveService** - Persistent mod data storage -- **GregUIBuilder** - FixedTableUI, Panel System, Canvas Management -- **GregPersistenceService** - Centralized `UserData/gregCore/Data/` storage -- **GregMCPServer** - Embedded HTTP MCP server (Port 10420) for external tooling -- **GregMultiplayerService** - WebSocket relay-based multiplayer -- **Harmony Patches** - MainMenu, MODS Button injection -- **IL2CPP Compatibility** - InputSystem, Coroutines, Il2CppTMPro -- **MoonSharp Lua** - Embedded scripting engine -- **Integrated DataCenter Compatibility Layer** - RustBridge/LangCompat runtime is embedded in-core under `src/Compatibility/DataCenterModLoader` - -## Installation - -1. Install **MelonLoader** (v0.6+) -2. Place `gregCore.dll` + `gregCore.dll` into `Game/Mods/` -3. Start the game and press **Framework auto-initializes on game start** - -## Dependencies - -- Built-in only (this IS the core) -- Legacy `RustBridge` and `LangCompatBridge` are integrated into `gregCore` and are no longer shipped as standalone external plugin/mod dependencies - -## Architecture Update - -- Legacy external trees `plugins/DataCenter-RustBridge` and `mods/greg.Plugin.LangCompatBridge` were retired from `gregCore` -- Runtime compatibility lifecycle is now wired directly from `GregCoreMod` to `DataCenterModLoader.Core` -- Compatibility sources are maintained in-core at `src/Compatibility/DataCenterModLoader` - -## Building from Source - -```bash -cd gregFramework/gregCore -dotnet build -c Release -# Output: bin/Release/net6.0/gregCore.dll -``` - -Or build everything at once: - -```bash -cd gregFramework/deploy -./build-all.ps1 -# Output: gregFramework/BuiltModsForGame/ -``` - -## Links - -- **Primary:** [git.datacentermods.com/teamGreg](https://git.datacentermods.com/teamGreg) -- **Discord:** [discord.gg/greg](https://discord.gg/greg) - ---- - -## Contributors & Thanks - -### Discord Community -**Thanks to:** -- **Noootry** -- **TheSlickers** -- **Jarvis** -- **Kirei** -- **TeamWaseku** (ModernSamurai, GamerFrankstar, Ultra, Zyn) - -*...for keeping the community alive!* - -### Code & Testing -**Special thanks:** -- **Joniii** & **mochimus** - Code + Tests -- **Baker**, **Sharpy1o1**, **MachineFreak** - Testing + Modeling - -### Sponsors -- **@tobiasreichel** - Haupt-Sponsor -- **SQ8** - Infrastructure Hosting - ---- -*gregFramework - Powered by the Community!* - - - -## Contributors -- @mleem97 -- @Joniii11 -