Converting everything into Harmony patches part 1

This commit is contained in:
Evil Factory
2026-02-09 21:54:44 -03:00
parent d14c353115
commit fb4648d759
14 changed files with 236 additions and 68 deletions

View File

@@ -297,6 +297,8 @@ namespace Barotrauma
MainThread = Thread.CurrentThread;
Window.FileDropped += OnFileDropped;
LuaCs.GetType();
}
public static void ExecuteAfterContentFinishedLoading(Action action)
@@ -1051,9 +1053,6 @@ namespace Barotrauma
SoundManager?.Update();
LuaCs.EventService.PublishEvent<IEventUpdate>(sub => sub.OnUpdate(Timing.Step));
LuaCs.Logger.ProcessLogs();
Timing.Accumulator -= Timing.Step;
updateCount++;

View File

@@ -7,11 +7,11 @@ using System.Collections.Generic;
namespace Barotrauma.LuaCs;
partial class NetworkingService : INetworkingService, IEventConnectedToServer, IEventServerRawNetMessageReceived
partial class NetworkingService : INetworkingService, IEventServerConnected, IEventServerRawNetMessageReceived
{
private ConcurrentDictionary<ushort, ConcurrentQueue<IReadMessage>> receiveQueue = new();
public void OnConnectedToServer()
public void OnServerConnected()
{
SendSyncMessage();
}

View File

@@ -495,8 +495,6 @@ namespace Barotrauma
allowInput = true;
}
GameMain.LuaCs.Hook.Call("keyUpdate", deltaTime);
oldMouseState = mouseState;
mouseState = latestMouseState;
UpdateVariable();

View File

@@ -1532,8 +1532,6 @@ namespace Barotrauma
public override void Select()
{
Select(enableAutoSave: true);
GameMain.LuaCs.EventService.PublishEvent<IEventScreenSelected>(sub => sub.OnScreenSelected(this));
}
public void Select(bool enableAutoSave = true)

View File

@@ -114,6 +114,8 @@ namespace Barotrauma
GameScreen = new GameScreen();
MainThread = Thread.CurrentThread;
LuaCs.GetType();
}
public void Init()
@@ -364,9 +366,6 @@ namespace Barotrauma
TaskPool.Update();
CoroutineManager.Update(paused: false, (float)Timing.Step);
LuaCs.EventService.PublishEvent<IEventUpdate>(sub => sub.OnUpdate(Timing.Step));
LuaCs.Logger.ProcessLogs();
performanceCounterTimer.Stop();
if (GameMain.LuaCs.PerformanceCounter.EnablePerformanceCounter)
{

View File

@@ -1433,8 +1433,6 @@ namespace Barotrauma
}
#endif
GameMain.LuaCs.Hook.Call("character.created", new object[] { newCharacter });
return newCharacter;
}
@@ -1889,7 +1887,6 @@ namespace Barotrauma
}
}
info.Job?.GiveJobItems(this, isPvPMode, spawnPoint);
GameMain.LuaCs.Hook.Call("character.giveJobItems", this, spawnPoint, isPvPMode);
}
public void GiveIdCardTags(WayPoint spawnPoint, bool createNetworkEvent = false)

View File

@@ -482,7 +482,6 @@ namespace Barotrauma
{
GrainEffectStrength -= amount;
}
GameMain.LuaCs.Hook.Call("afflictionUpdate", new object[] { this, characterHealth, targetLimb, deltaTime });
}
public void ApplyStatusEffects(ActionType type, float deltaTime, CharacterHealth characterHealth, Limb targetLimb)

View File

@@ -53,8 +53,6 @@ namespace Barotrauma
public static void SetCore(CorePackage newCore)
{
SetCoreEnumerable(newCore).Consume();
GameMain.LuaCs.EventService.PublishEvent<IEventEnabledPackageListChanged>(
sub => sub.OnEnabledPackageListChanged(Core, Regular));
}
public static IEnumerable<LoadProgress> SetCoreEnumerable(CorePackage newCore)
@@ -94,8 +92,6 @@ namespace Barotrauma
public static void SetRegular(IReadOnlyList<RegularPackage> newRegular)
{
SetRegularEnumerable(newRegular).Consume();
GameMain.LuaCs.EventService.PublishEvent<IEventEnabledPackageListChanged>(
sub => sub.OnEnabledPackageListChanged(Core, Regular));
}
public static IEnumerable<LoadProgress> SetRegularEnumerable(IReadOnlyList<RegularPackage> inNewRegular)
@@ -338,9 +334,6 @@ namespace Barotrauma
Debug.WriteLine($"Loaded \"{newPackage.Name}\"");
}
GameMain.LuaCs.EventService.PublishEvent<IEventAllPackageListChanged>(sub =>
sub.OnAllPackageListChanged(ContentPackageManager.CorePackages, ContentPackageManager.RegularPackages));
}
private readonly string directory;
@@ -580,12 +573,6 @@ namespace Barotrauma
yield return p.Transform(loadingRange);
}
GameMain.LuaCs.EventService.PublishEvent<IEventAllPackageListChanged>(
sub => sub.OnAllPackageListChanged(CorePackages, RegularPackages));
GameMain.LuaCs.EventService.PublishEvent<IEventEnabledPackageListChanged>(
sub => sub.OnEnabledPackageListChanged(EnabledPackages.Core, EnabledPackages.Regular));
yield return LoadProgress.Progress(1.0f);
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Runtime.CompilerServices;
using System;
using System.Collections.Generic;
using System.Reflection;
using Barotrauma.LuaCs.Data;
@@ -69,6 +70,69 @@ internal interface IEventSettingInstanceLifetime : IEvent<IEventSettingInstanceL
#region GameEvents
internal interface IEventAfflictionUpdate : IEvent<IEventAfflictionUpdate>
{
void OnAfflictionUpdate(Affliction affliction, CharacterHealth characterHealth, Limb targetLimb, float deltaTime);
static IEventAfflictionUpdate IEvent<IEventAfflictionUpdate>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc) => new
{
IsLuaRunner = Return<bool>.Arguments(() => true),
OnKeyUpdate = ReturnVoid.Arguments((Affliction affliction, CharacterHealth characterHealth, Limb targetLimb, float deltaTime) => luaFunc[nameof(OnAfflictionUpdate)](affliction, characterHealth, targetLimb, deltaTime))
}.ActLike<IEventAfflictionUpdate>();
}
internal interface IEventGiveCharacterJobItems : IEvent<IEventGiveCharacterJobItems>
{
void OnGiveCharacterJobItems(Character character, WayPoint spawnPoint, bool isPvPMode);
static IEventGiveCharacterJobItems IEvent<IEventGiveCharacterJobItems>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc) => new
{
IsLuaRunner = Return<bool>.Arguments(() => true),
OnKeyUpdate = ReturnVoid.Arguments((Character character, WayPoint spawnPoint, bool isPvPMode) => luaFunc[nameof(OnGiveCharacterJobItems)](character, spawnPoint, isPvPMode))
}.ActLike<IEventGiveCharacterJobItems>();
}
internal interface IEventCharacterCreated : IEvent<IEventCharacterCreated>
{
void OnCharacterCreated(Character character);
static IEventCharacterCreated IEvent<IEventCharacterCreated>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc) => new
{
IsLuaRunner = Return<bool>.Arguments(() => true),
OnKeyUpdate = ReturnVoid.Arguments((Character character) => luaFunc[nameof(OnCharacterCreated)](character))
}.ActLike<IEventCharacterCreated>();
}
/*
internal interface IEventHumanCPRFailed : IEvent<IEventHumanCPRFailed>
{
void OnHumanCPRFailed(Character character);
static IEventHumanCPRFailed IEvent<IEventHumanCPRFailed>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc) => new
{
IsLuaRunner = Return<bool>.Arguments(() => true),
OnKeyUpdate = ReturnVoid.Arguments((Character character) => luaFunc[nameof(OnHumanCPRFailed)](character))
}.ActLike<IEventHumanCPRFailed>();
}
internal interface IEventHumanCPRSuccess : IEvent<IEventHumanCPRSuccess>
{
void OnHumanCPRSuccess(Character character);
static IEventHumanCPRSuccess IEvent<IEventHumanCPRSuccess>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc) => new
{
IsLuaRunner = Return<bool>.Arguments(() => true),
OnKeyUpdate = ReturnVoid.Arguments((Character character) => luaFunc[nameof(OnHumanCPRSuccess)](character))
}.ActLike<IEventHumanCPRSuccess>();
}
*/
public interface IEventKeyUpdate : IEvent<IEventKeyUpdate>
{
void OnKeyUpdate(double deltaTime);
static IEventKeyUpdate IEvent<IEventKeyUpdate>.GetLuaRunner(IDictionary<string, LuaCsFunc> luaFunc) => new
{
IsLuaRunner = Return<bool>.Arguments(() => true),
OnKeyUpdate = ReturnVoid.Arguments((double deltaTime) => luaFunc[nameof(OnKeyUpdate)](deltaTime))
}.ActLike<IEventKeyUpdate>();
}
/// <summary>
/// Called as soon as round begins to load before any loading takes place.
/// </summary>
@@ -121,31 +185,17 @@ public interface IEventDrawUpdate : IEvent<IEventDrawUpdate>
}.ActLike<IEventDrawUpdate>();
}
#if CLIENT
public interface IEventServerRawNetMessageReceived : IEvent<IEventServerRawNetMessageReceived>
{
void OnReceivedServerNetMessage(IReadMessage netMessage, ServerPacketHeader serverPacketHeader);
}
public interface IEventConnectedToServer : IEvent<IEventConnectedToServer>
{
void OnConnectedToServer();
}
#elif SERVER
public interface IEventClientRawNetMessageReceived : IEvent<IEventClientRawNetMessageReceived>
{
void OnReceivedClientNetMessage(IReadMessage netMessage, ClientPacketHeader serverPacketHeader, NetworkConnection sender);
}
#endif
#endregion
#region Networking
#region Networking-Server
#if SERVER
public interface IEventClientRawNetMessageReceived : IEvent<IEventClientRawNetMessageReceived>
{
void OnReceivedClientNetMessage(IReadMessage netMessage, ClientPacketHeader serverPacketHeader, NetworkConnection sender);
}
/// <summary>
/// Called when a client connects to the server and has loaded into the lobby.
/// </summary>
@@ -163,10 +213,17 @@ interface IEventClientConnected : IEvent<IEventClientConnected>
}.ActLike<IEventClientConnected>();
}
#endif
#endregion
#region Networking-Client
#if CLIENT
public interface IEventServerRawNetMessageReceived : IEvent<IEventServerRawNetMessageReceived>
{
void OnReceivedServerNetMessage(IReadMessage netMessage, ServerPacketHeader serverPacketHeader);
}
/// <summary>
/// Called when the client has connected to the server and loaded to the lobby.
/// </summary>

View File

@@ -1,25 +1,21 @@
using System;
using System.Collections.Concurrent;
using Barotrauma.LuaCs;
using Barotrauma.LuaCs.Compatibility;
using Barotrauma.LuaCs.Data;
using Barotrauma.LuaCs.Events;
using Barotrauma.Networking;
using FluentResults;
using ImpromptuInterface;
using LightInject;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Net.Mime;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Barotrauma.LuaCs;
using Barotrauma.LuaCs.Data;
using Barotrauma.LuaCs.Events;
using Barotrauma.LuaCs.Compatibility;
using Barotrauma.Networking;
using Barotrauma.Steam;
using FluentResults;
using ImpromptuInterface;
using LightInject;
using Microsoft.Toolkit.Diagnostics;
using System.Runtime.CompilerServices;
using AssemblyLoader = Barotrauma.LuaCs.AssemblyLoader;
[assembly: InternalsVisibleTo("ImpromptuInterfaceDynamicAssembly")]
[assembly: InternalsVisibleTo("Dynamitey")]
namespace Barotrauma
{
internal delegate void LuaCsMessageLogger(string message);
@@ -34,6 +30,9 @@ namespace Barotrauma
// == startup
_servicesProvider = SetupServicesProvider();
_runStateMachine = SetupStateMachine();
_servicesProvider.GetService<HarmonyEventPatchesService>();
SubscribeToLuaCsEvents();
}
@@ -186,6 +185,7 @@ namespace Barotrauma
servicesProvider.RegisterServiceType<IConfigService, ConfigService>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<INetworkingService, NetworkingService>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<INetworkIdProvider, NetworkingIdProvider>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<HarmonyEventPatchesService, HarmonyEventPatchesService>(ServiceLifetime.Singleton);
// Extension/Sub Services
servicesProvider.RegisterServiceType<IAssemblyLoaderService.IFactory, AssemblyLoader.Factory>(ServiceLifetime.Transient);
@@ -379,7 +379,7 @@ namespace Barotrauma
// Technically not very accurate, but we want to call after we run mods anyway
if (GameMain.Client != null)
{
EventService.PublishEvent<IEventConnectedToServer>(static p => p.OnConnectedToServer());
EventService.PublishEvent<IEventServerConnected>(static p => p.OnServerConnected());
}
#endif
CurrentRunState = RunState.Running;

View File

@@ -0,0 +1,130 @@
using Barotrauma.LuaCs;
using Barotrauma.LuaCs.Events;
using Barotrauma.Networking;
using HarmonyLib;
using Microsoft.Xna.Framework;
using System;
using static Barotrauma.ContentPackageManager;
namespace Barotrauma.LuaCs;
[HarmonyPatch]
internal class HarmonyEventPatchesService : IService
{
public bool IsDisposed { get; private set; }
private static IEventService _eventService;
private static ILoggerService _loggerService;
private readonly Harmony Harmony;
public HarmonyEventPatchesService(IEventService eventService, ILoggerService loggerService)
{
_eventService = eventService;
_loggerService = loggerService;
Harmony = new Harmony("LuaCsForBarotrauma.Events");
Harmony.PatchAll(typeof(HarmonyEventPatchesService));
}
[HarmonyPatch(typeof(CoroutineManager), nameof(CoroutineManager.Update)), HarmonyPostfix]
public static void CoroutineManager_Update_Post()
{
_eventService.PublishEvent<IEventUpdate>(x => x.OnUpdate(Timing.TotalTime));
_loggerService.ProcessLogs();
}
[HarmonyPatch(typeof(Screen), nameof(Screen.Select)), HarmonyPostfix]
public static void Screen_Selected_Post(Screen __instance)
{
_eventService.PublishEvent<IEventScreenSelected>(x => x.OnScreenSelected(__instance));
}
[HarmonyPatch(typeof(ContentPackageManager.PackageSource), nameof(ContentPackageManager.PackageSource.Refresh)), HarmonyPostfix]
public static void PackageSource_Refresh_Post()
{
_eventService.PublishEvent<IEventAllPackageListChanged>(x => x.OnAllPackageListChanged(ContentPackageManager.CorePackages, ContentPackageManager.RegularPackages));
}
[HarmonyPatch(typeof(ContentPackageManager), nameof(ContentPackageManager.Init)), HarmonyPostfix]
public static void ContentPackageManager_Init_Post()
{
_eventService.PublishEvent<IEventAllPackageListChanged>(x => x.OnAllPackageListChanged(ContentPackageManager.CorePackages, ContentPackageManager.RegularPackages));
_eventService.PublishEvent<IEventEnabledPackageListChanged>(sub => sub.OnEnabledPackageListChanged(EnabledPackages.Core, EnabledPackages.Regular));
}
[HarmonyPatch(typeof(ContentPackageManager.EnabledPackages), nameof(ContentPackageManager.EnabledPackages.SetCore)), HarmonyPostfix]
public static void EnabledPackages_SetCore_Post()
{
_eventService.PublishEvent<IEventEnabledPackageListChanged>(sub => sub.OnEnabledPackageListChanged(EnabledPackages.Core, EnabledPackages.Regular));
}
[HarmonyPatch(typeof(ContentPackageManager.EnabledPackages), nameof(ContentPackageManager.EnabledPackages.SetRegular)), HarmonyPostfix]
public static void EnabledPackages_SetRegular_Post()
{
_eventService.PublishEvent<IEventEnabledPackageListChanged>(sub => sub.OnEnabledPackageListChanged(EnabledPackages.Core, EnabledPackages.Regular));
}
#if CLIENT
[HarmonyPatch(typeof(GameClient), "ReadDataMessage"), HarmonyPrefix]
public static void GameClient_ReadDataMessage_Pre(IReadMessage inc)
{
ServerPacketHeader header = (ServerPacketHeader)inc.PeekByte(); // Read but don't advance the read pointer
_eventService.PublishEvent<IEventServerRawNetMessageReceived>(x => x.OnReceivedServerNetMessage(inc, header));
}
[HarmonyPatch(typeof(SubEditorScreen), nameof(SubEditorScreen.Select), new Type[] { }), HarmonyPostfix]
public static void SubEditorScreen_Selected_Post(Screen __instance)
{
_eventService.PublishEvent<IEventScreenSelected>(x => x.OnScreenSelected(__instance));
}
[HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.Update)), HarmonyPrefix]
public static void PlayerInput_Update_Pre(double deltaTime)
{
_eventService.PublishEvent<IEventKeyUpdate>(x => x.OnKeyUpdate(deltaTime));
}
#elif SERVER
[HarmonyPatch(typeof(GameServer), "ReadDataMessage"), HarmonyPrefix]
public static void GameServer_ReadDataMessage_Pre(NetworkConnection sender, IReadMessage inc)
{
ClientPacketHeader header = (ClientPacketHeader)inc.PeekByte(); // Read but don't advance the read pointer
_eventService.PublishEvent<IEventClientRawNetMessageReceived>(x => x.OnReceivedClientNetMessage(inc, header, sender));
}
#endif
[HarmonyPatch(typeof(Character), nameof(Character.Create), new[] {
typeof(CharacterPrefab),
typeof(Vector2),
typeof(string),
typeof(CharacterInfo),
typeof(ushort),
typeof(bool),
typeof(bool),
typeof(bool),
typeof(RagdollParams),
typeof(bool)
}), HarmonyPostfix]
public static void Character_Create_Post(Character __result)
{
_eventService.PublishEvent<IEventCharacterCreated>(x => x.OnCharacterCreated(__result));
}
[HarmonyPatch(typeof(Character), nameof(Character.GiveJobItems)), HarmonyPostfix]
public static void Character_GiveJobItems_Post(Character __instance, WayPoint spawnPoint, bool isPvPMode)
{
_eventService.PublishEvent<IEventGiveCharacterJobItems>(x => x.OnGiveCharacterJobItems(__instance, spawnPoint, isPvPMode));
}
[HarmonyPatch(typeof(Affliction), nameof(Affliction.Update)), HarmonyPostfix]
public static void Affliction_Update_Post(Affliction __instance, CharacterHealth characterHealth, Limb targetLimb, float deltaTime)
{
_eventService.PublishEvent<IEventAfflictionUpdate>(x => x.OnAfflictionUpdate(__instance, characterHealth, targetLimb, deltaTime));
}
public void Dispose()
{
Harmony.UnpatchSelf();
IsDisposed = true;
}
}

View File

@@ -172,6 +172,11 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService
private void RegisterLuaEvents()
{
_eventService.RegisterLuaEventAlias<IEventUpdate>("think", "OnUpdate");
_eventService.RegisterLuaEventAlias<IEventKeyUpdate>("keyUpdate", "OnKeyUpdate");
_eventService.RegisterLuaEventAlias<IEventCharacterCreated>("character.created", "OnCharacterCreated");
_eventService.RegisterLuaEventAlias<IEventCharacterCreated>("character.giveJobItems", "OnGiveCharacterJobItems");
_eventService.RegisterLuaEventAlias<IEventCharacterCreated>("afflictionUpdate", "OnAfflictionUpdate");
}
private void SetupEnvironment(bool enableSandbox)

View File

@@ -147,7 +147,7 @@ internal partial class NetworkingService : INetworkingService
private void SubscribeToEvents()
{
#if CLIENT
_eventService.Subscribe<IEventConnectedToServer>(this);
_eventService.Subscribe<IEventServerConnected>(this);
_eventService.Subscribe<IEventServerRawNetMessageReceived>(this);
#elif SERVER
_eventService.Subscribe<IEventClientRawNetMessageReceived>(this);

View File

@@ -43,7 +43,6 @@
GUI.SettingsMenuOpen = false;
#endif
Selected = this;
GameMain.LuaCs.EventService.PublishEvent<LuaCs.Events.IEventScreenSelected>(sub => sub.OnScreenSelected(this));
}
public virtual Camera Cam => null;