XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEExtension.NetCore.MemoryEditor

【DLL】内存读写工具/编辑器

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFEExtension.NetCore.MemoryEditor

完善内存监听器,添加可更新内存地址监听器

cb15a3d
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

5 个文件 +153 -185
Modified XFEExtension.NetCore.MemoryEditor/DynamicMemoryListener.cs +1 -1
@@ -50,7 +50,7 @@ public abstract class DynamicMemoryListener(string customName, Func<nint?> getAd
50 50 var currentValue = MemoryEditor.ReadMemory(processHandler, memoryAddress!.Value, memoryAddressType);
51 51 if (lastValue is null == currentValue is null || lastValue?.Equals(currentValue) == false)
52 52 {
53 valueChanged?.Invoke(this, new(lastValue is not null, currentValue is not null, lastValue, currentValue, customName));
53 valueChanged?.Invoke(this, new(lastValue is not null, currentValue is not null, lastValue, currentValue, name));
54 54 lastValue = currentValue;
55 55 }
56 56 await Task.Delay(frequency);
Modified XFEExtension.NetCore.MemoryEditor/Manager/MemoryListenerManager.cs +70 -169
@@ -10,14 +10,11 @@ namespace XFEExtension.NetCore.MemoryEditor.Manager;
10 10 public class MemoryListenerManager : IDisposable, IEnumerable
11 11 {
12 12 private bool disposedValue;
13 private readonly List<nint> addressListToListen = [];
14 private readonly Dictionary<string, Func<nint?>> addressFuncDictionaryToListen = [];
15 private readonly Dictionary<nint, bool> listeningAddressDictionary = [];
16 private readonly Dictionary<string, bool> listeningAddressFuncDictionary = [];
13 private readonly Dictionary<string, MemoryListener> listenerDictionary = [];
17 14 /// <summary>
18 15 /// 当监听值发生改变时触发
19 16 /// </summary>
20 public event XFEEventHandler<MemoryValue>? ValueChanged;
17 public event XFEEventHandler<MemoryListener, MemoryValue>? ValueChanged;
21 18 /// <summary>
22 19 /// 当前进程结束时触发
23 20 /// </summary>
@@ -40,208 +37,112 @@ public class MemoryListenerManager : IDisposable, IEnumerable
40 37 currentProcess?.Dispose();
41 38 currentProcess = value;
42 39 ProcessHandler = MemoryEditor.GetProcessHandle(value.Id, ProcessAccessFlags.All);
43 isCurrentProcessRunning = true;
44 currentProcess.Exited += (sender, e) => CurrentProcessExit?.Invoke(sender, e);
45 foreach (var address in addressListToListen)
40 currentProcess.Exited += CurrentProcess_Exited;
41 if (IsListening)
46 42 {
47
43 foreach (var listener in listenerDictionary.Values)
44 {
45 if (listener is UpdatableMemoryListener updatableMemoryListener)
46 updatableMemoryListener.UpdateAddress();
47 if (!listener.IsListening)
48 _ = listener.StartListen(ProcessHandler, listener.Frequency);
49 }
48 50 }
49 51 }
50 52 }
51 53 }
54 private async void CurrentProcess_Exited(object? sender, EventArgs e)
55 {
56 CurrentProcessExit?.Invoke(sender, e);
57 await StopListeners();
58 }
52 59 /// <summary>
53 60 /// 是否启用监听
54 61 /// </summary>
55 62 public bool IsListening { get; set; }
56 63 /// <summary>
57 /// 开始监听
64 /// 索引器
58 65 /// </summary>
59 /// <typeparam name="T">待监听的内存的数据类型(int,float,long等)</typeparam>
60 /// <param name="memoryAddress">待监听的内存地址</param>
61 /// <param name="customName">自定义监听器标识名</param>
66 /// <param name="customName">监听器自定义标识名</param>
62 67 /// <returns></returns>
63 public async Task StartListen<T>(nint memoryAddress, string? customName = null) where T : struct
68 public MemoryListener this[string customName]
64 69 {
65 IsListening = true;
66 await Task.Run(() =>
67 {
68 bool lastSuccess = false;
69 var lastValue = default(T);
70 try { lastSuccess = MemoryEditor.ReadMemory(ProcessHandler, memoryAddress, out lastValue); } catch { }
71 addressListToListen.Add(memoryAddress);
72 listeningAddressDictionary.Add(memoryAddress, true);
73 ReStart:
74 try
75 {
76 while (listeningAddressDictionary[memoryAddress] && IsListening && isCurrentProcessRunning)
77 {
78 try
79 {
80 var currentSuccess = MemoryEditor.ReadMemory<T>(ProcessHandler, memoryAddress, out var currentValue);
81 if (!currentValue.Equals(lastValue) || lastSuccess != currentSuccess)
82 {
83 ValueChanged?.Invoke(memoryAddress, new(lastSuccess, currentSuccess, lastValue, currentValue, customName));
84 lastValue = currentValue;
85 lastSuccess = currentSuccess;
86 }
87 }
88 catch { }
89 }
90 listeningAddressDictionary.Remove(memoryAddress);
91 }
92 catch
93 {
94 goto ReStart;
95 }
96 });
70 get => listenerDictionary[customName];
71 set => listenerDictionary[customName] = value;
97 72 }
98 73 /// <summary>
99 74 /// 开始监听
100 75 /// </summary>
101 76 /// <typeparam name="T">待监听的内存的数据类型(int,float,long等)</typeparam>
102 /// <param name="memoryAddress">待监听的内存地址</param>
103 /// <param name="delay">检测频率,以毫秒为单位</param>
104 77 /// <param name="customName">自定义监听器标识名</param>
78 /// <param name="memoryAddress">待监听的内存地址</param>
79 /// <param name="frequency">检测频率,以毫秒为单位</param>
105 80 /// <returns></returns>
106 public async Task StartListen<T>(nint memoryAddress, int delay, string? customName = null) where T : struct => await StartListen<T>(memoryAddress, TimeSpan.FromMilliseconds(delay), customName);
81 public MemoryListener AddListener<T>(string customName, nint memoryAddress, int frequency = 1) where T : struct => AddListener<T>(customName
82 , memoryAddress, TimeSpan.FromMilliseconds(frequency));
107 83 /// <summary>
108 84 /// 开始监听
109 85 /// </summary>
110 86 /// <typeparam name="T">待监听的内存的数据类型(int,float,long等)</typeparam>
111 /// <param name="memoryAddress">待监听的内存地址</param>
112 /// <param name="delay">检测频率</param>
113 87 /// <param name="customName">自定义监听器标识名</param>
88 /// <param name="memoryAddress">待监听的内存地址</param>
89 /// <param name="frequency">检测频率</param>
114 90 /// <returns></returns>
115 public async Task StartListen<T>(nint memoryAddress, TimeSpan delay, string? customName = null) where T : struct
91 public MemoryListener AddListener<T>(string customName, nint memoryAddress, TimeSpan frequency) where T : struct
116 92 {
117 IsListening = true;
118 await Task.Run(async () =>
119 {
120 bool lastSuccess = false;
121 var lastValue = default(T);
122 try { lastSuccess = MemoryEditor.ReadMemory(ProcessHandler, memoryAddress, out lastValue); } catch { }
123 addressListToListen.Add(memoryAddress);
124 listeningAddressDictionary.Add(memoryAddress, true);
125 ReStart:
126 try
127 {
128 while (listeningAddressDictionary[memoryAddress] && IsListening && isCurrentProcessRunning)
129 {
130 try
131 {
132 var currentSuccess = MemoryEditor.ReadMemory<T>(ProcessHandler, memoryAddress, out var currentValue);
133 if (!currentValue.Equals(lastValue) || lastSuccess != currentSuccess)
134 {
135 ValueChanged?.Invoke(memoryAddress, new(lastSuccess, currentSuccess, lastValue, currentValue, customName));
136 lastValue = currentValue;
137 lastSuccess = currentSuccess;
138 }
139 await Task.Delay(delay);
140 }
141 catch { }
142 }
143 listeningAddressDictionary.Remove(memoryAddress);
144 }
145 catch
146 {
147 goto ReStart;
148 }
149 });
93
150 94 }
151 /// <summary>
152 /// 开始监听
153 /// </summary>
154 /// <typeparam name="T">待监听的内存的数据类型(int,float,long等)</typeparam>
155 /// <param name="getMemoryAddressFunc">动态获取内存地址的方法</param>
156 /// <param name="delay">检测频率</param>
157 /// <param name="customName">自定义监听器标识名</param>
158 /// <returns></returns>
159 public async Task StartListen<T>(Func<nint?> getMemoryAddressFunc, int delay, string customName) where T : struct => await StartListen<T>(getMemoryAddressFunc, TimeSpan.FromMilliseconds(delay), customName);
160 /// <summary>
161 /// 开始监听
162 /// </summary>
163 /// <typeparam name="T">待监听的内存的数据类型(int,float,long等)</typeparam>
164 /// <param name="getMemoryAddressFunc">动态获取内存地址的方法</param>
165 /// <param name="delay">检测频率</param>
166 /// <param name="customName">自定义监听器标识名</param>
167 /// <returns></returns>
168 public async Task StartListen<T>(Func<nint?> getMemoryAddressFunc, TimeSpan delay, string customName) where T : struct
95 internal StaticMemoryListener AddStaticListener(string customName, nint memoryAddress, TimeSpan frequency, Type type)
169 96 {
170 IsListening = true;
171 await Task.Run(async () =>
172 {
173 var memoryAddress = getMemoryAddressFunc.Invoke();
174 bool lastSuccess = false;
175 var lastValue = default(T);
176 if (memoryAddress is not null)
177 try { lastSuccess = MemoryEditor.ReadMemory(ProcessHandler, memoryAddress.Value, out lastValue); } catch { }
178 addressFuncDictionaryToListen.Add(customName, getMemoryAddressFunc);
179 listeningAddressFuncDictionary.Add(customName, true);
180 ReStart:
181 try
182 {
183 while (listeningAddressFuncDictionary[customName] && IsListening && isCurrentProcessRunning)
184 {
185 try
186 {
187 memoryAddress = getMemoryAddressFunc.Invoke();
188 if (memoryAddress == 0)
189 {
190 if (lastSuccess)
191 ValueChanged?.Invoke(memoryAddress, new(lastSuccess, false, lastValue, null, customName));
192 lastSuccess = false;
193 lastValue = default;
194 while (memoryAddress == 0 && listeningAddressFuncDictionary[customName] && IsListening && isCurrentProcessRunning)
195 {
196 memoryAddress = getMemoryAddressFunc.Invoke();
197 await Task.Delay(delay);
198 }
199 }
200 var currentSuccess = MemoryEditor.ReadMemory<T>(ProcessHandler, memoryAddress!.Value, out var currentValue);
201 if (!currentValue.Equals(lastValue) || lastSuccess != currentSuccess)
202 {
203 ValueChanged?.Invoke(memoryAddress, new(lastSuccess, currentSuccess, lastValue, currentValue, customName));
204 lastValue = currentValue;
205 lastSuccess = currentSuccess;
206 }
207 await Task.Delay(delay);
208 }
209 catch { }
210 }
211 listeningAddressFuncDictionary.Remove(customName);
212 }
213 catch
214 {
215 goto ReStart;
216 }
217 });
97 if (!IsListening)
98 IsListening = true;
99 var staticMemoryListener = MemoryListener.CreateStaticListener(customName, memoryAddress, type);
100 _ = staticMemoryListener.StartListen(ProcessHandler, frequency);
101 return staticMemoryListener;
102 }
103 internal DynamicMemoryListener AddDynamicListener(string customName, Func<nint?> memoryAddressGetFunc, TimeSpan frequency, Type type)
104 {
105 if (!IsListening)
106 IsListening = true;
107 var dynamicMemoryListener = MemoryListener.CreateDynamicListener(customName, memoryAddressGetFunc, type);
108 _ = dynamicMemoryListener.StartListen(ProcessHandler, frequency);
109 return dynamicMemoryListener;
218 110 }
219 111 /// <summary>
220 112 /// 停止所有监听
221 113 /// </summary>
222 public void StopListener()
114 public async Task StopListeners()
223 115 {
224 116 IsListening = false;
225 addressListToListen.Clear();
226 addressFuncDictionaryToListen.Clear();
117 var taskList = new List<Task>();
118 foreach (var listener in listenerDictionary.Values)
119 {
120 taskList.Add(listener.StopListen());
121 }
122 await Task.WhenAll(taskList);
227 123 }
228 124 /// <summary>
229 /// 停止指定进程的监听
125 /// 停止指定的监听器
126 /// </summary>
127 /// <param name="customName">自定义名称</param>
128 public async Task StopListener(string customName) => await listenerDictionary[customName].StopListen();
129 /// <summary>
130 /// 移除指定监听器
230 131 /// </summary>
231 /// <param name="memoryAddress">内存地址</param>
232 public void StopListener(nint memoryAddress)
132 /// <param name="customName"></param>
133 public void RemoveListener(string customName)
233 134 {
234 listeningAddressDictionary[memoryAddress] = false;
235 addressListToListen.Remove(memoryAddress);
135 listenerDictionary.Remove(customName);
136 if (listenerDictionary.Count == 0)
137 IsListening = false;
236 138 }
237 139 /// <summary>
238 /// 停止指定进程的监听
140 /// 清除所有监听器
239 141 /// </summary>
240 /// <param name="customName">自定义名称</param>
241 public void StopListener(string customName)
142 public void Clear()
242 143 {
243 listeningAddressFuncDictionary[customName] = false;
244 addressFuncDictionaryToListen.Remove(customName);
144 IsListening = false;
145 listenerDictionary.Clear();
245 146 }
246 147 /// <summary>
247 148 /// 内存监听器
@@ -288,9 +189,9 @@ public class MemoryListenerManager : IDisposable, IEnumerable
288 189 Dispose(disposing: true);
289 190 GC.SuppressFinalize(this);
290 191 }
291
292 public IEnumerator GetEnumerator()
293 {
294 throw new NotImplementedException();
295 }
192 /// <summary>
193 /// 获取枚举器
194 /// </summary>
195 /// <returns></returns>
196 public IEnumerator GetEnumerator() => listenerDictionary.GetEnumerator();
296 197 }
Modified XFEExtension.NetCore.MemoryEditor/MemoryListener.cs +18 -12
@@ -24,20 +24,17 @@ public abstract class MemoryListener(string customName, Type memoryAddressType)
24 24 /// <summary>
25 25 /// 监听器自定义标识名
26 26 /// </summary>
27 public string Name
28 {
29 get { return name; }
30 set { name = value; }
31 }
32 private protected Type memoryAddressType = memoryAddressType;
27 public string Name { get => name; }
28 private protected TimeSpan frequency;
29 /// <summary>
30 /// 监听检测频率
31 /// </summary>
32 public TimeSpan Frequency { get => frequency; }
33 private protected readonly Type memoryAddressType = memoryAddressType;
33 34 /// <summary>
34 35 /// 内存地址类型
35 36 /// </summary>
36 public Type MemoryAddressType
37 {
38 get { return memoryAddressType; }
39 set { memoryAddressType = value; }
40 }
37 public Type MemoryAddressType { get => memoryAddressType; }
41 38 /// <summary>
42 39 /// 是否正在监听
43 40 /// </summary>
@@ -50,7 +47,7 @@ public abstract class MemoryListener(string customName, Type memoryAddressType)
50 47 /// <summary>
51 48 /// 当前进程句柄
52 49 /// </summary>
53 public nint ProcessHandler { get => processHandler; }
50 public nint ProcessHandler { get => processHandler; set => processHandler = value; }
54 51 /// <summary>
55 52 /// 当前的监听线程
56 53 /// </summary>
@@ -67,6 +64,7 @@ public abstract class MemoryListener(string customName, Type memoryAddressType)
67 64 if (isListening)
68 65 throw new InvalidOperationException("监听已启动,无法重复启动监听");
69 66 isListening = true;
67 this.frequency = frequency;
70 68 this.processHandler = processHandler;
71 69 await Task.CompletedTask;
72 70 }
@@ -129,4 +127,12 @@ public abstract class MemoryListener(string customName, Type memoryAddressType)
129 127 /// <param name="memoryAddressType">内存地址数据类型</param>
130 128 /// <returns></returns>
131 129 public static StaticMemoryListener CreateStaticListener(string customName, nint memoryAddress, Type memoryAddressType) => new StaticMemoryListenerImpl(customName, memoryAddress, memoryAddressType);
130 /// <summary>
131 /// 创建可更新的内存地址监听器
132 /// </summary>
133 /// <param name="customName">监听器自定义标识名</param>
134 /// <param name="memoryAddressUpdateFunc">存地址动态更新方法</param>
135 /// <param name="memoryAddressType">内存地址数据类型</param>
136 /// <returns></returns>
137 public static UpdatableMemoryListener CreateUpdatableListener(string customName, Func<nint?> memoryAddressUpdateFunc, Type memoryAddressType) => new UpdatableMemoryListenerImpl(customName, memoryAddressUpdateFunc, memoryAddressType);
132 138 }
Modified XFEExtension.NetCore.MemoryEditor/StaticMemoryListener.cs +2 -3
@@ -1,5 +1,4 @@
1 
2 using XFEExtension.NetCore.ImplExtension;
1 using XFEExtension.NetCore.ImplExtension;
3 2
4 3 namespace XFEExtension.NetCore.MemoryEditor;
5 4
@@ -41,7 +40,7 @@ public abstract class StaticMemoryListener(string customName, nint memoryAddress
41 40 var currentValue = MemoryEditor.ReadMemory(processHandler, memoryAddress, memoryAddressType);
42 41 if (lastValue is null == currentValue is null || lastValue?.Equals(currentValue) == false)
43 42 {
44 valueChanged?.Invoke(this, new(lastValue is not null, currentValue is not null, lastValue, currentValue, customName));
43 valueChanged?.Invoke(this, new(lastValue is not null, currentValue is not null, lastValue, currentValue, name));
45 44 lastValue = currentValue;
46 45 }
47 46 await Task.Delay(frequency);
Added XFEExtension.NetCore.MemoryEditor/UpdatableMemoryListener.cs +62 -0
@@ -0,0 +1,62 @@
1 using XFEExtension.NetCore.ImplExtension;
2
3 namespace XFEExtension.NetCore.MemoryEditor;
4
5 /// <summary>
6 /// 可更新的内存监听器
7 /// </summary>
8 /// <param name="customName"></param>
9 /// <param name="updateAddressFunc"></param>
10 /// <param name="memoryAddressType"></param>
11 [CreateImpl]
12 public abstract class UpdatableMemoryListener(string customName, Func<nint?> updateAddressFunc, Type memoryAddressType) : MemoryListener(customName, memoryAddressType)
13 {
14 private nint memoryAddress = updateAddressFunc.Invoke() ?? default;
15 /// <summary>
16 /// 内存地址
17 /// </summary>
18 public nint MemoryAddress
19 {
20 get { return memoryAddress; }
21 set { memoryAddress = value; }
22 }
23 private Func<nint?> updateAddressFunc = updateAddressFunc;
24 /// <summary>
25 /// 获取目标内存地址方法
26 /// </summary>
27 public Func<nint?> UpdateAddressFunc { get => updateAddressFunc; set => updateAddressFunc = value; }
28 /// <summary>
29 /// 开始监听
30 /// </summary>
31 /// <param name="processHandler">监听的进程句柄</param>
32 /// <param name="frequency">监听检测频率</param>
33 /// <returns></returns>
34 public override async Task StartListen(nint processHandler, TimeSpan frequency)
35 {
36 await base.StartListen(processHandler, frequency);
37 CurrentListeningTask = Task.Run(async () =>
38 {
39 object? lastValue = null;
40 try { lastValue = MemoryEditor.ReadMemory(processHandler, memoryAddress, memoryAddressType); } catch { }
41 while (isListening)
42 {
43 try
44 {
45 var currentValue = MemoryEditor.ReadMemory(processHandler, memoryAddress, memoryAddressType);
46 if (lastValue is null == currentValue is null || lastValue?.Equals(currentValue) == false)
47 {
48 valueChanged?.Invoke(this, new(lastValue is not null, currentValue is not null, lastValue, currentValue, name));
49 lastValue = currentValue;
50 }
51 await Task.Delay(frequency);
52 }
53 catch { }
54 }
55 });
56 await CurrentListeningTask;
57 }
58 /// <summary>
59 /// 更新地址值
60 /// </summary>
61 public void UpdateAddress() => memoryAddress = updateAddressFunc.Invoke() ?? memoryAddress;
62 }