Skip to content

Commit 559d9b5

Browse files
committed
fix: Admin Client disconnect and closed when ban or mute a player
#2782
1 parent c8a1a08 commit 559d9b5

File tree

2 files changed

+73
-68
lines changed
  • Intersect.Client.Core/Interface/Game/Admin
  • Intersect.Client.Framework/Gwen/Control

2 files changed

+73
-68
lines changed

Intersect.Client.Core/Interface/Game/Admin/BanMuteBox.cs

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,47 +8,23 @@ namespace Intersect.Client.Interface.Game.Admin;
88
public partial class BanMuteBox : WindowControl
99
{
1010
private readonly TextBox _textboxReason;
11-
private readonly ComboBox _comboboxDuration;
11+
private readonly ComboBox? _comboboxDuration;
1212
private readonly LabeledCheckBox _checkboxIP;
1313

14-
private readonly Dictionary<string, int> _dayCount = new()
14+
private static readonly List<(string Label, int Days)> _durationOptions = new()
1515
{
16-
{
17-
Strings.BanMute.OneDay, 1
18-
},
19-
{
20-
Strings.BanMute.TwoDays, 2
21-
},
22-
{
23-
Strings.BanMute.ThreeDays, 3
24-
},
25-
{
26-
Strings.BanMute.FourDays, 4
27-
},
28-
{
29-
Strings.BanMute.FiveDays, 5
30-
},
31-
{
32-
Strings.BanMute.OneWeek, 7
33-
},
34-
{
35-
Strings.BanMute.TwoWeeks, 14
36-
},
37-
{
38-
Strings.BanMute.OneMonth, 30
39-
},
40-
{
41-
Strings.BanMute.TwoMonths, 60
42-
},
43-
{
44-
Strings.BanMute.SixMonths, 180
45-
},
46-
{
47-
Strings.BanMute.OneYear, 365
48-
},
49-
{
50-
Strings.BanMute.Forever, 999999
51-
},
16+
(Strings.BanMute.OneDay, 1),
17+
(Strings.BanMute.TwoDays, 2),
18+
(Strings.BanMute.ThreeDays, 3),
19+
(Strings.BanMute.FourDays, 4),
20+
(Strings.BanMute.FiveDays, 5),
21+
(Strings.BanMute.OneWeek, 7),
22+
(Strings.BanMute.TwoWeeks, 14),
23+
(Strings.BanMute.OneMonth, 30),
24+
(Strings.BanMute.TwoMonths, 60),
25+
(Strings.BanMute.SixMonths, 180),
26+
(Strings.BanMute.OneYear, 365),
27+
(Strings.BanMute.Forever, int.MaxValue),
5228
};
5329

5430
public BanMuteBox(string title, string prompt, EventHandler okayHandler) : base(
@@ -84,9 +60,9 @@ public BanMuteBox(string title, string prompt, EventHandler okayHandler) : base(
8460

8561
// Duration combobox
8662
_comboboxDuration = new ComboBox(this, "ComboBoxDuration");
87-
foreach (var day in _dayCount)
63+
foreach (var option in _durationOptions)
8864
{
89-
_ = _comboboxDuration.AddItem(day.Key, userData: day.Value);
65+
_ = _comboboxDuration.AddItem(option.Label, userData: option.Days);
9066
}
9167

9268
// Include IP checkbox
@@ -103,17 +79,23 @@ public BanMuteBox(string title, string prompt, EventHandler okayHandler) : base(
10379
buttonOkay.Clicked += (s, e) =>
10480
{
10581
okayHandler?.Invoke(this, EventArgs.Empty);
106-
Dispose();
82+
Close();
10783
};
10884

10985
var buttonCancel = new Button(this, "ButtonCancel")
11086
{
11187
Text = Strings.BanMute.Cancel,
11288
};
113-
buttonCancel.Clicked += (s, e) => Dispose();
89+
buttonCancel.Clicked += (s, e) => Close();
11490

11591
LoadJsonUi(UI.InGame, Graphics.Renderer?.GetResolutionString(), true);
11692

93+
// Set the first element by default after loading the UI (ensures deterministic selection).
94+
if (_comboboxDuration != null && _durationOptions.Count > 0)
95+
{
96+
_ = _comboboxDuration.SelectByUserData(_durationOptions[0].Days);
97+
}
98+
11799
richLabelPrompt.ClearText();
118100
richLabelPrompt.Width = promptContainer.Width - promptContainer.VerticalScrollBar.Width;
119101
richLabelPrompt.AddText(prompt, labelPrompt);
@@ -122,24 +104,34 @@ public BanMuteBox(string title, string prompt, EventHandler okayHandler) : base(
122104

123105
protected override void Dispose(bool disposing)
124106
{
125-
Close();
126-
Interface.GameUi.GameCanvas.RemoveChild(this, false);
107+
Interface.InputBlockingComponents.Remove(this);
108+
109+
if (_textboxReason != null)
110+
{
111+
Interface.FocusComponents.Remove(_textboxReason);
112+
}
127113

128114
base.Dispose(disposing);
129115
}
130116

131117
public int GetDuration()
132118
{
133-
return (int)_comboboxDuration.SelectedItem.UserData;
119+
var selected = _comboboxDuration?.SelectedItem;
120+
121+
if (selected?.UserData is int days)
122+
{
123+
return days;
124+
}
125+
return 1; // default value should be 1 day for safety
134126
}
135127

136128
public string GetReason()
137129
{
138-
return _textboxReason.Text;
130+
return _textboxReason?.Text ?? string.Empty;
139131
}
140132

141133
public bool BanIp()
142134
{
143-
return _checkboxIP.IsChecked;
135+
return _checkboxIP?.IsChecked ?? false;
144136
}
145137
}

Intersect.Client.Framework/Gwen/Control/Base.cs

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,23 +1295,27 @@ private static void PropagateDrawDebugOutlinesToChildren(Base @this, bool drawDe
12951295
/// </summary>
12961296
public void Dispose()
12971297
{
1298-
try
1298+
// TODO : GWEN: We need to spend more time on this.
1299+
if (_disposed)
12991300
{
1300-
ObjectDisposedException.ThrowIf(_disposed, this);
1301-
}
1302-
catch
1303-
{
1304-
throw;
1301+
return;
13051302
}
13061303

1304+
// I think its only used for diagnosis, so Im adding the DEBUG condition. I hope so
1305+
#if DEBUG
13071306
_disposeStack = new StackTrace(fNeedFileInfo: true);
1307+
#endif
13081308

1309+
// We mark that Dispose() has been called to prevents Dispose from being executed again
13091310
_disposed = true;
13101311

1312+
// Remove all pending tasks from the thread queue of this control
13111313
_threadQueue.ClearPending();
13121314

1315+
// Virtual Dispose() so that inherited classes can release their resources
13131316
Dispose(disposing: true);
13141317

1318+
// Reserve an assistant variable for the texture caching mechanism
13151319
ICacheToTexture? cache = default;
13161320

13171321
#pragma warning disable CA1031 // Do not catch general exception types
@@ -1325,34 +1329,35 @@ public void Dispose()
13251329
}
13261330
#pragma warning restore CA1031 // Do not catch general exception types
13271331

1332+
// If the control was cached in the texture cache, free that memory
13281333
if (ShouldCacheToTexture && cache != null)
13291334
{
13301335
cache.DisposeCachedTexture(this);
13311336
}
13321337

1338+
// Clear input indicators if they point to this control
13331339
if (InputHandler.HoveredControl == this)
1334-
{
13351340
InputHandler.HoveredControl = null;
1336-
}
1337-
13381341
if (InputHandler.KeyboardFocus == this)
1339-
{
13401342
InputHandler.KeyboardFocus = null;
1341-
}
1342-
13431343
if (InputHandler.MouseFocus == this)
1344-
{
13451344
InputHandler.MouseFocus = null;
1346-
}
13471345

13481346
DragAndDrop.ControlDeleted(this);
13491347
ToolTip.ControlDeleted(this);
13501348
Animation.Cancel(this);
13511349

1350+
// Remove and release all child controls
13521351
DisposeChildrenOf(this);
13531352

1353+
// TODO : check if we need to dispose tooltip
1354+
// if (_tooltip != null)
1355+
// _tooltip.Dispose();
1356+
1357+
// Prevents the finalizer from restarting for this object
13541358
GC.SuppressFinalize(this);
13551359

1360+
// Informs that the object has completed the resource release process
13561361
_disposeCompleted = true;
13571362

13581363
try
@@ -1370,6 +1375,14 @@ public void Dispose()
13701375
}
13711376
}
13721377

1378+
/// <summary>
1379+
/// Releases resources used by the control.
1380+
/// When <paramref name="disposing"/> is true, both managed and unmanaged resources
1381+
/// should be released. When false (finalizer), only unmanaged resources should be released.
1382+
/// Override this method in derived classes to dispose additional resources and ensure
1383+
/// to call the base implementation.
1384+
/// </summary>
1385+
/// <param name="disposing">True when called from <see cref="Dispose()"/>, false when called from finalizer.</param>
13731386
protected virtual void Dispose(bool disposing)
13741387
{
13751388
}
@@ -1591,7 +1604,7 @@ public void LoadJsonUi(GameContentManager.UI stage, string? resolution = default
15911604
}
15921605
catch (Exception exception)
15931606
{
1594-
//Log JSON UI Loading Error
1607+
// Log JSON UI Loading Error
15951608
throw new Exception("Error loading json ui for " + ParentQualifiedName, exception);
15961609
}
15971610
}
@@ -1717,30 +1730,30 @@ public virtual void LoadJson(JToken token, bool isRoot = default)
17171730

17181731
if (obj["DrawBackground"] != null)
17191732
{
1720-
ShouldDrawBackground = (bool) obj["DrawBackground"];
1733+
ShouldDrawBackground = (bool)obj["DrawBackground"];
17211734
}
17221735

17231736
if (obj["Disabled"] != null)
17241737
{
1725-
IsDisabled = (bool) obj["Disabled"];
1738+
IsDisabled = (bool)obj["Disabled"];
17261739
}
17271740

17281741
if (obj["Hidden"] != null)
17291742
{
1730-
IsHidden = (bool) obj["Hidden"];
1743+
IsHidden = (bool)obj["Hidden"];
17311744
}
17321745

17331746
if (obj[nameof(RestrictToParent)] != null)
17341747
{
1735-
RestrictToParent = (bool) obj[nameof(RestrictToParent)];
1748+
RestrictToParent = (bool)obj[nameof(RestrictToParent)];
17361749
}
17371750

17381751
if (obj[nameof(MouseInputEnabled)] != null)
17391752
{
1740-
MouseInputEnabled = (bool) obj[nameof(MouseInputEnabled)];
1753+
MouseInputEnabled = (bool)obj[nameof(MouseInputEnabled)];
17411754
}
17421755

1743-
if (obj["HideToolTip"] != null && (bool) obj["HideToolTip"])
1756+
if (obj["HideToolTip"] != null && (bool)obj["HideToolTip"])
17441757
{
17451758
_tooltipEnabled = false;
17461759
SetToolTipText(null);

0 commit comments

Comments
 (0)