Фичи для педалей (#202)

This commit is contained in:
Aviu00
2023-07-16 11:32:42 +03:00
committed by Aviu00
parent 65ef100acd
commit 3f8ff32206
21 changed files with 337 additions and 32 deletions

View File

@@ -19,11 +19,11 @@ namespace Content.Client.Administration.Systems
OnBwoinkTextMessageRecieved?.Invoke(this, message);
}
public void Send(NetUserId channelId, string text)
public void Send(NetUserId channelId, string text, bool isAdmin)
{
// Reuse the channel ID as the 'true sender'.
// Server will ignore this and if someone makes it not ignore this (which is bad, allows impersonation!!!), that will help.
RaiseNetworkEvent(new BwoinkTextMessage(channelId, channelId, text));
RaiseNetworkEvent(new BwoinkTextMessage(channelId, channelId, text, isAdmin));
SendInputTextUpdated(channelId, false);
}

View File

@@ -4,6 +4,9 @@
x:Class="Content.Client.Options.UI.Tabs.AdminSettingsTab">
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Vertical" Margin="5 0 0 0" VerticalExpand="True">
<BoxContainer Orientation="Horizontal" Margin="4 10 4 0">
<CheckBox Name="DeadChatAdminCheckbox" Text="Отображать сообщения в гост чате как админские" />
</BoxContainer>
<BoxContainer Orientation="Horizontal" Margin="0 3 0 0">
<Label Text="Громкость звука ахелпа" HorizontalExpand="True"/>
<Control MinSize="8 0" />
@@ -28,10 +31,6 @@
StyleClasses="Caution"
HorizontalExpand="True"
HorizontalAlignment="Right" />
<Button Name="DefaultButton"
Text="{Loc 'ui-options-default'}"
TextAlign="Center"
HorizontalAlignment="Right" />
<Control MinSize="2 0" />
<Button Name="ApplyButton"
Text="{Loc 'ui-options-apply'}"

View File

@@ -1,7 +1,7 @@
using Content.Shared.CCVar;
using Content.Shared.White;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Configuration;
using Range = Robust.Client.UserInterface.Controls.Range;
@@ -18,28 +18,72 @@ public sealed partial class AdminSettingsTab : Control
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
LoadData();
Reset();
ApplyButton.OnPressed += OnApplyButtonPressed;
ResetButton.OnPressed += OnResetButtonPressed;
DeadChatAdminCheckbox.OnToggled += OnDeadChatAdminToggled;
AhelpSoundVolume.OnValueChanged += OnAhelpVolumeChanged;
}
protected override void Dispose(bool disposing)
{
ApplyButton.OnPressed -= OnApplyButtonPressed;
ResetButton.OnPressed -= OnResetButtonPressed;
DeadChatAdminCheckbox.OnToggled -= OnDeadChatAdminToggled;
AhelpSoundVolume.OnValueChanged -= OnAhelpVolumeChanged;
base.Dispose(disposing);
}
private void LoadData()
private void OnApplyButtonPressed(BaseButton.ButtonEventArgs args)
{
var bwoinkVolume = _cfg.GetCVar(WhiteCVars.BwoinkVolume);
AhelpSoundVolume.Value = bwoinkVolume;
AhelpSoundVolumeLabel.Text = ((int) bwoinkVolume).ToString();
_cfg.SetCVar(WhiteCVars.BwoinkVolume, LV100ToDB(AhelpSoundVolume.Value));
_cfg.SetCVar(WhiteCVars.DeadChatAdmin, DeadChatAdminCheckbox.Pressed);
_cfg.SaveToFile();
UpdateChanges();
}
private void OnResetButtonPressed(BaseButton.ButtonEventArgs args)
{
Reset();
}
private void Reset()
{
DeadChatAdminCheckbox.Pressed = _cfg.GetCVar(WhiteCVars.DeadChatAdmin);
AhelpSoundVolume.Value = DBToLV100(_cfg.GetCVar(WhiteCVars.BwoinkVolume));
UpdateChanges();
}
private void UpdateChanges()
{
var isAhelpSoundVolumeSame =
Math.Abs(AhelpSoundVolume.Value - DBToLV100(_cfg.GetCVar(WhiteCVars.BwoinkVolume))) < 0.01f;
var isDeadChatAdminSame = DeadChatAdminCheckbox.Pressed == _cfg.GetCVar(WhiteCVars.DeadChatAdmin);
var isEverythingSame = isAhelpSoundVolumeSame && isDeadChatAdminSame;
ApplyButton.Disabled = isEverythingSame;
ResetButton.Disabled = isEverythingSame;
AhelpSoundVolumeLabel.Text =
Loc.GetString("ui-options-volume-percent", ("volume", AhelpSoundVolume.Value / 100));
}
private void OnAhelpVolumeChanged(Range newValue)
{
_cfg.SetCVar(WhiteCVars.BwoinkVolume, LV100ToDB(newValue.Value));
AhelpSoundVolumeLabel.Text = ((int)newValue.Value).ToString();
UpdateChanges();
}
private void OnDeadChatAdminToggled(BaseButton.ButtonToggledEventArgs obj)
{
UpdateChanges();
}
private float DBToLV100(float db)
{
return MathF.Pow(10, db / 10) * 100;
}
private float LV100ToDB(float lv100)

View File

@@ -143,8 +143,9 @@ public sealed class AHelpUIController: UIController, IOnSystemChanged<BwoinkSyst
return;
}
float bwoinkVolume = _clientAdminManager.IsActive() ? adminBwoinkVolume : defaultBwoinkVolume;
var isAdmin = _adminManager.IsActive();
var notify = !isAdmin || !message.IsAdmin;
float bwoinkVolume = isAdmin ? adminBwoinkVolume : defaultBwoinkVolume;
var audioParams = new AudioParams()
{
@@ -152,7 +153,7 @@ public sealed class AHelpUIController: UIController, IOnSystemChanged<BwoinkSyst
};
if (localPlayer.UserId != message.TrueSender)
if (localPlayer.UserId != message.TrueSender && notify)
{
if (_aHelpSound != null)
_audio.PlayGlobal(_aHelpSound, Filter.Local(), false, audioParams);
@@ -161,7 +162,7 @@ public sealed class AHelpUIController: UIController, IOnSystemChanged<BwoinkSyst
EnsureUIHelper();
if (!UIHelper!.IsOpen)
if (!UIHelper!.IsOpen && notify)
{
UnreadAHelpReceived();
}
@@ -192,7 +193,7 @@ public sealed class AHelpUIController: UIController, IOnSystemChanged<BwoinkSyst
UIHelper = isAdmin ? new AdminAHelpUIHandler(ownerUserId) : new UserAHelpUIHandler(ownerUserId);
UIHelper.DiscordRelayChanged(_discordRelayActive);
UIHelper.SendMessageAction = (userId, textMessage) => _bwoinkSystem?.Send(userId, textMessage);
UIHelper.SendMessageAction = (userId, textMessage) => _bwoinkSystem?.Send(userId, textMessage, isAdmin);
UIHelper.InputTextChanged += (channel, text) => _bwoinkSystem?.SendInputTextUpdated(channel, text.Length > 0);
UIHelper.OnClose += () => { SetAHelpPressed(false); };
UIHelper.OnOpen += () => { SetAHelpPressed(true); };

View File

@@ -0,0 +1,55 @@
using Content.Shared.Actions;
using Content.Shared.Popups;
using Content.Shared.White.Administration;
using Robust.Client.Console;
using Robust.Client.GameObjects;
namespace Content.Client.White.Administration;
public sealed class InvisibilitySystem : SharedInvisibilitySystem
{
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly IClientConsoleHost _console = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<InvisibilityComponent, ComponentInit>(OnInvisibilityInit);
SubscribeLocalEvent<InvisibilityComponent, ComponentRemove>(OnInvisibilityRemove);
SubscribeLocalEvent<InvisibilityComponent, ToggleInvisibilityActionEvent>(OnToggleGhosts);
SubscribeNetworkEvent<InvisibilityToggleEvent>(OnInvisibilityToggle);
}
private void OnInvisibilityToggle(InvisibilityToggleEvent ev)
{
if (!EntityManager.TryGetComponent(ev.Uid, out SpriteComponent? sprite))
return;
var newAlpha = Math.Clamp(ev.Invisible ? sprite.Color.A / 3f : sprite.Color.A * 3f, 0f, 1f);
sprite.Color = sprite.Color.WithAlpha(newAlpha);
}
private void OnInvisibilityInit(EntityUid uid, InvisibilityComponent component, ComponentInit args)
{
_actions.AddAction(uid, component.ToggleInvisibilityAction, null);
}
private void OnInvisibilityRemove(EntityUid uid, InvisibilityComponent component, ComponentRemove args)
{
_actions.RemoveAction(uid, component.ToggleInvisibilityAction);
}
private void OnToggleGhosts(EntityUid uid, InvisibilityComponent component, ToggleInvisibilityActionEvent args)
{
if (args.Handled)
return;
_popup.PopupEntity("Невидимость переключена", args.Performer);
_console.RemoteExecuteCommand(null, "invisibility");
args.Handled = true;
}
}

View File

@@ -21,24 +21,34 @@ public sealed class AdminWhoCommand : IConsoleCommand
var sb = new StringBuilder();
var first = true;
// WD start
var isAdmin = shell.Player is {} player && adminMgr.HasAdminFlag(player, AdminFlags.Admin);
foreach (var admin in adminMgr.ActiveAdmins)
{
var adminData = adminMgr.GetAdminData(admin)!;
DebugTools.AssertNotNull(adminData);
if (!isAdmin && adminData.Stealth)
continue;
if (!first)
sb.Append('\n');
first = false;
var adminData = adminMgr.GetAdminData(admin)!;
DebugTools.AssertNotNull(adminData);
sb.Append(admin.Name);
if (adminData.Title is { } title)
sb.Append($": [{title}]");
if (shell.Player is { } player && adminMgr.HasAdminFlag(player, AdminFlags.Admin))
{
if (afk.IsAfk(admin))
sb.Append(" [AFK]");
}
if (!isAdmin)
continue;
if (afk.IsAfk(admin))
sb.Append(" [AFK]");
if (adminData.Stealth)
sb.Append(" [Stealth]");
// WD end
}
shell.WriteLine(sb.ToString());

View File

@@ -418,7 +418,7 @@ namespace Content.Server.Administration.Systems
bwoinkText = $"{senderSession.Name}: {escapedText}";
}
var msg = new BwoinkTextMessage(message.UserId, senderSession.UserId, bwoinkText);
var msg = new BwoinkTextMessage(message.UserId, senderSession.UserId, bwoinkText, senderAHelpAdmin);
LogBwoink(msg);
@@ -487,7 +487,7 @@ namespace Content.Server.Administration.Systems
// No admin online, let the player know
var systemText = Loc.GetString("bwoink-system-starmute-message-no-other-users");
var starMuteMsg = new BwoinkTextMessage(message.UserId, SystemUserId, systemText);
var starMuteMsg = new BwoinkTextMessage(message.UserId, SystemUserId, systemText, senderAHelpAdmin);
RaiseNetworkEvent(starMuteMsg, senderSession.ConnectedClient);
}
@@ -592,7 +592,7 @@ namespace Content.Server.Administration.Systems
{
var bwoinkText = $"[color=red](D) {sender}[/color]: {text}";
_playerManager.TryGetUserId(sender, out var senderId);
var msg = new BwoinkTextMessage(receiver, senderId, bwoinkText);
var msg = new BwoinkTextMessage(receiver, senderId, bwoinkText, true);
LogBwoink(msg);

View File

@@ -58,6 +58,7 @@ public sealed partial class ChatSystem : SharedChatSystem
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
[Dependency] private readonly ReplacementAccentSystem _wordreplacement = default!;
[Dependency] private readonly INetConfigurationManager _netConfigurationManager = default!; // WD
//WD-EDIT
[Dependency] private readonly UtkaTCPWrapper _utkaSockets = default!;
@@ -667,7 +668,8 @@ public sealed partial class ChatSystem : SharedChatSystem
var clients = GetDeadChatClients();
var playerName = Name(source);
string wrappedMessage;
if (_adminManager.IsAdmin(player))
if (_adminManager.IsAdmin(player) &&
_netConfigurationManager.GetClientCVar(player.ConnectedClient, WhiteCVars.DeadChatAdmin)) // WD
{
wrappedMessage = Loc.GetString("chat-manager-send-admin-dead-chat-wrap-message",
("adminChannelName", Loc.GetString("chat-manager-admin-channel-name")),

View File

@@ -21,6 +21,9 @@ using Content.Shared.Mobs.Systems;
using Content.Shared.Movement.Events;
using Content.Shared.Movement.Systems;
using Content.Shared.Storage.Components;
using Content.Shared.White;
using Content.Shared.White.Administration;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Content.Shared.White;

View File

@@ -0,0 +1,60 @@
using Content.Server.Ghost.Components;
using Content.Shared.Eye;
using Content.Shared.Follower;
using Content.Shared.Ghost;
using Content.Shared.White.Administration;
using Robust.Server.GameObjects;
namespace Content.Server.White.Administration;
public sealed class InvisibilitySystem : SharedInvisibilitySystem
{
[Dependency] private readonly VisibilitySystem _visibilitySystem = default!;
[Dependency] private readonly FollowerSystem _followerSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<InvisibilityComponent, ComponentStartup>(OnInvisibilityStartup);
SubscribeLocalEvent<InvisibilityComponent, ComponentShutdown>(OnInvisibilityShutdown);
}
private void OnInvisibilityStartup(EntityUid uid, InvisibilityComponent component, ComponentStartup args)
{
if (EntityManager.TryGetComponent(uid, out EyeComponent? eye))
{
eye.VisibilityMask |= (int) VisibilityFlags.AdminInvisible;
}
}
private void OnInvisibilityShutdown(EntityUid uid, InvisibilityComponent component, ComponentShutdown args)
{
if (EntityManager.TryGetComponent(uid, out VisibilityComponent? visibility))
{
_visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.AdminInvisible);
}
if (EntityManager.TryGetComponent(uid, out EyeComponent? eye))
{
eye.VisibilityMask &= ~(int) VisibilityFlags.AdminInvisible;
}
}
public void ToggleInvisibility(EntityUid uid, InvisibilityComponent component)
{
if (!EntityManager.TryGetComponent(uid, out VisibilityComponent? visibility))
return;
_followerSystem.StopAllFollowers(uid);
component.Invisible = !component.Invisible;
_visibilitySystem.SetLayer((uid, visibility),
(ushort) (component.Invisible ? VisibilityFlags.AdminInvisible :
EntityManager.HasComponent<GhostComponent>(uid) ? VisibilityFlags.Ghost : VisibilityFlags.Normal
));
RaiseNetworkEvent(new InvisibilityToggleEvent(uid, component.Invisible));
}
}

View File

@@ -0,0 +1,29 @@
using Content.Server.Administration;
using Content.Server.White.Administration;
using Content.Shared.Administration;
using Content.Shared.White.Administration;
using Robust.Shared.Console;
namespace Content.Server.White.Commands;
[AdminCommand(AdminFlags.Admin)]
public sealed class InvisibilityCommand : IConsoleCommand
{
public string Command => "invisibility";
public string Description => "Переключает режим невидимости.";
public string Help => "invisibility";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (shell.Player == null)
shell.WriteLine("You can only toggle invisibility on a client.");
var entityManager = IoCManager.Resolve<EntityManager>();
var uid = shell.Player?.AttachedEntity;
if (uid == null
|| !entityManager.TryGetComponent<InvisibilityComponent>(uid, out var invisibilityComponent))
return;
entityManager.System<InvisibilitySystem>().ToggleInvisibility(uid.Value, invisibilityComponent);
}
}

View File

@@ -0,0 +1,35 @@
using Content.Server.Administration;
using Content.Server.Administration.Managers;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
using Robust.Shared.Utility;
namespace Content.Server.White.Commands;
[AdminCommand(AdminFlags.Admin)]
public sealed class StealthCommand : IConsoleCommand
{
public string Command => "stealth";
public string Description => "Переключает стелс режим.";
public string Help => "stealth";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (shell.Player is not IPlayerSession player)
{
shell.WriteLine("You cannot use this command from the server console.");
return;
}
var mgr = IoCManager.Resolve<IAdminManager>();
var data = mgr.GetAdminData(player)!;
DebugTools.AssertNotNull(data);
data.Stealth = !data.Stealth;
shell.WriteLine(data.Stealth
? "Теперь вы в режиме стелс"
: "Теперь вы не в режиме стелс");
}
}

View File

@@ -12,6 +12,8 @@ namespace Content.Shared.Administration
/// </summary>
public bool Active;
public bool Stealth; // WD
/// <summary>
/// The admin's title.
/// </summary>

View File

@@ -38,12 +38,16 @@ namespace Content.Shared.Administration
public NetUserId TrueSender { get; }
public string Text { get; }
public BwoinkTextMessage(NetUserId userId, NetUserId trueSender, string text, DateTime? sentAt = default)
public bool IsAdmin { get; }
public BwoinkTextMessage(NetUserId userId, NetUserId trueSender, string text, bool isAdmin,
DateTime? sentAt = default)
{
SentAt = sentAt ?? DateTime.Now;
UserId = userId;
TrueSender = trueSender;
Text = text;
IsAdmin = isAdmin;
}
}
}

View File

@@ -9,5 +9,6 @@ namespace Content.Shared.Eye
None = 0,
Normal = 1 << 0,
Ghost = 1 << 1,
AdminInvisible = 1 << 2,
}
}

View File

@@ -7,6 +7,7 @@ using Content.Shared.Movement.Events;
using Content.Shared.Physics.Pull;
using Content.Shared.Tag;
using Content.Shared.Verbs;
using Content.Shared.White.Administration;
using Robust.Shared.Containers;
using Robust.Shared.Map;
using Robust.Shared.Map.Events;
@@ -128,6 +129,11 @@ public sealed class FollowerSystem : EntitySystem
/// <param name="entity">The entity to be followed</param>
public void StartFollowingEntity(EntityUid follower, EntityUid entity)
{
// WD
if (!EntityManager.HasComponent<InvisibilityComponent>(follower) &&
EntityManager.TryGetComponent(entity, out InvisibilityComponent? component) && component.Invisible)
return;
// No recursion for you
var targetXform = Transform(entity);
while (targetXform.ParentUid.IsValid())

View File

@@ -0,0 +1,26 @@
using Content.Shared.Actions;
using Content.Shared.Actions.ActionTypes;
using Robust.Shared.Utility;
namespace Content.Shared.White.Administration;
[RegisterComponent]
[Access(typeof(SharedInvisibilitySystem))]
public sealed class InvisibilityComponent : Component
{
public bool Invisible;
public readonly InstantAction ToggleInvisibilityAction = new()
{
Icon = new SpriteSpecifier.Texture(new("White/Icons/transparent-ghost.png")),
DisplayName = "Переключить невидимость",
Description = "Переключить невидимость вашего призрака.",
ClientExclusive = true,
CheckCanInteract = false,
Event = new ToggleInvisibilityActionEvent()
};
}
public sealed class ToggleInvisibilityActionEvent : InstantActionEvent
{
}

View File

@@ -0,0 +1,20 @@
using Robust.Shared.Serialization;
namespace Content.Shared.White.Administration;
public abstract class SharedInvisibilitySystem : EntitySystem
{
}
[Serializable, NetSerializable]
public sealed class InvisibilityToggleEvent : EntityEventArgs
{
public EntityUid Uid { get; }
public bool Invisible { get; }
public InvisibilityToggleEvent(EntityUid uid, bool invisible)
{
Uid = uid;
Invisible = invisible;
}
}

View File

@@ -181,6 +181,13 @@ public sealed class WhiteCVars
public static readonly CVarDef<string> DefaultChatSize =
CVarDef.Create("white.chat_size_default", "300;500", CVar.CLIENTONLY | CVar.ARCHIVE);
/*
* Mark dead chat messages as admin
*/
public static readonly CVarDef<bool> DeadChatAdmin =
CVarDef.Create("white.admin.deadChatAdmin", false, CVar.CLIENT | CVar.REPLICATED | CVar.ARCHIVE);
/*
* End of round stats
*/

View File

@@ -88,6 +88,7 @@
damageContainers:
- Biological
- type: ShowWhiteHealthBars
- type: Invisibility
- type: entity
id: ActionAGhostShowSolar

Binary file not shown.

After

Width:  |  Height:  |  Size: 732 B