-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathMod.cs
114 lines (96 loc) · 4.61 KB
/
Mod.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
using System.Drawing;
using Reloaded.Hooks.Definitions;
using Reloaded.Mod.Interfaces;
using Reloaded.Mod.Interfaces.Internal;
using RNSReloaded.Interfaces;
using RNSReloaded.Interfaces.Structs;
using RNSReloaded.PlayerColorChanger.Config;
namespace RNSReloaded.PlayerColorChanger;
public unsafe class Mod : IMod {
private WeakReference<IRNSReloaded>? rnsReloadedRef;
private WeakReference<IReloadedHooks>? hooksRef;
private ILoggerV1 logger = null!;
private Configurator configurator = null!;
private Config.Config config = null!;
private IHook<ScriptDelegate>? playerColorSetHook;
private uint color;
private uint darkColor;
private uint baseColor;
private uint satColor;
public void StartEx(IModLoaderV1 loader, IModConfigV1 modConfig) {
this.rnsReloadedRef = loader.GetController<IRNSReloaded>()!;
this.hooksRef = loader.GetController<IReloadedHooks>()!;
this.logger = loader.GetLogger();
if (this.rnsReloadedRef.TryGetTarget(out var rnsReloaded)) {
rnsReloaded.OnReady += this.Ready;
}
this.configurator = new Configurator(((IModLoader) loader).GetModConfigDirectory(modConfig.ModId));
this.config = this.configurator.GetConfiguration<Config.Config>(0);
this.config.ConfigurationUpdated += this.ConfigurationUpdated;
this.ApplyConfig();
}
private void ApplyConfig() {
this.color = this.ParseColor(this.config.String);
this.darkColor = this.ParseColor(this.config.DarkString);
this.baseColor = this.ParseColor(this.config.BaseString);
this.satColor = this.ParseColor(this.config.SatString);
}
private uint ParseColor(string colorString) {
try {
if (colorString.StartsWith('#')) colorString = colorString.TrimStart('#');
var parsed = uint.Parse(colorString, System.Globalization.NumberStyles.HexNumber);
return (parsed & 0xFF00FF00) | ((parsed & 0x00FF0000) >> 16) | ((parsed & 0x000000FF) << 16);
} catch {
this.logger.PrintMessage("[Player Color Changer] Invalid color: " + colorString, Color.Red);
return 0xFFFFFF;
}
}
private void ConfigurationUpdated(IUpdatableConfigurable newConfig) {
this.config = (Config.Config) newConfig;
this.ApplyConfig();
}
public void Ready() {
if (
this.rnsReloadedRef != null
&& this.rnsReloadedRef.TryGetTarget(out var rnsReloaded)
&& this.hooksRef != null
&& this.hooksRef.TryGetTarget(out var hooks)
) {
var id = rnsReloaded.ScriptFindId("scr_playercolor_set");
var script = rnsReloaded.GetScriptData(id - 100000);
this.playerColorSetHook =
hooks.CreateHook<ScriptDelegate>(this.PlayerColorSetDetour, script->Functions->Function);
this.playerColorSetHook =
this.playerColorSetHook?.Activate();
this.playerColorSetHook?.Enable();
}
}
private RValue* PlayerColorSetDetour(
CInstance* self, CInstance* other, RValue* returnValue, int argc, RValue** argv
) {
returnValue = this.playerColorSetHook!.OriginalFunction(self, other, returnValue, argc, argv);
if (this.rnsReloadedRef != null && this.rnsReloadedRef.TryGetTarget(out var rnsReloaded)) {
RValue global = rnsReloaded.GetGlobalInstance();
var clientOwnId = global["clientOwnId"]->Int32;
var playerCharId = global["playerCharId"]->Get(0)->Get(clientOwnId);
var allyId = new RValue(self)["allyId"];
if (allyId->Int32 == playerCharId->Int32) {
var playerColor = global["playerColor"]->Get(0)->Get(clientOwnId);
if (playerColor != null) playerColor->Real = this.color;
var playerColorDark = global["playerColorDark"]->Get(0)->Get(clientOwnId);
if (playerColorDark != null) playerColorDark->Real = this.darkColor;
var playerColorBase = global["playerColorBase"]->Get(0)->Get(clientOwnId);
if (playerColorBase != null) playerColorBase->Real = this.baseColor;
var playerColorSat = global["playerColorSat"]->Get(0)->Get(clientOwnId);
if (playerColorSat != null) playerColorSat->Real = this.satColor;
}
}
return returnValue;
}
public void Suspend() => this.playerColorSetHook?.Disable();
public void Resume() => this.playerColorSetHook?.Enable();
public bool CanSuspend() => true;
public void Unload() { }
public bool CanUnload() => false;
public Action Disposing => () => { };
}