99 lines
4.5 KiB
C#
99 lines
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using ShrinkContext;
|
|
using UnityEngine;
|
|
|
|
namespace ShrinkModFramework
|
|
{
|
|
public sealed class ShrinkModContext
|
|
{
|
|
private readonly ShrinkModRegistryManager _registryManager;
|
|
private readonly IReadOnlyDictionary<string, ShrinkModHandle> _loadedMods;
|
|
private readonly bool _verboseLogging;
|
|
private readonly ShrinkCtx _effectContext;
|
|
|
|
internal ShrinkModContext(ShrinkModInfo modInfo, ShrinkModRegistryManager registryManager,
|
|
IReadOnlyDictionary<string, ShrinkModHandle> loadedMods, bool verboseLogging,
|
|
ShrinkCtx effectContext = null)
|
|
{
|
|
ModInfo = modInfo;
|
|
_registryManager = registryManager;
|
|
_loadedMods = loadedMods;
|
|
_verboseLogging = verboseLogging;
|
|
_effectContext = effectContext;
|
|
}
|
|
|
|
public ShrinkModInfo ModInfo { get; }
|
|
public IReadOnlyDictionary<string, ShrinkModHandle> LoadedMods => _loadedMods;
|
|
public bool IsContextManaged => _effectContext != null;
|
|
|
|
public IReadOnlyShrinkModRegistry<T> GetRegistry<T>(string name) =>
|
|
_registryManager.GetOrCreateRegistry<T>(name);
|
|
|
|
public bool TryGetRegistry<T>(string name, out IReadOnlyShrinkModRegistry<T> registry)
|
|
=> _registryManager.TryGetRegistry(name, out registry);
|
|
|
|
/// <summary>用当前 ModId 作为 namespace 注册内容,并返回最终完整键。</summary>
|
|
public string RegisterContent<T>(string registryName, string localKey, T value) =>
|
|
_registryManager.GetOrCreateMutableRegistry<T>(registryName)
|
|
.RegisterNamespaced(ModInfo.ModId, localKey, value);
|
|
|
|
/// <summary>以当前模组为 owner 覆盖已有内容;同目标、同优先级冲突会直接失败。</summary>
|
|
public void OverrideContent<T>(string registryName, string targetKey, int priority, T value) =>
|
|
_registryManager.GetOrCreateMutableRegistry<T>(registryName)
|
|
.RegisterOverride(ModInfo.ModId, targetKey, priority, value);
|
|
|
|
public bool IsModLoaded(string modId) => !string.IsNullOrWhiteSpace(modId) && _loadedMods.ContainsKey(modId);
|
|
|
|
public bool TryGetLoadedMod(string modId, out ShrinkModHandle handle)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(modId))
|
|
return _loadedMods.TryGetValue(modId, out handle);
|
|
|
|
handle = null;
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 在模组组件上下文中执行前向动作并就地登记逆操作。逆操作随 fiber 卸载按 LIFO 执行。
|
|
/// 旧 ShrinkModLoader 路径没有可逆上下文,调用本 API 会明确失败而不是静默丢失 cleanup。
|
|
/// </summary>
|
|
public void Effect(Action forward, Action inverse)
|
|
{
|
|
if (_effectContext == null)
|
|
throw new InvalidOperationException(
|
|
"ShrinkModContext.Effect requires ShrinkModContextHost. The legacy ShrinkModLoader cannot track inverses.");
|
|
_effectContext.Effect(forward, inverse);
|
|
}
|
|
|
|
/// <summary>为已完成的前向动作登记同步逆操作。</summary>
|
|
public void EffectInverse(Action inverse)
|
|
{
|
|
if (inverse == null)
|
|
throw new ArgumentNullException(nameof(inverse));
|
|
Effect(() => { }, inverse);
|
|
}
|
|
|
|
public void Log(string message)
|
|
{
|
|
if (_verboseLogging)
|
|
Debug.Log($"[ShrinkMod:{ModInfo.ModId}] {message}");
|
|
}
|
|
|
|
public void RegisterNetworkHandler<T>(string channel, System.Action<ShrinkModNetworkMessageContext, T> handler)
|
|
=> ShrinkModNetworkManager.RegisterHandler(ModInfo.ModId, channel, handler);
|
|
|
|
public void SendToServer<T>(string channel, T payload, string senderPeerId = null)
|
|
=> ShrinkModNetworkManager.SendToServer(ModInfo.ModId, channel, payload, senderPeerId);
|
|
|
|
public void SendToAllClients<T>(string channel, T payload, string senderPeerId = null)
|
|
=> ShrinkModNetworkManager.SendToAllClients(ModInfo.ModId, channel, payload, senderPeerId);
|
|
|
|
public void SendToClient<T>(string channel, T payload, string targetPeerId, string senderPeerId = null)
|
|
=> ShrinkModNetworkManager.SendToClient(ModInfo.ModId, channel, payload, targetPeerId, senderPeerId);
|
|
|
|
public void LogWarning(string message) => Debug.LogWarning($"[ShrinkMod:{ModInfo.ModId}] {message}");
|
|
public void LogError(string message) => Debug.LogError($"[ShrinkMod:{ModInfo.ModId}] {message}");
|
|
}
|
|
}
|