Initial import of gregCore
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using HarmonyLib;
|
||||
using MelonLoader;
|
||||
using greg.Sdk.Services;
|
||||
using Il2Cpp;
|
||||
|
||||
namespace greg.Harmony
|
||||
{
|
||||
/// <summary>
|
||||
/// Harmony patches for performance optimizations.
|
||||
/// Implements SafePatch pattern as per GregCore standards.
|
||||
/// </summary>
|
||||
|
||||
[HarmonyPatch(typeof(PacketSpawnerSystem), "SpawnPacket")]
|
||||
public static class Patch_PacketSpawnerSystem_SpawnPacket
|
||||
{
|
||||
static bool Prefix(PacketSpawnerSystem __instance)
|
||||
{
|
||||
try
|
||||
{
|
||||
// P0: Data Orb density control (B-49)
|
||||
// For now, use a default customer ID or fetch from context if available.
|
||||
// In a real implementation, we'd map spawnerEntity to a customer ID.
|
||||
const int defaultCustomerId = 0;
|
||||
|
||||
if (!GregOrbRenderService.ShouldSpawn(defaultCustomerId))
|
||||
{
|
||||
return false; // Skip original SpawnPacket
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MelonLogger.Error($"[SafePatch] PacketSpawnerSystem.SpawnPacket: {ex.Message}");
|
||||
return true; // Always return true to avoid breaking core game logic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(NetworkMap), nameof(NetworkMap.FindAllRoutes))]
|
||||
public static class Patch_NetworkMap_FindAllRoutes
|
||||
{
|
||||
static bool Prefix(NetworkMap __instance, string baseName, string serverName, ref List<List<string>> __result)
|
||||
{
|
||||
try
|
||||
{
|
||||
// P1: Route evaluation optimization (B-46) - Pointer-Swap Strategy
|
||||
if (GregRouteEvaluationService.TryGetCachedRoute(baseName, serverName, out var cachedRoutes))
|
||||
{
|
||||
__result = cachedRoutes;
|
||||
return false; // Skip original expensive FindAllRoutes
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MelonLogger.Error($"[SafePatch] NetworkMap.FindAllRoutes Prefix: {ex.Message}");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static void Postfix(string baseName, string serverName, List<List<string>> __result)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (__result != null)
|
||||
{
|
||||
GregRouteEvaluationService.CacheRoute(baseName, serverName, __result);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MelonLogger.Error($"[SafePatch] NetworkMap.FindAllRoutes Postfix: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(NetworkMap), nameof(NetworkMap.RemoveDevice))]
|
||||
public static class Patch_NetworkMap_InvalidateCache
|
||||
{
|
||||
static void Postfix(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Invalidate route cache when network topology changes
|
||||
GregRouteEvaluationService.InvalidateCache(name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MelonLogger.Error($"[SafePatch] NetworkMap.RemoveDevice: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace greg.Sdk.Services
|
||||
{
|
||||
public enum OrbRenderDensity
|
||||
{
|
||||
All = 0,
|
||||
SeventyFive = 1,
|
||||
Fifty = 2,
|
||||
TwentyFive = 3,
|
||||
Off = 4
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Service to manage data orb rendering density and per-customer toggles.
|
||||
/// Addresses P0 performance issue B-49.
|
||||
/// </summary>
|
||||
public static class GregOrbRenderService
|
||||
{
|
||||
public static OrbRenderDensity Density { get; set; } = OrbRenderDensity.All;
|
||||
private static readonly Dictionary<int, bool> _customerToggles = new();
|
||||
private static int _spawnCounter = 0;
|
||||
|
||||
public static void SetCustomerToggle(int customerId, bool enabled)
|
||||
{
|
||||
_customerToggles[customerId] = enabled;
|
||||
}
|
||||
|
||||
public static bool IsCustomerEnabled(int customerId)
|
||||
{
|
||||
if (_customerToggles.TryGetValue(customerId, out bool enabled))
|
||||
return enabled;
|
||||
return true; // Default to enabled
|
||||
}
|
||||
|
||||
public static bool ShouldSpawn(int customerId)
|
||||
{
|
||||
if (Density == OrbRenderDensity.Off) return false;
|
||||
|
||||
if (!IsCustomerEnabled(customerId))
|
||||
return false;
|
||||
|
||||
_spawnCounter++;
|
||||
return Density switch
|
||||
{
|
||||
OrbRenderDensity.SeventyFive => _spawnCounter % 4 != 0,
|
||||
OrbRenderDensity.Fifty => _spawnCounter % 2 == 0,
|
||||
OrbRenderDensity.TwentyFive => _spawnCounter % 4 == 0,
|
||||
_ => true
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace greg.Sdk.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Service for throttling expensive update loops and profiling.
|
||||
/// Addresses P1 performance issue B-52.
|
||||
/// </summary>
|
||||
public static class GregPerformanceProfilerService
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns true if the current frame is an update interval for the given key.
|
||||
/// </summary>
|
||||
public static bool ShouldUpdate(int interval)
|
||||
{
|
||||
if (interval <= 1) return true;
|
||||
return Time.frameCount % interval == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the current frame is an update interval for a specific key/tag.
|
||||
/// This allows staggered updates across different systems.
|
||||
/// </summary>
|
||||
public static bool ShouldUpdateStaggered(string key, int interval)
|
||||
{
|
||||
if (interval <= 1) return true;
|
||||
int hash = key.GetHashCode();
|
||||
return (Time.frameCount + (hash % interval)) % interval == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace greg.Sdk.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Service for optimizing route evaluation.
|
||||
/// Addresses P1 performance issue B-46.
|
||||
/// </summary>
|
||||
public static class GregRouteEvaluationService
|
||||
{
|
||||
private static readonly Dictionary<string, List<List<string>>> _routeCache = new();
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a cached route (Pointer-Swap optimization).
|
||||
/// </summary>
|
||||
public static bool TryGetCachedRoute(string baseName, string serverName, out List<List<string>> routes)
|
||||
{
|
||||
string key = $"{baseName}->{serverName}";
|
||||
return _routeCache.TryGetValue(key, out routes);
|
||||
}
|
||||
|
||||
public static void CacheRoute(string baseName, string serverName, List<List<string>> routes)
|
||||
{
|
||||
string key = $"{baseName}->{serverName}";
|
||||
_routeCache[key] = routes;
|
||||
|
||||
// Dispatch event for UI/Metrics
|
||||
// GregHookBus.Emit("greg.SERVER.RoutePointerSwapped", new { baseName, serverName });
|
||||
}
|
||||
|
||||
public static void InvalidateCache(string deviceId = null)
|
||||
{
|
||||
if (deviceId == null)
|
||||
{
|
||||
_routeCache.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Simple implementation: clear all if any device changes.
|
||||
// A more complex version would map devices to routes.
|
||||
_routeCache.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user