Role ban UI updates (#16736)
This commit is contained in:
@@ -60,7 +60,7 @@ namespace Content.Client.Entry
|
|||||||
[Dependency] private readonly DocumentParsingManager _documentParsingManager = default!;
|
[Dependency] private readonly DocumentParsingManager _documentParsingManager = default!;
|
||||||
[Dependency] private readonly GhostKickManager _ghostKick = default!;
|
[Dependency] private readonly GhostKickManager _ghostKick = default!;
|
||||||
[Dependency] private readonly ExtendedDisconnectInformationManager _extendedDisconnectInformation = default!;
|
[Dependency] private readonly ExtendedDisconnectInformationManager _extendedDisconnectInformation = default!;
|
||||||
[Dependency] private readonly PlayTimeTrackingManager _playTimeTracking = default!;
|
[Dependency] private readonly JobRequirementsManager _jobRequirements = default!;
|
||||||
[Dependency] private readonly ContentLocalizationManager _contentLoc = default!;
|
[Dependency] private readonly ContentLocalizationManager _contentLoc = default!;
|
||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
@@ -130,7 +130,7 @@ namespace Content.Client.Entry
|
|||||||
_viewportManager.Initialize();
|
_viewportManager.Initialize();
|
||||||
_ghostKick.Initialize();
|
_ghostKick.Initialize();
|
||||||
_extendedDisconnectInformation.Initialize();
|
_extendedDisconnectInformation.Initialize();
|
||||||
_playTimeTracking.Initialize();
|
_jobRequirements.Initialize();
|
||||||
|
|
||||||
//AUTOSCALING default Setup!
|
//AUTOSCALING default Setup!
|
||||||
_configManager.SetCVar("interface.resolutionAutoScaleUpperCutoffX", 1080);
|
_configManager.SetCVar("interface.resolutionAutoScaleUpperCutoffX", 1080);
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace Content.Client.IoC
|
|||||||
IoCManager.Register<ISharedAdminLogManager, SharedAdminLogManager>();
|
IoCManager.Register<ISharedAdminLogManager, SharedAdminLogManager>();
|
||||||
IoCManager.Register<GhostKickManager>();
|
IoCManager.Register<GhostKickManager>();
|
||||||
IoCManager.Register<ExtendedDisconnectInformationManager>();
|
IoCManager.Register<ExtendedDisconnectInformationManager>();
|
||||||
IoCManager.Register<PlayTimeTrackingManager>();
|
IoCManager.Register<JobRequirementsManager>();
|
||||||
IoCManager.Register<DocumentParsingManager>();
|
IoCManager.Register<DocumentParsingManager>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace Content.Client.LateJoin
|
|||||||
[Dependency] private readonly IClientConsoleHost _consoleHost = default!;
|
[Dependency] private readonly IClientConsoleHost _consoleHost = default!;
|
||||||
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
||||||
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
|
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
|
||||||
[Dependency] private readonly PlayTimeTrackingManager _playTimeTracking = default!;
|
[Dependency] private readonly JobRequirementsManager _jobRequirements = default!;
|
||||||
|
|
||||||
public event Action<(EntityUid, string)> SelectedId;
|
public event Action<(EntityUid, string)> SelectedId;
|
||||||
|
|
||||||
@@ -54,6 +54,7 @@ namespace Content.Client.LateJoin
|
|||||||
|
|
||||||
Contents.AddChild(_base);
|
Contents.AddChild(_base);
|
||||||
|
|
||||||
|
_jobRequirements.Updated += RebuildUI;
|
||||||
RebuildUI();
|
RebuildUI();
|
||||||
|
|
||||||
SelectedId += x =>
|
SelectedId += x =>
|
||||||
@@ -249,7 +250,7 @@ namespace Content.Client.LateJoin
|
|||||||
|
|
||||||
jobButton.OnPressed += _ => SelectedId.Invoke((id, jobButton.JobId));
|
jobButton.OnPressed += _ => SelectedId.Invoke((id, jobButton.JobId));
|
||||||
|
|
||||||
if (!_playTimeTracking.IsAllowed(prototype, out var reason))
|
if (!_jobRequirements.IsAllowed(prototype, out var reason))
|
||||||
{
|
{
|
||||||
jobButton.Disabled = true;
|
jobButton.Disabled = true;
|
||||||
|
|
||||||
@@ -289,6 +290,7 @@ namespace Content.Client.LateJoin
|
|||||||
|
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
|
_jobRequirements.Updated -= RebuildUI;
|
||||||
_gameTicker.LobbyJobsAvailableUpdated -= JobsAvailableUpdated;
|
_gameTicker.LobbyJobsAvailableUpdated -= JobsAvailableUpdated;
|
||||||
_jobButtons.Clear();
|
_jobButtons.Clear();
|
||||||
_jobCategories.Clear();
|
_jobCategories.Clear();
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
|
using Content.Shared.Players;
|
||||||
using Content.Shared.Players.PlayTimeTracking;
|
using Content.Shared.Players.PlayTimeTracking;
|
||||||
using Content.Shared.Roles;
|
using Content.Shared.Roles;
|
||||||
using Robust.Client;
|
using Robust.Client;
|
||||||
@@ -11,7 +13,7 @@ using Robust.Shared.Prototypes;
|
|||||||
|
|
||||||
namespace Content.Client.Players.PlayTimeTracking;
|
namespace Content.Client.Players.PlayTimeTracking;
|
||||||
|
|
||||||
public sealed class PlayTimeTrackingManager
|
public sealed class JobRequirementsManager
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IBaseClient _client = default!;
|
[Dependency] private readonly IBaseClient _client = default!;
|
||||||
[Dependency] private readonly IClientNetManager _net = default!;
|
[Dependency] private readonly IClientNetManager _net = default!;
|
||||||
@@ -20,9 +22,18 @@ public sealed class PlayTimeTrackingManager
|
|||||||
[Dependency] private readonly IPrototypeManager _prototypes = default!;
|
[Dependency] private readonly IPrototypeManager _prototypes = default!;
|
||||||
|
|
||||||
private readonly Dictionary<string, TimeSpan> _roles = new();
|
private readonly Dictionary<string, TimeSpan> _roles = new();
|
||||||
|
private readonly List<string> _roleBans = new();
|
||||||
|
|
||||||
|
private ISawmill _sawmill = default!;
|
||||||
|
|
||||||
|
public event Action? Updated;
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
|
_sawmill = Logger.GetSawmill("job_requirements");
|
||||||
|
|
||||||
|
// Yeah the client manager handles role bans and playtime but the server ones are separate DEAL.
|
||||||
|
_net.RegisterNetMessage<MsgRoleBans>(RxRoleBans);
|
||||||
_net.RegisterNetMessage<MsgPlayTime>(RxPlayTime);
|
_net.RegisterNetMessage<MsgPlayTime>(RxPlayTime);
|
||||||
|
|
||||||
_client.RunLevelChanged += ClientOnRunLevelChanged;
|
_client.RunLevelChanged += ClientOnRunLevelChanged;
|
||||||
@@ -37,6 +48,18 @@ public sealed class PlayTimeTrackingManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RxRoleBans(MsgRoleBans message)
|
||||||
|
{
|
||||||
|
_sawmill.Debug($"Received roleban info containing {message.Bans.Count} entries.");
|
||||||
|
|
||||||
|
if (_roleBans.Equals(message.Bans))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_roleBans.Clear();
|
||||||
|
_roleBans.AddRange(message.Bans);
|
||||||
|
Updated?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
private void RxPlayTime(MsgPlayTime message)
|
private void RxPlayTime(MsgPlayTime message)
|
||||||
{
|
{
|
||||||
_roles.Clear();
|
_roles.Clear();
|
||||||
@@ -52,27 +75,36 @@ public sealed class PlayTimeTrackingManager
|
|||||||
{
|
{
|
||||||
sawmill.Info($"{tracker}: {time}");
|
sawmill.Info($"{tracker}: {time}");
|
||||||
}*/
|
}*/
|
||||||
|
Updated?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsAllowed(JobPrototype job, [NotNullWhen(false)] out string? reason)
|
public bool IsAllowed(JobPrototype job, [NotNullWhen(false)] out string? reason)
|
||||||
{
|
{
|
||||||
reason = null;
|
reason = null;
|
||||||
|
|
||||||
|
if (_roleBans.Contains($"Job:{job.ID}"))
|
||||||
|
{
|
||||||
|
reason = Loc.GetString("role-ban");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (job.Requirements == null ||
|
if (job.Requirements == null ||
|
||||||
!_cfg.GetCVar(CCVars.GameRoleTimers))
|
!_cfg.GetCVar(CCVars.GameRoleTimers))
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var player = _playerManager.LocalPlayer?.Session;
|
var player = _playerManager.LocalPlayer?.Session;
|
||||||
|
|
||||||
if (player == null) return true;
|
if (player == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
var roles = _roles;
|
|
||||||
var reasonBuilder = new StringBuilder();
|
var reasonBuilder = new StringBuilder();
|
||||||
|
|
||||||
var first = true;
|
var first = true;
|
||||||
foreach (var requirement in job.Requirements)
|
foreach (var requirement in job.Requirements)
|
||||||
{
|
{
|
||||||
if (JobRequirements.TryRequirementMet(requirement, roles, out reason, _prototypes))
|
if (JobRequirements.TryRequirementMet(requirement, _roles, out reason, _prototypes))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!first)
|
if (!first)
|
||||||
@@ -53,6 +53,7 @@ namespace Content.Client.Preferences.UI
|
|||||||
private readonly IEntityManager _entMan;
|
private readonly IEntityManager _entMan;
|
||||||
private readonly IConfigurationManager _configurationManager;
|
private readonly IConfigurationManager _configurationManager;
|
||||||
private readonly MarkingManager _markingManager;
|
private readonly MarkingManager _markingManager;
|
||||||
|
private readonly JobRequirementsManager _requirements;
|
||||||
|
|
||||||
private LineEdit _ageEdit => CAgeEdit;
|
private LineEdit _ageEdit => CAgeEdit;
|
||||||
private LineEdit _nameEdit => CNameEdit;
|
private LineEdit _nameEdit => CNameEdit;
|
||||||
@@ -377,96 +378,9 @@ namespace Content.Client.Preferences.UI
|
|||||||
|
|
||||||
_jobPriorities = new List<JobPrioritySelector>();
|
_jobPriorities = new List<JobPrioritySelector>();
|
||||||
_jobCategories = new Dictionary<string, BoxContainer>();
|
_jobCategories = new Dictionary<string, BoxContainer>();
|
||||||
|
_requirements = IoCManager.Resolve<JobRequirementsManager>();
|
||||||
var firstCategory = true;
|
_requirements.Updated += UpdateRoleRequirements;
|
||||||
var playTime = IoCManager.Resolve<PlayTimeTrackingManager>();
|
UpdateRoleRequirements();
|
||||||
|
|
||||||
foreach (var department in _prototypeManager.EnumeratePrototypes<DepartmentPrototype>())
|
|
||||||
{
|
|
||||||
var departmentName = Loc.GetString($"department-{department.ID}");
|
|
||||||
|
|
||||||
if (!_jobCategories.TryGetValue(department.ID, out var category))
|
|
||||||
{
|
|
||||||
category = new BoxContainer
|
|
||||||
{
|
|
||||||
Orientation = LayoutOrientation.Vertical,
|
|
||||||
Name = department.ID,
|
|
||||||
ToolTip = Loc.GetString("humanoid-profile-editor-jobs-amount-in-department-tooltip",
|
|
||||||
("departmentName", departmentName))
|
|
||||||
};
|
|
||||||
|
|
||||||
if (firstCategory)
|
|
||||||
{
|
|
||||||
firstCategory = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
category.AddChild(new Control
|
|
||||||
{
|
|
||||||
MinSize = new Vector2(0, 23),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
category.AddChild(new PanelContainer
|
|
||||||
{
|
|
||||||
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#464966")},
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new Label
|
|
||||||
{
|
|
||||||
Text = Loc.GetString("humanoid-profile-editor-department-jobs-label",
|
|
||||||
("departmentName", departmentName)),
|
|
||||||
Margin = new Thickness(5f, 0, 0, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_jobCategories[department.ID] = category;
|
|
||||||
_jobList.AddChild(category);
|
|
||||||
}
|
|
||||||
|
|
||||||
var jobs = department.Roles.Select(o => _prototypeManager.Index<JobPrototype>(o)).Where(o => o.SetPreference).ToList();
|
|
||||||
jobs.Sort((x, y) => -string.Compare(x.LocalizedName, y.LocalizedName, StringComparison.CurrentCultureIgnoreCase));
|
|
||||||
|
|
||||||
foreach (var job in jobs)
|
|
||||||
{
|
|
||||||
var selector = new JobPrioritySelector(job);
|
|
||||||
|
|
||||||
if (!playTime.IsAllowed(job, out var reason))
|
|
||||||
{
|
|
||||||
selector.LockRequirements(reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
category.AddChild(selector);
|
|
||||||
_jobPriorities.Add(selector);
|
|
||||||
|
|
||||||
selector.PriorityChanged += priority =>
|
|
||||||
{
|
|
||||||
Profile = Profile?.WithJobPriority(job.ID, priority);
|
|
||||||
IsDirty = true;
|
|
||||||
|
|
||||||
foreach (var jobSelector in _jobPriorities)
|
|
||||||
{
|
|
||||||
// Sync other selectors with the same job in case of multiple department jobs
|
|
||||||
if (jobSelector.Job == selector.Job)
|
|
||||||
{
|
|
||||||
jobSelector.Priority = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lower any other high priorities to medium.
|
|
||||||
if (priority == JobPriority.High)
|
|
||||||
{
|
|
||||||
if (jobSelector.Job != selector.Job && jobSelector.Priority == JobPriority.High)
|
|
||||||
{
|
|
||||||
jobSelector.Priority = JobPriority.Medium;
|
|
||||||
Profile = Profile?.WithJobPriority(jobSelector.Job.ID, JobPriority.Medium);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Jobs
|
#endregion Jobs
|
||||||
|
|
||||||
@@ -603,6 +517,101 @@ namespace Content.Client.Preferences.UI
|
|||||||
IsDirty = false;
|
IsDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateRoleRequirements()
|
||||||
|
{
|
||||||
|
_jobList.DisposeAllChildren();
|
||||||
|
_jobPriorities.Clear();
|
||||||
|
_jobCategories.Clear();
|
||||||
|
var firstCategory = true;
|
||||||
|
|
||||||
|
foreach (var department in _prototypeManager.EnumeratePrototypes<DepartmentPrototype>())
|
||||||
|
{
|
||||||
|
var departmentName = Loc.GetString($"department-{department.ID}");
|
||||||
|
|
||||||
|
if (!_jobCategories.TryGetValue(department.ID, out var category))
|
||||||
|
{
|
||||||
|
category = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
|
Name = department.ID,
|
||||||
|
ToolTip = Loc.GetString("humanoid-profile-editor-jobs-amount-in-department-tooltip",
|
||||||
|
("departmentName", departmentName))
|
||||||
|
};
|
||||||
|
|
||||||
|
if (firstCategory)
|
||||||
|
{
|
||||||
|
firstCategory = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
category.AddChild(new Control
|
||||||
|
{
|
||||||
|
MinSize = new Vector2(0, 23),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
category.AddChild(new PanelContainer
|
||||||
|
{
|
||||||
|
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#464966")},
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new Label
|
||||||
|
{
|
||||||
|
Text = Loc.GetString("humanoid-profile-editor-department-jobs-label",
|
||||||
|
("departmentName", departmentName)),
|
||||||
|
Margin = new Thickness(5f, 0, 0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_jobCategories[department.ID] = category;
|
||||||
|
_jobList.AddChild(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
var jobs = department.Roles.Select(o => _prototypeManager.Index<JobPrototype>(o)).Where(o => o.SetPreference).ToList();
|
||||||
|
jobs.Sort((x, y) => -string.Compare(x.LocalizedName, y.LocalizedName, StringComparison.CurrentCultureIgnoreCase));
|
||||||
|
|
||||||
|
foreach (var job in jobs)
|
||||||
|
{
|
||||||
|
var selector = new JobPrioritySelector(job);
|
||||||
|
|
||||||
|
if (!_requirements.IsAllowed(job, out var reason))
|
||||||
|
{
|
||||||
|
selector.LockRequirements(reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
category.AddChild(selector);
|
||||||
|
_jobPriorities.Add(selector);
|
||||||
|
|
||||||
|
selector.PriorityChanged += priority =>
|
||||||
|
{
|
||||||
|
Profile = Profile?.WithJobPriority(job.ID, priority);
|
||||||
|
IsDirty = true;
|
||||||
|
|
||||||
|
foreach (var jobSelector in _jobPriorities)
|
||||||
|
{
|
||||||
|
// Sync other selectors with the same job in case of multiple department jobs
|
||||||
|
if (jobSelector.Job == selector.Job)
|
||||||
|
{
|
||||||
|
jobSelector.Priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lower any other high priorities to medium.
|
||||||
|
if (priority == JobPriority.High)
|
||||||
|
{
|
||||||
|
if (jobSelector.Job != selector.Job && jobSelector.Priority == JobPriority.High)
|
||||||
|
{
|
||||||
|
jobSelector.Priority = JobPriority.Medium;
|
||||||
|
Profile = Profile?.WithJobPriority(jobSelector.Job.ID, JobPriority.Medium);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void OnFlavorTextChange(string content)
|
private void OnFlavorTextChange(string content)
|
||||||
{
|
{
|
||||||
if (Profile is null)
|
if (Profile is null)
|
||||||
@@ -694,6 +703,8 @@ namespace Content.Client.Preferences.UI
|
|||||||
if (_previewDummy != null)
|
if (_previewDummy != null)
|
||||||
_entMan.DeleteEntity(_previewDummy.Value);
|
_entMan.DeleteEntity(_previewDummy.Value);
|
||||||
|
|
||||||
|
var playTime = IoCManager.Resolve<JobRequirementsManager>();
|
||||||
|
playTime.Updated -= UpdateRoleRequirements;
|
||||||
_preferencesManager.OnServerDataLoaded -= LoadServerData;
|
_preferencesManager.OnServerDataLoaded -= LoadServerData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ namespace Content.Server.Administration.Commands;
|
|||||||
[AdminCommand(AdminFlags.Ban)]
|
[AdminCommand(AdminFlags.Ban)]
|
||||||
public sealed class DepartmentBanCommand : IConsoleCommand
|
public sealed class DepartmentBanCommand : IConsoleCommand
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IPlayerLocator _locater = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _protoManager = default!;
|
||||||
|
[Dependency] private readonly RoleBanManager _bans = default!;
|
||||||
|
|
||||||
public string Command => "departmentban";
|
public string Command => "departmentban";
|
||||||
public string Description => Loc.GetString("cmd-departmentban-desc");
|
public string Description => Loc.GetString("cmd-departmentban-desc");
|
||||||
public string Help => Loc.GetString("cmd-departmentban-help");
|
public string Help => Loc.GetString("cmd-departmentban-help");
|
||||||
@@ -46,19 +50,25 @@ public sealed class DepartmentBanCommand : IConsoleCommand
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var protoManager = IoCManager.Resolve<IPrototypeManager>();
|
if (!_protoManager.TryIndex<DepartmentPrototype>(department, out var departmentProto))
|
||||||
|
|
||||||
if (!protoManager.TryIndex<DepartmentPrototype>(department, out var departmentProto))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var banManager = IoCManager.Resolve<RoleBanManager>();
|
var located = await _locater.LookupIdByNameOrIdAsync(target);
|
||||||
|
|
||||||
|
if (located == null)
|
||||||
|
{
|
||||||
|
shell.WriteError(Loc.GetString("cmd-roleban-name-parse"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var job in departmentProto.Roles)
|
foreach (var job in departmentProto.Roles)
|
||||||
{
|
{
|
||||||
banManager.CreateJobBan(shell, target, job, reason, minutes);
|
_bans.CreateJobBan(shell, located, job, reason, minutes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_bans.SendRoleBans(located);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletionResult GetCompletion(IConsoleShell shell, string[] args)
|
public CompletionResult GetCompletion(IConsoleShell shell, string[] args)
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ namespace Content.Server.Administration.Commands;
|
|||||||
[AdminCommand(AdminFlags.Ban)]
|
[AdminCommand(AdminFlags.Ban)]
|
||||||
public sealed class RoleBanCommand : IConsoleCommand
|
public sealed class RoleBanCommand : IConsoleCommand
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IPlayerLocator _locator = default!;
|
||||||
|
[Dependency] private readonly RoleBanManager _bans = default!;
|
||||||
|
|
||||||
public string Command => "roleban";
|
public string Command => "roleban";
|
||||||
public string Description => Loc.GetString("cmd-roleban-desc");
|
public string Description => Loc.GetString("cmd-roleban-desc");
|
||||||
public string Help => Loc.GetString("cmd-roleban-help");
|
public string Help => Loc.GetString("cmd-roleban-help");
|
||||||
@@ -49,7 +52,16 @@ public sealed class RoleBanCommand : IConsoleCommand
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IoCManager.Resolve<RoleBanManager>().CreateJobBan(shell, target, job, reason, minutes);
|
var located = await _locator.LookupIdByNameOrIdAsync(target);
|
||||||
|
|
||||||
|
if (located == null)
|
||||||
|
{
|
||||||
|
shell.WriteError(Loc.GetString("cmd-roleban-name-parse"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_bans.CreateJobBan(shell, located, job, reason, minutes);
|
||||||
|
_bans.SendRoleBans(located);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletionResult GetCompletion(IConsoleShell shell, string[] args)
|
public CompletionResult GetCompletion(IConsoleShell shell, string[] args)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Net.Sockets;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Content.Server.Database;
|
using Content.Server.Database;
|
||||||
|
using Content.Shared.Players;
|
||||||
using Content.Shared.Roles;
|
using Content.Shared.Roles;
|
||||||
using Robust.Server.Player;
|
using Robust.Server.Player;
|
||||||
using Robust.Shared.Console;
|
using Robust.Shared.Console;
|
||||||
@@ -16,17 +17,21 @@ namespace Content.Server.Administration.Managers;
|
|||||||
|
|
||||||
public sealed class RoleBanManager
|
public sealed class RoleBanManager
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly INetManager _netManager = default!;
|
||||||
[Dependency] private readonly IServerDbManager _db = default!;
|
[Dependency] private readonly IServerDbManager _db = default!;
|
||||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
[Dependency] private readonly IPlayerLocator _playerLocator = default!;
|
|
||||||
|
|
||||||
private const string JobPrefix = "Job:";
|
private const string JobPrefix = "Job:";
|
||||||
|
|
||||||
|
private ISawmill _sawmill = default!;
|
||||||
|
|
||||||
private readonly Dictionary<NetUserId, HashSet<ServerRoleBanDef>> _cachedRoleBans = new();
|
private readonly Dictionary<NetUserId, HashSet<ServerRoleBanDef>> _cachedRoleBans = new();
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
|
_sawmill = Logger.GetSawmill("rolebans");
|
||||||
|
_netManager.RegisterNetMessage<MsgRoleBans>();
|
||||||
_playerManager.PlayerStatusChanged += OnPlayerStatusChanged;
|
_playerManager.PlayerStatusChanged += OnPlayerStatusChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,10 +39,13 @@ public sealed class RoleBanManager
|
|||||||
{
|
{
|
||||||
if (e.NewStatus != SessionStatus.Connected
|
if (e.NewStatus != SessionStatus.Connected
|
||||||
|| _cachedRoleBans.ContainsKey(e.Session.UserId))
|
|| _cachedRoleBans.ContainsKey(e.Session.UserId))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var netChannel = e.Session.ConnectedClient;
|
var netChannel = e.Session.ConnectedClient;
|
||||||
await CacheDbRoleBans(e.Session.UserId, netChannel.RemoteEndPoint.Address, netChannel.UserData.HWId.Length == 0 ? null : netChannel.UserData.HWId);
|
await CacheDbRoleBans(e.Session.UserId, netChannel.RemoteEndPoint.Address, netChannel.UserData.HWId.Length == 0 ? null : netChannel.UserData.HWId);
|
||||||
|
SendRoleBans(e.Session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> AddRoleBan(ServerRoleBanDef banDef)
|
private async Task<bool> AddRoleBan(ServerRoleBanDef banDef)
|
||||||
@@ -49,7 +57,7 @@ public sealed class RoleBanManager
|
|||||||
roleBans = new HashSet<ServerRoleBanDef>();
|
roleBans = new HashSet<ServerRoleBanDef>();
|
||||||
_cachedRoleBans.Add(banDef.UserId.Value, roleBans);
|
_cachedRoleBans.Add(banDef.UserId.Value, roleBans);
|
||||||
}
|
}
|
||||||
if (!roleBans.Contains(banDef))
|
|
||||||
roleBans.Add(banDef);
|
roleBans.Add(banDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +65,33 @@ public sealed class RoleBanManager
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SendRoleBans(LocatedPlayerData located)
|
||||||
|
{
|
||||||
|
if (!_playerManager.TryGetSessionById(located.UserId, out var player))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendRoleBans(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendRoleBans(IPlayerSession pSession)
|
||||||
|
{
|
||||||
|
if (!_cachedRoleBans.TryGetValue(pSession.UserId, out var roleBans))
|
||||||
|
{
|
||||||
|
_sawmill.Error($"Tried to send rolebans for {pSession.Name} but none cached?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bans = new MsgRoleBans()
|
||||||
|
{
|
||||||
|
Bans = roleBans.Select(o => o.Role).ToList()
|
||||||
|
};
|
||||||
|
|
||||||
|
_sawmill.Debug($"Sent rolebans to {pSession.Name}");
|
||||||
|
_netManager.ServerSendMessage(bans, pSession.ConnectedClient);
|
||||||
|
}
|
||||||
|
|
||||||
public HashSet<string>? GetRoleBans(NetUserId playerUserId)
|
public HashSet<string>? GetRoleBans(NetUserId playerUserId)
|
||||||
{
|
{
|
||||||
return _cachedRoleBans.TryGetValue(playerUserId, out var roleBans) ? roleBans.Select(banDef => banDef.Role).ToHashSet() : null;
|
return _cachedRoleBans.TryGetValue(playerUserId, out var roleBans) ? roleBans.Select(banDef => banDef.Role).ToHashSet() : null;
|
||||||
@@ -98,7 +133,7 @@ public sealed class RoleBanManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region Job Bans
|
#region Job Bans
|
||||||
public async void CreateJobBan(IConsoleShell shell, string target, string job, string reason, uint minutes)
|
public async void CreateJobBan(IConsoleShell shell, LocatedPlayerData located, string job, string reason, uint minutes)
|
||||||
{
|
{
|
||||||
if (!_prototypeManager.TryIndex(job, out JobPrototype? _))
|
if (!_prototypeManager.TryIndex(job, out JobPrototype? _))
|
||||||
{
|
{
|
||||||
@@ -107,7 +142,7 @@ public sealed class RoleBanManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
job = string.Concat(JobPrefix, job);
|
job = string.Concat(JobPrefix, job);
|
||||||
CreateRoleBan(shell, target, job, reason, minutes);
|
CreateRoleBan(shell, located, job, reason, minutes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashSet<string>? GetJobBans(NetUserId playerUserId)
|
public HashSet<string>? GetJobBans(NetUserId playerUserId)
|
||||||
@@ -122,15 +157,8 @@ public sealed class RoleBanManager
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Commands
|
#region Commands
|
||||||
private async void CreateRoleBan(IConsoleShell shell, string target, string role, string reason, uint minutes)
|
private async void CreateRoleBan(IConsoleShell shell, LocatedPlayerData located, string role, string reason, uint minutes)
|
||||||
{
|
{
|
||||||
var located = await _playerLocator.LookupIdByNameOrIdAsync(target);
|
|
||||||
if (located == null)
|
|
||||||
{
|
|
||||||
shell.WriteError(Loc.GetString("cmd-roleban-name-parse"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var targetUid = located.UserId;
|
var targetUid = located.UserId;
|
||||||
var targetHWid = located.LastHWId;
|
var targetHWid = located.LastHWId;
|
||||||
var targetAddress = located.LastAddress;
|
var targetAddress = located.LastAddress;
|
||||||
@@ -167,12 +195,12 @@ public sealed class RoleBanManager
|
|||||||
|
|
||||||
if (!await AddRoleBan(banDef))
|
if (!await AddRoleBan(banDef))
|
||||||
{
|
{
|
||||||
shell.WriteLine(Loc.GetString("cmd-roleban-existing", ("target", target), ("role", role)));
|
shell.WriteLine(Loc.GetString("cmd-roleban-existing", ("target", located.Username), ("role", role)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var length = expires == null ? Loc.GetString("cmd-roleban-inf") : Loc.GetString("cmd-roleban-until", ("expires", expires));
|
var length = expires == null ? Loc.GetString("cmd-roleban-inf") : Loc.GetString("cmd-roleban-until", ("expires", expires));
|
||||||
shell.WriteLine(Loc.GetString("cmd-roleban-success", ("target", target), ("role", role), ("reason", reason), ("length", length)));
|
shell.WriteLine(Loc.GetString("cmd-roleban-success", ("target", located.Username), ("role", role), ("reason", reason), ("length", length)));
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
36
Content.Shared/Players/MsgRoleBans.cs
Normal file
36
Content.Shared/Players/MsgRoleBans.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using Lidgren.Network;
|
||||||
|
using Robust.Shared.Network;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Players;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sent server -> client to inform the client of their role bans.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class MsgRoleBans : NetMessage
|
||||||
|
{
|
||||||
|
public override MsgGroups MsgGroup => MsgGroups.EntityEvent;
|
||||||
|
|
||||||
|
public List<string> Bans = new();
|
||||||
|
|
||||||
|
public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer)
|
||||||
|
{
|
||||||
|
var count = buffer.ReadVariableInt32();
|
||||||
|
Bans.EnsureCapacity(count);
|
||||||
|
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
Bans.Add(buffer.ReadString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteToBuffer(NetOutgoingMessage buffer, IRobustSerializer serializer)
|
||||||
|
{
|
||||||
|
buffer.WriteVariableInt32(Bans.Count);
|
||||||
|
|
||||||
|
foreach (var ban in Bans)
|
||||||
|
{
|
||||||
|
buffer.Write(ban);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,8 @@ public sealed class MsgPlayTime : NetMessage
|
|||||||
public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer)
|
public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer)
|
||||||
{
|
{
|
||||||
var count = buffer.ReadVariableInt32();
|
var count = buffer.ReadVariableInt32();
|
||||||
|
Trackers.EnsureCapacity(count);
|
||||||
|
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
Trackers.Add(buffer.ReadString(), buffer.ReadTimeSpan());
|
Trackers.Add(buffer.ReadString(), buffer.ReadTimeSpan());
|
||||||
|
|||||||
@@ -6,3 +6,5 @@ role-timer-role-insufficient = You require {TOSTRING($time, "0")} more minutes w
|
|||||||
role-timer-role-too-high = You require {TOSTRING($time, "0")} fewer minutes with {$job} to play this role. (Are you trying to play a trainee role?)
|
role-timer-role-too-high = You require {TOSTRING($time, "0")} fewer minutes with {$job} to play this role. (Are you trying to play a trainee role?)
|
||||||
|
|
||||||
role-timer-locked = Locked (hover for details)
|
role-timer-locked = Locked (hover for details)
|
||||||
|
|
||||||
|
role-ban = You have been banned from this role.
|
||||||
|
|||||||
Reference in New Issue
Block a user