feat(CableRemoval): Implement mass cable removal feature with user hints and settings
gregCore CI / build (push) Has been cancelled

feat(CommonShop): Add custom shop item registration and checkout handling
feat(CommonShop): Create CustomShopItem class for better item management
feat(CommonShop): Develop ShopAPI for injecting custom items into the shop
feat(FasterSFP): Introduce faster SFP modules with custom speeds and prices
feat(NoMoreEOL): Add patch to control visibility of error warning signs
feat(QoL): Implement various quality of life improvements including shop layout fixes and item deletion
refactor(Sdk): Create legacy event dispatcher for backward compatibility
This commit is contained in:
Marvin
2026-04-23 21:05:49 +02:00
parent 84fb3ad4fd
commit 8634792e2b
30 changed files with 37504 additions and 35 deletions
Binary file not shown.
File diff suppressed because it is too large Load Diff
+379
View File
@@ -0,0 +1,379 @@
using System;
using HarmonyLib;
using greg.Core;
using greg.Sdk;
using Il2Cpp;
using Il2CppSystem.Collections.Generic;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using UnityEngine;
namespace gregFramework.Hooks;
/// <summary>
/// Harmony hooks for domain Customer (generated from Il2Cpp unpack).
/// </summary>
[HarmonyPatch]
internal static class GregCustomerHooks
{
// CustomerBase.Awake
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.Awake))]
[HarmonyPostfix]
private static void OnCustomerBaseAwake(CustomerBase __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "ComponentInitialized"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseAwake failed: {ex.Message}");
}
}
// CustomerBase.Start
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.Start))]
[HarmonyPostfix]
private static void OnCustomerBaseStart(CustomerBase __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "ComponentInitialized"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseStart failed: {ex.Message}");
}
}
// CustomerBase.GetEffectiveMoneySpeed
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.GetEffectiveMoneySpeed))]
[HarmonyPostfix]
private static void OnCustomerBaseGetEffectiveMoneySpeed(CustomerBase __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "GetEffectiveMoneySpeed"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseGetEffectiveMoneySpeed failed: {ex.Message}");
}
}
// CustomerBase.AreAllAppRequirementsMet
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.AreAllAppRequirementsMet))]
[HarmonyPostfix]
private static void OnCustomerBaseAreAllAppRequirementsMet(CustomerBase __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "AreAllAppRequirementsMet"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseAreAllAppRequirementsMet failed: {ex.Message}");
}
}
// CustomerBase.UpdateCustomerServerCountAndSpeed
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.UpdateCustomerServerCountAndSpeed))]
[HarmonyPostfix]
private static void OnCustomerBaseUpdateCustomerServerCountAndSpeed(CustomerBase __instance, int count, float speed)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "CustomerServerCountAndSpeedChanged"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseUpdateCustomerServerCountAndSpeed failed: {ex.Message}");
}
}
// CustomerBase.AddAppPerformance
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.AddAppPerformance))]
[HarmonyPostfix]
private static void OnCustomerBaseAddAppPerformance(CustomerBase __instance, int appID, float speed)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "AppPerformanceAdded"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseAddAppPerformance failed: {ex.Message}");
}
}
// CustomerBase.ResetAllAppSpeeds
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.ResetAllAppSpeeds))]
[HarmonyPostfix]
private static void OnCustomerBaseResetAllAppSpeeds(CustomerBase __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "ResetAllAppSpeeds"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseResetAllAppSpeeds failed: {ex.Message}");
}
}
// CustomerBase.IsIPPresent
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.IsIPPresent))]
[HarmonyPostfix]
private static void OnCustomerBaseIsIPPresent(CustomerBase __instance, string ip)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "IsIPPresent"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseIsIPPresent failed: {ex.Message}");
}
}
// CustomerBase.GetAppIDForIP
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.GetAppIDForIP))]
[HarmonyPostfix]
private static void OnCustomerBaseGetAppIDForIP(CustomerBase __instance, string ip)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "GetAppIDForIP"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseGetAppIDForIP failed: {ex.Message}");
}
}
// CustomerBase.SetUpBase
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.SetUpBase))]
[HarmonyPostfix]
private static void OnCustomerBaseSetUpBase(CustomerBase __instance, CustomerItem customerItem, CustomerBaseSaveData saveData)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "UpBaseSet"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseSetUpBase failed: {ex.Message}");
}
}
// CustomerBase.SetUpApp
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.SetUpApp))]
[HarmonyPostfix]
private static void OnCustomerBaseSetUpApp(CustomerBase __instance, int appID, int difficulty, CustomerBaseSaveData saveData)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "UpAppSet"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseSetUpApp failed: {ex.Message}");
}
}
// CustomerBase.AppText
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.AppText))]
[HarmonyPostfix]
private static void OnCustomerBaseAppText(CustomerBase __instance, int lastUsedApp)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "AppText"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseAppText failed: {ex.Message}");
}
}
// CustomerBase.UpdateSpeedOnCustomerBaseApp
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.UpdateSpeedOnCustomerBaseApp))]
[HarmonyPostfix]
private static void OnCustomerBaseUpdateSpeedOnCustomerBaseApp(CustomerBase __instance, int appID, float speed)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "SpeedOnCustomerBaseAppChanged"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseUpdateSpeedOnCustomerBaseApp failed: {ex.Message}");
}
}
// CustomerBase.GetSubnetsPerApp
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.GetSubnetsPerApp))]
[HarmonyPostfix]
private static void OnCustomerBaseGetSubnetsPerApp(CustomerBase __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "GetSubnetsPerApp"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseGetSubnetsPerApp failed: {ex.Message}");
}
}
// CustomerBase.GetVlanIdsPerApp
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.GetVlanIdsPerApp))]
[HarmonyPostfix]
private static void OnCustomerBaseGetVlanIdsPerApp(CustomerBase __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "GetVlanIdsPerApp"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseGetVlanIdsPerApp failed: {ex.Message}");
}
}
// CustomerBase.GetServerTypeForIP
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.GetServerTypeForIP))]
[HarmonyPostfix]
private static void OnCustomerBaseGetServerTypeForIP(CustomerBase __instance, string ip)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "GetServerTypeForIP"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseGetServerTypeForIP failed: {ex.Message}");
}
}
// CustomerBase.GetTotalAppSpeed
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.GetTotalAppSpeed))]
[HarmonyPostfix]
private static void OnCustomerBaseGetTotalAppSpeed(CustomerBase __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "GetTotalAppSpeed"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseGetTotalAppSpeed failed: {ex.Message}");
}
}
// CustomerBase.LoadData
[HarmonyPatch(typeof(CustomerBase), nameof(CustomerBase.LoadData))]
[HarmonyPostfix]
private static void OnCustomerBaseLoadData(CustomerBase __instance, CustomerBaseSaveData data)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Customer, "DataLoaded"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnCustomerBaseLoadData failed: {ex.Message}");
}
}
}
+579
View File
@@ -0,0 +1,579 @@
using System;
using HarmonyLib;
using greg.Core;
using greg.Sdk;
using Il2Cpp;
using Il2CppSystem.Collections.Generic;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using UnityEngine;
namespace gregFramework.Hooks;
/// <summary>
/// Harmony hooks for domain Employee (generated from Il2Cpp unpack).
/// </summary>
[HarmonyPatch]
internal static class GregEmployeeHooks
{
// HRSystem.OnEnable
[HarmonyPatch(typeof(HRSystem), nameof(HRSystem.OnEnable))]
[HarmonyPostfix]
private static void OnHRSystemOnEnable(HRSystem __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "ComponentInitialized"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnHRSystemOnEnable failed: {ex.Message}");
}
}
// HRSystem.ButtonHireEmployee
[HarmonyPatch(typeof(HRSystem), nameof(HRSystem.ButtonHireEmployee))]
[HarmonyPostfix]
private static void OnHRSystemButtonHireEmployee(HRSystem __instance, int i)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "ButtonHireEmployee"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnHRSystemButtonHireEmployee failed: {ex.Message}");
}
}
// HRSystem.ButtonCancelBuying
[HarmonyPatch(typeof(HRSystem), nameof(HRSystem.ButtonCancelBuying))]
[HarmonyPostfix]
private static void OnHRSystemButtonCancelBuying(HRSystem __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "ButtonCancelBuying"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnHRSystemButtonCancelBuying failed: {ex.Message}");
}
}
// HRSystem.ButtonConfirmHire
[HarmonyPatch(typeof(HRSystem), nameof(HRSystem.ButtonConfirmHire))]
[HarmonyPostfix]
private static void OnHRSystemButtonConfirmHire(HRSystem __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "ButtonConfirmHire"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnHRSystemButtonConfirmHire failed: {ex.Message}");
}
}
// HRSystem.ButtonFireEmployee
[HarmonyPatch(typeof(HRSystem), nameof(HRSystem.ButtonFireEmployee))]
[HarmonyPostfix]
private static void OnHRSystemButtonFireEmployee(HRSystem __instance, int i)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "ButtonFireEmployee"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnHRSystemButtonFireEmployee failed: {ex.Message}");
}
}
// HRSystem.ButtonConfirmFireEmployee
[HarmonyPatch(typeof(HRSystem), nameof(HRSystem.ButtonConfirmFireEmployee))]
[HarmonyPostfix]
private static void OnHRSystemButtonConfirmFireEmployee(HRSystem __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "ButtonConfirmFireEmployee"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnHRSystemButtonConfirmFireEmployee failed: {ex.Message}");
}
}
// Technician.Awake
[HarmonyPatch(typeof(Technician), nameof(Technician.Awake))]
[HarmonyPostfix]
private static void OnTechnicianAwake(Technician __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "ComponentInitialized"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianAwake failed: {ex.Message}");
}
}
// Technician.Start
[HarmonyPatch(typeof(Technician), nameof(Technician.Start))]
[HarmonyPostfix]
private static void OnTechnicianStart(Technician __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "ComponentInitialized"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianStart failed: {ex.Message}");
}
}
// Technician.AssignJob
[HarmonyPatch(typeof(Technician), nameof(Technician.AssignJob))]
[HarmonyPostfix]
private static void OnTechnicianAssignJob(Technician __instance, TechnicianManager.RepairJob job)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "AssignJob"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianAssignJob failed: {ex.Message}");
}
}
// Technician.GetCurrentDevicePrefabID
[HarmonyPatch(typeof(Technician), nameof(Technician.GetCurrentDevicePrefabID))]
[HarmonyPostfix]
private static void OnTechnicianGetCurrentDevicePrefabID(Technician __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "GetCurrentDevicePrefabID"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianGetCurrentDevicePrefabID failed: {ex.Message}");
}
}
// Technician.RepairDevice
[HarmonyPatch(typeof(Technician), nameof(Technician.RepairDevice))]
[HarmonyPostfix]
private static void OnTechnicianRepairDevice(Technician __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "DeviceRepaired"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianRepairDevice failed: {ex.Message}");
}
}
// Technician.GetCorrectDevicePrefab
[HarmonyPatch(typeof(Technician), nameof(Technician.GetCorrectDevicePrefab))]
[HarmonyPostfix]
private static void OnTechnicianGetCorrectDevicePrefab(Technician __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "GetCorrectDevicePrefab"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianGetCorrectDevicePrefab failed: {ex.Message}");
}
}
// Technician.RotateTowardsGoal
[HarmonyPatch(typeof(Technician), nameof(Technician.RotateTowardsGoal))]
[HarmonyPostfix]
private static void OnTechnicianRotateTowardsGoal(Technician __instance, Vector3 goal)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "RotateTowardsGoal"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianRotateTowardsGoal failed: {ex.Message}");
}
}
// Technician.PositionHandTargetsOnDevice
[HarmonyPatch(typeof(Technician), nameof(Technician.PositionHandTargetsOnDevice))]
[HarmonyPostfix]
private static void OnTechnicianPositionHandTargetsOnDevice(Technician __instance, GameObject device)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "PositionHandTargetsOnDevice"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianPositionHandTargetsOnDevice failed: {ex.Message}");
}
}
// Technician.OnLoadingStarted
[HarmonyPatch(typeof(Technician), nameof(Technician.OnLoadingStarted))]
[HarmonyPostfix]
private static void OnTechnicianOnLoadingStarted(Technician __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "OnLoadingStarted"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianOnLoadingStarted failed: {ex.Message}");
}
}
// Technician.OnDestroy
[HarmonyPatch(typeof(Technician), nameof(Technician.OnDestroy))]
[HarmonyPostfix]
private static void OnTechnicianOnDestroy(Technician __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "OnDestroy"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianOnDestroy failed: {ex.Message}");
}
}
// TechnicianManager.Awake
[HarmonyPatch(typeof(TechnicianManager), nameof(TechnicianManager.Awake))]
[HarmonyPostfix]
private static void OnTechnicianManagerAwake(TechnicianManager __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "ComponentInitialized"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianManagerAwake failed: {ex.Message}");
}
}
// TechnicianManager.AddTechnician
[HarmonyPatch(typeof(TechnicianManager), nameof(TechnicianManager.AddTechnician))]
[HarmonyPostfix]
private static void OnTechnicianManagerAddTechnician(TechnicianManager __instance, Technician technician)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "Hired"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianManagerAddTechnician failed: {ex.Message}");
}
}
// TechnicianManager.SendTechnician
[HarmonyPatch(typeof(TechnicianManager), nameof(TechnicianManager.SendTechnician))]
[HarmonyPostfix]
private static void OnTechnicianManagerSendTechnician(TechnicianManager __instance, NetworkSwitch networkSwitch, Server server)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "Dispatched"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianManagerSendTechnician failed: {ex.Message}");
}
}
// TechnicianManager.RequestNextJob
[HarmonyPatch(typeof(TechnicianManager), nameof(TechnicianManager.RequestNextJob))]
[HarmonyPostfix]
private static void OnTechnicianManagerRequestNextJob(TechnicianManager __instance, Technician technician)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "NextJobRequested"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianManagerRequestNextJob failed: {ex.Message}");
}
}
// TechnicianManager.EnqueueDispatch
[HarmonyPatch(typeof(TechnicianManager), nameof(TechnicianManager.EnqueueDispatch))]
[HarmonyPostfix]
private static void OnTechnicianManagerEnqueueDispatch(TechnicianManager __instance, TechnicianManager.RepairJob job)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "JobQueued"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianManagerEnqueueDispatch failed: {ex.Message}");
}
}
// TechnicianManager.IsDeviceAlreadyAssigned
[HarmonyPatch(typeof(TechnicianManager), nameof(TechnicianManager.IsDeviceAlreadyAssigned))]
[HarmonyPostfix]
private static void OnTechnicianManagerIsDeviceAlreadyAssigned(TechnicianManager __instance, NetworkSwitch networkSwitch, Server server)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "IsDeviceAlreadyAssigned"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianManagerIsDeviceAlreadyAssigned failed: {ex.Message}");
}
}
// TechnicianManager.RestoreJobQueue
[HarmonyPatch(typeof(TechnicianManager), nameof(TechnicianManager.RestoreJobQueue))]
[HarmonyPostfix]
private static void OnTechnicianManagerRestoreJobQueue(TechnicianManager __instance, Il2CppSystem.Collections.Generic.List<RepairJobSaveData> savedJobs)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "JobQueueLoaded"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianManagerRestoreJobQueue failed: {ex.Message}");
}
}
// TechnicianManager.FireTechnician
[HarmonyPatch(typeof(TechnicianManager), nameof(TechnicianManager.FireTechnician))]
[HarmonyPostfix]
private static void OnTechnicianManagerFireTechnician(TechnicianManager __instance, int technicianID)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "Fired"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianManagerFireTechnician failed: {ex.Message}");
}
}
// TechnicianManager.OpenDumpsterArea
[HarmonyPatch(typeof(TechnicianManager), nameof(TechnicianManager.OpenDumpsterArea))]
[HarmonyPostfix]
private static void OnTechnicianManagerOpenDumpsterArea(TechnicianManager __instance, int areaID)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "OpenDumpsterArea"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianManagerOpenDumpsterArea failed: {ex.Message}");
}
}
// TechnicianManager.GetClosestOpenedDumpsterIndex
[HarmonyPatch(typeof(TechnicianManager), nameof(TechnicianManager.GetClosestOpenedDumpsterIndex))]
[HarmonyPostfix]
private static void OnTechnicianManagerGetClosestOpenedDumpsterIndex(TechnicianManager __instance, Vector3 position)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "GetClosestOpenedDumpsterIndex"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianManagerGetClosestOpenedDumpsterIndex failed: {ex.Message}");
}
}
// TechnicianManager.OnDestroy
[HarmonyPatch(typeof(TechnicianManager), nameof(TechnicianManager.OnDestroy))]
[HarmonyPostfix]
private static void OnTechnicianManagerOnDestroy(TechnicianManager __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "OnDestroy"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianManagerOnDestroy failed: {ex.Message}");
}
}
// TechnicianManager.OnLoadingStarted
[HarmonyPatch(typeof(TechnicianManager), nameof(TechnicianManager.OnLoadingStarted))]
[HarmonyPostfix]
private static void OnTechnicianManagerOnLoadingStarted(TechnicianManager __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Employee, "OnLoadingStarted"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnTechnicianManagerOnLoadingStarted failed: {ex.Message}");
}
}
}
+279
View File
@@ -0,0 +1,279 @@
using System;
using HarmonyLib;
using greg.Core;
using greg.Sdk;
using Il2Cpp;
using Il2CppSystem.Collections.Generic;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using UnityEngine;
namespace gregFramework.Hooks;
/// <summary>
/// Harmony hooks for domain Gameplay (generated from Il2Cpp unpack).
/// </summary>
[HarmonyPatch]
internal static class GregGameplayHooks
{
// Objectives.Awake
[HarmonyPatch(typeof(Objectives), nameof(Objectives.Awake))]
[HarmonyPostfix]
private static void OnObjectivesAwake(Objectives __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Gameplay, "ComponentInitialized"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnObjectivesAwake failed: {ex.Message}");
}
}
// Objectives.Start
[HarmonyPatch(typeof(Objectives), nameof(Objectives.Start))]
[HarmonyPostfix]
private static void OnObjectivesStart(Objectives __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Gameplay, "ComponentInitialized"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnObjectivesStart failed: {ex.Message}");
}
}
// Objectives.GetTimedObjective
[HarmonyPatch(typeof(Objectives), nameof(Objectives.GetTimedObjective))]
[HarmonyPostfix]
private static void OnObjectivesGetTimedObjective(Objectives __instance, int objectiveUID)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Gameplay, "GetTimedObjective"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnObjectivesGetTimedObjective failed: {ex.Message}");
}
}
// Objectives.IsTutorialInProgress
[HarmonyPatch(typeof(Objectives), nameof(Objectives.IsTutorialInProgress))]
[HarmonyPostfix]
private static void OnObjectivesIsTutorialInProgress(Objectives __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Gameplay, "IsTutorialInProgress"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnObjectivesIsTutorialInProgress failed: {ex.Message}");
}
}
// Objectives.CreateAppObjective
[HarmonyPatch(typeof(Objectives), nameof(Objectives.CreateAppObjective))]
[HarmonyPostfix]
private static void OnObjectivesCreateAppObjective(Objectives __instance, int customerID, int appID, int time, int requiredIOPS)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Gameplay, "CreateAppObjective"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnObjectivesCreateAppObjective failed: {ex.Message}");
}
}
// Objectives.ObjectiveTimedText
[HarmonyPatch(typeof(Objectives), nameof(Objectives.ObjectiveTimedText))]
[HarmonyPostfix]
private static void OnObjectivesObjectiveTimedText(Objectives __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Gameplay, "ObjectiveTimedText"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnObjectivesObjectiveTimedText failed: {ex.Message}");
}
}
// Objectives.DestroyObjective
[HarmonyPatch(typeof(Objectives), nameof(Objectives.DestroyObjective))]
[HarmonyPostfix]
private static void OnObjectivesDestroyObjective(Objectives __instance, int _objectiveUID)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Gameplay, "DestroyObjective"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnObjectivesDestroyObjective failed: {ex.Message}");
}
}
// Objectives.ClearObjectives
[HarmonyPatch(typeof(Objectives), nameof(Objectives.ClearObjectives))]
[HarmonyPostfix]
private static void OnObjectivesClearObjectives(Objectives __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Gameplay, "ClearObjectives"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnObjectivesClearObjectives failed: {ex.Message}");
}
}
// Objectives.StartObjective
[HarmonyPatch(typeof(Objectives), nameof(Objectives.StartObjective))]
[HarmonyPostfix]
private static void OnObjectivesStartObjective(Objectives __instance, int _objectiveUID, Vector3 objectivePosition, bool _loadSave)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Gameplay, "StartObjective"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnObjectivesStartObjective failed: {ex.Message}");
}
}
// Objectives.InstantiateObjectiveSign
[HarmonyPatch(typeof(Objectives), nameof(Objectives.InstantiateObjectiveSign))]
[HarmonyPostfix]
private static void OnObjectivesInstantiateObjectiveSign(Objectives __instance, int objectiveUID, Vector3 objectPos)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Gameplay, "InstantiateObjectiveSign"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnObjectivesInstantiateObjectiveSign failed: {ex.Message}");
}
}
// Objectives.RemoveObjectiveSign
[HarmonyPatch(typeof(Objectives), nameof(Objectives.RemoveObjectiveSign))]
[HarmonyPostfix]
private static void OnObjectivesRemoveObjectiveSign(Objectives __instance, int objectiveUID)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Gameplay, "ObjectiveSignRemoved"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnObjectivesRemoveObjectiveSign failed: {ex.Message}");
}
}
// Objectives.OnDestroy
[HarmonyPatch(typeof(Objectives), nameof(Objectives.OnDestroy))]
[HarmonyPostfix]
private static void OnObjectivesOnDestroy(Objectives __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Gameplay, "OnDestroy"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnObjectivesOnDestroy failed: {ex.Message}");
}
}
// Objectives.OnLoad
[HarmonyPatch(typeof(Objectives), nameof(Objectives.OnLoad))]
[HarmonyPostfix]
private static void OnObjectivesOnLoad(Objectives __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Gameplay, "OnLoad"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnObjectivesOnLoad failed: {ex.Message}");
}
}
}
File diff suppressed because it is too large Load Diff
+355
View File
@@ -0,0 +1,355 @@
using System;
using HarmonyLib;
using greg.Core;
using greg.Sdk;
using Il2Cpp;
using Il2CppSystem.Collections.Generic;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using UnityEngine;
namespace gregFramework.Hooks;
/// <summary>
/// Harmony hooks for domain Player (generated from Il2Cpp unpack).
/// </summary>
[HarmonyPatch]
internal static class GregPlayerHooks
{
// Player.Start
[HarmonyPatch(typeof(Player), nameof(Player.Start))]
[HarmonyPostfix]
private static void OnPlayerStart(Player __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "ComponentInitialized"),
new
{
money = __instance.money,
reputation = __instance.reputation,
xp = __instance.xp,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerStart failed: {ex.Message}");
}
}
// Player.CheckFallsThroughMap
[HarmonyPatch(typeof(Player), nameof(Player.CheckFallsThroughMap))]
[HarmonyPostfix]
private static void OnPlayerCheckFallsThroughMap(Player __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "CheckFallsThroughMap"),
new
{
money = __instance.money,
reputation = __instance.reputation,
xp = __instance.xp,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerCheckFallsThroughMap failed: {ex.Message}");
}
}
// Player.LoadPlayer
[HarmonyPatch(typeof(Player), nameof(Player.LoadPlayer))]
[HarmonyPostfix]
private static void OnPlayerLoadPlayer(Player __instance, PlayerData data)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "Loaded"),
new
{
money = __instance.money,
reputation = __instance.reputation,
xp = __instance.xp,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerLoadPlayer failed: {ex.Message}");
}
}
// Player.UpdateCoin
[HarmonyPatch(typeof(Player), nameof(Player.UpdateCoin))]
[HarmonyPostfix]
private static void OnPlayerUpdateCoin(Player __instance, float _coinChhangeAmount, bool withoutSound)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "MoneyChanged"),
new
{
money = __instance.money,
reputation = __instance.reputation,
xp = __instance.xp,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerUpdateCoin failed: {ex.Message}");
}
}
// Player.DropAllItems
[HarmonyPatch(typeof(Player), nameof(Player.DropAllItems))]
[HarmonyPostfix]
private static void OnPlayerDropAllItems(Player __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "DroppedAllItems"),
new
{
money = __instance.money,
reputation = __instance.reputation,
xp = __instance.xp,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerDropAllItems failed: {ex.Message}");
}
}
// Player.WarpPlayer
[HarmonyPatch(typeof(Player), nameof(Player.WarpPlayer))]
[HarmonyPostfix]
private static void OnPlayerWarpPlayer(Player __instance, Vector3 _position, Quaternion _rotation)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "Warped"),
new
{
money = __instance.money,
reputation = __instance.reputation,
xp = __instance.xp,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerWarpPlayer failed: {ex.Message}");
}
}
// Player.UpdateReputation
[HarmonyPatch(typeof(Player), nameof(Player.UpdateReputation))]
[HarmonyPostfix]
private static void OnPlayerUpdateReputation(Player __instance, float amount)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "ReputationChanged"),
new
{
money = __instance.money,
reputation = __instance.reputation,
xp = __instance.xp,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerUpdateReputation failed: {ex.Message}");
}
}
// Player.UpdateXP
[HarmonyPatch(typeof(Player), nameof(Player.UpdateXP))]
[HarmonyPostfix]
private static void OnPlayerUpdateXP(Player __instance, float amount)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "XpChanged"),
new
{
money = __instance.money,
reputation = __instance.reputation,
xp = __instance.xp,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerUpdateXP failed: {ex.Message}");
}
}
// PlayerHit.OnEnable
[HarmonyPatch(typeof(PlayerHit), nameof(PlayerHit.OnEnable))]
[HarmonyPostfix]
private static void OnPlayerHitOnEnable(PlayerHit __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "ComponentInitialized"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerHitOnEnable failed: {ex.Message}");
}
}
// PlayerManager.Awake
[HarmonyPatch(typeof(PlayerManager), nameof(PlayerManager.Awake))]
[HarmonyPostfix]
private static void OnPlayerManagerAwake(PlayerManager __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "ComponentInitialized"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerManagerAwake failed: {ex.Message}");
}
}
// PlayerManager.Start
[HarmonyPatch(typeof(PlayerManager), nameof(PlayerManager.Start))]
[HarmonyPostfix]
private static void OnPlayerManagerStart(PlayerManager __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "ComponentInitialized"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerManagerStart failed: {ex.Message}");
}
}
// PlayerManager.ConfinedCursorforUI
[HarmonyPatch(typeof(PlayerManager), nameof(PlayerManager.ConfinedCursorforUI))]
[HarmonyPostfix]
private static void OnPlayerManagerConfinedCursorforUI(PlayerManager __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "ConfinedCursorforUI"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerManagerConfinedCursorforUI failed: {ex.Message}");
}
}
// PlayerManager.PlayerStopMovement
[HarmonyPatch(typeof(PlayerManager), nameof(PlayerManager.PlayerStopMovement))]
[HarmonyPostfix]
private static void OnPlayerManagerPlayerStopMovement(PlayerManager __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "PlayerStopMovement"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerManagerPlayerStopMovement failed: {ex.Message}");
}
}
// PlayerManager.LockedCursorForPlayerMovement
[HarmonyPatch(typeof(PlayerManager), nameof(PlayerManager.LockedCursorForPlayerMovement))]
[HarmonyPostfix]
private static void OnPlayerManagerLockedCursorForPlayerMovement(PlayerManager __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "LockedCursorForPlayerMovement"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerManagerLockedCursorForPlayerMovement failed: {ex.Message}");
}
}
// PlayerManager.DefaultActionEffect
[HarmonyPatch(typeof(PlayerManager), nameof(PlayerManager.DefaultActionEffect))]
[HarmonyPostfix]
private static void OnPlayerManagerDefaultActionEffect(PlayerManager __instance, Vector3 _position, float _time)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "DefaultActionEffect"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerManagerDefaultActionEffect failed: {ex.Message}");
}
}
// PlayerManager.GainIOPSEffect
[HarmonyPatch(typeof(PlayerManager), nameof(PlayerManager.GainIOPSEffect))]
[HarmonyPostfix]
private static void OnPlayerManagerGainIOPSEffect(PlayerManager __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Player, "GainIOPSEffect"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnPlayerManagerGainIOPSEffect failed: {ex.Message}");
}
}
}
+11
View File
@@ -0,0 +1,11 @@
using HarmonyLib;
namespace gregFramework.Hooks;
/// <summary>
/// Reserved for Power / UPS / PDU hooks once matching Il2Cpp surface is classified.
/// </summary>
[HarmonyPatch]
internal static class GregPowerHooks
{
}
+339
View File
@@ -0,0 +1,339 @@
using System;
using HarmonyLib;
using greg.Core;
using greg.Sdk;
using Il2Cpp;
using Il2CppSystem.Collections.Generic;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using UnityEngine;
namespace gregFramework.Hooks;
/// <summary>
/// Harmony hooks for domain Rack (generated from Il2Cpp unpack).
/// </summary>
[HarmonyPatch]
internal static class GregRackHooks
{
// Rack.Awake
[HarmonyPatch(typeof(Rack), nameof(Rack.Awake))]
[HarmonyPostfix]
private static void OnRackAwake(Rack __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "ComponentInitialized"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackAwake failed: {ex.Message}");
}
}
// Rack.Start
[HarmonyPatch(typeof(Rack), nameof(Rack.Start))]
[HarmonyPostfix]
private static void OnRackStart(Rack __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "ComponentInitialized"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackStart failed: {ex.Message}");
}
}
// Rack.IsPositionAvailable
[HarmonyPatch(typeof(Rack), nameof(Rack.IsPositionAvailable))]
[HarmonyPostfix]
private static void OnRackIsPositionAvailable(Rack __instance, int index, int sizeInU)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "IsPositionAvailable"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackIsPositionAvailable failed: {ex.Message}");
}
}
// Rack.MarkPositionAsUsed
[HarmonyPatch(typeof(Rack), nameof(Rack.MarkPositionAsUsed))]
[HarmonyPostfix]
private static void OnRackMarkPositionAsUsed(Rack __instance, int index, int sizeInU)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "MarkPositionAsUsed"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackMarkPositionAsUsed failed: {ex.Message}");
}
}
// Rack.MarkPositionAsUnused
[HarmonyPatch(typeof(Rack), nameof(Rack.MarkPositionAsUnused))]
[HarmonyPostfix]
private static void OnRackMarkPositionAsUnused(Rack __instance, int index, int sizeInU)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "MarkPositionAsUnused"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackMarkPositionAsUnused failed: {ex.Message}");
}
}
// Rack.UpdateAudioVolume
[HarmonyPatch(typeof(Rack), nameof(Rack.UpdateAudioVolume))]
[HarmonyPostfix]
private static void OnRackUpdateAudioVolume(Rack __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "AudioVolumeChanged"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackUpdateAudioVolume failed: {ex.Message}");
}
}
// Rack.ButtonDisablePositionsInRack
[HarmonyPatch(typeof(Rack), nameof(Rack.ButtonDisablePositionsInRack))]
[HarmonyPostfix]
private static void OnRackButtonDisablePositionsInRack(Rack __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "ButtonDisablePositionsInRack"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackButtonDisablePositionsInRack failed: {ex.Message}");
}
}
// Rack.SetDisablePositionsButtonMaterial
[HarmonyPatch(typeof(Rack), nameof(Rack.SetDisablePositionsButtonMaterial))]
[HarmonyPostfix]
private static void OnRackSetDisablePositionsButtonMaterial(Rack __instance, Material material)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "DisablePositionsButtonMaterialSet"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackSetDisablePositionsButtonMaterial failed: {ex.Message}");
}
}
// Rack.ButtonUnmountRack
[HarmonyPatch(typeof(Rack), nameof(Rack.ButtonUnmountRack))]
[HarmonyPostfix]
private static void OnRackButtonUnmountRack(Rack __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "ButtonUnmountRack"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackButtonUnmountRack failed: {ex.Message}");
}
}
// Rack.OnLoad
[HarmonyPatch(typeof(Rack), nameof(Rack.OnLoad))]
[HarmonyPostfix]
private static void OnRackOnLoad(Rack __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "OnLoad"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackOnLoad failed: {ex.Message}");
}
}
// Rack.OnDestroy
[HarmonyPatch(typeof(Rack), nameof(Rack.OnDestroy))]
[HarmonyPostfix]
private static void OnRackOnDestroy(Rack __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "OnDestroy"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackOnDestroy failed: {ex.Message}");
}
}
// RackMount.InstantiateRack
[HarmonyPatch(typeof(RackMount), nameof(RackMount.InstantiateRack))]
[HarmonyPostfix]
private static void OnRackMountInstantiateRack(RackMount __instance, InteractObjectData saveData)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "InstantiateRack"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackMountInstantiateRack failed: {ex.Message}");
}
}
// RackMount.ApplyMaterialToLODs
[HarmonyPatch(typeof(RackMount), nameof(RackMount.ApplyMaterialToLODs))]
[HarmonyPostfix]
private static void OnRackMountApplyMaterialToLODs(RackMount __instance, GameObject rackGO, Material mat)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "ApplyMaterialToLODs"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackMountApplyMaterialToLODs failed: {ex.Message}");
}
}
// RackMount.OnLoad
[HarmonyPatch(typeof(RackMount), nameof(RackMount.OnLoad))]
[HarmonyPostfix]
private static void OnRackMountOnLoad(RackMount __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "OnLoad"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackMountOnLoad failed: {ex.Message}");
}
}
// RackMount.OnDestroy
[HarmonyPatch(typeof(RackMount), nameof(RackMount.OnDestroy))]
[HarmonyPostfix]
private static void OnRackMountOnDestroy(RackMount __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "OnDestroy"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackMountOnDestroy failed: {ex.Message}");
}
}
// RackMount.CheatInsertRack
[HarmonyPatch(typeof(RackMount), nameof(RackMount.CheatInsertRack))]
[HarmonyPostfix]
private static void OnRackMountCheatInsertRack(RackMount __instance, GameObject go, int type)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Rack, "CheatInsertRack"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnRackMountCheatInsertRack failed: {ex.Message}");
}
}
}
+519
View File
@@ -0,0 +1,519 @@
using System;
using HarmonyLib;
using greg.Core;
using greg.Sdk;
using Il2Cpp;
using Il2CppSystem.Collections.Generic;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using UnityEngine;
namespace gregFramework.Hooks;
/// <summary>
/// Harmony hooks for domain Server (generated from Il2Cpp unpack).
/// </summary>
[HarmonyPatch]
internal static class GregServerHooks
{
// Server.Start
[HarmonyPatch(typeof(Server), nameof(Server.Start))]
[HarmonyPostfix]
private static void OnServerStart(Server __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "ComponentInitialized"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerStart failed: {ex.Message}");
}
}
// Server.OnLoadingStarted
[HarmonyPatch(typeof(Server), nameof(Server.OnLoadingStarted))]
[HarmonyPostfix]
private static void OnServerOnLoadingStarted(Server __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "OnLoadingStarted"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerOnLoadingStarted failed: {ex.Message}");
}
}
// Server.OnLoadingComplete
[HarmonyPatch(typeof(Server), nameof(Server.OnLoadingComplete))]
[HarmonyPostfix]
private static void OnServerOnLoadingComplete(Server __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "OnLoadingComplete"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerOnLoadingComplete failed: {ex.Message}");
}
}
// Server.PowerButton
[HarmonyPatch(typeof(Server), nameof(Server.PowerButton))]
[HarmonyPostfix]
private static void OnServerPowerButton(Server __instance, bool forceState)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "PowerButton"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerPowerButton failed: {ex.Message}");
}
}
// Server.TurnOffCommonFunctions
[HarmonyPatch(typeof(Server), nameof(Server.TurnOffCommonFunctions))]
[HarmonyPostfix]
private static void OnServerTurnOffCommonFunctions(Server __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "TurnOffCommonFunctions"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerTurnOffCommonFunctions failed: {ex.Message}");
}
}
// Server.TurnOnCommonFunction
[HarmonyPatch(typeof(Server), nameof(Server.TurnOnCommonFunction))]
[HarmonyPostfix]
private static void OnServerTurnOnCommonFunction(Server __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "TurnOnCommonFunction"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerTurnOnCommonFunction failed: {ex.Message}");
}
}
// Server.IsAnyCableConnected
[HarmonyPatch(typeof(Server), nameof(Server.IsAnyCableConnected))]
[HarmonyPostfix]
private static void OnServerIsAnyCableConnected(Server __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "IsAnyCableConnected"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerIsAnyCableConnected failed: {ex.Message}");
}
}
// Server.GenerateUniqueServerId
[HarmonyPatch(typeof(Server), nameof(Server.GenerateUniqueServerId))]
[HarmonyPostfix]
private static void OnServerGenerateUniqueServerId(Server __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "GenerateUniqueServerId"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerGenerateUniqueServerId failed: {ex.Message}");
}
}
// Server.ServerInsertedInRack
[HarmonyPatch(typeof(Server), nameof(Server.ServerInsertedInRack))]
[HarmonyPostfix]
private static void OnServerServerInsertedInRack(Server __instance, ServerSaveData serverSaveData)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "ServerInsertedInRack"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerServerInsertedInRack failed: {ex.Message}");
}
}
// Server.RegisterLink
[HarmonyPatch(typeof(Server), nameof(Server.RegisterLink))]
[HarmonyPostfix]
private static void OnServerRegisterLink(Server __instance, CableLink link)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "RegisterLink"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerRegisterLink failed: {ex.Message}");
}
}
// Server.UnregisterLink
[HarmonyPatch(typeof(Server), nameof(Server.UnregisterLink))]
[HarmonyPostfix]
private static void OnServerUnregisterLink(Server __instance, CableLink link)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "UnregisterLink"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerUnregisterLink failed: {ex.Message}");
}
}
// Server.UpdateServerScreenUI
[HarmonyPatch(typeof(Server), nameof(Server.UpdateServerScreenUI))]
[HarmonyPostfix]
private static void OnServerUpdateServerScreenUI(Server __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "ServerScreenUIChanged"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerUpdateServerScreenUI failed: {ex.Message}");
}
}
// Server.ButtonClickChangeCustomer
[HarmonyPatch(typeof(Server), nameof(Server.ButtonClickChangeCustomer))]
[HarmonyPostfix]
private static void OnServerButtonClickChangeCustomer(Server __instance, bool forward)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "ButtonClickChangeCustomer"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerButtonClickChangeCustomer failed: {ex.Message}");
}
}
// Server.GetNextCustomerID
[HarmonyPatch(typeof(Server), nameof(Server.GetNextCustomerID))]
[HarmonyPostfix]
private static void OnServerGetNextCustomerID(Server __instance, int currentCustomerID, bool forward)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "GetNextCustomerID"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerGetNextCustomerID failed: {ex.Message}");
}
}
// Server.ButtonClickChangeIP
[HarmonyPatch(typeof(Server), nameof(Server.ButtonClickChangeIP))]
[HarmonyPostfix]
private static void OnServerButtonClickChangeIP(Server __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "ButtonClickChangeIP"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerButtonClickChangeIP failed: {ex.Message}");
}
}
// Server.SetIP
[HarmonyPatch(typeof(Server), nameof(Server.SetIP))]
[HarmonyPostfix]
private static void OnServerSetIP(Server __instance, string _ip)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "IPSet"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerSetIP failed: {ex.Message}");
}
}
// Server.GetCustomerID
[HarmonyPatch(typeof(Server), nameof(Server.GetCustomerID))]
[HarmonyPostfix]
private static void OnServerGetCustomerID(Server __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "GetCustomerID"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerGetCustomerID failed: {ex.Message}");
}
}
// Server.UpdateCustomer
[HarmonyPatch(typeof(Server), nameof(Server.UpdateCustomer))]
[HarmonyPostfix]
private static void OnServerUpdateCustomer(Server __instance, int newCustomerID)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "CustomerChanged"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerUpdateCustomer failed: {ex.Message}");
}
}
// Server.UpdateAppID
[HarmonyPatch(typeof(Server), nameof(Server.UpdateAppID))]
[HarmonyPostfix]
private static void OnServerUpdateAppID(Server __instance, int _appID)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "AppIDChanged"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerUpdateAppID failed: {ex.Message}");
}
}
// Server.ItIsBroken
[HarmonyPatch(typeof(Server), nameof(Server.ItIsBroken))]
[HarmonyPostfix]
private static void OnServerItIsBroken(Server __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "ItIsBroken"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerItIsBroken failed: {ex.Message}");
}
}
// Server.ValidateRackPosition
[HarmonyPatch(typeof(Server), nameof(Server.ValidateRackPosition))]
[HarmonyPostfix]
private static void OnServerValidateRackPosition(Server __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "ValidateRackPosition"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerValidateRackPosition failed: {ex.Message}");
}
}
// Server.ClearWarningSign
[HarmonyPatch(typeof(Server), nameof(Server.ClearWarningSign))]
[HarmonyPostfix]
private static void OnServerClearWarningSign(Server __instance, bool isPreserved)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "ClearWarningSign"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerClearWarningSign failed: {ex.Message}");
}
}
// Server.ClearErrorSign
[HarmonyPatch(typeof(Server), nameof(Server.ClearErrorSign))]
[HarmonyPostfix]
private static void OnServerClearErrorSign(Server __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "ClearErrorSign"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerClearErrorSign failed: {ex.Message}");
}
}
// Server.SetPowerLightMaterial
[HarmonyPatch(typeof(Server), nameof(Server.SetPowerLightMaterial))]
[HarmonyPostfix]
private static void OnServerSetPowerLightMaterial(Server __instance, Material material)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "PowerLightMaterialSet"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerSetPowerLightMaterial failed: {ex.Message}");
}
}
// Server.RepairDevice
[HarmonyPatch(typeof(Server), nameof(Server.RepairDevice))]
[HarmonyPostfix]
private static void OnServerRepairDevice(Server __instance)
{
try
{
gregEventDispatcher.Emit(
gregHookName.Create(GregDomain.Server, "DeviceRepaired"),
new
{
instance = __instance,
});
}
catch (System.Exception ex)
{
MelonLogger.Warning($"[gregCore] Hook OnServerRepairDevice failed: {ex.Message}");
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -13,7 +13,7 @@
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
<EnableDefaultNoneItems>false</EnableDefaultNoneItems>
<Version>1.0.0.35-pre</Version>
<Version>1.0.0.35</Version>
<FileVersion>1.0.0.35</FileVersion>
<AssemblyVersion>1.0.0.35</AssemblyVersion>
</PropertyGroup>
+2 -2
View File
@@ -6,7 +6,7 @@
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v6.0": {
"gregCore/1.0.0.35-pre": {
"gregCore/1.0.0.35": {
"dependencies": {
"Jint": "4.8.0",
"LiteDB": "5.0.21",
@@ -93,7 +93,7 @@
}
},
"libraries": {
"gregCore/1.0.0.35-pre": {
"gregCore/1.0.0.35": {
"type": "project",
"serviceable": false,
"sha512": ""
Binary file not shown.
Binary file not shown.
+13 -1
View File
@@ -37,7 +37,19 @@ $harmonyEmitClasses = [System.Collections.Generic.HashSet[string]]::new([StringC
'Server', 'MainGameManager', 'ComputerShop', 'HRSystem', 'SaveSystem', 'CustomerBase',
'CablePositions', 'CableLink', 'Rack', 'NetworkMap', 'BalanceSheet', 'MainMenu',
'TimeController', 'TechnicianManager', 'Technician', 'Objectives',
'PacketSpawnerSystem', 'NetworkSwitch', 'SFPModule', 'SFPBox', 'PatchPanel'
'PacketSpawnerSystem', 'NetworkSwitch', 'SFPModule', 'SFPBox', 'PatchPanel',
'AutoDisable', 'Benchmark01', 'Benchmark02', 'Benchmark03', 'Benchmark04',
'GetCurrentVersion', 'LocalisedText', 'MouseLook', 'ObjectSpin', 'PositionIndicator',
'RayLookAt', 'SimpleScript', 'TextConsoleSimulator', 'TextMeshProFloatingText', 'TextMeshSpawner',
'VertexJitter', 'VertexShakeA', 'VertexShakeB', 'VertexZoom', 'WarpTextExample',
'AICharacterControl', 'AICharacterExpressions', 'CameraController', 'CarController',
'CheckIfTouchingWall', 'FirstPersonController', 'InputManager', 'ObjImporter',
'GODMOD', 'RackMount', 'AssetManagement', 'AssetManagementDeviceLine', 'AudioManager',
'FootSteps', 'OSK_Keyboard', 'OSK_KeySounds', 'SettingsVolume', 'ThirdPersonCharacter',
'OSK_AccentConsole', 'OSK_GamepadHelper', 'OSK_UI_InputReceiver', 'OSK_UI_Keyboard',
'SettingsControls', 'SettingsGraphics', 'ShopCartItem', 'SkewTextExample', 'StaticUIElements',
'TerrainDetector', 'UsableObject', 'viperInput', 'WaypointInitializationSystem',
'_PrivateImplementationDetails_', 'ModLoader', 'CommandCenter'
) | ForEach-Object { [void]$harmonyEmitClasses.Add($_) }
function Test-SkipTypeName([string]$n) {
@@ -2121,7 +2121,7 @@ public class MultiplayerBridge
_statusStyle = new GUIStyle { fontSize = 18, fontStyle = FontStyle.Bold, normal = { textColor = new Color(0.0f, 0.9f, 0.6f) } };
_buttonStyle = new GUIStyle { fontSize = 18, fontStyle = FontStyle.Bold, alignment = TextAnchor.MiddleCenter, normal = { background = _buttonBg, textColor = Color.white }, hover = { background = _buttonHoverBg, textColor = Color.white } };
_stopHostButtonStyle = new GUIStyle(_buttonStyle) { normal = { background = _stopBtnBg }, hover = { background = _stopBtnHoverBg } };
_stopHostButtonStyle = new GUIStyle { fontSize = 18, fontStyle = FontStyle.Bold, alignment = TextAnchor.MiddleCenter, normal = { background = _stopBtnBg, textColor = Color.white }, hover = { background = _stopBtnHoverBg, textColor = Color.white } };
_stylesInitialized = true;
}
+2 -2
View File
@@ -32,7 +32,7 @@ public static class OverlayManager
}
// Apply raycast blocker state based on global visibility
UiRaycastBlocker.SetBlocking(IsAnyOverlayVisible);
// UiRaycastBlocker.SetBlocking(IsAnyOverlayVisible);
}
/// <summary>
@@ -41,6 +41,6 @@ public static class OverlayManager
public static void HideAll()
{
_visibleOverlays.Clear();
UiRaycastBlocker.SetBlocking(false);
// UiRaycastBlocker.SetBlocking(false);
}
}
+231
View File
@@ -0,0 +1,231 @@
using System;
using HarmonyLib;
using Il2Cpp;
using MelonLoader;
using UnityEngine;
using UnityEngine.InputSystem;
using greg.Logging;
namespace greg.CableRemoval
{
public class Main : MelonMod
{
private GregModLogger _log = null!;
private bool _enabled = true;
private const float WorldPurgeHoldSeconds = 10f;
private bool _showMassRemoveHint;
private bool _showWorldPurgeHint;
private bool _charging;
private float _chargeElapsed;
private float _chargeHoldSeconds = 0.85f;
private NetworkSwitch? _chargeSwitch;
private PatchPanel? _chargePanel;
private float _worldPurgeElapsed;
public override void OnInitializeMelon()
{
if (gregCore.Core.GregCoreMod.Instance == null)
{
LoggerInstance.Warning("[gC-CableRemoval] gregCore not ready.");
return;
}
_log = new GregModLogger("CableRemoval");
RegisterSettings();
_log.FeatureState("CableRemoval", true);
_log.Msg("Initialization complete.");
}
private void RegisterSettings()
{
string modId = "cable_removal";
gregCore.API.GregAPI.RegisterMod(modId, "Mass Cable Removal", "1.0.0");
gregCore.API.GregAPI.Settings.RegisterToggle(modId, "enable_mass_removal", "Enable Mass Cable Removal", true, val => _enabled = val, "Maintenance", "Allows mass removing cables by holding a button (default: Left Alt + Click).");
}
public override void OnUpdate()
{
if (!_enabled) return;
_showMassRemoveHint = false;
_showWorldPurgeHint = false;
var kb = Keyboard.current;
var mouse = Mouse.current;
// Simplified default binding: Left Alt + Left Click
if (kb == null || mouse == null)
{
CancelCharge();
CancelWorldPurge();
return;
}
bool isAimHeld = kb.leftAltKey.isPressed;
bool isChargePressed = isAimHeld && mouse.leftButton.isPressed;
bool chargePressedThisFrame = isAimHeld && mouse.leftButton.wasPressedThisFrame;
if (!isAimHeld)
{
CancelCharge();
CancelWorldPurge();
return;
}
if (TryGetLookedAtCableDevice(out var sw, out var panel))
{
CancelWorldPurge();
UpdateDeviceChargeFlow(isChargePressed, chargePressedThisFrame, sw, panel);
return;
}
CancelCharge();
if (!isChargePressed)
{
CancelWorldPurge();
return;
}
_worldPurgeElapsed += Time.deltaTime;
_showWorldPurgeHint = true;
if (_worldPurgeElapsed < WorldPurgeHoldSeconds)
return;
TryDisconnectAllInWorld();
CancelWorldPurge();
}
private void UpdateDeviceChargeFlow(bool isChargePressed, bool chargePressedThisFrame, NetworkSwitch? sw, PatchPanel? panel)
{
if (_charging && !IsSameChargeTarget(sw, panel))
CancelCharge();
_showMassRemoveHint = true;
if (!_charging)
{
if (!chargePressedThisFrame) return;
if (sw != null)
{
_chargeSwitch = sw;
_chargePanel = null;
_chargeHoldSeconds = 0.85f;
}
else
{
_chargePanel = panel;
_chargeSwitch = null;
_chargeHoldSeconds = 0.85f;
}
_chargeElapsed = 0f;
_charging = true;
return;
}
if (!isChargePressed)
{
CancelCharge();
return;
}
_chargeElapsed += Time.deltaTime;
if (_chargeElapsed < _chargeHoldSeconds) return;
var s = _chargeSwitch;
var p = _chargePanel;
CancelCharge();
if (s != null) TryDisconnectOnNetworkSwitch(s);
else if (p != null) TryDisconnectOnPatchPanel(p);
}
private bool IsSameChargeTarget(NetworkSwitch? sw, PatchPanel? panel)
{
if (_chargeSwitch != null) return sw == _chargeSwitch;
if (_chargePanel != null) return panel == _chargePanel;
return false;
}
private void CancelCharge() { _charging = false; _chargeElapsed = 0f; _chargeSwitch = null; _chargePanel = null; }
private void CancelWorldPurge() { _worldPurgeElapsed = 0f; }
public override void OnGUI()
{
if (!_enabled) return;
if (_showWorldPurgeHint)
{
const float w = 680f;
const float h = 96f;
var x = (Screen.width - w) * 0.5f;
var y = Screen.height - 140f;
GUI.Box(new Rect(x, y, w, h), GUIContent.none);
var msg = $"L-ALT: WORLD purge — NOT looking at a device.\nKeep holding L-CLICK for {WorldPurgeHoldSeconds:0}s to remove ALL cables everywhere.";
GUI.Label(new Rect(x + 12f, y + 8f, w - 24f, h - 12f), msg);
return;
}
if (!_showMassRemoveHint) return;
const float w2 = 620f;
const float h2 = 72f;
var x2 = (Screen.width - w2) * 0.5f;
var y2 = Screen.height - 130f;
GUI.Box(new Rect(x2, y2, w2, h2), GUIContent.none);
var msg2 = _charging ? $"L-ALT: Removing ALL cables — keep holding L-CLICK." : $"L-ALT: Hold L-CLICK to remove ALL cables from this device.";
GUI.Label(new Rect(x2 + 12f, y2 + 10f, w2 - 24f, h2 - 16f), msg2);
}
private bool TryGetLookedAtCableDevice(out NetworkSwitch? sw, out PatchPanel? panel)
{
sw = null; panel = null;
var cam = Camera.main;
if (cam == null) return false;
var ray = cam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
if (Physics.Raycast(ray, out var hit, 14f))
{
sw = hit.collider.GetComponentInParent<NetworkSwitch>();
if (sw != null) return true;
panel = hit.collider.GetComponentInParent<PatchPanel>();
return panel != null;
}
return false;
}
private void TryDisconnectOnNetworkSwitch(NetworkSwitch sw)
{
try { sw.DisconnectCables(); } catch { }
}
private void TryDisconnectOnPatchPanel(PatchPanel p)
{
try
{
if (p.cableLinkPorts == null) return;
foreach (var port in p.cableLinkPorts)
{
if (port != null)
{
port.SecondActionOnClick();
}
}
}
catch { }
}
private void TryDisconnectAllInWorld()
{
foreach (var sw in Resources.FindObjectsOfTypeAll<NetworkSwitch>())
if (sw.gameObject.scene.isLoaded) TryDisconnectOnNetworkSwitch(sw);
foreach (var p in Resources.FindObjectsOfTypeAll<PatchPanel>())
if (p.gameObject.scene.isLoaded) TryDisconnectOnPatchPanel(p);
_log.Msg("World purge finished.");
}
}
}
+54
View File
@@ -0,0 +1,54 @@
using HarmonyLib;
using Il2Cpp;
using System;
using gregCore.GameLayer.Hooks;
namespace greg.CommonShop
{
[HarmonyPatch]
public static class CommonShopPatch
{
[HarmonyPatch(typeof(global::Il2Cpp.ComputerShop), nameof(global::Il2Cpp.ComputerShop.ButtonShopScreen))]
[HarmonyPostfix]
public static void OnShopScreenOpened(global::Il2Cpp.ComputerShop __instance)
{
try
{
ShopAPI.InjectAll(__instance);
}
catch (Exception ex)
{
HookIntegration.LogPatchError(nameof(CommonShopPatch), ex);
}
}
[HarmonyPatch(typeof(global::Il2Cpp.ComputerShop), nameof(global::Il2Cpp.ComputerShop.ButtonCheckOut))]
[HarmonyPrefix]
public static void OnCheckout(global::Il2Cpp.ComputerShop __instance)
{
try
{
if (__instance.cartUIItems == null) return;
foreach (var cartItem in __instance.cartUIItems)
{
if (cartItem == null) continue;
foreach (var customItem in ShopAPI.RegisteredItems)
{
int targetID = customItem.ResultItemID ?? customItem.TemplateID;
if (cartItem.itemID == targetID && cartItem.itemName == customItem.Name)
{
customItem.OnCheckout?.Invoke(cartItem.Quantity);
}
}
}
}
catch (Exception ex)
{
HookIntegration.LogPatchError(nameof(CommonShopPatch), ex);
}
}
}
}
+37
View File
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using Il2Cpp;
using UnityEngine;
namespace greg.CommonShop
{
public class CustomShopItem
{
public string Name = string.Empty;
public int Price;
public Sprite? Icon;
public Action? OnBuy;
public PlayerManager.ObjectInHand TemplateType;
public int TemplateID;
public Color? BackgroundColor;
public GameObject? CustomPrefab;
public Action<GameObject>? OnUIReady;
public int? ResultItemID;
public Action<int>? OnCheckout;
public string Category = "Mods";
public string SubCategory = "";
internal static ShopItem? FindTemplate(ComputerShop shop, PlayerManager.ObjectInHand type, int id)
{
if (shop.shopItems == null) return null;
foreach (var si in shop.shopItems)
{
if (si?.shopItemSO != null && si.shopItemSO.itemType == type && si.shopItemSO.itemID == id)
return si;
}
return shop.shopItems.Length > 0 ? shop.shopItems[0] : null;
}
}
}
+142
View File
@@ -0,0 +1,142 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Il2Cpp;
using UnityEngine;
using Object = UnityEngine.Object;
using UnityEngine.UI;
using greg.Logging;
namespace greg.CommonShop
{
public static class ShopAPI
{
private static List<CustomShopItem> _registeredItems = new();
internal static List<CustomShopItem> RegisteredItems => _registeredItems;
private static GregModLogger _log = new GregModLogger("CommonShop");
public static void RegisterItem(CustomShopItem item)
{
if (_registeredItems.Any(i => i.Name == item.Name))
{
_log.Warn($"Conflict: An item named '{item.Name}' is already registered! Skipping.");
return;
}
if (item.ResultItemID.HasValue)
{
if (_registeredItems.Any((i => i.TemplateType == item.TemplateType && i.ResultItemID == item.ResultItemID)))
{
_log.Warn($"Conflict: ResultItemID {item.ResultItemID} for {item.TemplateType} is already claimed! Skipping.");
return;
}
}
_registeredItems.Add(item);
_log.Msg($"Registered: {item.Name} in {item.Category}");
}
internal static void InjectAll(ComputerShop shop)
{
if (_registeredItems.Count == 0) return;
var injectedGrids = new List<Transform>();
var categoryGroups = _registeredItems.GroupBy(item => item.Category);
foreach (var catGroup in categoryGroups)
{
string mainCategory = catGroup.Key;
var subGroups = catGroup.GroupBy(item => item.SubCategory ?? "");
foreach (var subGroup in subGroups)
{
string subCategory = subGroup.Key;
Transform container = EnsureCategoryContainer(shop, mainCategory, subCategory);
if (container == null) continue;
for (int i = container.childCount - 1; i >= 0; i--)
{
if (container.GetChild(i).name.StartsWith("ModCard_"))
Object.DestroyImmediate(container.GetChild(i).gameObject);
}
foreach (var data in subGroup)
{
if (HasExternalModConflict(shop, data))
{
_log.Error($"External Conflict: Another mod is using '{data.Name}'. Skipping injection.");
continue;
}
ShopItem? template = CustomShopItem.FindTemplate(shop, data.TemplateType, data.TemplateID);
if (template != null)
{
CreateShopCard(shop, container, template, data);
}
}
injectedGrids.Add(container);
}
}
var sr = shop.shopItemParent.GetComponentInParent<ScrollRect>();
if (sr?.content != null)
LayoutRebuilder.ForceRebuildLayoutImmediate(sr.content);
}
private static bool HasExternalModConflict(ComputerShop shop, CustomShopItem data)
{
int targetID = data.ResultItemID ?? data.TemplateID;
var allUIItems = shop.shopItemParent.GetComponentsInChildren<ShopItem>(true);
foreach (var uiItem in allUIItems)
{
if (uiItem?.shopItemSO != null)
{
if (uiItem.shopItemSO.itemName == data.Name) return true;
if (data.ResultItemID.HasValue &&
uiItem.shopItemSO.itemType == data.TemplateType &&
uiItem.shopItemSO.itemID == targetID)
{
return true;
}
}
}
return false;
}
private static Transform EnsureCategoryContainer(ComputerShop shop, string category, string subCategory)
{
// Try to find the vanilla parent
var parent = shop.shopItemParent.transform;
if (parent == null) return null!;
return parent; // Simplification: append directly to main shop parent for now
}
private static void CreateShopCard(ComputerShop shop, Transform container, ShopItem template, CustomShopItem data)
{
var clone = Object.Instantiate(template.gameObject, container);
clone.name = "ModCard_" + data.Name;
clone.SetActive(true);
var si = clone.GetComponent<ShopItem>();
if (si != null)
{
var newSo = ScriptableObject.CreateInstance<ShopItemSO>();
newSo.itemName = data.Name;
newSo.price = data.Price;
newSo.itemType = data.TemplateType;
newSo.itemID = data.ResultItemID ?? data.TemplateID;
if (data.Icon != null) newSo.sprite = data.Icon;
si.shopItemSO = newSo;
si.Start(); // Force update UI texts based on new SO
// Invoke callback
data.OnUIReady?.Invoke(clone);
}
}
}
}
+157
View File
@@ -0,0 +1,157 @@
using HarmonyLib;
using Il2Cpp;
using MelonLoader;
using UnityEngine;
using System.Collections.Generic;
using greg.Logging;
namespace greg.FasterSFP
{
public class ModuleDef
{
public string Name;
public int SpeedGbps;
public float SpeedInternal => SpeedGbps / 5f;
public int Price;
public int ResultID;
public ModuleDef(string name, int speed, int price, int id)
{
Name = name; SpeedGbps = speed; Price = price; ResultID = id;
}
}
public class Main : MelonMod
{
private GregModLogger _log = null!;
private bool _enabled = true;
public static List<ModuleDef> Modules = new()
{
new ModuleDef("QSFP28 100Gbps", 100, 1000, 100),
new ModuleDef("QSFP56 200Gbps", 200, 2500, 101),
new ModuleDef("QSFP-DD 400Gbps", 400, 6000, 102),
new ModuleDef("QSFP-DD 800Gbps", 800, 12000, 103),
new ModuleDef("QSFP-DWDM 1.6Tbps", 1600, 25000, 104),
new ModuleDef("QSFP-DWDM 3.2Tbps", 3200, 50000, 105),
new ModuleDef("QSFP-DWDM 6.4Tbps", 6400, 100000, 106)
};
public override void OnInitializeMelon()
{
if (gregCore.Core.GregCoreMod.Instance == null) return;
_log = new GregModLogger("FasterSFP");
string modId = "faster_sfp";
gregCore.API.GregAPI.RegisterMod(modId, "Faster SFP Modules", "1.0.0");
gregCore.API.GregAPI.Settings.RegisterToggle(modId, "enable_faster_sfp", "Enable Faster SFP Modules", true, val => _enabled = val, "Hardware", "Adds 100Gbps to 6.4Tbps SFP modules to the shop.");
RegisterShopItems();
_log.FeatureState("FasterSFP", true);
}
private void RegisterShopItems()
{
foreach (var mod in Modules)
{
var item = new greg.CommonShop.CustomShopItem
{
Name = mod.Name,
Price = mod.Price,
TemplateType = PlayerManager.ObjectInHand.SFPModule,
TemplateID = 0, // Vanilla QSFP+ is usually index 0
ResultItemID = mod.ResultID,
Category = "Hardware",
SubCategory = "SFP Modules",
OnUIReady = (go) => { }, // Visuals could be set here
OnCheckout = (qty) =>
{
// Logic to give the player the custom SFP module
// The actual prefab injection happens via Harmony patches
// so the shop naturally dispenses them if the shop ID matches.
}
};
greg.CommonShop.ShopAPI.RegisterItem(item);
}
}
}
[HarmonyPatch]
public static class SFPPatch
{
[HarmonyPatch(typeof(global::Il2Cpp.MainGameManager), nameof(global::Il2Cpp.MainGameManager.Awake))]
[HarmonyPostfix]
public static void SetupRegistry(global::Il2Cpp.MainGameManager __instance)
{
// Expand sfpPrefabs to hold our new modules
if (__instance.sfpPrefabs == null) return;
int maxId = 106;
if (__instance.sfpPrefabs.Length <= maxId)
{
var newArr = new Il2CppInterop.Runtime.InteropTypes.Arrays.Il2CppReferenceArray<GameObject>(maxId + 1);
for (int i = 0; i < __instance.sfpPrefabs.Length; i++) newArr[i] = __instance.sfpPrefabs[i];
// Clone vanilla SFP for each new type
var basePrefab = __instance.sfpPrefabs[0];
if (basePrefab != null)
{
foreach (var mod in Main.Modules)
{
var clone = UnityEngine.Object.Instantiate(basePrefab);
clone.name = "CustomSFP_" + mod.Name;
clone.SetActive(false);
UnityEngine.Object.DontDestroyOnLoad(clone);
var comp = clone.GetComponent<SFPModule>();
if (comp != null) comp.speed = mod.SpeedInternal;
var usable = clone.GetComponent<UsableObject>();
if (usable != null) usable.prefabID = mod.ResultID;
newArr[mod.ResultID] = clone;
}
}
__instance.sfpPrefabs = newArr;
greg.Logging.GregLogger.Msg("FasterSFP modules injected into MainGameManager.", "FasterSFP");
}
}
[HarmonyPatch(typeof(global::Il2Cpp.ComputerShop), nameof(global::Il2Cpp.ComputerShop.GetPrefabForItem))]
[HarmonyPrefix]
public static bool GetPrefabForItemPatch(int itemID, PlayerManager.ObjectInHand itemType, ref GameObject __result)
{
var mgm = MainGameManager.instance;
if (mgm == null || mgm.sfpPrefabs == null) return true;
if (itemType == PlayerManager.ObjectInHand.SFPModule && itemID >= 100 && itemID <= 106)
{
if (itemID < mgm.sfpPrefabs.Length && mgm.sfpPrefabs[itemID] != null)
{
__result = mgm.sfpPrefabs[itemID];
return false;
}
}
return true;
}
[HarmonyPatch(typeof(global::Il2Cpp.CableLink), nameof(global::Il2Cpp.CableLink.InsertSFP))]
[HarmonyPrefix]
public static void InsertSFPPatch(float speed, SFPModule module)
{
var usableObj = module?.GetComponent<UsableObject>();
if (usableObj == null) return;
foreach (var def in Main.Modules)
{
if (Mathf.Approximately(speed, def.SpeedInternal))
{
usableObj.prefabID = def.ResultID;
break;
}
}
}
}
}
+21
View File
@@ -18,6 +18,7 @@ namespace greg.NoMoreEOL
private bool _autoRepairBrokenServers = true;
private bool _disableSwitchesEOL = true;
private bool _disableServersEOL = true;
internal static bool WarningsVisible = true;
// Internal State
private bool _readyToRun;
@@ -56,6 +57,26 @@ namespace greg.NoMoreEOL
gregCore.API.GregAPI.Settings.RegisterToggle(modId, "auto_repair_servers", "Auto Repair Servers", true, val => _autoRepairBrokenServers = val, "Maintenance", "Automatically repairs broken servers.");
gregCore.API.GregAPI.Settings.RegisterToggle(modId, "disable_switches_eol", "Disable Switches EOL", true, val => _disableSwitchesEOL = val, "Maintenance", "Prevents switches from reaching End-Of-Life.");
gregCore.API.GregAPI.Settings.RegisterToggle(modId, "disable_servers_eol", "Disable Servers EOL", true, val => _disableServersEOL = val, "Maintenance", "Prevents servers from reaching End-Of-Life.");
gregCore.API.GregAPI.Settings.RegisterToggle(modId, "show_warning_signs", "Show Warning Signs", true, val =>
{
WarningsVisible = val;
UpdateWarningSignsVisibility();
}, "Maintenance", "Show or hide EOL and error warning triangles above devices.");
}
private void UpdateWarningSignsVisibility()
{
var indicators = UnityEngine.Object.FindObjectsOfType<PositionIndicator>();
if (indicators != null)
{
foreach (var indicator in indicators)
{
if (indicator != null && indicator.gameObject != null)
{
indicator.gameObject.SetActive(WarningsVisible);
}
}
}
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
+2 -2
View File
@@ -4,13 +4,13 @@
- Prevents servers & switches from reaching end-of-life
- Automatically repairs broken devices
- Runs continuously during gameplay
- Includes an in-game config menu (via RustBridge)
- Includes an in-game config menu (via gregCore Settings API)
## Why I made it
I wanted to remove the repetitive maintenance part of the game and focus more on building and optimizing the network.
## Details
This module is fully integrated into the `gregCore` framework. It utilizes the new Settings API to expose configuration toggles directly in the F8 Settings Hub.
This module is fully integrated into the `gregCore` framework. It utilizes the native Settings API (accessible via the SDK and RustAPI) to expose configuration toggles directly in the F8 Settings Hub.
### Configuration Options
- **Auto Repair Switches**: Automatically repairs broken network switches.
+30
View File
@@ -0,0 +1,30 @@
using HarmonyLib;
using Il2Cpp;
using System;
using gregCore.GameLayer.Hooks;
namespace greg.NoMoreEOL
{
[HarmonyPatch]
public static class WarningSignPatch
{
[HarmonyPatch(typeof(global::Il2Cpp.StaticUIElements), "InstantiateErrorWarningSign")]
[HarmonyPrefix]
public static bool SkipInstantiate(ref int __result)
{
try
{
if (!Main.WarningsVisible)
{
__result = -1;
return false; // Skip the original method
}
}
catch (Exception ex)
{
HookIntegration.LogPatchError(nameof(WarningSignPatch), ex);
}
return true;
}
}
}
+204
View File
@@ -0,0 +1,204 @@
using HarmonyLib;
using Il2Cpp;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using greg.Logging;
namespace greg.QoL
{
public class Main : MelonMod
{
private bool _hasFixedLayout = false;
private GregModLogger _log = null!;
private bool _shopGridFixEnabled = true;
private bool _deleteHeldItemEnabled = true;
private bool _trashCleanerEnabled = true;
private float _cableSpoolLengthThreshold = 1.5f;
public override void OnInitializeMelon()
{
if (gregCore.Core.GregCoreMod.Instance == null)
{
LoggerInstance.Warning("[gC-QoL] gregCore not ready.");
return;
}
_log = new GregModLogger("QoL");
RegisterSettings();
_log.FeatureState("QoL", true);
_log.Msg("Initialization complete.");
}
private void RegisterSettings()
{
string modId = "qol";
gregCore.API.GregAPI.RegisterMod(modId, "Quality of Life", "1.0.0");
gregCore.API.GregAPI.Settings.RegisterToggle(modId, "shop_grid_fix", "Shop Grid Fix", true, val => _shopGridFixEnabled = val, "QoL", "Fixes the mod shop layout by converting it to a grid.");
gregCore.API.GregAPI.Settings.RegisterToggle(modId, "delete_held_item", "Delete Held Item (E at Dumpster)", true, val => _deleteHeldItemEnabled = val, "QoL", "Allows deleting modded items in your hand by pressing E while looking at the dumpster.");
gregCore.API.GregAPI.Settings.RegisterToggle(modId, "trash_cleaner", "Enable Trash Cleaner (F9)", true, val => _trashCleanerEnabled = val, "QoL", "Allows cleaning empty boxes and short cable spools manually by pressing F9.");
gregCore.API.GregAPI.Settings.RegisterSlider(modId, "trash_cleaner_spool_threshold", "Cable Spool Length Threshold", 1.5f, val => _cableSpoolLengthThreshold = val, "QoL", "Max length of cable spools to consider as trash.");
}
public override void OnUpdate()
{
if (_shopGridFixEnabled && !_hasFixedLayout)
{
foreach (HorizontalLayoutGroup hGroup in UnityEngine.Object.FindObjectsOfType<HorizontalLayoutGroup>())
{
if (hGroup.gameObject.name == "HL Mods")
{
_log.Msg($"Found HL Mods with {hGroup.transform.childCount} children - applying grid fix...");
ConvertToGrid(hGroup);
break;
}
}
}
if (_deleteHeldItemEnabled)
{
var kb = Keyboard.current;
if (kb != null && kb.eKey.wasPressedThisFrame)
{
TryDumpModdedItem();
}
}
if (_trashCleanerEnabled)
{
var kb = Keyboard.current;
if (kb != null && kb.f9Key.wasPressedThisFrame)
{
int removedBoxes = RemoveEmptySfpBoxes();
int removedSpools = RemoveEmptyCableSpools();
gregCore.API.GregAPI.ShowNotification($"Trash Cleaned: {removedBoxes} boxes, {removedSpools} spools.");
_log.Msg($"Trash Cleaned: {removedBoxes} boxes, {removedSpools} spools.");
}
}
}
private int RemoveEmptySfpBoxes()
{
int count = 0;
foreach (var box in UnityEngine.Object.FindObjectsOfType<global::Il2Cpp.SFPBox>())
{
if (box == null || box.objectInHands || box.isOnTrolley || box.currentRackPosition != null) continue;
bool isEmpty = true;
if (box.usedPositions != null)
{
foreach (var pos in box.usedPositions) if (pos != 0) { isEmpty = false; break; }
}
if (isEmpty)
{
foreach (var module in box.GetComponentsInChildren<global::Il2Cpp.SFPModule>(true))
{
if (module != null && module.isInTheBox) { isEmpty = false; break; }
}
}
if (isEmpty)
{
UnityEngine.Object.Destroy(box.gameObject);
count++;
}
}
return count;
}
private int RemoveEmptyCableSpools()
{
int count = 0;
foreach (var spool in UnityEngine.Object.FindObjectsOfType<global::Il2Cpp.CableSpinner>())
{
if (spool == null || spool.objectInHands || spool.cableLenght > _cableSpoolLengthThreshold) continue;
UnityEngine.Object.Destroy(spool.gameObject);
count++;
}
return count;
}
private void TryDumpModdedItem()
{
GameObject gameObject = GameObject.Find("Player/vCam/holdingPos/holdingPosChangedFromObject");
if (gameObject == null || gameObject.transform.childCount == 0)
return;
Transform child = gameObject.transform.GetChild(0);
bool isUsable = false;
bool isHardware = false;
foreach (Component component in child.GetComponents<Component>())
{
if (component != null)
{
try
{
string name = component.GetIl2CppType().Name;
if (name == "UsableObject") isUsable = true;
if (name == "Server" || name == "NetworkSwitch" || name == "PatchPanel" || name == "Rack") isHardware = true;
}
catch { }
}
}
if (!isUsable && !isHardware) return;
Camera main = Camera.main;
if (main == null) return;
RaycastHit hitInfo;
if (!Physics.Raycast(main.ScreenPointToRay(new Vector3(Screen.width / 2f, Screen.height / 2f, 0.0f)), out hitInfo, 3f))
return;
if (hitInfo.collider == null || hitInfo.collider.gameObject.name != "Dumpster_body")
return;
_log.Msg("Deleting modded item: " + child.name);
UnityEngine.Object.Destroy(child.gameObject);
}
private void ConvertToGrid(HorizontalLayoutGroup hGroup)
{
GameObject gameObject = hGroup.gameObject;
UnityEngine.Object.DestroyImmediate(hGroup);
GridLayoutGroup gridLayoutGroup = gameObject.AddComponent<GridLayoutGroup>();
if (gridLayoutGroup == null)
{
_log.Error("Failed to add GridLayoutGroup");
return;
}
gridLayoutGroup.cellSize = new Vector2(150f, 150f);
gridLayoutGroup.spacing = new Vector2(10f, 10f);
gridLayoutGroup.startCorner = GridLayoutGroup.Corner.UpperLeft;
gridLayoutGroup.startAxis = GridLayoutGroup.Axis.Horizontal;
gridLayoutGroup.childAlignment = TextAnchor.UpperLeft;
gridLayoutGroup.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
gridLayoutGroup.constraintCount = 5;
try
{
ContentSizeFitter contentSizeFitter = gameObject.AddComponent<ContentSizeFitter>();
if (contentSizeFitter != null)
{
contentSizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
contentSizeFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
}
}
catch
{
_log.Msg("ContentSizeFitter skipped");
}
_hasFixedLayout = true;
_log.Msg($"Grid fix applied! {gameObject.transform.childCount} items arranged in rows of 5.");
}
}
}
+26
View File
@@ -0,0 +1,26 @@
using System;
using gregCore.Core.Events;
namespace greg.Sdk
{
/// <summary>
/// Legacy proxy for the event dispatcher to maintain compatibility with older mods.
/// </summary>
public static class gregEventDispatcher
{
public static void On(string hookName, Action<object> handler, string modId = "legacy")
{
GregEventDispatcher.On(hookName, handler, modId);
}
public static void Emit(string hookName, object data)
{
GregEventDispatcher.Emit(hookName, data);
}
public static void UnregisterAll(string modId)
{
GregEventDispatcher.UnregisterAll(modId);
}
}
}
+15 -26
View File
@@ -11,33 +11,22 @@ namespace greg.Sdk
public static class gregNativeEventHooks
{
// Legacy support for older mods expecting static actions.
public static Action? SystemGameLoaded;
public static Action? SystemGameSaved;
public static Action<float>? PlayerCoinChanged;
public static Action<float>? PlayerReputationChanged;
public static Action<float>? PlayerXpChanged;
public static Action<int>? DayEnded;
public static Action<int>? MonthEnded;
public static Action<object>? CustomerAccepted;
public static Action<object>? ServerInstalled;
public static Action<object>? ServerBroken;
public static Action<object>? ServerRepaired;
public static Action<float>? ShopCheckout;
public static Action SystemGameLoaded = delegate { };
public static Action SystemGameSaved = delegate { };
public static Action<float> PlayerCoinChanged = _ => { };
public static Action<float> PlayerReputationChanged = _ => { };
public static Action<float> PlayerXpChanged = _ => { };
public static Action<int> DayEnded = _ => { };
public static Action<int> MonthEnded = _ => { };
public static Action<object> CustomerAccepted = _ => { };
public static Action<object> ServerInstalled = _ => { };
public static Action<object> ServerBroken = _ => { };
public static Action<object> ServerRepaired = _ => { };
public static Action<float> ShopCheckout = _ => { };
static gregNativeEventHooks()
{
SystemGameLoaded = delegate { };
SystemGameSaved = delegate { };
PlayerCoinChanged = delegate { };
PlayerReputationChanged = delegate { };
PlayerXpChanged = delegate { };
DayEnded = delegate { };
MonthEnded = delegate { };
CustomerAccepted = delegate { };
ServerInstalled = delegate { };
ServerBroken = delegate { };
ServerRepaired = delegate { };
ShopCheckout = delegate { };
// Initialized above for field-level safety
}
public static class ByEventId
@@ -53,9 +42,9 @@ namespace greg.Sdk
}
// --- Hilfsmethoden für Legacy-Mods ---
public static float GetPlayerMoney() => 0f;
public static float GetPlayerMoney() => (float)(Il2Cpp.SaveData.instance?.playerData?.coins ?? 0f);
public static int GetTimeOfDay() => (int)(Il2Cpp.TimeController.instance?.currentTimeOfDay ?? 0f);
public static int GetDay() => 1;
public static int GetDay() => 1; // Todo: Find real day field if needed
public static Transform? GetPlayerCamera() => Camera.main?.transform;
}
}