public static void Parse(ISettings settings, List <ISettingsHolder> draws, int id = -1) { if (settings == null) { DebugWindow.LogError("Cant parse null settings."); return; } var props = settings.GetType().GetProperties(); foreach (var property in props) { if (property.GetCustomAttribute <IgnoreMenuAttribute>() != null) { continue; } var menuAttribute = property.GetCustomAttribute <MenuAttribute>(); var isSettings = property.PropertyType.GetInterfaces().ContainsF(typeof(ISettings)); if (property.Name == "Enable" && menuAttribute == null) { continue; } if (menuAttribute == null) { menuAttribute = new MenuAttribute(Regex.Replace(property.Name, "(\\B[A-Z])", " $1")); } var holder = new SettingsHolder { Name = menuAttribute.MenuName, Tooltip = menuAttribute.Tooltip, ID = menuAttribute.index == -1 ? MathHepler.Randomizer.Next(int.MaxValue) : menuAttribute.index }; if (isSettings) { HandleSubSettings(settings, draws, property, menuAttribute, holder); continue; } if (IsISettingsList(property, settings)) { IList list = property.GetValue(settings) as IList; foreach (var item in list) { Parse(item as ISettings, draws); } continue; } if (menuAttribute.parentIndex != -1) { var parent = GetAllDrawers(draws).Find(x => x.ID == menuAttribute.parentIndex); parent?.Children.Add(holder); } else if (id != -1) { var parent = GetAllDrawers(draws).Find(x => x.ID == id); parent?.Children.Add(holder); } else { draws.Add(holder); } var type = property.GetValue(settings); HandleType(menuAttribute, holder, type); } }
public MenuWindow(Core core, SettingsContainer settingsContainer, Dictionary <string, FontContainer> fonts, ref VersionChecker versionChecker) { this.Core = core; _settingsContainer = settingsContainer; CoreSettings = settingsContainer.CoreSettings; Fonts = fonts; CoreSettingsDrawers = new List <ISettingsHolder>(); SettingsParser.Parse(CoreSettings, CoreSettingsDrawers); PluginsUpdateSettings = settingsContainer.PluginsUpdateSettings; PluginsUpdateSettingsDrawers = new List <ISettingsHolder>(); SettingsParser.Parse(PluginsUpdateSettings, PluginsUpdateSettingsDrawers); VersionChecker = versionChecker; Selected = CoreSettingsAction; CoreSettingsAction = () => { foreach (var drawer in CoreSettingsDrawers) { drawer.Draw(); } }; _index = -1; Selected = CoreSettingsAction; Core.DebugInformations.CollectionChanged += OnDebugInformationsOnCollectionChanged; debugInformation = new DebugInformation("DebugWindow", false); OpenWindow = Windows.MainDebugs; WindowsName = Enum.GetValues(typeof(Windows)); OnWindowChange += () => { MoreInformation = null; selectedName = ""; }; Input.RegisterKey(CoreSettings.MainMenuKeyToggle); CoreSettings.MainMenuKeyToggle.OnValueChanged += () => { Input.RegisterKey(CoreSettings.MainMenuKeyToggle); }; CoreSettings.Enable.OnValueChanged += (sender, b) => { if (!CoreSettings.Enable) { try { _settingsContainer.SaveCoreSettings(); try { _settingsContainer.SavePluginAutoUpdateSettings(); } catch (Exception e) { DebugWindow.LogError($"SaveSettings for PluginAutoUpdate error: {e}"); } foreach (var plugin in core.pluginManager.Plugins) { try { _settingsContainer.SaveSettings(plugin.Plugin); } catch (Exception e) { DebugWindow.LogError($"SaveSettings for plugin error: {e}"); } } } catch (Exception e) { DebugWindow.LogError($"SaveSettings error: {e}"); } } }; }
public GameController(Memory memory, SoundController soundController, SettingsContainer settings, MultiThreadManager multiThreadManager) { _settings = settings.CoreSettings; Memory = memory; SoundController = soundController; Settings = settings; MultiThreadManager = multiThreadManager; try { Cache = new Cache(); Game = new TheGame(memory, Cache); Area = new AreaController(Game); Window = new GameWindow(memory.Process); Files = Game.Files; EntityListWrapper = new EntityListWrapper(this, _settings, multiThreadManager); } catch (Exception e) { DebugWindow.LogError(e.ToString()); } PluginBridge = new PluginBridge(); IsForeGroundCache = WinApi.IsForegroundWindow(Window.Process.MainWindowHandle); var values = Enum.GetValues(typeof(IconPriority)); LeftPanel = new PluginPanel(GetLeftCornerMap()); UnderPanel = new PluginPanel(GetUnderCornerMap()); var debParseFile = new DebugInformation("Parse files", false); debClearCache = new DebugInformation("Clear cache", false); // Core.DebugInformations.Add(debParseFile); /*Area.OnAreaChange += controller => * { * * debParseFile.TickAction(() => * { * Files.LoadFiles(); * }); * };*/ debDeltaTime = Core.DebugInformations.FirstOrDefault(x => x.Name == "Delta Time"); NativeMethods.LogError = _settings.LogReadMemoryError; _settings.LogReadMemoryError.OnValueChanged += (obj, b) => NativeMethods.LogError = _settings.LogReadMemoryError; LeftCornerMap = new TimeCache <Vector2>(GetLeftCornerMap, 500); UnderCornerMap = new TimeCache <Vector2>(GetUnderCornerMap, 500); eIsForegroundChanged += b => { if (b) { Core.MainRunner.ResumeCoroutines(Core.MainRunner.Coroutines); Core.ParallelRunner.ResumeCoroutines(Core.ParallelRunner.Coroutines); } else { Core.MainRunner.PauseCoroutines(Core.MainRunner.Coroutines); Core.ParallelRunner.PauseCoroutines(Core.ParallelRunner.Coroutines); } // DebugWindow.LogMsg($"Foreground: {b}"); }; _settings.RefreshArea.OnPressed += () => { Area.ForceRefreshArea(); }; Area.RefreshState(); EntityListWrapper.StartWork(); Initialized = true; }
private static void HandleType(MenuAttribute menuAttribute, SettingsHolder holder, object type) { switch (type) { case ButtonNode n: holder.DrawDelegate = () => { if (ImGui.Button(holder.Unique)) { n.OnPressed(); } }; break; case EmptyNode n: break; case HotkeyNode n: holder.DrawDelegate = () => { var holderName = $"{holder.Name} {n.Value}##{n.Value}"; var open = true; if (ImGui.Button(holderName)) { ImGui.OpenPopup(holderName); open = true; } if (ImGui.BeginPopupModal(holderName, ref open, (ImGuiWindowFlags)35)) { if (Input.GetKeyState(Keys.Escape)) { ImGui.CloseCurrentPopup(); ImGui.EndPopup(); return; } foreach (var key in Enum.GetValues(typeof(Keys))) { var keyState = Input.GetKeyState((Keys)key); if (keyState) { n.Value = (Keys)key; ImGui.CloseCurrentPopup(); break; } } ImGui.Text($" Press new key to change '{n.Value}' or Esc for exit."); ImGui.EndPopup(); } }; break; case ToggleNode n: holder.DrawDelegate = () => { var value = n.Value; ImGui.Checkbox(holder.Unique, ref value); n.Value = value; }; break; case ColorNode n: holder.DrawDelegate = () => { var vector4 = n.Value.ToVector4().ToVector4Num(); if (ImGui.ColorEdit4(holder.Unique, ref vector4, ImGuiColorEditFlags.AlphaBar | ImGuiColorEditFlags.NoInputs | ImGuiColorEditFlags.AlphaPreviewHalf)) { n.Value = vector4.ToSharpColor(); } }; break; case ListNode n: holder.DrawDelegate = () => { if (ImGui.BeginCombo(holder.Unique, n.Value)) { foreach (var t in n.Values) { if (ImGui.Selectable(t)) { n.Value = t; ImGui.EndCombo(); return; } } ImGui.EndCombo(); } }; break; case FileNode n: holder.DrawDelegate = () => { if (ImGui.TreeNode(holder.Unique)) { var selected = n.Value; if (ImGui.BeginChildFrame(1, new Vector2(0, 300))) { var di = new DirectoryInfo("config"); if (di.Exists) { foreach (var file in di.GetFiles()) { if (ImGui.Selectable(file.Name, selected == file.FullName)) { n.Value = file.FullName; } } } ImGui.EndChildFrame(); } ImGui.TreePop(); } }; break; case RangeNode <int> n: holder.DrawDelegate = () => { var r = n.Value; ImGui.SliderInt(holder.Unique, ref r, n.Min, n.Max); n.Value = r; }; break; case RangeNode <float> n: holder.DrawDelegate = () => { var r = n.Value; ImGui.SliderFloat(holder.Unique, ref r, n.Min, n.Max); n.Value = r; }; break; case RangeNode <long> n: holder.DrawDelegate = () => { var r = (int)n.Value; ImGui.SliderInt(holder.Unique, ref r, (int)n.Min, (int)n.Max); n.Value = r; }; break; case RangeNode <Vector2> n: holder.DrawDelegate = () => { var vect = n.Value; ImGui.SliderFloat2(holder.Unique, ref vect, n.Min.X, n.Max.X); n.Value = vect; }; break; case TextNode n: holder.DrawDelegate = () => { var input = n.Value; ImGui.InputText(holder.Unique, ref input, 200); n.Value = input; }; break; default: DebugWindow.LogDebug($"{type} not supported for menu now. Ask developers to add this type."); break; } }
public void LogMessage(string msg, float time, Color clr) { DebugWindow.LogMsg(msg, time, clr); }
public void LogMessage(string msg, float time = 1f) { DebugWindow.LogMsg(msg, time, Color.GreenYellow); }
public void LogMsg(string msg) { DebugWindow.LogMsg(msg); }
public void LogError(string msg, float time = 1f) { DebugWindow.LogError(msg, time); }
public void RefreshState() { if (gameController.Area.CurrentArea == null /*|| !EntitiesStack.CanRead */ || entityCollectSettingsContainer.NeedUpdate || Player == null || !Player.IsValid) { return; } // var entities = EntitiesStack.Read(); while (Simple.Count > 0) { var entity = Simple.Pop(); if (entity == null) { DebugWindow.LogError($"{nameof(EntityListWrapper)}.{nameof(RefreshState)} entity is null. (Very strange)."); continue; } var entityId = entity.Id; if (entityCache.TryGetValue(entityId, out _)) { continue; } if (entityId >= int.MaxValue && !_settings.ParseServerEntities) { continue; } if (/*!entity.IsValid ||*/ entity.Type == EntityType.Error) { continue; } /*if (entity.Type == EntityType.Monster && (entity.GetComponent<Life>() == null || * entity.GetComponent<ObjectMagicProperties>() == null)) * { * entity.IsValid = false; * continue; * }*/ if (entity.League == LeagueType.Legion) { if (entity.Stats == null) { continue; } } EntityAddedAny?.Invoke(entity); if ((int)entity.Type >= 100) { EntityAdded?.Invoke(entity); } entityCache[entityId] = entity; } UpdateEntityCollections(); entityCollectSettingsContainer.NeedUpdate = true; }
public void Process(object o) { if (threads == null) { return; } if (Interlocked.CompareExchange(ref _lock, 1, 0) == 1) { return; } if (ProcessWorking) { DebugWindow.LogMsg($"WTF {_objectInitWork.GetType()}"); } _objectInitWork = o; ProcessWorking = true; spinWait.Reset(); while (Jobs.TryDequeue(out var j)) { processJobs.Enqueue(j); } if (ThreadsCount > 1) { while (processJobs.Count > 0) { if (!FreeThreads.IsEmpty) { FreeThreads.TryDequeue(out var freeThread); var job = processJobs.Dequeue(); if (!freeThread.AddJob(job)) { processJobs.Enqueue(job); } else { if (freeThread.Free) { FreeThreads.Enqueue(freeThread); } } } else { spinWait.SpinOnce(); var allThreadsBusy = true; for (var i = 0; i < threads.Length; i++) { var th = threads[i]; if (th.Free) { allThreadsBusy = false; FreeThreads.Enqueue(th); } } if (allThreadsBusy) { for (var i = 0; i < threads.Length; i++) { var th = threads[i]; var thWorkingTime = th.WorkingTime; if (thWorkingTime > CriticalWorkTimeMs) { DebugWindow.LogMsg( $"Repair thread #{th.Number} with Job1: {th.Job.Name} (C: {th.Job.IsCompleted} F: {th.Job.IsFailed}) && Job2:{th.SecondJob.Name} (C: {th.SecondJob.IsCompleted} F: {th.SecondJob.IsFailed}) Time: {thWorkingTime} > {thWorkingTime >= CriticalWorkTimeMs}", 5); th.Abort(); BrokenThreads.Add(th); var newThread = new ThreadUnit($"Repair critical time {th.Number}", th.Number); threads[th.Number] = newThread; FreeThreads.Enqueue(newThread); Thread.Sleep(5); FailedThreadsCount++; break; } } } } } } else { var threadUnit = threads[0]; while (processJobs.Count > 0) { if (threadUnit.Free) { var job = processJobs.Dequeue(); threadUnit.AddJob(job); } else { spinWait.SpinOnce(); var threadUnitWorkingTime = threadUnit.WorkingTime; if (threadUnitWorkingTime > CriticalWorkTimeMs) { DebugWindow.LogMsg( $"Repair thread #{threadUnit.Number} withreadUnit Job1: {threadUnit.Job.Name} (C: {threadUnit.Job.IsCompleted} F: {threadUnit.Job.IsFailed}) && Job2:{threadUnit.SecondJob.Name} (C: {threadUnit.SecondJob.IsCompleted} F: {threadUnit.SecondJob.IsFailed}) Time: {threadUnitWorkingTime} > {threadUnitWorkingTime >= CriticalWorkTimeMs}", 5); threadUnit.Abort(); BrokenThreads.Add(threadUnit); threadUnit = new ThreadUnit($"Repair critical time {threadUnit.Number}", threadUnit.Number); Thread.Sleep(5); FailedThreadsCount++; } } } } if (BrokenThreads.Count > 0) { var criticalWorkTimeMs = CriticalWorkTimeMs * 2; for (var index = 0; index < BrokenThreads.Count; index++) { var brokenThread = BrokenThreads[index]; if (brokenThread == null) { continue; } if (brokenThread.WorkingTime > criticalWorkTimeMs) { brokenThread.ForceAbort(); BrokenThreads[index] = null; } } if (BrokenThreads.AllF(x => x == null)) { BrokenThreads.Clear(); } } Interlocked.CompareExchange(ref _lock, 0, 1); ProcessWorking = false; }
private static void Parse(ISettings settings, List <ISettingsHolder> draws, int id, ref int nextAvailableKey) { if (settings == null) { DebugWindow.LogError("Cant parse null settings."); return; } var props = settings.GetType().GetProperties(); foreach (var property in props) { if (property.GetCustomAttribute <IgnoreMenuAttribute>() != null) { continue; } var menuAttribute = property.GetCustomAttribute <MenuAttribute>(); if (property.Name == "Enable" && menuAttribute == null) { continue; } menuAttribute ??= new MenuAttribute(Regex.Replace(property.Name, "(\\B[A-Z])", " $1")); var holder = new SettingsHolder { Name = menuAttribute.MenuName, Tooltip = menuAttribute.Tooltip, ID = menuAttribute.index == -1 ? nextAvailableKey-- : menuAttribute.index }; if (property.PropertyType.GetInterfaces().ContainsF(typeof(ISettings))) { var innerSettings = (ISettings)property.GetValue(settings); if (menuAttribute.index == -1) { Parse(innerSettings, draws, id, ref nextAvailableKey); continue; } holder.Type = HolderChildType.Tab; draws.Add(holder); Parse(innerSettings, draws, menuAttribute.index, ref nextAvailableKey); var parent = GetAllDrawers(draws).Find(x => x.ID == menuAttribute.parentIndex); parent?.Children.Add(holder); continue; } if (IsISettingsList(property, settings)) { if (!(property.GetValue(settings) is IList list)) { continue; } foreach (var item in list) { Parse(item as ISettings, draws, id, ref nextAvailableKey); } continue; } if (menuAttribute.parentIndex != -1) { var parent = GetAllDrawers(draws).Find(x => x.ID == menuAttribute.parentIndex); if (parent != null) { // TODO - Check if the new setting index collides with any children. parent.Children.Add(holder); } else { DebugWindow.LogDebug( $"SettingsParser => ParentIndex used before created. [Menu(\"{menuAttribute.MenuName}\", ..., {menuAttribute.parentIndex})] added as a top-level setting."); draws.Add(holder); } } else if (id != -1) { var parent = GetAllDrawers(draws).Find(x => x.ID == id); if (parent != null) { // debug log spam during startup due to HealthBars, temporarly disabled for now //DebugWindow.LogDebug( // $"SettingsParser => Index collision. '[Menu(\"{menuAttribute.MenuName}\", ..., {id}, ...)] added as sub-setting of \"{parent.Name}\"."); parent.Children.Add(holder); } else { draws.Add(holder); } } else { draws.Add(holder); } var type = property.GetValue(settings); HandleType(holder, type, property.ToString()); } }
private static void HandleType(SettingsHolder holder, object type, string propertyInfo) { switch (type) { case ButtonNode buttonNode: holder.DrawDelegate = () => { if (ImGui.Button(holder.Unique)) { buttonNode.OnPressed(); } }; return; case null: case EmptyNode _: holder.DrawDelegate = () => { }; return; case HotkeyNode hotkeyNode: holder.DrawDelegate = () => { var str = $"{holder.Name} {hotkeyNode.Value}##{hotkeyNode.Value}"; if (ImGui.Button(str)) { // Clear async buffer state Input.ClearAsyncBuffer(); // Begin pop up ImGui.OpenPopup(str); } // Create modal var popupOpened = true; if (ImGui.BeginPopupModal(str, ref popupOpened, ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoCollapse)) { ButtonPopupVisible = true; } else { return; } // Close popup if escape was pressed if (Input.GetKeyState(Keys.Escape)) { ImGui.CloseCurrentPopup(); ImGui.EndPopup(); ButtonPopupVisible = false; return; } // Get prssed keys Keys key = Input.GetPressedKeys(true); // If a key was pressed, set value and close popup if ((key & Keys.KeyCode) != Keys.None) { // Set the node's value to the keys that were pressed and close the popup hotkeyNode.Value = key; ImGui.CloseCurrentPopup(); ButtonPopupVisible = false; } // End popup ImGui.Text($"Press new key to change '{hotkeyNode.Value}' or Esc for exit."); ImGui.EndPopup(); }; return; case ToggleNode toggleNode: holder.DrawDelegate = () => { var isChecked = toggleNode.Value; ImGui.Checkbox(holder.Unique, ref isChecked); toggleNode.Value = isChecked; }; return; case ColorNode colorNode: holder.DrawDelegate = () => { var color = colorNode.Value.ToVector4().ToVector4Num(); if (ImGui.ColorEdit4(holder.Unique, ref color, ImGuiColorEditFlags.NoInputs | ImGuiColorEditFlags.AlphaBar | ImGuiColorEditFlags.AlphaPreviewHalf)) { colorNode.Value = color.ToSharpColor(); } }; return; case ListNode listNode: holder.DrawDelegate = () => { if (!ImGui.BeginCombo(holder.Unique, listNode.Value)) { return; } foreach (var value in listNode.Values) { if (!ImGui.Selectable(value)) { continue; } listNode.Value = value; break; } ImGui.EndCombo(); }; return; case FileNode fileNode: holder.DrawDelegate = () => { if (!ImGui.TreeNode(holder.Unique)) { return; } var value = fileNode.Value; if (ImGui.BeginChildFrame(1, new Vector2(0f, 300f))) { var directoryInfo = new DirectoryInfo("config"); if (directoryInfo.Exists) { var files = directoryInfo.GetFiles(); foreach (var fileInfo in files) { if (ImGui.Selectable(fileInfo.Name, value == fileInfo.FullName)) { fileNode.Value = fileInfo.FullName; } } } ImGui.EndChildFrame(); } ImGui.TreePop(); }; return; case RangeNode <int> iRangeNode: holder.DrawDelegate = () => { var value = iRangeNode.Value; ImGui.SliderInt(holder.Unique, ref value, iRangeNode.Min, iRangeNode.Max); iRangeNode.Value = value; }; return; case RangeNode <float> fRangeNode: holder.DrawDelegate = () => { var value = fRangeNode.Value; ImGui.SliderFloat(holder.Unique, ref value, fRangeNode.Min, fRangeNode.Max); fRangeNode.Value = value; }; return; case RangeNode <long> lRangeNode: holder.DrawDelegate = () => { var value = (int)lRangeNode.Value; ImGui.SliderInt(holder.Unique, ref value, (int)lRangeNode.Min, (int)lRangeNode.Max); lRangeNode.Value = value; }; return; case RangeNode <Vector2> vRangeNode: holder.DrawDelegate = () => { var value = vRangeNode.Value; ImGui.SliderFloat2(holder.Unique, ref value, vRangeNode.Min.X, vRangeNode.Max.X); vRangeNode.Value = value; }; return; case TextNode textNode: holder.DrawDelegate = () => { var value = textNode.Value; ImGui.InputText(holder.Unique, ref value, 200); textNode.Value = value; }; return; } DebugWindow.LogDebug( $"SettingsParser => DrawDelegate not auto-generated for '{propertyInfo}'."); }
public MenuWindow(Core core, SettingsContainer settingsContainer, Dictionary <string, FontContainer> fonts) { this.core = core; _settingsContainer = settingsContainer; _CoreSettings = settingsContainer.CoreSettings; Fonts = fonts; themeEditor = new ThemeEditor(_CoreSettings); /*Input.RegisterKey(Keys.F12); * Input.ReleaseKey += (sender, keys) => * { * if (keys== SettingsCoreSettings.MainMenuKeyToggle.Value) * { * Enable = !Enable; * } * };*/ CoreSettingsDrawers = new List <ISettingsHolder>(); SettingsParser.Parse(_CoreSettings, CoreSettingsDrawers); Selected = CoreSettings; CoreSettings = () => { foreach (var drawer in CoreSettingsDrawers) { drawer.Draw(); } }; _index = -1; Selected = CoreSettings; Core.DebugInformations.CollectionChanged += OnDebugInformationsOnCollectionChanged; debugInformation = new DebugInformation("DebugWindow", false); OpenWindow = Windows.MainDebugs; WindowsName = Enum.GetValues(typeof(Windows)); OnWindowChange += () => { MoreInformation = null; selectedName = ""; }; Input.RegisterKey(_CoreSettings.MainMenuKeyToggle); _CoreSettings.MainMenuKeyToggle.OnValueChanged += () => { Input.RegisterKey(_CoreSettings.MainMenuKeyToggle); }; _CoreSettings.Enable.OnValueChanged += (sender, b) => { if (!_CoreSettings.Enable) { try { _settingsContainer.SaveCoreSettings(); foreach (var plugin in core.pluginManager.Plugins) { try { _settingsContainer.SaveSettings(plugin.Plugin); } catch (Exception e) { DebugWindow.LogError($"SaveSettings for plugin error: {e}"); } } } catch (Exception e) { DebugWindow.LogError($"SaveSettings error: {e}"); } } }; }