Persist deadmin to database, add admin suspension system (#34048)
This commit is contained in:
committed by
GitHub
parent
47042cc8dd
commit
c2e050ced0
@@ -130,6 +130,7 @@ namespace Content.Client.Administration.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
var title = string.IsNullOrWhiteSpace(popup.TitleEdit.Text) ? null : popup.TitleEdit.Text;
|
var title = string.IsNullOrWhiteSpace(popup.TitleEdit.Text) ? null : popup.TitleEdit.Text;
|
||||||
|
var suspended = popup.SuspendedCheckbox.Pressed;
|
||||||
|
|
||||||
if (popup.SourceData is { } src)
|
if (popup.SourceData is { } src)
|
||||||
{
|
{
|
||||||
@@ -139,7 +140,8 @@ namespace Content.Client.Administration.UI
|
|||||||
Title = title,
|
Title = title,
|
||||||
PosFlags = pos,
|
PosFlags = pos,
|
||||||
NegFlags = neg,
|
NegFlags = neg,
|
||||||
RankId = rank
|
RankId = rank,
|
||||||
|
Suspended = suspended,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -152,7 +154,8 @@ namespace Content.Client.Administration.UI
|
|||||||
Title = title,
|
Title = title,
|
||||||
PosFlags = pos,
|
PosFlags = pos,
|
||||||
NegFlags = neg,
|
NegFlags = neg,
|
||||||
RankId = rank
|
RankId = rank,
|
||||||
|
Suspended = suspended,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +174,7 @@ namespace Content.Client.Administration.UI
|
|||||||
{
|
{
|
||||||
Id = src,
|
Id = src,
|
||||||
Flags = flags,
|
Flags = flags,
|
||||||
Name = name
|
Name = name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -351,6 +354,7 @@ namespace Content.Client.Administration.UI
|
|||||||
public readonly OptionButton RankButton;
|
public readonly OptionButton RankButton;
|
||||||
public readonly Button SaveButton;
|
public readonly Button SaveButton;
|
||||||
public readonly Button? RemoveButton;
|
public readonly Button? RemoveButton;
|
||||||
|
public readonly CheckBox SuspendedCheckbox;
|
||||||
|
|
||||||
public readonly Dictionary<AdminFlags, (Button inherit, Button sub, Button plus)> FlagButtons
|
public readonly Dictionary<AdminFlags, (Button inherit, Button sub, Button plus)> FlagButtons
|
||||||
= new();
|
= new();
|
||||||
@@ -381,6 +385,12 @@ namespace Content.Client.Administration.UI
|
|||||||
RankButton = new OptionButton();
|
RankButton = new OptionButton();
|
||||||
SaveButton = new Button { Text = Loc.GetString("permissions-eui-edit-admin-window-save-button"), HorizontalAlignment = HAlignment.Right };
|
SaveButton = new Button { Text = Loc.GetString("permissions-eui-edit-admin-window-save-button"), HorizontalAlignment = HAlignment.Right };
|
||||||
|
|
||||||
|
SuspendedCheckbox = new CheckBox
|
||||||
|
{
|
||||||
|
Text = Loc.GetString("permissions-eui-edit-admin-window-suspended"),
|
||||||
|
Pressed = data?.Suspended ?? false,
|
||||||
|
};
|
||||||
|
|
||||||
RankButton.AddItem(Loc.GetString("permissions-eui-edit-admin-window-no-rank-button"), NoRank);
|
RankButton.AddItem(Loc.GetString("permissions-eui-edit-admin-window-no-rank-button"), NoRank);
|
||||||
foreach (var (rId, rank) in ui._ranks)
|
foreach (var (rId, rank) in ui._ranks)
|
||||||
{
|
{
|
||||||
@@ -488,7 +498,8 @@ namespace Content.Client.Administration.UI
|
|||||||
{
|
{
|
||||||
nameControl,
|
nameControl,
|
||||||
TitleEdit,
|
TitleEdit,
|
||||||
RankButton
|
RankButton,
|
||||||
|
SuspendedCheckbox,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
permGrid
|
permGrid
|
||||||
|
|||||||
2084
Content.Server.Database/Migrations/Postgres/20241223235939_AdminStatus.Designer.cs
generated
Normal file
2084
Content.Server.Database/Migrations/Postgres/20241223235939_AdminStatus.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Content.Server.Database.Migrations.Postgres
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AdminStatus : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "deadminned",
|
||||||
|
table: "admin",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "suspended",
|
||||||
|
table: "admin",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "deadminned",
|
||||||
|
table: "admin");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "suspended",
|
||||||
|
table: "admin");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,6 +36,14 @@ namespace Content.Server.Database.Migrations.Postgres
|
|||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("admin_rank_id");
|
.HasColumnName("admin_rank_id");
|
||||||
|
|
||||||
|
b.Property<bool>("Deadminned")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("deadminned");
|
||||||
|
|
||||||
|
b.Property<bool>("Suspended")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("suspended");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("title");
|
.HasColumnName("title");
|
||||||
|
|||||||
2007
Content.Server.Database/Migrations/Sqlite/20241223235932_AdminStatus.Designer.cs
generated
Normal file
2007
Content.Server.Database/Migrations/Sqlite/20241223235932_AdminStatus.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Content.Server.Database.Migrations.Sqlite
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AdminStatus : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "deadminned",
|
||||||
|
table: "admin",
|
||||||
|
type: "INTEGER",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "suspended",
|
||||||
|
table: "admin",
|
||||||
|
type: "INTEGER",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "deadminned",
|
||||||
|
table: "admin");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "suspended",
|
||||||
|
table: "admin");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,14 @@ namespace Content.Server.Database.Migrations.Sqlite
|
|||||||
.HasColumnType("INTEGER")
|
.HasColumnType("INTEGER")
|
||||||
.HasColumnName("admin_rank_id");
|
.HasColumnName("admin_rank_id");
|
||||||
|
|
||||||
|
b.Property<bool>("Deadminned")
|
||||||
|
.HasColumnType("INTEGER")
|
||||||
|
.HasColumnName("deadminned");
|
||||||
|
|
||||||
|
b.Property<bool>("Suspended")
|
||||||
|
.HasColumnType("INTEGER")
|
||||||
|
.HasColumnName("suspended");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasColumnType("TEXT")
|
.HasColumnType("TEXT")
|
||||||
.HasColumnName("title");
|
.HasColumnName("title");
|
||||||
|
|||||||
@@ -610,6 +610,16 @@ namespace Content.Server.Database
|
|||||||
[Key] public Guid UserId { get; set; }
|
[Key] public Guid UserId { get; set; }
|
||||||
public string? Title { get; set; }
|
public string? Title { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, the admin is voluntarily deadminned. They can re-admin at any time.
|
||||||
|
/// </summary>
|
||||||
|
public bool Deadminned { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, the admin is suspended by an admin with <c>PERMISSIONS</c>. They will not have in-game permissions.
|
||||||
|
/// </summary>
|
||||||
|
public bool Suspended { get; set; }
|
||||||
|
|
||||||
public int? AdminRankId { get; set; }
|
public int? AdminRankId { get; set; }
|
||||||
public AdminRank? AdminRank { get; set; }
|
public AdminRank? AdminRank { get; set; }
|
||||||
public List<AdminFlag> Flags { get; set; } = default!;
|
public List<AdminFlag> Flags { get; set; } = default!;
|
||||||
|
|||||||
@@ -91,14 +91,29 @@ namespace Content.Server.Administration.Managers
|
|||||||
_chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-de-admin-message", ("exAdminName", session.Name)));
|
_chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-de-admin-message", ("exAdminName", session.Name)));
|
||||||
_chat.DispatchServerMessage(session, Loc.GetString("admin-manager-became-normal-player-message"));
|
_chat.DispatchServerMessage(session, Loc.GetString("admin-manager-became-normal-player-message"));
|
||||||
|
|
||||||
var plyData = session.ContentData()!;
|
UpdateDatabaseDeadminnedState(session, true);
|
||||||
plyData.ExplicitlyDeadminned = true;
|
|
||||||
reg.Data.Active = false;
|
reg.Data.Active = false;
|
||||||
|
|
||||||
SendPermsChangedEvent(session);
|
SendPermsChangedEvent(session);
|
||||||
UpdateAdminStatus(session);
|
UpdateAdminStatus(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void UpdateDatabaseDeadminnedState(ICommonSession player, bool newState)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// NOTE: This function gets called if you deadmin/readmin from a transient admin status.
|
||||||
|
// (e.g. loginlocal)
|
||||||
|
// In which case there may not be a database record.
|
||||||
|
// The DB function handles this scenario fine, but it's worth noting.
|
||||||
|
await _dbManager.UpdateAdminDeadminnedAsync(player.UserId, newState);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_sawmill.Error("Failed to save deadmin state to database for {Admin}", player.UserId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Stealth(ICommonSession session)
|
public void Stealth(ICommonSession session)
|
||||||
{
|
{
|
||||||
if (!_admins.TryGetValue(session, out var reg))
|
if (!_admins.TryGetValue(session, out var reg))
|
||||||
@@ -151,8 +166,7 @@ namespace Content.Server.Administration.Managers
|
|||||||
|
|
||||||
_chat.DispatchServerMessage(session, Loc.GetString("admin-manager-became-admin-message"));
|
_chat.DispatchServerMessage(session, Loc.GetString("admin-manager-became-admin-message"));
|
||||||
|
|
||||||
var plyData = session.ContentData()!;
|
UpdateDatabaseDeadminnedState(session, false);
|
||||||
plyData.ExplicitlyDeadminned = false;
|
|
||||||
reg.Data.Active = true;
|
reg.Data.Active = true;
|
||||||
|
|
||||||
if (!reg.Data.Stealth)
|
if (!reg.Data.Stealth)
|
||||||
@@ -208,14 +222,14 @@ namespace Content.Server.Administration.Managers
|
|||||||
curAdmin.IsSpecialLogin = special;
|
curAdmin.IsSpecialLogin = special;
|
||||||
curAdmin.RankId = rankId;
|
curAdmin.RankId = rankId;
|
||||||
curAdmin.Data = aData;
|
curAdmin.Data = aData;
|
||||||
}
|
|
||||||
|
|
||||||
if (!player.ContentData()!.ExplicitlyDeadminned)
|
if (curAdmin.Data.Active)
|
||||||
{
|
{
|
||||||
aData.Active = true;
|
aData.Active = true;
|
||||||
|
|
||||||
_chat.DispatchServerMessage(player, Loc.GetString("admin-manager-admin-permissions-updated-message"));
|
_chat.DispatchServerMessage(player, Loc.GetString("admin-manager-admin-permissions-updated-message"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (player.ContentData()!.Stealthed)
|
if (player.ContentData()!.Stealthed)
|
||||||
{
|
{
|
||||||
@@ -381,10 +395,8 @@ namespace Content.Server.Administration.Managers
|
|||||||
if (session.ContentData()!.Stealthed)
|
if (session.ContentData()!.Stealthed)
|
||||||
reg.Data.Stealth = true;
|
reg.Data.Stealth = true;
|
||||||
|
|
||||||
if (!session.ContentData()!.ExplicitlyDeadminned)
|
if (reg.Data.Active)
|
||||||
{
|
{
|
||||||
reg.Data.Active = true;
|
|
||||||
|
|
||||||
if (_cfg.GetCVar(CCVars.AdminAnnounceLogin))
|
if (_cfg.GetCVar(CCVars.AdminAnnounceLogin))
|
||||||
{
|
{
|
||||||
if (reg.Data.Stealth)
|
if (reg.Data.Stealth)
|
||||||
@@ -430,6 +442,7 @@ namespace Content.Server.Administration.Managers
|
|||||||
{
|
{
|
||||||
Title = Loc.GetString("admin-manager-admin-data-host-title"),
|
Title = Loc.GetString("admin-manager-admin-data-host-title"),
|
||||||
Flags = AdminFlagsHelper.Everything,
|
Flags = AdminFlagsHelper.Everything,
|
||||||
|
Active = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (data, null, true);
|
return (data, null, true);
|
||||||
@@ -444,6 +457,12 @@ namespace Content.Server.Administration.Managers
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dbData.Suspended)
|
||||||
|
{
|
||||||
|
// Suspended admins don't count.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var flags = AdminFlags.None;
|
var flags = AdminFlags.None;
|
||||||
|
|
||||||
if (dbData.AdminRank != null)
|
if (dbData.AdminRank != null)
|
||||||
@@ -466,7 +485,8 @@ namespace Content.Server.Administration.Managers
|
|||||||
|
|
||||||
var data = new AdminData
|
var data = new AdminData
|
||||||
{
|
{
|
||||||
Flags = flags
|
Flags = flags,
|
||||||
|
Active = !dbData.Deadminned,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (dbData.Title != null && _cfg.GetCVar(CCVars.AdminUseCustomNamesAdminRank))
|
if (dbData.Title != null && _cfg.GetCVar(CCVars.AdminUseCustomNamesAdminRank))
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ namespace Content.Server.Administration.UI
|
|||||||
Title = p.a.Title,
|
Title = p.a.Title,
|
||||||
RankId = p.a.AdminRankId,
|
RankId = p.a.AdminRankId,
|
||||||
UserId = new NetUserId(p.a.UserId),
|
UserId = new NetUserId(p.a.UserId),
|
||||||
UserName = p.lastUserName
|
UserName = p.lastUserName,
|
||||||
|
Suspended = p.a.Suspended,
|
||||||
}).ToArray(),
|
}).ToArray(),
|
||||||
|
|
||||||
AdminRanks = _adminRanks.ToDictionary(a => a.Id, a => new PermissionsEuiState.AdminRankData
|
AdminRanks = _adminRanks.ToDictionary(a => a.Id, a => new PermissionsEuiState.AdminRankData
|
||||||
@@ -255,6 +256,7 @@ namespace Content.Server.Administration.UI
|
|||||||
admin.Title = ua.Title;
|
admin.Title = ua.Title;
|
||||||
admin.AdminRankId = ua.RankId;
|
admin.AdminRankId = ua.RankId;
|
||||||
admin.Flags = GenAdminFlagList(ua.PosFlags, ua.NegFlags);
|
admin.Flags = GenAdminFlagList(ua.PosFlags, ua.NegFlags);
|
||||||
|
admin.Suspended = ua.Suspended;
|
||||||
|
|
||||||
await _db.UpdateAdminAsync(admin);
|
await _db.UpdateAdminAsync(admin);
|
||||||
|
|
||||||
@@ -335,7 +337,8 @@ namespace Content.Server.Administration.UI
|
|||||||
Flags = GenAdminFlagList(ca.PosFlags, ca.NegFlags),
|
Flags = GenAdminFlagList(ca.PosFlags, ca.NegFlags),
|
||||||
AdminRankId = ca.RankId,
|
AdminRankId = ca.RankId,
|
||||||
UserId = userId.UserId,
|
UserId = userId.UserId,
|
||||||
Title = ca.Title
|
Title = ca.Title,
|
||||||
|
Suspended = ca.Suspended,
|
||||||
};
|
};
|
||||||
|
|
||||||
await _db.AddAdminAsync(admin);
|
await _db.AddAdminAsync(admin);
|
||||||
|
|||||||
@@ -751,6 +751,20 @@ namespace Content.Server.Database
|
|||||||
existing.Flags = admin.Flags;
|
existing.Flags = admin.Flags;
|
||||||
existing.Title = admin.Title;
|
existing.Title = admin.Title;
|
||||||
existing.AdminRankId = admin.AdminRankId;
|
existing.AdminRankId = admin.AdminRankId;
|
||||||
|
existing.Deadminned = admin.Deadminned;
|
||||||
|
existing.Suspended = admin.Suspended;
|
||||||
|
|
||||||
|
await db.DbContext.SaveChangesAsync(cancel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateAdminDeadminnedAsync(NetUserId userId, bool deadminned, CancellationToken cancel)
|
||||||
|
{
|
||||||
|
await using var db = await GetDb(cancel);
|
||||||
|
|
||||||
|
var adminRecord = db.DbContext.Admin.Where(a => a.UserId == userId);
|
||||||
|
await adminRecord.ExecuteUpdateAsync(
|
||||||
|
set => set.SetProperty(p => p.Deadminned, deadminned),
|
||||||
|
cancellationToken: cancel);
|
||||||
|
|
||||||
await db.DbContext.SaveChangesAsync(cancel);
|
await db.DbContext.SaveChangesAsync(cancel);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,6 +217,16 @@ namespace Content.Server.Database
|
|||||||
Task AddAdminAsync(Admin admin, CancellationToken cancel = default);
|
Task AddAdminAsync(Admin admin, CancellationToken cancel = default);
|
||||||
Task UpdateAdminAsync(Admin admin, CancellationToken cancel = default);
|
Task UpdateAdminAsync(Admin admin, CancellationToken cancel = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update whether an admin has voluntarily deadminned.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This does nothing if the player is not an admin.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="userId">The user ID of the admin.</param>
|
||||||
|
/// <param name="deadminned">Whether the admin is deadminned or not.</param>
|
||||||
|
Task UpdateAdminDeadminnedAsync(NetUserId userId, bool deadminned, CancellationToken cancel = default);
|
||||||
|
|
||||||
Task RemoveAdminRankAsync(int rankId, CancellationToken cancel = default);
|
Task RemoveAdminRankAsync(int rankId, CancellationToken cancel = default);
|
||||||
Task AddAdminRankAsync(AdminRank rank, CancellationToken cancel = default);
|
Task AddAdminRankAsync(AdminRank rank, CancellationToken cancel = default);
|
||||||
Task UpdateAdminRankAsync(AdminRank rank, CancellationToken cancel = default);
|
Task UpdateAdminRankAsync(AdminRank rank, CancellationToken cancel = default);
|
||||||
@@ -674,6 +684,12 @@ namespace Content.Server.Database
|
|||||||
return RunDbCommand(() => _db.UpdateAdminAsync(admin, cancel));
|
return RunDbCommand(() => _db.UpdateAdminAsync(admin, cancel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task UpdateAdminDeadminnedAsync(NetUserId userId, bool deadminned, CancellationToken cancel = default)
|
||||||
|
{
|
||||||
|
DbWriteOpsMetric.Inc();
|
||||||
|
return RunDbCommand(() => _db.UpdateAdminDeadminnedAsync(userId, deadminned, cancel));
|
||||||
|
}
|
||||||
|
|
||||||
public Task RemoveAdminRankAsync(int rankId, CancellationToken cancel = default)
|
public Task RemoveAdminRankAsync(int rankId, CancellationToken cancel = default)
|
||||||
{
|
{
|
||||||
DbWriteOpsMetric.Inc();
|
DbWriteOpsMetric.Inc();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ namespace Content.Shared.Administration
|
|||||||
public NetUserId UserId;
|
public NetUserId UserId;
|
||||||
public string? UserName;
|
public string? UserName;
|
||||||
public string? Title;
|
public string? Title;
|
||||||
|
public bool Suspended;
|
||||||
public AdminFlags PosFlags;
|
public AdminFlags PosFlags;
|
||||||
public AdminFlags NegFlags;
|
public AdminFlags NegFlags;
|
||||||
public int? RankId;
|
public int? RankId;
|
||||||
@@ -41,6 +42,7 @@ namespace Content.Shared.Administration
|
|||||||
public AdminFlags PosFlags;
|
public AdminFlags PosFlags;
|
||||||
public AdminFlags NegFlags;
|
public AdminFlags NegFlags;
|
||||||
public int? RankId;
|
public int? RankId;
|
||||||
|
public bool Suspended;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
@@ -57,6 +59,7 @@ namespace Content.Shared.Administration
|
|||||||
public AdminFlags PosFlags;
|
public AdminFlags PosFlags;
|
||||||
public AdminFlags NegFlags;
|
public AdminFlags NegFlags;
|
||||||
public int? RankId;
|
public int? RankId;
|
||||||
|
public bool Suspended;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -32,12 +32,6 @@ public sealed class ContentPlayerData
|
|||||||
[ViewVariables, Access(typeof(SharedMindSystem), typeof(SharedGameTicker))]
|
[ViewVariables, Access(typeof(SharedMindSystem), typeof(SharedGameTicker))]
|
||||||
public EntityUid? Mind { get; set; }
|
public EntityUid? Mind { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// If true, the player is an admin and they explicitly de-adminned mid-game,
|
|
||||||
/// so they should not regain admin if they reconnect.
|
|
||||||
/// </summary>
|
|
||||||
public bool ExplicitlyDeadminned { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If true, the admin will not show up in adminwho except to admins with the <see cref="AdminFlags.Stealth"/> flag.
|
/// If true, the admin will not show up in adminwho except to admins with the <see cref="AdminFlags.Stealth"/> flag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ permissions-eui-edit-admin-window-title-edit-placeholder = Custom title, leave b
|
|||||||
permissions-eui-edit-admin-window-no-rank-button = No rank
|
permissions-eui-edit-admin-window-no-rank-button = No rank
|
||||||
permissions-eui-edit-admin-rank-window-name-edit-placeholder = Rank name
|
permissions-eui-edit-admin-rank-window-name-edit-placeholder = Rank name
|
||||||
permissions-eui-edit-admin-title-control-text = none
|
permissions-eui-edit-admin-title-control-text = none
|
||||||
|
permissions-eui-edit-admin-window-suspended = Suspended?
|
||||||
permissions-eui-edit-no-rank-text = none
|
permissions-eui-edit-no-rank-text = none
|
||||||
permissions-eui-edit-title-button = Edit
|
permissions-eui-edit-title-button = Edit
|
||||||
permissions-eui-edit-admin-rank-button = Edit
|
permissions-eui-edit-admin-rank-button = Edit
|
||||||
|
|||||||
Reference in New Issue
Block a user