From 166d11d7be8e8395e96b892a0f2812f55282094b Mon Sep 17 00:00:00 2001 From: Sean Schwartz Date: Fri, 6 Feb 2015 18:40:47 -0600 Subject: [PATCH 1/5] Remove logging as we're checking for null, no reason to look into things further unless we see an impact in items not being highlighted. --- src/Hud/Loot/ItemAlertPlugin.cs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/Hud/Loot/ItemAlertPlugin.cs b/src/Hud/Loot/ItemAlertPlugin.cs index 32840286..a58d0258 100644 --- a/src/Hud/Loot/ItemAlertPlugin.cs +++ b/src/Hud/Loot/ItemAlertPlugin.cs @@ -124,17 +124,6 @@ private Vector2 DrawText(Vector2 playerPos, Vector2 position, int BOTTOM_MARGIN, protected override void OnEntityAdded(EntityWrapper entity) { - // Added a check to see if it's null, will need to figure out why it can be null, if crashes still occur one of the atributes of an entity can be null but only in partyplay (have to investigate). - string[] Attributes = new string[] { "Address", "Id", "IsAlive", "IsHostile", "IsValid", "LongId", "Minions", "Path" }; - for (int i = 0; i != 8; i++ ) - { - string output = ""; - if (entity.GetType().GetProperty(Attributes[1]).GetValue(entity, null) == null) - { - output = output + Attributes[i] + "is null \n"; - File.AppendAllText("drawlog", output); - } - } if (Settings.Enable && entity != null && !GameController.Area.CurrentArea.IsTown && !currentAlerts.ContainsKey(entity) && entity.HasComponent()) { IEntity item = entity.GetComponent().ItemEntity; From be97226b6d4644bf4e2b9f43617b05c042f363d0 Mon Sep 17 00:00:00 2001 From: Sean Schwartz Date: Fri, 6 Feb 2015 18:42:42 -0600 Subject: [PATCH 2/5] Remove unused "imports" --- src/Hud/Loot/ItemAlertPlugin.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Hud/Loot/ItemAlertPlugin.cs b/src/Hud/Loot/ItemAlertPlugin.cs index a58d0258..f05a06bc 100644 --- a/src/Hud/Loot/ItemAlertPlugin.cs +++ b/src/Hud/Loot/ItemAlertPlugin.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Threading; using System.Threading.Tasks; using PoeHUD.Controllers; From a1ee87befd1d6660421d3ed0d12de0d20a38f724 Mon Sep 17 00:00:00 2001 From: Sean Schwartz Date: Sat, 7 Feb 2015 08:55:34 -0600 Subject: [PATCH 3/5] Change exception caught to generic Exception to catch ALL exceptions. I think we were catching the base exception but not the SharpDXException. Will do some testing on this change to see if it works. --- src/Hud/UI/Renderers/FontRenderer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Hud/UI/Renderers/FontRenderer.cs b/src/Hud/UI/Renderers/FontRenderer.cs index 49b3dafe..4a624db9 100644 --- a/src/Hud/UI/Renderers/FontRenderer.cs +++ b/src/Hud/UI/Renderers/FontRenderer.cs @@ -37,9 +37,9 @@ public Size2 DrawText(string text, string fontName, int height, Vector2 position font.DrawText(sprite, text, fontDimension, align, color); return new Size2(fontDimension.Width, fontDimension.Height); } - catch (AccessViolationException exception) + catch (Exception exception) { - // Console.WriteLine("Access Violation! " + position.X + ", " + position.Y); + // Console.WriteLine("Exception! " + position.X + ", " + position.Y); } return new Size2(); } From 0b405be30fc5b460b80887bf0f8c29e885d3debe Mon Sep 17 00:00:00 2001 From: Sean Schwartz Date: Sat, 7 Feb 2015 11:13:30 -0600 Subject: [PATCH 4/5] Prevent ArgumentException due to health regen/revive. --- src/Hud/DPS/DpsMeterPlugin.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Hud/DPS/DpsMeterPlugin.cs b/src/Hud/DPS/DpsMeterPlugin.cs index de4d616a..e6a9047b 100644 --- a/src/Hud/DPS/DpsMeterPlugin.cs +++ b/src/Hud/DPS/DpsMeterPlugin.cs @@ -90,11 +90,14 @@ private double CalculateDps(TimeSpan elapsedTime) if (hp > -1000000 && hp < 10000000) { int lastHP; - if (lastMonsters.TryGetValue(monster.Id, out lastHP) && lastHP > hp) + if (lastMonsters.TryGetValue(monster.Id, out lastHP)) { - totalDamage += lastHP - hp; + // make this a separte if statement to prevent dictionary already containing item + if (lastHP > hp) + { + totalDamage += lastHP - hp; + } } - monsters.Add(monster.Id, hp); } } lastMonsters = monsters; From 615e5d76ea7eca3e6a964ad77f1bdc4bf2094854 Mon Sep 17 00:00:00 2001 From: Sean Schwartz Date: Sat, 7 Feb 2015 11:24:39 -0600 Subject: [PATCH 5/5] Work towards preventing access violation exceptions. Remove separate ForEach thread for DrawBorder and re-implement into single thread (UI Thread). Change dictionary over to ConcurrentDictionary (thread safe). Check for disposed Sprite before attempting to draw text. Changed debug output on exception catch, commented for releases. Disable "Hide Others" option for now as the "can pick up" check is incorrect at times. --- src/Hud/Loot/ItemAlertPlugin.cs | 46 ++++++++++++---------------- src/Hud/Loot/ItemAlertSettings.cs | 4 +-- src/Hud/Menu/MenuPlugin.cs | 2 +- src/Hud/UI/Renderers/FontRenderer.cs | 15 ++++++--- 4 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/Hud/Loot/ItemAlertPlugin.cs b/src/Hud/Loot/ItemAlertPlugin.cs index f05a06bc..2cfcf1c6 100644 --- a/src/Hud/Loot/ItemAlertPlugin.cs +++ b/src/Hud/Loot/ItemAlertPlugin.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Threading.Tasks; using PoeHUD.Controllers; using PoeHUD.Framework.Helpers; @@ -19,6 +18,7 @@ using SharpDX; using SharpDX.Direct3D9; +using System.Collections.Concurrent; namespace PoeHUD.Hud.Loot { @@ -26,20 +26,20 @@ public class ItemAlertPlugin : SizedPluginWithMapIcons { private readonly HashSet playedSoundsCache; - private readonly Dictionary currentAlerts; + private readonly ConcurrentDictionary currentAlerts; private readonly Dictionary craftingBases; private readonly HashSet currencyNames; - private Dictionary currentLabels; + private ConcurrentDictionary currentLabels; public ItemAlertPlugin(GameController gameController, Graphics graphics, ItemAlertSettings settings) : base(gameController, graphics, settings) { playedSoundsCache = new HashSet(); - currentAlerts = new Dictionary(); - currentLabels = new Dictionary(); + currentAlerts = new ConcurrentDictionary(); + currentLabels = new ConcurrentDictionary(); currencyNames = LoadCurrency(); craftingBases = LoadCraftingBases(); @@ -61,18 +61,6 @@ public override void Render() const int BOTTOM_MARGIN = 2; bool shouldUpdate = false; - if (Settings.BorderSettings.Enable) - { - Dictionary tempCopy = new Dictionary(currentAlerts); - Parallel.ForEach(tempCopy.Where(x => x.Key.IsValid), kv => - { - if (DrawBorder(kv.Key.Address) && !shouldUpdate) - { - shouldUpdate = true; - } - }); - } - foreach (KeyValuePair kv in currentAlerts.Where(x => x.Key.IsValid)) { string text = GetItemName(kv); @@ -84,11 +72,15 @@ public override void Render() ItemsOnGroundLabelElement entityLabel; if (currentLabels.TryGetValue(kv.Key.Address, out entityLabel)) { - // Don't make labels on the right for items we can't pick up UNTIL we can pick it up or invisible - if (Settings.HideOthers && !entityLabel.CanPickUp) + if (Settings.BorderSettings.Enable && DrawBorder(kv.Key.Address) && !shouldUpdate) { - return; + shouldUpdate = true; } + // Don't make labels on the right for items we can't pick up UNTIL we can pick it up or invisible + //if (Settings.HideOthers && !entityLabel.CanPickUp) + //{ + // return; + //} } else { @@ -104,7 +96,8 @@ public override void Render() if (shouldUpdate) { - currentLabels = GameController.Game.IngameState.IngameUi.ItemsOnGroundLabels.ToDictionary(y => y.ItemOnGround.Address, y => y); + // Change this in the future to prevent problems (create separate thread to do the updating, thread safe calls) + currentLabels = new ConcurrentDictionary (GameController.Game.IngameState.IngameUi.ItemsOnGroundLabels.ToDictionary(y => y.ItemOnGround.Address, y => y)); } } } @@ -131,7 +124,7 @@ protected override void OnEntityAdded(EntityWrapper entity) if (props.ShouldAlert(currencyNames, Settings)) { AlertDrawStyle drawStyle = props.GetDrawStyle(); - currentAlerts.Add(entity, drawStyle); + currentAlerts.TryAdd(entity, drawStyle); CurrentIcons[entity] = new MapIcon(entity, new HudTexture("minimap_default_icon.png", drawStyle.AlertColor), () => Settings.ShowItemOnMap, 8); if (Settings.PlaySound && !playedSoundsCache.Contains(entity.LongId)) @@ -146,8 +139,10 @@ protected override void OnEntityAdded(EntityWrapper entity) protected override void OnEntityRemoved(EntityWrapper entity) { base.OnEntityRemoved(entity); - currentAlerts.Remove(entity); - currentLabels.Remove(entity.Address); + AlertDrawStyle ignoredStyle; + currentAlerts.TryRemove(entity, out ignoredStyle); + ItemsOnGroundLabelElement ignoredLabel; + currentLabels.TryRemove(entity.Address, out ignoredLabel); } private static Dictionary LoadCraftingBases() @@ -244,8 +239,7 @@ private bool DrawBorder(int entityAddress) if (Settings.BorderSettings.ShowTimer && timeLeft.TotalMilliseconds > 0) { borderColor = Settings.BorderSettings.CantPickUpBorderColor; - Graphics.DrawText(timeLeft.ToString(@"mm\:ss"), Settings.BorderSettings.TimerTextSize, - rect.TopRight.Translate(4, 0)); + Graphics.DrawText(timeLeft.ToString(@"mm\:ss"), Settings.BorderSettings.TimerTextSize, rect.TopRight.Translate(4, 0)); } } Graphics.DrawFrame(rect, Settings.BorderSettings.BorderWidth, borderColor); diff --git a/src/Hud/Loot/ItemAlertSettings.cs b/src/Hud/Loot/ItemAlertSettings.cs index 7dd161d4..538fc59f 100644 --- a/src/Hud/Loot/ItemAlertSettings.cs +++ b/src/Hud/Loot/ItemAlertSettings.cs @@ -12,7 +12,7 @@ public ItemAlertSettings() ShowItemOnMap = true; Crafting = true; ShowText = true; - HideOthers = false; + //HideOthers = false; PlaySound = true; TextSize = new RangeNode(25, 10, 50); Rares = true; @@ -32,7 +32,7 @@ public ItemAlertSettings() public ToggleNode ShowText { get; set; } - public ToggleNode HideOthers { get; set; } + //public ToggleNode HideOthers { get; set; } public ToggleNode PlaySound { get; set; } diff --git a/src/Hud/Menu/MenuPlugin.cs b/src/Hud/Menu/MenuPlugin.cs index faaad9c4..f83df422 100644 --- a/src/Hud/Menu/MenuPlugin.cs +++ b/src/Hud/Menu/MenuPlugin.cs @@ -154,7 +154,7 @@ private void CreateMenu() AddChild(qualitySkillGemMenu, "Min. quality", qualityItemsSettings.SkillGem.MinQuality); AddChild(itemAlertMenu, "Play sound", settingsHub.ItemAlertSettings.PlaySound); MenuItem alertTextMenu = AddChild(itemAlertMenu, "Show text", settingsHub.ItemAlertSettings.ShowText); - AddChild(itemAlertMenu, "Hide Others", settingsHub.ItemAlertSettings.HideOthers); + //AddChild(itemAlertMenu, "Hide Others", settingsHub.ItemAlertSettings.HideOthers); AddChild(alertTextMenu, "Font size", settingsHub.ItemAlertSettings.TextSize); BorderSettings borderSettings = settingsHub.ItemAlertSettings.BorderSettings; MenuItem showBorderMenu = AddChild(itemAlertMenu, "Show border", borderSettings.Enable); diff --git a/src/Hud/UI/Renderers/FontRenderer.cs b/src/Hud/UI/Renderers/FontRenderer.cs index 4a624db9..7e53f546 100644 --- a/src/Hud/UI/Renderers/FontRenderer.cs +++ b/src/Hud/UI/Renderers/FontRenderer.cs @@ -30,16 +30,21 @@ public void Begin() public Size2 DrawText(string text, string fontName, int height, Vector2 position, Color color, FontDrawFlags align) { - try { - Font font = GetFont(fontName, height); + Font font; + Rectangle fontDimension; + try + { + font = GetFont(fontName, height); var rectangle = new Rectangle((int)position.X, (int)position.Y, 0, 0); - Rectangle fontDimension = font.MeasureText(null, text, rectangle, align); - font.DrawText(sprite, text, fontDimension, align, color); + fontDimension = font.MeasureText(null, text, rectangle, align); + if (!sprite.IsDisposed) + font.DrawText(sprite, text, fontDimension, align, color); return new Size2(fontDimension.Width, fontDimension.Height); } catch (Exception exception) { - // Console.WriteLine("Exception! " + position.X + ", " + position.Y); + //Console.WriteLine("Exception! X: " + position.X + ", Y: " + position.Y + ", Text: " + text); + //Console.WriteLine(exception.StackTrace); } return new Size2(); }