From ee3f30e5026d0636075905336880a8676e8dd59a Mon Sep 17 00:00:00 2001 From: Marvin <52848568+mleem97@users.noreply.github.com> Date: Fri, 10 Apr 2026 03:36:30 +0200 Subject: [PATCH] docs: update sidebar and documentation to include greg hooks registry - Added new items to the sidebar for 'greg-hooks-and-events' and 'greg-hooks-registry' under the Framework and Reference categories, respectively. - Enhanced the documentation layout by including references to the greg hooks registry in various guides and topics, improving accessibility to hook-related information. - Updated descriptions in the documentation to clarify the purpose and usage of the greg hooks and their registry. This commit aims to improve the visibility and usability of the greg hooks registry within the documentation. --- docs/framework/greg-hooks-and-events.md | 53 ++++++ docs/getting-started/documentation-layout.md | 2 +- .../mod-developers/greg-hooks-showcase.md | 64 +++++-- docs/guides/mod-developers/overview.md | 1 + docs/mods/framework.md | 1 + docs/reference/fmf-hook-naming.md | 4 + docs/reference/fmf-hooks-catalog.md | 162 +++++++++--------- docs/reference/greg-hooks-registry.md | 80 +++++++++ docs/reference/reference-data-files.md | 10 ++ docs/topics/ffi-and-hooks/overview.md | 1 + docs/topics/index.md | 2 +- docs/topics/reference/overview.md | 1 + sidebars.js | 8 +- 13 files changed, 292 insertions(+), 97 deletions(-) create mode 100644 docs/framework/greg-hooks-and-events.md create mode 100644 docs/reference/greg-hooks-registry.md diff --git a/docs/framework/greg-hooks-and-events.md b/docs/framework/greg-hooks-and-events.md new file mode 100644 index 0000000..273e684 --- /dev/null +++ b/docs/framework/greg-hooks-and-events.md @@ -0,0 +1,53 @@ +--- +title: Greg hooks & event runtime +sidebar_label: Greg hooks & events +description: greg.* hook registry, GregEventDispatcher, Rust FFI event ids, and how they relate to legacy FFM strings. +--- + +# Greg hooks & event runtime + +The **FrikaModdingFramework** assembly (`gregCore/FrikaMF.csproj`, output **`FrikaModdingFramework.dll`**) combines Harmony patches, C# mod events, and the Rust/native bridge. Mod and plugin authors should understand **three related surfaces**: + +| Surface | Purpose | Typical entry | +|--------|---------|----------------| +| **`greg.*` string hooks** | Canonical hook names for new work; registry drives codegen and docs. | `GregEventDispatcher.On("greg....", handler, modId)` in **`gregFramework.Core`** | +| **Legacy `FFM.*` strings** | Numeric Rust/game pipeline still resolves through **`HookNames`** constants today. | [`FrikaMF/HookNames.cs`](https://github.com/mleem97/gregFramework/blob/main/gregCore/FrikaMF/HookNames.cs), [`EventIds.cs`](https://github.com/mleem97/gregFramework/blob/main/gregCore/FrikaMF/EventIds.cs) | +| **In-process mod messages** | Cross-mod C# notifications (not the same as `greg.*`). | `AssetExporter.ModFramework` / **`ModFramework.Events`** | + +Naming policy for **new** public identifiers remains **`FMF..*`** — see [FMF hook naming](/wiki/reference/fmf-hook-naming). The **`greg.*`** registry is generated from the Il2Cpp unpack and is the **runtime source of truth** for Harmony bridge patches in **`gregFramework.Hooks`** (auto-generated types under `gregCore/Hooks/`). + +## `greg_hooks.json` (version 2) + +- **Repo paths:** `gregCore/gregFramework/greg_hooks.json` (and a mirrored copy under `gregCore/framework/gregFramework/` for some builds). +- **Meaning:** canonical list of `greg..` hooks with patch targets, strategies, and payload hints. +- **Regenerate:** `gregCore/scripts/Generate-GregHooksFromIl2CppDump.ps1` when `gregReferences/` Il2Cpp unpack or merged interop changes. +- **Runtime compat:** **`GregCompatBridge`** (`gregFramework.Core`) can load **`greg_hooks.json`** next to the framework DLL to map legacy spellings. + +## `GregEventDispatcher` + +Implemented in **`gregCore/Core/GregEventDispatcher.cs`** (`namespace gregFramework.Core`). Use **`On` / `Once` / `Off` / `Emit`** (and cancelable overloads where exposed) for string-keyed hooks with optional **`modId`** for diagnostics. + +## Rust FFI and numeric events + +Rust mods receive **numeric** event ids; C# maps them via **`EventDispatcher`** / **`GregHookIntegration`** in the **`FrikaMF`** tree so that game and bridge traffic can still surface as **`greg.*`** where integrated. Standalone bridge documentation: `gregCore/bridges/gregSta.RustBridge/README.md`. + +## MelonLoader entry points (same DLL) + +Two **`MelonMod`** types ship in one assembly for different scenarios (check `MelonInfo` / `MelonGame` attributes in source): + +- **`DataCenterModLoader.Core`** — primary Data Center + Rust load path (`FrikaMF/Core.cs`). +- **`AssetExporter.Main`** — broader tooling / dev entry (`Main.cs`), also participates in framework bootstrap paths. + +Exact responsibilities evolve in **`gregCore`**; treat this split as **“two hosts, one framework DLL”** when debugging load order. + +## Tooling & assistants + +- **MCP:** `greg_hook_registry`, `greg_hook_search`, `greg_hook_stats` read **`greg_hooks.json`** when `dataRoot` points at **`gregCore/`** — see [MCP server](/wiki/reference/mcp-server). +- **Legacy catalog page:** [FMF hooks catalog](/wiki/reference/fmf-hooks-catalog) is generated from **`FrikaMF/HookNames.cs`** and **`FrikaMF/EventIds.cs`** (`tools/Generate-FmfHookCatalog.ps1`). +- **Declarative doc stub:** [FMF Hook Reference](/wiki/framework/fmf-hooks) (from `fmf_hooks.json` / scanner, may lag core). + +## See also + +- [Repository architecture](/wiki/framework/architecture) +- [FFI, hooks & Lua (hub)](/wiki/topics/ffi-and-hooks/overview) +- [Getting started](/wiki/getting-started) diff --git a/docs/getting-started/documentation-layout.md b/docs/getting-started/documentation-layout.md index 7896964..a8b64ec 100644 --- a/docs/getting-started/documentation-layout.md +++ b/docs/getting-started/documentation-layout.md @@ -22,7 +22,7 @@ This folder is the **single source of truth** for the public Docusaurus site. Th | **Tools** | [`tools/`](../tools/workshop-uploader.md) | Workshop uploader and related. | | **Guides** | [`guides/`](../guides/players/overview.md) | Role-based paths (players, mod developers, contributors, sponsors). | | **Releases** | [`releases/`](../releases/index.mdx) | Per-artifact release notes. | -| **Reference** | [`reference/`](../reference/wiki-mapping.md) | Naming, catalogs, MCP, release channels. | +| **Reference** | [`reference/`](../reference/wiki-mapping.md) | Naming, catalogs, [`greg_hooks` registry](../reference/greg-hooks-registry.md), MCP, release channels. | | **Contributors** | [`contributors/`](../contributors/repo-inventory.md) | Repo inventory, Docusaurus workflow, design system. | | **Roadmap** | [`roadmap/`](../roadmap/unified-roadmap.md) | Planning docs. | | **Topics hub** | [`topics/`](../topics/index.md) | Cross-cutting overviews (assets, multiplayer, security, …). | diff --git a/docs/guides/mod-developers/greg-hooks-showcase.md b/docs/guides/mod-developers/greg-hooks-showcase.md index 91a935c..13d257f 100644 --- a/docs/guides/mod-developers/greg-hooks-showcase.md +++ b/docs/guides/mod-developers/greg-hooks-showcase.md @@ -1,41 +1,77 @@ --- title: Greg hooks showcase (sample mod) sidebar_label: Greg hooks showcase -description: How to subscribe to greg.* hooks via GregShowcaseMod and gregFramework.Core APIs. +description: Subscribe to greg.* hooks via GregShowcaseMod, GregEventDispatcher, GregPayload, and optional OnCancelable veto. --- # Greg hooks showcase -The repository includes **GregShowcaseMod** (`mods/GregShowcaseMod/` in **gregFramework**): a minimal MelonLoader mod that logs one representative event per **GregDomain**, using only public APIs: +The **gregFramework** repo ships **GregShowcaseMod** at `mods/GregShowcaseMod/`. It demonstrates the public API only: -- `GregEventDispatcher.On` / `UnregisterAll` +- `GregEventDispatcher.On` / `Once` / `OnCancelable` / `UnregisterAll` - `GregHookName.Create(GregDomain.*, "Action")` -- `GregPayload.Get` / `GregPayload.Dump` for anonymous payloads +- `GregPayload.Get` / `GregPayload.Dump` for anonymous payloads ## Canonical hook strings -Runtime hook names look like `greg..`, e.g. `greg.PLAYER.MoneyChanged`. Build the string with `GregHookName.Create` — do not concatenate raw strings in mods. +Runtime names look like `greg..`. Always build them with `GregHookName.Create` — do not concatenate raw strings in mods. -## Registry file +## Registry -`greg_hooks.json` (shipped beside `FrikaModdingFramework.dll`) is generated from `MergedCode.md` by: +**`greg_hooks.json`** at the **gregFramework** repository root is the canonical catalog (`description`, `payloadSchema`, `strategy`, optional `legacy`). A copy is emitted next to **`FrikaModdingFramework.dll`** for `GregCompatBridge` legacy resolution. -```bash -pwsh gregCore/scripts/Generate-GregHooksFromMergedCode.ps1 +Authoritative documentation: [greg hooks registry (IL2CPP)](/wiki/reference/greg-hooks-registry) — regeneration script, whitelist, and Harmony deduplication rules. + +## FFI bridge and greg.* emission + +`DataCenterModLoader.EventDispatcher` emits **`greg.*`** events through **`GregHookIntegration`** for the same gameplay moments as the Rust FFI event ids (money, cables, customers, save/load, etc.), even when the FFI bridge is not connected. + +## Payload access patterns + +**Pattern A — dynamic (anonymous types from compiler):** + +```csharp +private static void OnMoneyChanged(object payload) +{ + dynamic p = payload; + float delta = (float)p.coinChangeAmount; + float balance = (float)p.newBalance; + MelonLogger.Msg($"Δ={delta} → {balance}"); +} ``` -Options are passed through to `parse_merged_code.py` (e.g. `--no-hot-loops` to omit `Update`/`FixedUpdate` from the catalog). The dump is large; regeneration can take several minutes. +**Pattern B — `GregPayload` (reflection, case-insensitive property names):** -## Sample subscriptions +```csharp +private static void OnReputationChanged(object payload) +{ + var amount = GregPayload.Get(payload, "amount"); + var rep = GregPayload.Get(payload, "reputation"); + MelonLogger.Msg($"Reputation: {amount} → {rep}"); +} +``` -See `mods/GregShowcaseMod/Handlers/*.cs` — each file registers one hook for its domain (except **POWER**, where `GregPowerHooks` is still empty until Il2Cpp types are classified). +**Pattern C — typed record (when you define a shared contract in your mod or core):** + +```csharp +// public record PlayerMoneyPayload(float CoinChangeAmount, float NewBalance, bool WithoutSound, bool Accepted); +// if (payload is PlayerMoneyPayload p) { ... } +``` + +Use **`GregPayload.Dump(payload)`** for one-line debug strings. + +## Prefix hooks and cancellation + +Hooks that run **before** the original method (Harmony Prefix) can call **`GregEventDispatcher.InvokeCancelable(hookName, payload)`**. Mods register **`GregEventDispatcher.OnCancelable(hookName, p => bool, modId)`**; if any handler returns `false`, the integration can skip the original (e.g. `Player.UpdateCoin`). + +Showcase: enable `blockNegativeTransactions` in `content/modconfig.json` to register a veto on large negative `coinChangeAmount` values. ## Configuration -Copy `mods/GregShowcaseMod/modconfig.example.json` to `{Game}/Mods/GregShowcaseMod/modconfig.json` to toggle per-domain logging. +Edit **`content/modconfig.json`** next to the built DLL (defaults are copied from the repo). Keys include `logPlayerEvents`, `logNetworkEvents`, `blockNegativeTransactions`, `reputationWarningThreshold`. ## See also - [Mod developers (hub)](./overview) - [System architecture principles](/wiki/meta/system-architecture-principles) -- [Framework](/wiki/mods/framework) — runtime overview +- [Framework](/wiki/mods/framework) diff --git a/docs/guides/mod-developers/overview.md b/docs/guides/mod-developers/overview.md index ea946c4..8542ee2 100644 --- a/docs/guides/mod-developers/overview.md +++ b/docs/guides/mod-developers/overview.md @@ -9,6 +9,7 @@ description: Getting started, mod config, debugging — curated docs for FMF mod **Mod authors** — build your own mods (hooks, configuration, debugging). Role overview: [By audience](/wiki/guides/players/audiences-overview). - [Greg hooks showcase](/wiki/guides/mod-developers/greg-hooks-showcase) — sample mod (`GregShowcaseMod`) and `GregPayload` usage +- [greg hooks registry (IL2CPP)](/wiki/reference/greg-hooks-registry) — `greg_hooks.json`, regeneration, overlap with `HarmonyPatches` - [System architecture & documentation principles](/wiki/meta/system-architecture-principles) — layer model **ModManager → Framework → Plugins → Mods**, priorities, wiki rules - [By audience — intermediates](/wiki/audiences/intermediates) and [professionals](/wiki/audiences/professionals) - [Framework overview](/wiki/mods/framework) — runtime capabilities and repo layout diff --git a/docs/mods/framework.md b/docs/mods/framework.md index b10256d..607d502 100644 --- a/docs/mods/framework.md +++ b/docs/mods/framework.md @@ -19,4 +19,5 @@ The core `FrikaMF` runtime provides: - [FMF hooks (generated)](/wiki/framework/fmf-hooks) — hook surface and categories - [FMF hook naming](/wiki/reference/fmf-hook-naming) — `FMF.*` vs legacy `FFM.*` - [FMF hooks catalog](/wiki/reference/fmf-hooks-catalog) — strings from core `HookNames.cs` +- [greg hooks registry (IL2CPP)](/wiki/reference/greg-hooks-registry) — `greg.*` Harmony hooks and `greg_hooks.json` - [Framework architecture](/wiki/framework/architecture) — runtime layout and bridges diff --git a/docs/reference/fmf-hook-naming.md b/docs/reference/fmf-hook-naming.md index 971c427..f53769e 100644 --- a/docs/reference/fmf-hook-naming.md +++ b/docs/reference/fmf-hook-naming.md @@ -40,6 +40,10 @@ Domains are **closed by default**. Add a new domain only via changelog + maintai | `SAVE` | Save/load lifecycle | | `FRAMEWORK` | Loader, bridge, diagnostics | +## Runtime IL2CPP (MelonLoader): `greg.*` + +Harmony patches in **gregFramework** emit stable **`greg..`** strings via `GregHookName` / `GregEventDispatcher`. That surface is documented in **[greg hooks registry (IL2CPP)](/wiki/reference/greg-hooks-registry)** (`greg_hooks.json`, regeneration, overlap with hand-written `HarmonyPatches`). It is separate from the `FMF.*` / `FFM.*` documentation constants below. + ## Legacy: `FFM.*` strings in code The runtime currently maps numeric event IDs to **`FFM.*`** string constants in [`FrikaMF/HookNames.cs`](https://github.com/mleem97/gregFramework/blob/master/FrikaMF/HookNames.cs) (e.g. `FFM.Economy.Balance.OnChanged`). That is **legacy naming** (four segments after `FFM`). diff --git a/docs/reference/fmf-hooks-catalog.md b/docs/reference/fmf-hooks-catalog.md index ac62bb4..4c7766d 100644 --- a/docs/reference/fmf-hooks-catalog.md +++ b/docs/reference/fmf-hooks-catalog.md @@ -9,101 +9,103 @@ description: Auto-generated catalog of hook strings and event id mappings from F # FMF hooks catalog -This page is **generated** from `framework/FrikaMF/HookNames.cs` and `framework/FrikaMF/EventIds.cs`. +This page is **generated** from `gregCore/FrikaMF/HookNames.cs` and `gregCore/FrikaMF/EventIds.cs`. +Regenerate after hook changes: `./tools/Generate-FmfHookCatalog.ps1` -**Generated:** 2026-04-06 14:26:09 UTC +**Generated:** 2026-04-10 01:36:21 UTC ## Hook string constants | C# field | Hook string | |----------|-------------| -| ``CustomerContractOnSigned`` | ``FFM.Customer.Contract.OnSigned`` | -| ``CustomerReputationOnChanged`` | ``FFM.Customer.Reputation.OnChanged`` | -| ``CustomerSlaOnBreached`` | ``FFM.Customer.SLA.OnBreached`` | -| ``CustomerSlaOnRestored`` | ``FFM.Customer.SLA.OnRestored`` | -| ``EconomyBalanceOnChanged`` | ``FFM.Economy.Balance.OnChanged`` | -| ``EmployeesStaffOnHiredCustom`` | ``FFM.Employees.Staff.OnHired`` | -| ``EmployeesStaffOnTerminatedCustom`` | ``FFM.Employees.Staff.OnTerminated`` | -| ``FrameworkHooksOnBridgeInstalled`` | ``FFM.Framework.Hooks.OnBridgeInstalled`` | -| ``FrameworkHooksOnBridgeTriggered`` | ``FFM.Framework.Hooks.OnBridgeTriggered`` | -| ``GameLoadOnCompleted`` | ``FFM.Game.Load.OnCompleted`` | -| ``GameSaveOnCompleted`` | ``FFM.Game.Save.OnCompleted`` | -| ``GameSaveOnRequested`` | ``FFM.Game.Save.OnRequested`` | -| ``GameTimeOnDayChanged`` | ``FFM.Game.Time.OnDayChanged`` | -| ``GameTimeOnMonthChanged`` | ``FFM.Game.Time.OnMonthChanged`` | -| ``GameXpOnGained`` | ``FFM.Game.XP.OnGained`` | -| ``NetworkCableOnConnected`` | ``FFM.Network.Cable.OnConnected`` | -| ``NetworkCableOnConnectedSuppress`` | ``FFM.Network.Cable.OnConnected.Suppress`` | -| ``NetworkCableOnDisconnected`` | ``FFM.Network.Cable.OnDisconnected`` | -| ``NetworkCableOnDisconnectedSuppress`` | ``FFM.Network.Cable.OnDisconnected.Suppress`` | -| ``NetworkCableOnLinkDown`` | ``FFM.Network.Cable.OnLinkDown`` | -| ``NetworkCableOnLinkUp`` | ``FFM.Network.Cable.OnLinkUp`` | -| ``NetworkTrafficOnThresholdExceeded`` | ``FFM.Network.Traffic.OnThresholdExceeded`` | -| ``ObjectsDeviceOnDegraded`` | ``FFM.Objects.Device.OnDegraded`` | -| ``ObjectsDeviceOnEOL`` | ``FFM.Objects.Device.OnEOL`` | -| ``ObjectsDeviceOnPoweredOff`` | ``FFM.Objects.Device.OnPoweredOff`` | -| ``ObjectsDeviceOnPoweredOn`` | ``FFM.Objects.Device.OnPoweredOn`` | -| ``ObjectsDeviceOnRepaired`` | ``FFM.Objects.Device.OnRepaired`` | -| ``ObjectsRackOnDevicePlaced`` | ``FFM.Objects.Rack.OnDevicePlaced`` | -| ``ObjectsRackOnRemoved`` | ``FFM.Objects.Rack.OnRemoved`` | -| ``ObjectsServerOnClientAssigned`` | ``FFM.Objects.Server.OnClientAssigned`` | -| ``ObjectsServerOnClientUnassigned`` | ``FFM.Objects.Server.OnClientUnassigned`` | -| ``StoreCartOnCheckedOutCleared`` | ``FFM.Store.Cart.OnCheckedOut`` | -| ``StoreCartOnItemAdded`` | ``FFM.Store.Cart.OnItemAdded`` | -| ``StoreCartOnItemRemoved`` | ``FFM.Store.Cart.OnItemRemoved`` | -| ``WorldRoomOnExpanded`` | ``FFM.World.Room.OnExpanded`` | +| ``CustomerContractOnSigned`` | ``greg.Customer.Contract.OnSigned`` | +| ``CustomerReputationOnChanged`` | ``greg.Customer.Reputation.OnChanged`` | +| ``CustomerSlaOnBreached`` | ``greg.Customer.SLA.OnBreached`` | +| ``CustomerSlaOnRestored`` | ``greg.Customer.SLA.OnRestored`` | +| ``EconomyBalanceOnChanged`` | ``greg.Economy.Balance.OnChanged`` | +| ``EmployeesStaffOnHired`` | ``greg.Employees.Staff.OnHired`` | +| ``EmployeesStaffOnTerminatedCustom`` | ``greg.Employees.Staff.OnTerminated`` | +| ``FrameworkHooksOnBridgeInstalled`` | ``greg.Framework.Hooks.OnBridgeInstalled`` | +| ``FrameworkHooksOnBridgeTriggered`` | ``greg.Framework.Hooks.OnBridgeTriggered`` | +| ``GameLoadOnCompleted`` | ``greg.Game.Load.OnCompleted`` | +| ``GameSaveOnCompleted`` | ``greg.Game.Save.OnCompleted`` | +| ``GameSaveOnRequested`` | ``greg.Game.Save.OnRequested`` | +| ``GameTimeOnDayChanged`` | ``greg.Game.Time.OnDayChanged`` | +| ``GameTimeOnMonthChanged`` | ``greg.Game.Time.OnMonthChanged`` | +| ``GameXpOnGained`` | ``greg.Game.XP.OnGained`` | +| ``NetworkCableOnConnected`` | ``greg.Network.Cable.OnConnected`` | +| ``NetworkCableOnConnectedSuppress`` | ``greg.Network.Cable.OnConnected.Suppress`` | +| ``NetworkCableOnDisconnected`` | ``greg.Network.Cable.OnDisconnected`` | +| ``NetworkCableOnDisconnectedSuppress`` | ``greg.Network.Cable.OnDisconnected.Suppress`` | +| ``NetworkCableOnLinkDown`` | ``greg.Network.Cable.OnLinkDown`` | +| ``NetworkCableOnLinkUp`` | ``greg.Network.Cable.OnLinkUp`` | +| ``NetworkTrafficOnThresholdExceeded`` | ``greg.Network.Traffic.OnThresholdExceeded`` | +| ``ObjectsDeviceOnDegraded`` | ``greg.Objects.Device.OnDegraded`` | +| ``ObjectsDeviceOnEOL`` | ``greg.Objects.Device.OnEOL`` | +| ``ObjectsDeviceOnPoweredOff`` | ``greg.Objects.Device.OnPoweredOff`` | +| ``ObjectsDeviceOnPoweredOn`` | ``greg.Objects.Device.OnPoweredOn`` | +| ``ObjectsDeviceOnRepaired`` | ``greg.Objects.Device.OnRepaired`` | +| ``ObjectsRackOnDevicePlaced`` | ``greg.Objects.Rack.OnDevicePlaced`` | +| ``ObjectsRackOnRemoved`` | ``greg.Objects.Rack.OnRemoved`` | +| ``ObjectsServerOnClientAssigned`` | ``greg.Objects.Server.OnClientAssigned`` | +| ``ObjectsServerOnClientUnassigned`` | ``greg.Objects.Server.OnClientUnassigned`` | +| ``StoreCartOnCheckedOut`` | ``greg.Store.Cart.OnCheckedOut`` | +| ``StoreCartOnItemAdded`` | ``greg.Store.Cart.OnItemAdded`` | +| ``StoreCartOnItemRemoved`` | ``greg.Store.Cart.OnItemRemoved`` | +| ``WorldRoomOnExpanded`` | ``greg.World.Room.OnExpanded`` | ## Event id to hook mapping | Event id (uint) | EventIds name | Resolves to field | Hook string | |-----------------|---------------|---------------------|-------------| -| 213 | `CableCleared` | `StoreCartOnCheckedOutCleared` | `FFM.Store.Cart.OnCheckedOut` | -| 204 | `CableConnected` | `NetworkCableOnConnected` | `FFM.Network.Cable.OnConnected` | -| 211 | `CableCreated` | `NetworkCableOnConnected` | `FFM.Network.Cable.OnConnected` | -| 205 | `CableDisconnected` | `NetworkCableOnDisconnected` | `FFM.Network.Cable.OnDisconnected` | -| 212 | `CableRemoved` | `NetworkCableOnDisconnected` | `FFM.Network.Cable.OnDisconnected` | -| 215 | `CableSfpInserted` | `NetworkCableOnConnected` | `FFM.Network.Cable.OnConnected` | -| 216 | `CableSfpRemoved` | `NetworkCableOnDisconnected` | `FFM.Network.Cable.OnDisconnected` | -| 214 | `CableSpeedChanged` | `NetworkTrafficOnThresholdExceeded` | `FFM.Network.Traffic.OnThresholdExceeded` | -| 1001 | `CustomEmployeeFired` | `EmployeesStaffOnTerminatedCustom` | `FFM.Employees.Staff.OnTerminated` | -| 1000 | `CustomEmployeeHired` | `EmployeesStaffOnHiredCustom` | `FFM.Employees.Staff.OnHired` | -| 400 | `CustomerAccepted` | `CustomerContractOnSigned` | `FFM.Customer.Contract.OnSigned` | -| 401 | `CustomerSatisfied` | `CustomerSlaOnRestored` | `FFM.Customer.SLA.OnRestored` | -| 402 | `CustomerUnsatisfied` | `CustomerSlaOnBreached` | `FFM.Customer.SLA.OnBreached` | -| 300 | `DayEnded` | `GameTimeOnDayChanged` | `FFM.Game.Time.OnDayChanged` | -| 601 | `EmployeeFired` | `EmployeesStaffOnTerminated` | `FFM.Employees.Staff.OnTerminated` | -| 600 | `EmployeeHired` | `EmployeesStaffOnHired` | `FFM.Employees.Staff.OnHired` | -| 702 | `GameAutoSaved` | `GameSaveOnRequested` | `FFM.Game.Save.OnRequested` | -| 701 | `GameLoaded` | `GameLoadOnCompleted` | `FFM.Game.Load.OnCompleted` | -| 700 | `GameSaved` | `GameSaveOnCompleted` | `FFM.Game.Save.OnCompleted` | -| 1100 | `HookBridgeInstalled` | `FrameworkHooksOnBridgeInstalled` | `FFM.Framework.Hooks.OnBridgeInstalled` | -| 1101 | `HookBridgeTriggered` | `FrameworkHooksOnBridgeTriggered` | `FFM.Framework.Hooks.OnBridgeTriggered` | -| 100 | `MoneyChanged` | `EconomyBalanceOnChanged` | `FFM.Economy.Balance.OnChanged` | -| 301 | `MonthEnded` | `GameTimeOnMonthChanged` | `FFM.Game.Time.OnMonthChanged` | -| 900 | `NetWatchDispatched` | `NetworkTrafficOnThresholdExceeded` | `FFM.Network.Traffic.OnThresholdExceeded` | -| 208 | `RackUnmounted` | `ObjectsRackOnRemoved` | `FFM.Objects.Rack.OnRemoved` | -| 102 | `ReputationChanged` | `CustomerReputationOnChanged` | `FFM.Customer.Reputation.OnChanged` | -| 207 | `ServerAppChanged` | `ObjectsServerOnClientUnassigned` | `FFM.Objects.Server.OnClientUnassigned` | -| 201 | `ServerBroken` | `ObjectsDeviceOnDegraded` | `FFM.Objects.Device.OnDegraded` | -| 206 | `ServerCustomerChanged` | `ObjectsServerOnClientAssigned` | `FFM.Objects.Server.OnClientAssigned` | -| 203 | `ServerInstalled` | `ObjectsRackOnDevicePlaced` | `FFM.Objects.Rack.OnDevicePlaced` | -| 200 | `ServerPowered` | `ObjectsDeviceOnPoweredOn` | `FFM.Objects.Device.OnPoweredOn` | -| 202 | `ServerRepaired` | `ObjectsDeviceOnRepaired` | `FFM.Objects.Device.OnRepaired` | -| 502 | `ShopCartCleared` | `StoreCartOnCheckedOutCleared` | `FFM.Store.Cart.OnCheckedOut` | -| 500 | `ShopCheckout` | `StoreCartOnCheckedOut` | `FFM.Store.Cart.OnCheckedOut` | -| 501 | `ShopItemAdded` | `StoreCartOnItemAdded` | `FFM.Store.Cart.OnItemAdded` | -| 503 | `ShopItemRemoved` | `StoreCartOnItemRemoved` | `FFM.Store.Cart.OnItemRemoved` | -| 209 | `SwitchBroken` | `NetworkCableOnLinkDown` | `FFM.Network.Cable.OnLinkDown` | -| 210 | `SwitchRepaired` | `NetworkCableOnLinkUp` | `FFM.Network.Cable.OnLinkUp` | -| 800 | `WallPurchased` | `WorldRoomOnExpanded` | `FFM.World.Room.OnExpanded` | -| 101 | `XPChanged` | `GameXpOnGained` | `FFM.Game.XP.OnGained` | +| 213 | `CableCleared` | `StoreCartOnCheckedOutCleared` | `greg.Store.Cart.OnCheckedOut` | +| 204 | `CableConnected` | `NetworkCableOnConnected` | `greg.Network.Cable.OnConnected` | +| 211 | `CableCreated` | `NetworkCableOnConnected` | `greg.Network.Cable.OnConnected` | +| 205 | `CableDisconnected` | `NetworkCableOnDisconnected` | `greg.Network.Cable.OnDisconnected` | +| 212 | `CableRemoved` | `NetworkCableOnDisconnected` | `greg.Network.Cable.OnDisconnected` | +| 215 | `CableSfpInserted` | `NetworkCableOnConnected` | `greg.Network.Cable.OnConnected` | +| 216 | `CableSfpRemoved` | `NetworkCableOnDisconnected` | `greg.Network.Cable.OnDisconnected` | +| 214 | `CableSpeedChanged` | `NetworkTrafficOnThresholdExceeded` | `greg.Network.Traffic.OnThresholdExceeded` | +| 1001 | `CustomEmployeeFired` | `EmployeesStaffOnTerminatedCustom` | `greg.Employees.Staff.OnTerminated` | +| 1000 | `CustomEmployeeHired` | `EmployeesStaffOnHiredCustom` | `greg.Employees.Staff.OnHired` | +| 400 | `CustomerAccepted` | `CustomerContractOnSigned` | `greg.Customer.Contract.OnSigned` | +| 401 | `CustomerSatisfied` | `CustomerSlaOnRestored` | `greg.Customer.SLA.OnRestored` | +| 402 | `CustomerUnsatisfied` | `CustomerSlaOnBreached` | `greg.Customer.SLA.OnBreached` | +| 300 | `DayEnded` | `GameTimeOnDayChanged` | `greg.Game.Time.OnDayChanged` | +| 601 | `EmployeeFired` | `EmployeesStaffOnTerminated` | `greg.Employees.Staff.OnTerminated` | +| 600 | `EmployeeHired` | `EmployeesStaffOnHired` | `greg.Employees.Staff.OnHired` | +| 702 | `GameAutoSaved` | `GameSaveOnRequested` | `greg.Game.Save.OnRequested` | +| 701 | `GameLoaded` | `GameLoadOnCompleted` | `greg.Game.Load.OnCompleted` | +| 700 | `GameSaved` | `GameSaveOnCompleted` | `greg.Game.Save.OnCompleted` | +| 1100 | `HookBridgeInstalled` | `FrameworkHooksOnBridgeInstalled` | `greg.Framework.Hooks.OnBridgeInstalled` | +| 1101 | `HookBridgeTriggered` | `FrameworkHooksOnBridgeTriggered` | `greg.Framework.Hooks.OnBridgeTriggered` | +| 100 | `MoneyChanged` | `EconomyBalanceOnChanged` | `greg.Economy.Balance.OnChanged` | +| 301 | `MonthEnded` | `GameTimeOnMonthChanged` | `greg.Game.Time.OnMonthChanged` | +| 900 | `NetWatchDispatched` | `NetworkTrafficOnThresholdExceeded` | `greg.Network.Traffic.OnThresholdExceeded` | +| 208 | `RackUnmounted` | `ObjectsRackOnRemoved` | `greg.Objects.Rack.OnRemoved` | +| 102 | `ReputationChanged` | `CustomerReputationOnChanged` | `greg.Customer.Reputation.OnChanged` | +| 207 | `ServerAppChanged` | `ObjectsServerOnClientUnassigned` | `greg.Objects.Server.OnClientUnassigned` | +| 201 | `ServerBroken` | `ObjectsDeviceOnDegraded` | `greg.Objects.Device.OnDegraded` | +| 206 | `ServerCustomerChanged` | `ObjectsServerOnClientAssigned` | `greg.Objects.Server.OnClientAssigned` | +| 203 | `ServerInstalled` | `ObjectsRackOnDevicePlaced` | `greg.Objects.Rack.OnDevicePlaced` | +| 200 | `ServerPowered` | `ObjectsDeviceOnPoweredOn` | `greg.Objects.Device.OnPoweredOn` | +| 202 | `ServerRepaired` | `ObjectsDeviceOnRepaired` | `greg.Objects.Device.OnRepaired` | +| 502 | `ShopCartCleared` | `StoreCartOnCheckedOutCleared` | `greg.Store.Cart.OnCheckedOut` | +| 500 | `ShopCheckout` | `StoreCartOnCheckedOut` | `greg.Store.Cart.OnCheckedOut` | +| 501 | `ShopItemAdded` | `StoreCartOnItemAdded` | `greg.Store.Cart.OnItemAdded` | +| 503 | `ShopItemRemoved` | `StoreCartOnItemRemoved` | `greg.Store.Cart.OnItemRemoved` | +| 209 | `SwitchBroken` | `NetworkCableOnLinkDown` | `greg.Network.Cable.OnLinkDown` | +| 210 | `SwitchRepaired` | `NetworkCableOnLinkUp` | `greg.Network.Cable.OnLinkUp` | +| 800 | `WallPurchased` | `WorldRoomOnExpanded` | `greg.World.Room.OnExpanded` | +| 101 | `XPChanged` | `GameXpOnGained` | `greg.Game.XP.OnGained` | ## Fallback -Unknown event ids resolve to ``FFM.Framework.Unknown.OnEvent`` in `HookNames.Resolve`. +Unknown event ids resolve to ``greg.Framework.Unknown.OnEvent`` in `HookNames.Resolve`. ## See also - [FMF hook naming](./fmf-hook-naming.md) -- [EventIds source](https://github.com/mleem97/gregFramework/blob/master/framework/FrikaMF/EventIds.cs) -- [HookNames source](https://github.com/mleem97/gregFramework/blob/master/framework/FrikaMF/HookNames.cs) +- [EventIds source](https://github.com/mleem97/gregFramework/blob/main/gregCore/FrikaMF/EventIds.cs) +- [HookNames source](https://github.com/mleem97/gregFramework/blob/main/gregCore/FrikaMF/HookNames.cs) +- [Greg hooks & event runtime](/wiki/framework/greg-hooks-and-events) diff --git a/docs/reference/greg-hooks-registry.md b/docs/reference/greg-hooks-registry.md new file mode 100644 index 0000000..6ab265f --- /dev/null +++ b/docs/reference/greg-hooks-registry.md @@ -0,0 +1,80 @@ +--- +id: greg-hooks-registry +title: greg.* hooks registry (IL2CPP) +slug: /reference/greg-hooks-registry +description: greg_hooks.json, Harmony hook sources under gregCore, regeneration from Il2Cpp unpack, and overlap with Rust bridge patches. +--- + +# greg.* hooks registry (IL2CPP) + +This page documents the **canonical C# / MelonLoader hook surface** for *Data Center* IL2CPP interop: stable string ids, JSON registry, generated Harmony patches, and how they coexist with the existing Rust FFI bridge. + +## Canonical hook ids + +Runtime identifiers follow: + +```text +greg.. +``` + +- **`greg`** — fixed prefix (never `FMF`, `FFM`, or product-specific spellings in new APIs). +- **``** — uppercase segment from `GregDomain` (`PLAYER`, `EMPLOYEE`, `NETWORK`, `UI`, `SYSTEM`, …). Same logical areas as the framework domain model; see `GregHookName` in **gregFramework** sources. +- **``** — `PascalCase` verb or noun phrase (`MoneyChanged`, `Hired`, `ComponentInitialized`, …). + +Always build ids with `GregHookName.Create(GregDomain.*, "Action")` in mods — do not concatenate raw strings. + +## Registry file: `greg_hooks.json` + +| Location | Role | +|----------|------| +| **Repo root** `greg_hooks.json` | Source of truth checked into **gregFramework**; documents every emitted hook (`name`, `patchTarget`, `strategy`, `payloadSchema`, optional `legacy`). | +| **Next to `FrikaModdingFramework.dll`** (build output) | Copy via `FrikaMF.csproj` (`gregCore/framework/gregFramework/greg_hooks.json`) so `GregCompatBridge` can resolve legacy ids at runtime. | + +The file is **generated**; edit the generator or whitelist (see below), then re-run the script — do not hand-edit hundreds of entries unless you are fixing metadata only. + +## Code layout (gregFramework repo) + +| Path | Purpose | +|------|---------| +| `gregCore/Core/` | `GregDomain`, `GregHookName`, `GregEventDispatcher`, `GregCompatBridge`, `GregPayload` | +| `gregCore/Hooks/` | `GregPlayerHooks`, `GregEmployeeHooks`, … — Harmony postfix patches compiled into the MelonLoader plugin | +| `gregCore/scripts/Generate-GregHooksFromIl2CppDump.ps1` | Regenerates `greg_hooks.json` and all `Greg*Hooks.cs` files | + +The main plugin project (`gregCore/framework/FrikaMF.csproj`) references `..\Core\**\*.cs` and `..\Hooks\**\*.cs`. Harmony discovers any type in that assembly marked with `[HarmonyPatch]` (see `Core.ApplyHarmonyPatchesWithDiagnostics`). + +## Regeneration pipeline + +1. **Source of truth for patchable signatures** — Il2CppInterop C# under `gregReferences/il2cpp-unpack/Assembly-CSharp/Il2Cpp/*.cs` (stand-in when a single-file `MergedCode.md` dump is not in the repo). +2. Run from repo root (PowerShell): + + ```powershell + pwsh -NoProfile -File gregCore/scripts/Generate-GregHooksFromIl2CppDump.ps1 + ``` + +3. Rebuild **FrikaMF** so hooks and copied JSON match. + +### Generator behaviour (summary) + +- Emits **postfix** Harmony stubs with `GregEventDispatcher.Emit` and try/catch around each emit. +- Skips high-frequency Unity loops (`Update`, `FixedUpdate`, `LateUpdate`, `OnUpdate`), coroutine `IEnumerator` entrypoints, property accessors, and obvious IL2CPP noise (`codegen`, `MethodInternalStatic`, …). +- Skips **ECS-heavy** signatures unless Unity.Entities (and related) references are added to the project (`Entity`, `EntityCommandBuffer`, `SystemState`, `BlobArray`, …). +- Skips additional interop-only types where the project lacks references (e.g. some `Unity.InputSystem`, UI event types) — extend `Test-SkipInteropSignature` or add references when you need those patches. +- **Overload policy:** only the **first** overload per `Type|MethodName` per file is emitted (Harmony `nameof` ambiguity otherwise). +- **Whitelist (`gameHookClasses`)** — keeps the **FrikaMF** build green without pulling the entire game surface into scope; expand the list in the script when you add assembly references for more types. +- **Harmony exclusion set** — parses `gregCore/framework/FrikaMF/HarmonyPatches.cs` for `HarmonyPatch(typeof(...), nameof(...))` / string method names so **Rust bridge patches are not duplicated** by generated `Greg*Hooks` (e.g. `Player.UpdateCoin` stays owned by the hand-written patch that already forwards to `GregEventDispatcher`). + +## Mod author entry points + +- [Greg hooks showcase](/wiki/guides/mod-developers/greg-hooks-showcase) — subscribe to `greg.*`, use `GregPayload`, optional cancelable flows where the bridge exposes them. +- [FMF hook naming](/wiki/reference/fmf-hook-naming) — older **`FMF.*` / `FFM.*`** string catalog and domain policy for *documentation* constants; runtime IL2CPP Harmony surface is **`greg.*`** as above. +- [FMF hooks catalog](/wiki/reference/fmf-hooks-catalog) — generated table from legacy `HookNames` / `EventIds` sources (distinct from `greg_hooks.json`). + +## Legacy hook ids + +`GregCompatBridge` loads optional `legacy` → `name` mappings from `greg_hooks.json` next to the assembly. Populate `legacy` only when you intentionally support old spellings; keep new public API strictly on **`greg.*`**. + +## See also + +- [FFI, hooks & Lua](/wiki/topics/ffi-and-hooks/overview) +- [Framework architecture](/wiki/framework/architecture) +- [Reference & technical hub](/wiki/topics/reference/overview) diff --git a/docs/reference/reference-data-files.md b/docs/reference/reference-data-files.md index 7a241aa..296a31d 100644 --- a/docs/reference/reference-data-files.md +++ b/docs/reference/reference-data-files.md @@ -31,6 +31,16 @@ $gzip.CopyTo($out) $gzip.Dispose(); $out.Dispose(); $in.Dispose() ``` +## JSON hook registry (gregFramework) + +The **gregFramework** repo also ships a **structured** hook list for IL2CPP Harmony patches: + +- **Path:** `greg_hooks.json` at repo root (and a build-staged copy under `gregCore/framework/gregFramework/`). +- **Purpose:** canonical `greg..` ids, `patchTarget`, `payloadSchema`, and optional `legacy` aliases for `GregCompatBridge`. +- **Docs:** [greg hooks registry (IL2CPP)](/wiki/reference/greg-hooks-registry). + +This file is **generated** from Il2CppInterop sources; it is not one of the gzip archives above. + ## Pipeline usage - Prefer reading `.gz` directly from scripts when possible. diff --git a/docs/topics/ffi-and-hooks/overview.md b/docs/topics/ffi-and-hooks/overview.md index c8f6f25..62d25a9 100644 --- a/docs/topics/ffi-and-hooks/overview.md +++ b/docs/topics/ffi-and-hooks/overview.md @@ -11,5 +11,6 @@ The framework is intended to act as a **hook proxy**: Unity / IL2CPP events are - [FMF hooks](/wiki/framework/fmf-hooks) — generated hook surface - [FMF hooks catalog](/wiki/reference/fmf-hooks-catalog) — strings from core sources - [FMF hook naming](/wiki/reference/fmf-hook-naming) — `FMF.*` vs legacy `FFM.*` +- [greg hooks registry (IL2CPP)](/wiki/reference/greg-hooks-registry) — `greg_hooks.json`, `Greg*Hooks` Harmony emitters, regeneration script - [Framework architecture](/wiki/framework/architecture) — bridges (including Rust) and runtime layout - [Modding language requirement](/wiki/reference/modding-language-requirement) — C# policy for mods/plugins diff --git a/docs/topics/index.md b/docs/topics/index.md index 0867524..8e500c4 100644 --- a/docs/topics/index.md +++ b/docs/topics/index.md @@ -16,7 +16,7 @@ Documentation is **curated** in this repository: guides, framework articles, ref |------|------------| | **Roles** | [By audience](/wiki/guides/players/audiences-overview) — [End users](/wiki/guides/players/overview), [Mod developers](/wiki/guides/mod-developers/overview), [Contributors (workflow)](/wiki/guides/contributors/topics-overview), [Sponsors](/wiki/guides/sponsors/overview) | | **Experience paths** | [Newbies](/wiki/audiences/newbies) · [Intermediates](/wiki/audiences/intermediates) · [Professionals](/wiki/audiences/professionals) | -| **Technical reference** | [Reference & technical](/wiki/topics/reference/overview) | +| **Technical reference** | [Reference & technical](/wiki/topics/reference/overview) — includes [greg IL2CPP hook registry](/wiki/reference/greg-hooks-registry) | | **Ship planning** | [Roadmap & planning](/wiki/topics/roadmap/overview) | | **Repository inventory** | [Repo inventory](/wiki/contributors/repo-inventory) | | **Steam, betas, backlog, game paths** | [Meta & operations](/wiki/topics/meta/overview) — [Game folder layout](/wiki/topics/meta/game-folder-layout) | diff --git a/docs/topics/reference/overview.md b/docs/topics/reference/overview.md index 2348daf..2c7723e 100644 --- a/docs/topics/reference/overview.md +++ b/docs/topics/reference/overview.md @@ -13,6 +13,7 @@ Authoritative reference material for the framework and documentation site. - [Modding language (C# only)](/wiki/reference/modding-language-requirement) — mods, plugins, extensions: **C#** only. - [FMF hook naming](/wiki/reference/fmf-hook-naming) — conventions for hook identifiers. - [FMF hooks catalog](/wiki/reference/fmf-hooks-catalog) — generated listing from framework sources. +- [greg hooks registry (IL2CPP)](/wiki/reference/greg-hooks-registry) — `greg.*` Harmony hooks, `greg_hooks.json`, codegen from Il2Cpp unpack. - [Release channels](/wiki/reference/release-channels) — how builds are staged. See also [FFI, hooks & Lua](/wiki/topics/ffi-and-hooks/overview) for imported deep dives from the legacy wiki. diff --git a/sidebars.js b/sidebars.js index eb0e836..4f310dd 100644 --- a/sidebars.js +++ b/sidebars.js @@ -27,7 +27,12 @@ const sidebars = { { type: 'category', label: 'Framework', - items: ['framework/architecture', 'framework/fmf-hooks', 'framework/hexmod'], + items: [ + 'framework/architecture', + 'framework/greg-hooks-and-events', + 'framework/fmf-hooks', + 'framework/hexmod', + ], }, { type: 'category', @@ -141,6 +146,7 @@ const sidebars = { 'reference/wiki-mapping', 'reference/mod-store-vision', 'reference/fmf-hook-naming', + 'reference/greg-hooks-registry', 'reference/fmf-hooks-catalog', 'reference/mcp-server', 'reference/reference-data-files',