CrabUI
Loading...
Searching...
No Matches
CUI Patches.cs
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Reflection;
5using System.Diagnostics;
6using System.Runtime.CompilerServices;
7using System.IO;
8
9using Barotrauma;
10using Microsoft.Xna.Framework;
11using Microsoft.Xna.Framework.Input;
12using Microsoft.Xna.Framework.Graphics;
13using HarmonyLib;
14using EventInput;
15
16namespace CrabUI
17{
18 public partial class CUI
19 {
20 public static void CheckOtherPatches(string msg = "")
21 {
22 CUI.Log(msg);
23 CUI.Log($"Harmony.GetAllPatchedMethods:", Color.Lime);
24 foreach (MethodBase mb in Harmony.GetAllPatchedMethods())
25 {
26 Patches patches = Harmony.GetPatchInfo(mb);
27
28 if (patches.Prefixes.Count() > 0 || patches.Postfixes.Count() > 0)
29 {
30 CUI.Log($"{mb.DeclaringType}.{mb.Name}:");
31 if (patches.Prefixes.Count() > 0)
32 {
33 CUI.Log($" Prefixes:");
34 foreach (Patch patch in patches.Prefixes) { CUI.Log($" {patch.owner}"); }
35 }
36
37 if (patches.Postfixes.Count() > 0)
38 {
39 CUI.Log($" Postfixes:");
40 foreach (Patch patch in patches.Postfixes) { CUI.Log($" {patch.owner}"); }
41 }
42 }
43 }
44 }
45
46 public static void CheckPatches(string typeName, string methodName)
47 {
48 CUI.Log($"Harmony.GetAllPatchedMethods:", Color.Lime);
49 foreach (MethodBase mb in Harmony.GetAllPatchedMethods())
50 {
51 if (
52 !string.Equals(typeName, mb.DeclaringType.Name, StringComparison.OrdinalIgnoreCase) ||
53 !string.Equals(methodName, mb.Name, StringComparison.OrdinalIgnoreCase)
54 ) continue;
55
56 Patches patches = Harmony.GetPatchInfo(mb);
57
58 if (patches.Prefixes.Count() > 0 || patches.Postfixes.Count() > 0)
59 {
60 CUI.Log($"{mb.DeclaringType}.{mb.Name}:");
61 if (patches.Prefixes.Count() > 0)
62 {
63 CUI.Log($" Prefixes:");
64 foreach (Patch patch in patches.Prefixes) { CUI.Log($" {patch.owner}"); }
65 }
66
67 if (patches.Postfixes.Count() > 0)
68 {
69 CUI.Log($" Postfixes:");
70 foreach (Patch patch in patches.Postfixes) { CUI.Log($" {patch.owner}"); }
71 }
72 }
73 }
74 }
75
76 private static void AddHooks()
77 {
78 GameMain.LuaCs.Hook.Add("GUI_Draw_Prefix", CUIHookID, (object[] args) =>
79 {
80 GUI_Draw_Prefix((SpriteBatch)args.ElementAtOrDefault(0));
81 return null;
82 });
83
84 GameMain.LuaCs.Hook.Add("GUI_DrawCursor_Prefix", CUIHookID, (object[] args) =>
85 {
86 GUI_DrawCursor_Prefix((SpriteBatch)args.ElementAtOrDefault(0));
87 return null;
88 });
89
90
91 // this hook seems to do nothing
92 // GameMain.LuaCs.Hook.Add("Camera_MoveCamera_Prefix", CUIHookID, (object[] args) =>
93 // {
94 // return Camera_MoveCamera_Prefix(); ;
95 // });
96
97 GameMain.LuaCs.Hook.Add("KeyboardDispatcher_set_Subscriber_Prefix", CUIHookID, (object[] args) =>
98 {
99 KeyboardDispatcher_set_Subscriber_Prefix(
100 (KeyboardDispatcher)args.ElementAtOrDefault(0),
101 (IKeyboardSubscriber)args.ElementAtOrDefault(1)
102 );
103 return null;
104 });
105
106 GameMain.LuaCs.Hook.Add("GUI_InputBlockingMenuOpen_Postfix", CUIHookID, (object[] args) => CUI.InputBlockingMenuOpen);
107
108 GameMain.LuaCs.Hook.Add("GUI_TogglePauseMenu_Postfix", CUIHookID, (object[] args) =>
109 {
110 GUI_TogglePauseMenu_Postfix();
111 return null;
112 });
113 }
114
115 private static void AddHarmonyPatches()
116 {
117 harmony.Patch(
118 original: typeof(GUI).GetMethod("Draw", AccessTools.all),
119 prefix: new HarmonyMethod(typeof(CUI).GetMethod("GUI_Draw_Prefix", AccessTools.all))
120 );
121
122 harmony.Patch(
123 original: typeof(GUI).GetMethod("DrawCursor", AccessTools.all),
124 prefix: new HarmonyMethod(typeof(CUI).GetMethod("GUI_DrawCursor_Prefix", AccessTools.all))
125 );
126
127 // harmony.Patch(
128 // original: typeof(GameMain).GetMethod("Update", AccessTools.all),
129 // postfix: new HarmonyMethod(typeof(CUI).GetMethod("GameMain_Update_Postfix", AccessTools.all))
130 // );
131
132 // harmony.Patch(
133 // original: typeof(GUI).GetMethod("UpdateMouseOn", AccessTools.all),
134 // postfix: new HarmonyMethod(typeof(CUI).GetMethod("GUI_UpdateMouseOn_Postfix", AccessTools.all))
135 // );
136
137 harmony.Patch(
138 original: typeof(Camera).GetMethod("MoveCamera", AccessTools.all),
139 prefix: new HarmonyMethod(typeof(CUI).GetMethod("Camera_MoveCamera_Prefix", AccessTools.all))
140 );
141
142 harmony.Patch(
143 original: typeof(KeyboardDispatcher).GetMethod("set_Subscriber", AccessTools.all),
144 prefix: new HarmonyMethod(typeof(CUI).GetMethod("KeyboardDispatcher_set_Subscriber_Prefix", AccessTools.all))
145 );
146
147 harmony.Patch(
148 original: typeof(GUI).GetMethod("TogglePauseMenu", AccessTools.all, new Type[] { }),
149 postfix: new HarmonyMethod(typeof(CUI).GetMethod("GUI_TogglePauseMenu_Postfix", AccessTools.all))
150 );
151
152 harmony.Patch(
153 original: typeof(GUI).GetMethod("get_InputBlockingMenuOpen", AccessTools.all),
154 postfix: new HarmonyMethod(typeof(CUI).GetMethod("GUI_InputBlockingMenuOpen_Postfix", AccessTools.all))
155 );
156 }
157
158 private static void AddAnyway()
159 {
160 GameMain.LuaCs.Hook.Add("think", CUIHookID, (object[] args) =>
161 {
162 CUIUpdateMouseOn();
163 CUIUpdate(Timing.TotalTime);
164 return null;
165 });
166
167 GameMain.LuaCs.Hook.Add("item.created", CUIHookID, (object[] args) =>
168 {
169 Item item = args.ElementAtOrDefault(0) as Item;
170 AttachedItems.ConnectIfMapped(item);
171 return null;
172 });
173
174 GameMain.LuaCs.Hook.Add("roundStart", CUIHookID, (object[] args) =>
175 {
176 AttachedItems.ShakeTheRefs();
177 return null;
178 });
179 }
180
181
182 private static void PatchAll()
183 {
184 if (UseCursedPatches) AddHarmonyPatches();
185 else AddHooks();
186
187 AddAnyway();
188 }
189
190
191 private static void GameMain_Update_Postfix(GameTime gameTime)
192 {
193 if (GhostDetector.Check()) return;
194 CUIUpdate(gameTime.TotalGameTime.TotalSeconds);
195 }
196 private static void CUIUpdate(double time)
197 {
198 if (Main == null) CUI.Error($"CUIUpdate: CUI.Main in {HookIdentifier} was null, tell the dev", 20, 5);
199 try
200 {
201 AttachedItems.UpdateAll();
202 CUIAnimation.UpdateAllAnimations(time);
203 CUI.Input?.Scan(time);
204 TopMain?.Update(time);
205 Main?.Update(time);
206 }
207 catch (Exception e)
208 {
209 CUI.Warning($"CUI: {e}");
210 }
211 }
212
213 private static void GUI_Draw_Prefix(SpriteBatch spriteBatch)
214 {
215 if (GhostDetector.Check()) return;
216 try { Main?.Draw(spriteBatch); }
217 catch (Exception e) { CUI.Warning($"CUI: {e}"); }
218 }
219
220 private static void GUI_DrawCursor_Prefix(SpriteBatch spriteBatch)
221 {
222 if (GhostDetector.Check()) return;
223 try { TopMain?.Draw(spriteBatch); }
224 catch (Exception e) { CUI.Warning($"CUI: {e}"); }
225 }
226
227 private static void GUI_UpdateMouseOn_Postfix(ref GUIComponent __result)
228 {
229 if (GhostDetector.Check()) return;
230 CUIUpdateMouseOn();
231 }
232
233 private static void CUIUpdateMouseOn()
234 {
235 if (Main == null) CUI.Error($"CUIUpdateMouseOn: CUI.Main in {HookIdentifier} was null, tell the dev", 20);
236 if (GUI.MouseOn == null && Main != null && Main.MouseOn != null && Main.MouseOn != Main) GUI.MouseOn = CUIComponent.dummyComponent;
237 if (TopMain != null && TopMain.MouseOn != null && TopMain.MouseOn != TopMain) GUI.MouseOn = CUIComponent.dummyComponent;
238 }
239
240 private static Dictionary<string, bool> CUIBlockScroll()
241 {
242 if (GUI.MouseOn != CUIComponent.dummyComponent) return null;
243
244 return new Dictionary<string, bool>()
245 {
246 ["allowZoom"] = false,
247 };
248 }
249
250 private static void Camera_MoveCamera_Prefix(float deltaTime, ref bool allowMove, ref bool allowZoom, bool allowInput, bool? followSub)
251 {
252 if (GhostDetector.Check()) return;
253 if (GUI.MouseOn == CUIComponent.dummyComponent) allowZoom = false;
254 }
255
256 private static void KeyboardDispatcher_set_Subscriber_Prefix(KeyboardDispatcher __instance, IKeyboardSubscriber value)
257 {
258 if (GhostDetector.Check()) return;
259 FocusResolver?.OnVanillaIKeyboardSubscriberSet(value);
260 }
261
262 public static void GUI_InputBlockingMenuOpen_Postfix(ref bool __result)
263 {
264 if (GhostDetector.Check()) return;
265 __result = __result || CUI.InputBlockingMenuOpen;
266 }
267
268 public static void GUI_TogglePauseMenu_Postfix()
269 {
270 if (GhostDetector.Check()) return;
271 try
272 {
273 if (GUI.PauseMenu != null)
274 {
275 GUIFrame frame = GUI.PauseMenu;
276 GUIComponent pauseMenuInner = frame.GetChild(1);
277 GUIComponent list = frame.GetChild(1).GetChild(0);
278 GUIButton resumeButton = (GUIButton)list.GetChild(0);
279
280 GUIButton.OnClickedHandler oldHandler = resumeButton.OnClicked;
281
282 resumeButton.OnClicked = (GUIButton button, object obj) =>
283 {
284 bool guh = oldHandler(button, obj);
285 CUI.InvokeOnPauseMenuToggled();
286 return guh;
287 };
288 }
289 }
290 catch (Exception e) { CUI.Warning(e); }
291
292 CUI.InvokeOnPauseMenuToggled();
293 }
294
295
296 }
297}
static CUIMainComponent TopMain
Orchestrates Drawing and updates, there could be only one CUI.TopMain is located above vanilla GUI.
Definition CUI.cs:89
static CUIMainComponent Main
Orchestrates Drawing and updates, there could be only one CUI.Main is located under vanilla GUI.
Definition CUI.cs:84
static bool UseCursedPatches
If true other compiled mods that use CUI will break But if false then you'll have to setup hooks with...
Definition CUI.cs:118
static CUIFocusResolver FocusResolver
Adapter to vanilla focus system, don't use.
Definition CUI.cs:101
new void Draw(SpriteBatch spriteBatch)
Here component should be drawn.