diff --git a/Content.Client/Administration/UI/Tabs/PanicBunkerTab/PanicBunkerTab.xaml b/Content.Client/Administration/UI/Tabs/PanicBunkerTab/PanicBunkerTab.xaml
index f5b91ddde8f..ee7ba4d34ff 100644
--- a/Content.Client/Administration/UI/Tabs/PanicBunkerTab/PanicBunkerTab.xaml
+++ b/Content.Client/Administration/UI/Tabs/PanicBunkerTab/PanicBunkerTab.xaml
@@ -38,11 +38,6 @@
-
-
-
-
-
diff --git a/Content.Client/Administration/UI/Tabs/PanicBunkerTab/PanicBunkerTab.xaml.cs b/Content.Client/Administration/UI/Tabs/PanicBunkerTab/PanicBunkerTab.xaml.cs
index 81982452a31..c3bcf3ffa09 100644
--- a/Content.Client/Administration/UI/Tabs/PanicBunkerTab/PanicBunkerTab.xaml.cs
+++ b/Content.Client/Administration/UI/Tabs/PanicBunkerTab/PanicBunkerTab.xaml.cs
@@ -1,5 +1,4 @@
-using Content.Corvax.Interfaces.Shared;
-using Content.Shared.Administration.Events;
+using Content.Shared.Administration.Events;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.XAML;
@@ -29,14 +28,6 @@ public PanicBunkerTab()
MinOverallMinutes.OnTextEntered += args => SendMinOverallMinutes(args.Text);
MinOverallMinutes.OnFocusExit += args => SendMinOverallMinutes(args.Text);
_minOverallMinutes = MinOverallMinutes.Text;
- // Corvax-VPNGuard-Start
- var haveSecrets = IoCManager.Instance!.TryResolveType(out _); // TODO: Probably need better way to detect Secrets module
- if (haveSecrets)
- {
- VPNContainer.Visible = true;
- DenyVPN.OnPressed += _ => SendDenyVpn(DenyVPN.Pressed);
- }
- // Corvax-VPNGuard-End
}
private void SendMinAccountAge(string text)
@@ -63,13 +54,6 @@ private void SendMinOverallMinutes(string text)
_console.ExecuteCommand($"panicbunker_min_overall_minutes {minutes}");
}
- // Corvax-VPNGuard-Start
- private void SendDenyVpn(bool deny)
- {
- _console.ExecuteCommand($"panicbunker_deny_vpn {deny}");
- }
- // Corvax-VPNGuard-End
-
public void UpdateStatus(PanicBunkerStatus status)
{
EnabledButton.Pressed = status.Enabled;
@@ -89,6 +73,5 @@ public void UpdateStatus(PanicBunkerStatus status)
MinOverallMinutes.Text = status.MinOverallMinutes.ToString();
_minOverallMinutes = MinOverallMinutes.Text;
- DenyVPN.Pressed = status.DenyVpn; // Corvax-VPNGuard
}
}
diff --git a/Content.Client/Content.Client.csproj b/Content.Client/Content.Client.csproj
index 125bbac00df..956f2fd0351 100644
--- a/Content.Client/Content.Client.csproj
+++ b/Content.Client/Content.Client.csproj
@@ -22,8 +22,6 @@
-
-
diff --git a/Content.Client/Corvax/DiscordAuth/DiscordAuthGui.xaml b/Content.Client/Corvax/DiscordAuth/DiscordAuthGui.xaml
new file mode 100644
index 00000000000..389854ed529
--- /dev/null
+++ b/Content.Client/Corvax/DiscordAuth/DiscordAuthGui.xaml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/Corvax/DiscordAuth/DiscordAuthGui.xaml.cs b/Content.Client/Corvax/DiscordAuth/DiscordAuthGui.xaml.cs
new file mode 100644
index 00000000000..3427f5ff7f4
--- /dev/null
+++ b/Content.Client/Corvax/DiscordAuth/DiscordAuthGui.xaml.cs
@@ -0,0 +1,35 @@
+using Robust.Client.AutoGenerated;
+using Robust.Client.Console;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client.Corvax.DiscordAuth;
+
+[GenerateTypedNameReferences]
+public sealed partial class DiscordAuthGui : Control
+{
+ [Dependency] private readonly DiscordAuthManager _discordAuthManager = default!;
+ [Dependency] private readonly IClientConsoleHost _consoleHost = default!;
+
+ public DiscordAuthGui()
+ {
+ RobustXamlLoader.Load(this);
+ IoCManager.InjectDependencies(this);
+ LayoutContainer.SetAnchorPreset(this, LayoutContainer.LayoutPreset.Wide);
+
+ QuitButton.OnPressed += (_) =>
+ {
+ _consoleHost.ExecuteCommand("quit");
+ };
+
+ UrlEdit.Text = _discordAuthManager.AuthUrl;
+ OpenUrlButton.OnPressed += (_) =>
+ {
+ if (_discordAuthManager.AuthUrl != string.Empty)
+ {
+ IoCManager.Resolve().OpenUri(_discordAuthManager.AuthUrl);
+ }
+ };
+ }
+}
diff --git a/Content.Client/Corvax/DiscordAuth/DiscordAuthManager.cs b/Content.Client/Corvax/DiscordAuth/DiscordAuthManager.cs
new file mode 100644
index 00000000000..ea3944c8532
--- /dev/null
+++ b/Content.Client/Corvax/DiscordAuth/DiscordAuthManager.cs
@@ -0,0 +1,30 @@
+using System.Threading;
+using Content.Shared.Corvax.DiscordAuth;
+using Robust.Client.State;
+using Robust.Shared.Network;
+using Timer = Robust.Shared.Timing.Timer;
+
+namespace Content.Client.Corvax.DiscordAuth;
+
+public sealed class DiscordAuthManager
+{
+ [Dependency] private readonly IClientNetManager _netManager = default!;
+ [Dependency] private readonly IStateManager _stateManager = default!;
+
+ public string AuthUrl { get; private set; } = string.Empty;
+
+ public void Initialize()
+ {
+ _netManager.RegisterNetMessage();
+ _netManager.RegisterNetMessage(OnDiscordAuthRequired);
+ }
+
+ private void OnDiscordAuthRequired(MsgDiscordAuthRequired message)
+ {
+ if (_stateManager.CurrentState is not DiscordAuthState)
+ {
+ AuthUrl = message.AuthUrl;
+ _stateManager.RequestStateChange();
+ }
+ }
+}
diff --git a/Content.Client/Corvax/DiscordAuth/DiscordAuthState.cs b/Content.Client/Corvax/DiscordAuth/DiscordAuthState.cs
new file mode 100644
index 00000000000..b7512ec7fcd
--- /dev/null
+++ b/Content.Client/Corvax/DiscordAuth/DiscordAuthState.cs
@@ -0,0 +1,34 @@
+using System.Threading;
+using Content.Shared.Corvax.DiscordAuth;
+using Robust.Client.State;
+using Robust.Client.UserInterface;
+using Robust.Shared.Network;
+using Timer = Robust.Shared.Timing.Timer;
+
+namespace Content.Client.Corvax.DiscordAuth;
+
+public sealed class DiscordAuthState : State
+{
+ [Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
+ [Dependency] private readonly IClientNetManager _netManager = default!;
+
+ private DiscordAuthGui? _gui;
+ private readonly CancellationTokenSource _checkTimerCancel = new();
+
+ protected override void Startup()
+ {
+ _gui = new DiscordAuthGui();
+ _userInterfaceManager.StateRoot.AddChild(_gui);
+
+ Timer.SpawnRepeating(TimeSpan.FromSeconds(5), () =>
+ {
+ _netManager.ClientSendMessage(new MsgDiscordAuthCheck());
+ }, _checkTimerCancel.Token);
+ }
+
+ protected override void Shutdown()
+ {
+ _checkTimerCancel.Cancel();
+ _gui!.Dispose();
+ }
+}
diff --git a/Content.Client/Corvax/JoinQueue/JoinQueueManager.cs b/Content.Client/Corvax/JoinQueue/JoinQueueManager.cs
new file mode 100644
index 00000000000..78a5ed3de70
--- /dev/null
+++ b/Content.Client/Corvax/JoinQueue/JoinQueueManager.cs
@@ -0,0 +1,26 @@
+using Content.Shared.Corvax.JoinQueue;
+using Robust.Client.State;
+using Robust.Shared.Network;
+
+namespace Content.Client.Corvax.JoinQueue;
+
+public sealed class JoinQueueManager
+{
+ [Dependency] private readonly IClientNetManager _netManager = default!;
+ [Dependency] private readonly IStateManager _stateManager = default!;
+
+ public void Initialize()
+ {
+ _netManager.RegisterNetMessage(OnQueueUpdate);
+ }
+
+ private void OnQueueUpdate(MsgQueueUpdate msg)
+ {
+ if (_stateManager.CurrentState is not QueueState)
+ {
+ _stateManager.RequestStateChange();
+ }
+
+ ((QueueState) _stateManager.CurrentState).OnQueueUpdate(msg);
+ }
+}
\ No newline at end of file
diff --git a/Content.Client/Corvax/JoinQueue/QueueGui.xaml b/Content.Client/Corvax/JoinQueue/QueueGui.xaml
new file mode 100644
index 00000000000..5ad739b4f9f
--- /dev/null
+++ b/Content.Client/Corvax/JoinQueue/QueueGui.xaml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/Corvax/JoinQueue/QueueGui.xaml.cs b/Content.Client/Corvax/JoinQueue/QueueGui.xaml.cs
new file mode 100644
index 00000000000..391d464667a
--- /dev/null
+++ b/Content.Client/Corvax/JoinQueue/QueueGui.xaml.cs
@@ -0,0 +1,41 @@
+using Content.Shared.CCVar;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+using Robust.Shared.Configuration;
+
+namespace Content.Client.Corvax.JoinQueue;
+
+[GenerateTypedNameReferences]
+public sealed partial class QueueGui : Control
+{
+ [Dependency] private readonly IConfigurationManager _cfg = default!;
+
+ public event Action? QuitPressed;
+
+ public QueueGui()
+ {
+ RobustXamlLoader.Load(this);
+ IoCManager.InjectDependencies(this);
+ LayoutContainer.SetAnchorPreset(this, LayoutContainer.LayoutPreset.Wide);
+
+ QuitButton.OnPressed += (_) => QuitPressed?.Invoke();
+
+ // Disable "priority join" button on Steam builds
+ // since it violates Valve's rules about alternative storefronts.
+ PriorityJoinButton.Visible = !_cfg.GetCVar(CCVars.BrandingSteam);
+
+ PriorityJoinButton.OnPressed += (_) =>
+ {
+ var linkPatreon = _cfg.GetCVar(CCVars.InfoLinksPatreon);
+ IoCManager.Resolve().OpenUri(linkPatreon);
+ };
+ }
+
+ public void UpdateInfo(int total, int position)
+ {
+ QueueTotal.Text = total.ToString();
+ QueuePosition.Text = position.ToString();
+ }
+}
diff --git a/Content.Client/Corvax/JoinQueue/QueueState.cs b/Content.Client/Corvax/JoinQueue/QueueState.cs
new file mode 100644
index 00000000000..58ed4df0446
--- /dev/null
+++ b/Content.Client/Corvax/JoinQueue/QueueState.cs
@@ -0,0 +1,51 @@
+using Content.Shared.Corvax.JoinQueue;
+using Robust.Client.Console;
+using Robust.Client.GameObjects;
+using Robust.Client.State;
+using Robust.Client.UserInterface;
+using Robust.Shared.Audio.Systems;
+using Robust.Shared.Player;
+
+namespace Content.Client.Corvax.JoinQueue;
+
+public sealed class QueueState : State
+{
+ [Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
+ [Dependency] private readonly IClientConsoleHost _consoleHost = default!;
+ [Dependency] private readonly SharedAudioSystem _audio = default!;
+
+ private const string JoinSoundPath = "/Audio/Effects/voteding.ogg";
+
+ private QueueGui? _gui;
+
+ protected override void Startup()
+ {
+ _gui = new QueueGui();
+ _userInterfaceManager.StateRoot.AddChild(_gui);
+
+ _gui.QuitPressed += OnQuitPressed;
+ }
+
+ protected override void Shutdown()
+ {
+ _gui!.QuitPressed -= OnQuitPressed;
+ _gui.Dispose();
+
+ Ding();
+ }
+
+ private void Ding()
+ {
+ _audio.PlayGlobal(JoinSoundPath, Filter.Local(), false);
+ }
+
+ public void OnQueueUpdate(MsgQueueUpdate msg)
+ {
+ _gui?.UpdateInfo(msg.Total, msg.Position);
+ }
+
+ private void OnQuitPressed()
+ {
+ _consoleHost.ExecuteCommand("quit");
+ }
+}
diff --git a/Content.Client/Corvax/Sponsors/CheckSponsorClientSystem.cs b/Content.Client/Corvax/Sponsors/CheckSponsorClientSystem.cs
new file mode 100644
index 00000000000..5de2d5db241
--- /dev/null
+++ b/Content.Client/Corvax/Sponsors/CheckSponsorClientSystem.cs
@@ -0,0 +1,38 @@
+using System.Linq;
+using Content.Shared.Corvax.Sponsors;
+using Robust.Shared.Configuration;
+using Robust.Shared.Network;
+using Robust.Shared.Player;
+
+namespace Content.Client.Corvax.Sponsors
+{
+ public sealed class CheckSponsorClientSystem : EntitySystem
+ {
+ public bool IsSponsor = false;
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent(SetSponsorStatus);
+ }
+
+ private void SetSponsorStatus(CheckedUserSponsor ev)
+ {
+ IsSponsor = ev.IsSponsor;
+ }
+
+ public void TryCheckSponsor(string? player)
+ {
+ if (player != null)
+ {
+ var ev = new CheckUserSponsor(player);
+ RaiseNetworkEvent(ev);
+ }
+ }
+
+ public bool GetSponsorStatus()
+ {
+ return IsSponsor;
+ }
+
+ }
+}
diff --git a/Content.Client/Corvax/Sponsors/SponsorsManager.cs b/Content.Client/Corvax/Sponsors/SponsorsManager.cs
new file mode 100644
index 00000000000..b5e300d42aa
--- /dev/null
+++ b/Content.Client/Corvax/Sponsors/SponsorsManager.cs
@@ -0,0 +1,23 @@
+using System.Diagnostics.CodeAnalysis;
+using Content.Shared.Corvax.Sponsors;
+using Robust.Shared.Network;
+
+namespace Content.Client.Corvax.Sponsors;
+
+public sealed class SponsorsManager
+{
+ [Dependency] private readonly IClientNetManager _netMgr = default!;
+
+ private SponsorInfo? _info;
+
+ public void Initialize()
+ {
+ _netMgr.RegisterNetMessage(msg => _info = msg.Info);
+ }
+
+ public bool TryGetInfo([NotNullWhen(true)] out SponsorInfo? sponsor)
+ {
+ sponsor = _info;
+ return _info != null;
+ }
+}
diff --git a/Content.Client/Corvax/TTS/HumanoidProfileEditor.TTS.cs b/Content.Client/Corvax/TTS/HumanoidProfileEditor.TTS.cs
index bb61102c41f..4f6def64f84 100644
--- a/Content.Client/Corvax/TTS/HumanoidProfileEditor.TTS.cs
+++ b/Content.Client/Corvax/TTS/HumanoidProfileEditor.TTS.cs
@@ -1,15 +1,15 @@
using System.Linq;
+using Content.Client.Corvax.Sponsors;
using Content.Client.Corvax.TTS;
-using Content.Client.Lobby;
-using Content.Corvax.Interfaces.Shared;
using Content.Shared.Corvax.TTS;
using Content.Shared.Preferences;
+using Robust.Client.UserInterface;
+using Robust.Client.GameObjects;
namespace Content.Client.Lobby.UI;
public sealed partial class HumanoidProfileEditor
{
- private ISharedSponsorsManager? _sponsorsMgr;
private List _voiceList = new();
private void InitializeVoice()
@@ -27,8 +27,6 @@ private void InitializeVoice()
};
VoicePlayButton.OnPressed += _ => PlayPreviewTTS();
-
- IoCManager.Instance!.TryResolveType(out _sponsorsMgr);
}
private void UpdateTTSVoicesControls()
@@ -51,10 +49,9 @@ private void UpdateTTSVoicesControls()
if (firstVoiceChoiceId == 1)
firstVoiceChoiceId = i;
- if (_sponsorsMgr is null)
- continue;
- if (voice.SponsorOnly && _sponsorsMgr != null &&
- !_sponsorsMgr.GetClientPrototypes().Contains(voice.ID))
+ if (voice.SponsorOnly &&
+ IoCManager.Resolve().TryGetInfo(out var sponsor) &&
+ !sponsor.AllowedMarkings.Contains(voice.ID))
{
VoiceButton.SetItemDisabled(VoiceButton.GetIdx(i), true);
}
diff --git a/Content.Client/Entry/EntryPoint.cs b/Content.Client/Entry/EntryPoint.cs
index 0364e1f931f..7d1c454e57e 100644
--- a/Content.Client/Entry/EntryPoint.cs
+++ b/Content.Client/Entry/EntryPoint.cs
@@ -2,6 +2,9 @@
using Content.Client.Changelog;
using Content.Client.Chat.Managers;
using Content.Client.DebugMon;
+using Content.Client.Corvax.DiscordAuth;
+using Content.Client.Corvax.JoinQueue;
+using Content.Client.Corvax.Sponsors;
using Content.Client.Corvax.TTS;
using Content.Client.Options;
using Content.Client.Eui;
@@ -67,6 +70,9 @@ public sealed class EntryPoint : GameClient
[Dependency] private readonly ExtendedDisconnectInformationManager _extendedDisconnectInformation = default!;
[Dependency] private readonly JobRequirementsManager _jobRequirements = default!;
[Dependency] private readonly ContentLocalizationManager _contentLoc = default!;
+ [Dependency] private readonly SponsorsManager _sponsorsManager = default!; // Corvax-Sponsors
+ [Dependency] private readonly JoinQueueManager _queueManager = default!; // Corvax-Queue
+ [Dependency] private readonly DiscordAuthManager _discordAuthManager = default!; // Corvax-DiscordAuth
[Dependency] private readonly ContentReplayPlaybackManager _playbackMan = default!;
[Dependency] private readonly IResourceManager _resourceManager = default!;
[Dependency] private readonly IReplayLoadManager _replayLoad = default!;
@@ -161,6 +167,9 @@ public override void PostInit()
_voteManager.Initialize();
_userInterfaceManager.SetDefaultTheme("SS14DefaultTheme");
_userInterfaceManager.SetActiveTheme(_configManager.GetCVar(CVars.InterfaceTheme));
+ _sponsorsManager.Initialize(); // Corvax-Sponsors
+ _queueManager.Initialize(); // Corvax-Queue
+ _discordAuthManager.Initialize(); // Corvax-DiscordAuth
_documentParsingManager.Initialize();
_baseClient.RunLevelChanged += (_, args) =>
diff --git a/Content.Client/Humanoid/MarkingPicker.xaml.cs b/Content.Client/Humanoid/MarkingPicker.xaml.cs
index 885403aa563..8e331bed02d 100644
--- a/Content.Client/Humanoid/MarkingPicker.xaml.cs
+++ b/Content.Client/Humanoid/MarkingPicker.xaml.cs
@@ -1,5 +1,5 @@
using System.Linq;
-using Content.Corvax.Interfaces.Shared;
+using Content.Client.Corvax.Sponsors;
using Content.Shared.Humanoid;
using Content.Shared.Humanoid.Markings;
using Content.Shared.Humanoid.Prototypes;
@@ -19,7 +19,7 @@ public sealed partial class MarkingPicker : Control
{
[Dependency] private readonly MarkingManager _markingManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
- private ISharedSponsorsManager? _sponsorsManager; // Corvax-Sponsors
+ [Dependency] private readonly SponsorsManager _sponsorsManager = default!; // Corvax-Sponsors
public Action? OnMarkingAdded;
public Action? OnMarkingRemoved;
@@ -125,7 +125,6 @@ public MarkingPicker()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
- IoCManager.Instance!.TryResolveType(out _sponsorsManager); // Corvax-Sponsors
CMarkingCategoryButton.OnItemSelected += OnCategoryChange;
CMarkingsUnused.OnItemSelected += item =>
@@ -228,8 +227,14 @@ public void Populate(string filter)
var item = CMarkingsUnused.AddItem($"{GetMarkingName(marking)}", marking.Sprites[0].Frame0());
item.Metadata = marking;
// Corvax-Sponsors-Start
- if (marking.SponsorOnly && _sponsorsManager != null)
- item.Disabled = !_sponsorsManager.GetClientPrototypes().Contains(marking.ID);
+ if (marking.SponsorOnly)
+ {
+ item.Disabled = true;
+ if (_sponsorsManager.TryGetInfo(out var sponsor))
+ {
+ item.Disabled = !sponsor.AllowedMarkings.Contains(marking.ID);
+ }
+ }
// Corvax-Sponsors-End
}
diff --git a/Content.Client/Humanoid/SingleMarkingPicker.xaml.cs b/Content.Client/Humanoid/SingleMarkingPicker.xaml.cs
index a742d749f4c..c6f9f0b0481 100644
--- a/Content.Client/Humanoid/SingleMarkingPicker.xaml.cs
+++ b/Content.Client/Humanoid/SingleMarkingPicker.xaml.cs
@@ -1,5 +1,5 @@
using System.Linq;
-using Content.Corvax.Interfaces.Shared;
+using Content.Client.Corvax.Sponsors;
using Content.Shared.Humanoid.Markings;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
@@ -12,7 +12,7 @@ namespace Content.Client.Humanoid;
public sealed partial class SingleMarkingPicker : BoxContainer
{
[Dependency] private readonly MarkingManager _markingManager = default!;
- private ISharedSponsorsManager? _sponsorsManager; // Corvax-Sponsors
+ [Dependency] private readonly SponsorsManager _sponsorsManager = default!; // Corvax-Sponsors
///
/// What happens if a marking is selected.
@@ -124,7 +124,6 @@ public SingleMarkingPicker()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
- IoCManager.Instance!.TryResolveType(out _sponsorsManager); // Corvax-Sponsors
MarkingList.OnItemSelected += SelectMarking;
AddButton.OnPressed += _ =>
@@ -194,8 +193,14 @@ public void PopulateList(string filter)
var item = MarkingList.AddItem(Loc.GetString($"marking-{id}"), marking.Sprites[0].Frame0());
item.Metadata = marking.ID;
// Corvax-Sponsors-Start
- if (marking.SponsorOnly && _sponsorsManager != null)
- item.Disabled = !_sponsorsManager.GetClientPrototypes().Contains(marking.ID);
+ if (marking.SponsorOnly)
+ {
+ item.Disabled = true;
+ if (_sponsorsManager.TryGetInfo(out var sponsor))
+ {
+ item.Disabled = !sponsor.AllowedMarkings.Contains(marking.ID);
+ }
+ }
// Corvax-Sponsors-End
if (_markings[Slot].MarkingId == id)
diff --git a/Content.Client/IoC/ClientContentIoC.cs b/Content.Client/IoC/ClientContentIoC.cs
index a1cba2ed3fb..2739ddaa8d1 100644
--- a/Content.Client/IoC/ClientContentIoC.cs
+++ b/Content.Client/IoC/ClientContentIoC.cs
@@ -2,6 +2,9 @@
using Content.Client.Changelog;
using Content.Client.Chat.Managers;
using Content.Client.Clickable;
+using Content.Client.Corvax.DiscordAuth;
+using Content.Client.Corvax.JoinQueue;
+using Content.Client.Corvax.Sponsors;
using Content.Client.Corvax.TTS;
using Content.Client.DebugMon;
using Content.Client.Eui;
@@ -51,6 +54,9 @@ public static void Register()
collection.Register();
collection.Register();
collection.Register();
+ collection.Register(); // Corvax-Sponsors
+ collection.Register(); // Corvax-Queue
+ collection.Register(); // Corvax-DiscordAuth
}
}
}
diff --git a/Content.Client/Lobby/ClientPreferencesManager.cs b/Content.Client/Lobby/ClientPreferencesManager.cs
index b00d572a97f..fbd61331020 100644
--- a/Content.Client/Lobby/ClientPreferencesManager.cs
+++ b/Content.Client/Lobby/ClientPreferencesManager.cs
@@ -1,5 +1,5 @@
using System.Linq;
-using Content.Corvax.Interfaces.Shared;
+using Content.Client.Corvax.Sponsors;
using Content.Shared.Preferences;
using Robust.Client;
using Robust.Client.Player;
@@ -13,12 +13,12 @@ namespace Content.Client.Lobby
/// connection.
/// Stores preferences on the server through and .
///
- public partial class ClientPreferencesManager : IClientPreferencesManager
+ public sealed class ClientPreferencesManager : IClientPreferencesManager
{
[Dependency] private readonly IClientNetManager _netManager = default!;
+ [Dependency] private readonly SponsorsManager _sponsorsManager = default!; // Corvax-Sponsors
[Dependency] private readonly IBaseClient _baseClient = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
- private ISharedSponsorsManager? _sponsorsManager; // Corvax-Sponsors
public event Action? OnServerDataLoaded;
@@ -27,7 +27,6 @@ public partial class ClientPreferencesManager : IClientPreferencesManager
public void Initialize()
{
- IoCManager.Instance!.TryResolveType(out _sponsorsManager); // Corvax-Sponsors
_netManager.RegisterNetMessage(HandlePreferencesAndSettings);
_netManager.RegisterNetMessage();
_netManager.RegisterNetMessage();
@@ -64,8 +63,9 @@ public void UpdateCharacter(ICharacterProfile profile, int slot)
{
var collection = IoCManager.Instance!;
// Corvax-Sponsors-Start
- var sponsorPrototypes = _sponsorsManager?.GetClientPrototypes().ToArray() ?? [];
- profile.EnsureValid(_playerManager.LocalSession!, collection, sponsorPrototypes);
+ var allowedMarkings = _sponsorsManager.TryGetInfo(out var sponsor) ? sponsor.AllowedMarkings : [];
+ var session = _playerManager.LocalSession!;
+ profile.EnsureValid(session, collection, allowedMarkings);
// Corvax-Sponsors-End
var characters = new Dictionary(Preferences.Characters) {[slot] = profile};
Preferences = new PlayerPreferences(characters, Preferences.SelectedCharacterIndex, Preferences.AdminOOCColor);
diff --git a/Content.Client/Lobby/LobbyUIController.cs b/Content.Client/Lobby/LobbyUIController.cs
index 976c820fec3..58bfed16c1d 100644
--- a/Content.Client/Lobby/LobbyUIController.cs
+++ b/Content.Client/Lobby/LobbyUIController.cs
@@ -1,6 +1,5 @@
using System.Linq;
using Content.Client.Guidebook;
-using Content.Client.Corvax.TTS;
using Content.Client.Humanoid;
using Content.Client.Inventory;
using Content.Client.Lobby.UI;
diff --git a/Content.Client/Lobby/UI/CharacterSetupGui.xaml.cs b/Content.Client/Lobby/UI/CharacterSetupGui.xaml.cs
index a4413077ab3..777725b9eda 100644
--- a/Content.Client/Lobby/UI/CharacterSetupGui.xaml.cs
+++ b/Content.Client/Lobby/UI/CharacterSetupGui.xaml.cs
@@ -1,7 +1,6 @@
using Content.Client.Info;
using Content.Client.Info.PlaytimeStats;
using Content.Client.Resources;
-using Content.Corvax.Interfaces.Client;
using Content.Shared.Preferences;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
@@ -66,13 +65,6 @@ public CharacterSetupGui(
RulesButton.OnPressed += _ => new RulesAndInfoWindow().Open();
StatsButton.OnPressed += _ => new PlaytimeStatsWindow().OpenCentered();
- // Corvax-Sponsors-Start
- if (IoCManager.Instance!.TryResolveType(out var creator))
- {
- SponsorButton.Visible = true;
- SponsorButton.OnPressed += _ => creator.OpenWindow();
- }
- // Corvax-Sponsors-End
}
///
diff --git a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
index 00a3173e36e..846a13342a2 100644
--- a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
+++ b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
@@ -1,6 +1,7 @@
using System.IO;
using System.Linq;
using System.Numerics;
+using Content.Client.Corvax.Sponsors;
using Content.Client.Humanoid;
using Content.Client.Lobby.UI.Loadouts;
using Content.Client.Lobby.UI.Roles;
@@ -40,6 +41,7 @@ namespace Content.Client.Lobby.UI
[GenerateTypedNameReferences]
public sealed partial class HumanoidProfileEditor : BoxContainer
{
+ private readonly SponsorsManager _sponsorsManager = default!; // Corvax-Sponsors
private readonly IClientPreferencesManager _preferencesManager;
private readonly IConfigurationManager _cfgManager;
private readonly IEntityManager _entManager;
@@ -1597,7 +1599,8 @@ private async void ImportProfile()
try
{
- var profile = _entManager.System().FromStream(file, _playerManager.LocalSession!);
+ var sponsorPrototypes = _sponsorsManager.TryGetInfo(out var sponsor) ? sponsor.AllowedMarkings : [];
+ var profile = _entManager.System().FromStream(file, _playerManager.LocalSession!, sponsorPrototypes);
var oldProfile = Profile;
SetProfile(profile, CharacterSlot);
diff --git a/Content.Client/Lobby/UI/Loadouts/LoadoutGroupContainer.xaml.cs b/Content.Client/Lobby/UI/Loadouts/LoadoutGroupContainer.xaml.cs
index 337de39c941..2bafcfd0a44 100644
--- a/Content.Client/Lobby/UI/Loadouts/LoadoutGroupContainer.xaml.cs
+++ b/Content.Client/Lobby/UI/Loadouts/LoadoutGroupContainer.xaml.cs
@@ -1,5 +1,4 @@
using System.Linq;
-using Content.Corvax.Interfaces.Shared;
using Content.Shared.Clothing;
using Content.Shared.Preferences;
using Content.Shared.Preferences.Loadouts;
@@ -19,18 +18,18 @@ public sealed partial class LoadoutGroupContainer : BoxContainer
public event Action>? OnLoadoutPressed;
public event Action>? OnLoadoutUnpressed;
- public LoadoutGroupContainer(HumanoidCharacterProfile profile, RoleLoadout loadout, LoadoutGroupPrototype groupProto, ICommonSession session, IDependencyCollection collection)
+ public LoadoutGroupContainer(HumanoidCharacterProfile profile, RoleLoadout loadout, LoadoutGroupPrototype groupProto, ICommonSession session, IDependencyCollection collection, bool isSponsor)
{
RobustXamlLoader.Load(this);
_groupProto = groupProto;
- RefreshLoadouts(profile, loadout, session, collection);
+ RefreshLoadouts(profile, loadout, session, collection, isSponsor);
}
///
/// Updates button availabilities and buttons.
///
- public void RefreshLoadouts(HumanoidCharacterProfile profile, RoleLoadout loadout, ICommonSession session, IDependencyCollection collection)
+ public void RefreshLoadouts(HumanoidCharacterProfile profile, RoleLoadout loadout, ICommonSession session, IDependencyCollection collection, bool isSponsor)
{
var protoMan = collection.Resolve();
var loadoutSystem = collection.Resolve().System();
@@ -68,19 +67,16 @@ public void RefreshLoadouts(HumanoidCharacterProfile profile, RoleLoadout loadou
var selected = loadout.SelectedLoadouts[_groupProto.ID];
- // Corvax-Loadouts-Start
- var groupLoadouts = _groupProto.Loadouts;
- if (collection.TryResolveType(out var loadoutsManager) && _groupProto.ID == "Inventory")
- {
- groupLoadouts = loadoutsManager.GetClientPrototypes().Select(id => (ProtoId)id).ToList();
- }
- // Corvax-Loadouts-End
-
- foreach (var loadoutProto in groupLoadouts) // Corvax-Loadouts
+ foreach (var loadoutProto in _groupProto.Loadouts)
{
if (!protoMan.TryIndex(loadoutProto, out var loadProto))
continue;
+ //ADT-Sponsors-Loadout-Start
+ if (loadProto.SponsorOnly && !isSponsor)
+ continue;
+ //ADT-Sponsors-Loadout-End
+
var matchingLoadout = selected.FirstOrDefault(e => e.Prototype == loadoutProto);
var pressed = matchingLoadout != null;
diff --git a/Content.Client/Lobby/UI/Loadouts/LoadoutWindow.xaml.cs b/Content.Client/Lobby/UI/Loadouts/LoadoutWindow.xaml.cs
index d029eb1223d..f399f3d4681 100644
--- a/Content.Client/Lobby/UI/Loadouts/LoadoutWindow.xaml.cs
+++ b/Content.Client/Lobby/UI/Loadouts/LoadoutWindow.xaml.cs
@@ -1,3 +1,4 @@
+using Content.Client.Corvax.Sponsors;
using Content.Client.UserInterface.Controls;
using Content.Shared.Preferences;
using Content.Shared.Preferences.Loadouts;
@@ -16,6 +17,8 @@ public sealed partial class LoadoutWindow : FancyWindow
private List _groups = new();
+ public bool IsSponsor; //ADT-Sponsors-Loadout
+
public HumanoidCharacterProfile Profile;
public LoadoutWindow(HumanoidCharacterProfile profile, RoleLoadout loadout, RoleLoadoutPrototype proto, ICommonSession session, IDependencyCollection collection)
@@ -23,6 +26,11 @@ public LoadoutWindow(HumanoidCharacterProfile profile, RoleLoadout loadout, Role
RobustXamlLoader.Load(this);
Profile = profile;
var protoManager = collection.Resolve();
+ //ADT-Sponsors-Loadout-Start
+ var checkSponsorSystem = collection.Resolve().System();
+ checkSponsorSystem.TryCheckSponsor(session.AttachedEntity?.ToString());
+ IsSponsor = checkSponsorSystem.IsSponsor;
+ //ADT-Sponsors-Loadout-End
foreach (var group in proto.Groups)
{
@@ -32,7 +40,7 @@ public LoadoutWindow(HumanoidCharacterProfile profile, RoleLoadout loadout, Role
if (groupProto.Hidden)
continue;
- var container = new LoadoutGroupContainer(profile, loadout, protoManager.Index(group), session, collection);
+ var container = new LoadoutGroupContainer(profile, loadout, protoManager.Index(group), session, collection, IsSponsor); //ADT-Sponsors-Loadout
LoadoutGroupsContainer.AddTab(container, Loc.GetString(groupProto.Name));
_groups.Add(container);
@@ -52,7 +60,7 @@ public void RefreshLoadouts(RoleLoadout loadout, ICommonSession session, IDepend
{
foreach (var group in _groups)
{
- group.RefreshLoadouts(Profile, loadout, session, collection);
+ group.RefreshLoadouts(Profile, loadout, session, collection, IsSponsor); //ADT-Sponsors-Loadout
}
}
}
diff --git a/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs b/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs
index bd4ac877dbb..ab92c1d41bf 100644
--- a/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs
+++ b/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs
@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
+using Content.Client.Corvax.Sponsors;
using Content.Shared.CCVar;
using Content.Shared.Players;
using Content.Shared.Players.JobWhitelist;
@@ -22,6 +23,7 @@ public sealed class JobRequirementsManager : ISharedPlaytimeManager
[Dependency] private readonly IEntityManager _entManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IPrototypeManager _prototypes = default!;
+ [Dependency] private readonly SponsorsManager _sponsorsManager = default!; //ADT-Sponsors-Job
private readonly Dictionary _roles = new();
private readonly List _roleBans = new();
@@ -99,6 +101,15 @@ public bool IsAllowed(JobPrototype job, [NotNullWhen(false)] out FormattedMessag
return false;
}
+ //ADT-Sponsors-Job-Start
+ var info = _sponsorsManager.TryGetInfo(out var sponsorInfo);
+ if (info && sponsorInfo != null)
+ {
+ if (sponsorInfo.AllowJob)
+ return true;
+ }
+ //ADT-Sponsors-Job-End
+
if (!CheckWhitelist(job, out reason))
return false;
diff --git a/Content.Packaging/ClientPackaging.cs b/Content.Packaging/ClientPackaging.cs
index 4651164d7f0..0aafab5ef58 100644
--- a/Content.Packaging/ClientPackaging.cs
+++ b/Content.Packaging/ClientPackaging.cs
@@ -1,4 +1,4 @@
-using System.Diagnostics;
+using System.Diagnostics;
using System.IO.Compression;
using Robust.Packaging;
using Robust.Packaging.AssetProcessing;
@@ -10,7 +10,6 @@ namespace Content.Packaging;
public static class ClientPackaging
{
- private static readonly bool UseSecrets = File.Exists(Path.Combine("Secrets", "CorvaxSecrets.sln")); // Corvax-Secrets
///
/// Be advised this can be called from server packaging during a HybridACZ build.
///
@@ -35,24 +34,6 @@ await ProcessHelpers.RunCheck(new ProcessStartInfo
"/m"
}
});
- if (UseSecrets)
- {
- await ProcessHelpers.RunCheck(new ProcessStartInfo
- {
- FileName = "dotnet",
- ArgumentList =
- {
- "build",
- Path.Combine("Secrets","Content.Corvax.Client", "Content.Corvax.Client.csproj"),
- "-c", "Release",
- "--nologo",
- "/v:m",
- "/t:Rebuild",
- "/p:FullRelease=true",
- "/m"
- }
- });
- }
}
logger.Info("Packaging client...");
@@ -84,40 +65,15 @@ public static async Task WriteResources(
var inputPass = graph.Input;
- // Corvax-Secrets-Start: Add Corvax interfaces to Magic ACZ
- var assemblies = new List { "Content.Client", "Content.Shared", "Content.Shared.Database", "Content.Corvax.Interfaces.Client", "Content.Corvax.Interfaces.Shared" };
- if (UseSecrets)
- assemblies.AddRange(new[] { "Content.Corvax.Shared", "Content.Corvax.Client" });
- // Corvax-Secrets-End
-
await RobustSharedPackaging.WriteContentAssemblies(
inputPass,
contentDir,
"Content.Client",
- assemblies, // Corvax-Secrets
+ new[] { "Content.Client", "Content.Shared", "Content.Shared.Database" },
cancel: cancel);
- await WriteClientResources(contentDir, pass, cancel); // Corvax-Secrets: Support content resource ignore to ignore server-only prototypes
+ await RobustClientPackaging.WriteClientResources(contentDir, pass, cancel);
inputPass.InjectFinished();
}
-
- // Corvax-Secrets-Start
- public static IReadOnlySet ContentClientIgnoredResources { get; } = new HashSet
- {
- "CorvaxSecretsServer"
- };
-
- private static async Task WriteClientResources(
- string contentDir,
- AssetPass pass,
- CancellationToken cancel = default)
- {
- var ignoreSet = RobustClientPackaging.ClientIgnoredResources
- .Union(RobustSharedPackaging.SharedIgnoredResources)
- .Union(ContentClientIgnoredResources).ToHashSet();
-
- await RobustSharedPackaging.DoResourceCopy(Path.Combine(contentDir, "Resources"), pass, ignoreSet, cancel: cancel);
- }
- // Corvax-Secrets-End
}
diff --git a/Content.Packaging/ServerPackaging.cs b/Content.Packaging/ServerPackaging.cs
index cb09da74f66..d9ca57c4d11 100644
--- a/Content.Packaging/ServerPackaging.cs
+++ b/Content.Packaging/ServerPackaging.cs
@@ -33,10 +33,6 @@ public static class ServerPackaging
private static readonly List ServerContentAssemblies = new()
{
- // Corvax-Secrets-Start
- "Content.Corvax.Interfaces.Shared",
- "Content.Corvax.Interfaces.Server",
- // Corvax-Secrets-End
"Content.Server.Database",
"Content.Server",
"Content.Shared",
@@ -73,7 +69,6 @@ public static class ServerPackaging
"zh-Hant"
};
- private static readonly bool UseSecrets = File.Exists(Path.Combine("Secrets", "CorvaxSecrets.sln")); // Corvax-Secrets
public static async Task PackageServer(bool skipBuild, bool hybridAcz, IPackageLogger logger, string configuration, List? platforms = null)
{
if (platforms == null)
@@ -122,28 +117,6 @@ await ProcessHelpers.RunCheck(new ProcessStartInfo
"/m"
}
});
- // Corvax-Secrets-Start
- if (UseSecrets)
- {
- logger.Info($"Secrets found. Building secret project for {platform}...");
- await ProcessHelpers.RunCheck(new ProcessStartInfo
- {
- FileName = "dotnet",
- ArgumentList =
- {
- "build",
- Path.Combine("Secrets","Content.Corvax.Server", "Content.Corvax.Server.csproj"),
- "-c", "Release",
- "--nologo",
- "/v:m",
- $"/p:TargetOs={platform.TargetOs}",
- "/t:Rebuild",
- "/p:FullRelease=true",
- "/m"
- }
- });
- }
- // Corvax-Secrets-End
await PublishClientServer(platform.Rid, platform.TargetOs, configuration);
}
@@ -202,10 +175,6 @@ private static async Task WriteServerResources(
var inputPassCore = graph.InputCore;
var inputPassResources = graph.InputResources;
var contentAssemblies = new List(ServerContentAssemblies);
- // Corvax-Secrets-Start
- if (UseSecrets)
- contentAssemblies.AddRange(new[] { "Content.Corvax.Shared", "Content.Corvax.Server" });
- // Corvax-Secrets-End
// Additional assemblies that need to be copied such as EFCore.
var sourcePath = Path.Combine(contentDir, "bin", "Content.Server");
diff --git a/Content.Server.Database/Migrations/Postgres/20221128142328_Sponsors.Designer.cs b/Content.Server.Database/Migrations/Postgres/20221128142328_Sponsors.Designer.cs
new file mode 100644
index 00000000000..59fff0824a6
--- /dev/null
+++ b/Content.Server.Database/Migrations/Postgres/20221128142328_Sponsors.Designer.cs
@@ -0,0 +1,1378 @@
+//
+using System;
+using System.Net;
+using System.Text.Json;
+using Content.Server.Database;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace Content.Server.Database.Migrations.Postgres
+{
+ [DbContext(typeof(PostgresServerDbContext))]
+ [Migration("20221128142328_Sponsors")]
+ partial class Sponsors
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "6.0.5")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("Content.Server.Database.Admin", b =>
+ {
+ b.Property("UserId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.Property("AdminRankId")
+ .HasColumnType("integer")
+ .HasColumnName("admin_rank_id");
+
+ b.Property("Title")
+ .HasColumnType("text")
+ .HasColumnName("title");
+
+ b.HasKey("UserId")
+ .HasName("PK_admin");
+
+ b.HasIndex("AdminRankId")
+ .HasDatabaseName("IX_admin_admin_rank_id");
+
+ b.ToTable("admin", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminFlag", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("admin_flag_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("AdminId")
+ .HasColumnType("uuid")
+ .HasColumnName("admin_id");
+
+ b.Property("Flag")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("flag");
+
+ b.Property("Negative")
+ .HasColumnType("boolean")
+ .HasColumnName("negative");
+
+ b.HasKey("Id")
+ .HasName("PK_admin_flag");
+
+ b.HasIndex("AdminId")
+ .HasDatabaseName("IX_admin_flag_admin_id");
+
+ b.HasIndex("Flag", "AdminId")
+ .IsUnique();
+
+ b.ToTable("admin_flag", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("admin_log_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("RoundId")
+ .HasColumnType("integer")
+ .HasColumnName("round_id");
+
+ b.Property("Date")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("date");
+
+ b.Property("Impact")
+ .HasColumnType("smallint")
+ .HasColumnName("impact");
+
+ b.Property("Json")
+ .IsRequired()
+ .HasColumnType("jsonb")
+ .HasColumnName("json");
+
+ b.Property("Message")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("message");
+
+ b.Property("Type")
+ .HasColumnType("integer")
+ .HasColumnName("type");
+
+ b.HasKey("Id", "RoundId")
+ .HasName("PK_admin_log");
+
+ b.HasIndex("Date");
+
+ b.HasIndex("Message")
+ .HasAnnotation("Npgsql:TsVectorConfig", "english");
+
+ NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("Message"), "GIN");
+
+ b.HasIndex("RoundId")
+ .HasDatabaseName("IX_admin_log_round_id");
+
+ b.HasIndex("Type")
+ .HasDatabaseName("IX_admin_log_type");
+
+ b.ToTable("admin_log", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b =>
+ {
+ b.Property("Uid")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("uid");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Uid"));
+
+ b.Property("AdminLogId")
+ .HasColumnType("integer")
+ .HasColumnName("admin_log_id");
+
+ b.Property("AdminLogRoundId")
+ .HasColumnType("integer")
+ .HasColumnName("admin_log_round_id");
+
+ b.Property("Name")
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.HasKey("Uid")
+ .HasName("PK_admin_log_entity");
+
+ b.HasIndex("AdminLogId", "AdminLogRoundId")
+ .HasDatabaseName("IX_admin_log_entity_admin_log_id_admin_log_round_id");
+
+ b.ToTable("admin_log_entity", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b =>
+ {
+ b.Property("PlayerUserId")
+ .HasColumnType("uuid")
+ .HasColumnName("player_user_id");
+
+ b.Property("LogId")
+ .HasColumnType("integer")
+ .HasColumnName("log_id");
+
+ b.Property("RoundId")
+ .HasColumnType("integer")
+ .HasColumnName("round_id");
+
+ b.HasKey("PlayerUserId", "LogId", "RoundId")
+ .HasName("PK_admin_log_player");
+
+ b.HasIndex("LogId", "RoundId");
+
+ b.ToTable("admin_log_player", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminNote", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("admin_notes_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property("CreatedById")
+ .HasColumnType("uuid")
+ .HasColumnName("created_by_id");
+
+ b.Property("Deleted")
+ .HasColumnType("boolean")
+ .HasColumnName("deleted");
+
+ b.Property("DeletedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("deleted_at");
+
+ b.Property("DeletedById")
+ .HasColumnType("uuid")
+ .HasColumnName("deleted_by_id");
+
+ b.Property("LastEditedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("last_edited_at");
+
+ b.Property("LastEditedById")
+ .HasColumnType("uuid")
+ .HasColumnName("last_edited_by_id");
+
+ b.Property("Message")
+ .IsRequired()
+ .HasMaxLength(4096)
+ .HasColumnType("character varying(4096)")
+ .HasColumnName("message");
+
+ b.Property("PlayerUserId")
+ .HasColumnType("uuid")
+ .HasColumnName("player_user_id");
+
+ b.Property("RoundId")
+ .HasColumnType("integer")
+ .HasColumnName("round_id");
+
+ b.Property("ShownToPlayer")
+ .HasColumnType("boolean")
+ .HasColumnName("shown_to_player");
+
+ b.HasKey("Id")
+ .HasName("PK_admin_notes");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("DeletedById");
+
+ b.HasIndex("LastEditedById");
+
+ b.HasIndex("PlayerUserId")
+ .HasDatabaseName("IX_admin_notes_player_user_id");
+
+ b.HasIndex("RoundId")
+ .HasDatabaseName("IX_admin_notes_round_id");
+
+ b.ToTable("admin_notes", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminRank", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("admin_rank_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.HasKey("Id")
+ .HasName("PK_admin_rank");
+
+ b.ToTable("admin_rank", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("admin_rank_flag_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("AdminRankId")
+ .HasColumnType("integer")
+ .HasColumnName("admin_rank_id");
+
+ b.Property("Flag")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("flag");
+
+ b.HasKey("Id")
+ .HasName("PK_admin_rank_flag");
+
+ b.HasIndex("AdminRankId")
+ .HasDatabaseName("IX_admin_rank_flag_admin_rank_id");
+
+ b.HasIndex("Flag", "AdminRankId")
+ .IsUnique();
+
+ b.ToTable("admin_rank_flag", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Antag", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("antag_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("AntagName")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("antag_name");
+
+ b.Property("ProfileId")
+ .HasColumnType("integer")
+ .HasColumnName("profile_id");
+
+ b.HasKey("Id")
+ .HasName("PK_antag");
+
+ b.HasIndex("ProfileId", "AntagName")
+ .IsUnique();
+
+ b.ToTable("antag", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AssignedUserId", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("assigned_user_id_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.Property("UserName")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("user_name");
+
+ b.HasKey("Id")
+ .HasName("PK_assigned_user_id");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.HasIndex("UserName")
+ .IsUnique();
+
+ b.ToTable("assigned_user_id", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.ConnectionLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("connection_log_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Address")
+ .IsRequired()
+ .HasColumnType("inet")
+ .HasColumnName("address");
+
+ b.Property("Denied")
+ .HasColumnType("smallint")
+ .HasColumnName("denied");
+
+ b.Property("HWId")
+ .HasColumnType("bytea")
+ .HasColumnName("hwid");
+
+ b.Property("Time")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("time");
+
+ b.Property("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.Property("UserName")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("user_name");
+
+ b.HasKey("Id")
+ .HasName("PK_connection_log");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("connection_log", (string)null);
+
+ b.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Job", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("job_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("JobName")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("job_name");
+
+ b.Property("Priority")
+ .HasColumnType("integer")
+ .HasColumnName("priority");
+
+ b.Property("ProfileId")
+ .HasColumnType("integer")
+ .HasColumnName("profile_id");
+
+ b.HasKey("Id")
+ .HasName("PK_job");
+
+ b.HasIndex("ProfileId")
+ .HasDatabaseName("IX_job_profile_id");
+
+ b.HasIndex("ProfileId", "JobName")
+ .IsUnique();
+
+ b.HasIndex(new[] { "ProfileId" }, "IX_job_one_high_priority")
+ .IsUnique()
+ .HasFilter("priority = 3");
+
+ b.ToTable("job", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Player", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("player_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("FirstSeenTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("first_seen_time");
+
+ b.Property("LastReadRules")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("last_read_rules");
+
+ b.Property("LastSeenAddress")
+ .IsRequired()
+ .HasColumnType("inet")
+ .HasColumnName("last_seen_address");
+
+ b.Property("LastSeenHWId")
+ .HasColumnType("bytea")
+ .HasColumnName("last_seen_hwid");
+
+ b.Property("LastSeenTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("last_seen_time");
+
+ b.Property("LastSeenUserName")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("last_seen_user_name");
+
+ b.Property("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.HasKey("Id")
+ .HasName("PK_player");
+
+ b.HasAlternateKey("UserId")
+ .HasName("ak_player_user_id");
+
+ b.HasIndex("LastSeenUserName");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("player", (string)null);
+
+ b.HasCheckConstraint("LastSeenAddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= last_seen_address");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.PlayTime", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("play_time_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("PlayerId")
+ .HasColumnType("uuid")
+ .HasColumnName("player_id");
+
+ b.Property("TimeSpent")
+ .HasColumnType("interval")
+ .HasColumnName("time_spent");
+
+ b.Property("Tracker")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("tracker");
+
+ b.HasKey("Id")
+ .HasName("PK_play_time");
+
+ b.HasIndex("PlayerId", "Tracker")
+ .IsUnique();
+
+ b.ToTable("play_time", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Preference", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("preference_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("AdminOOCColor")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("admin_ooc_color");
+
+ b.Property("SelectedCharacterSlot")
+ .HasColumnType("integer")
+ .HasColumnName("selected_character_slot");
+
+ b.Property("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.HasKey("Id")
+ .HasName("PK_preference");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("preference", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Profile", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("profile_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Age")
+ .HasColumnType("integer")
+ .HasColumnName("age");
+
+ b.Property("Backpack")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("backpack");
+
+ b.Property("CharacterName")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("char_name");
+
+ b.Property("Clothing")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("clothing");
+
+ b.Property("EyeColor")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("eye_color");
+
+ b.Property("FacialHairColor")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("facial_hair_color");
+
+ b.Property("FacialHairName")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("facial_hair_name");
+
+ b.Property("FlavorText")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("flavor_text");
+
+ b.Property("Gender")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("gender");
+
+ b.Property("HairColor")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("hair_color");
+
+ b.Property("HairName")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("hair_name");
+
+ b.Property("Markings")
+ .HasColumnType("jsonb")
+ .HasColumnName("markings");
+
+ b.Property("PreferenceId")
+ .HasColumnType("integer")
+ .HasColumnName("preference_id");
+
+ b.Property("PreferenceUnavailable")
+ .HasColumnType("integer")
+ .HasColumnName("pref_unavailable");
+
+ b.Property("Sex")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("sex");
+
+ b.Property("SkinColor")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("skin_color");
+
+ b.Property("Slot")
+ .HasColumnType("integer")
+ .HasColumnName("slot");
+
+ b.Property("Species")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("species");
+
+ // Corvax-TTS-Start
+ b.Property("Voice")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("voice");
+ // Corvax-TTS-End
+
+ b.HasKey("Id")
+ .HasName("PK_profile");
+
+ b.HasIndex("PreferenceId")
+ .HasDatabaseName("IX_profile_preference_id");
+
+ b.HasIndex("Slot", "PreferenceId")
+ .IsUnique();
+
+ b.ToTable("profile", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Round", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("round_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("ServerId")
+ .HasColumnType("integer")
+ .HasColumnName("server_id");
+
+ b.HasKey("Id")
+ .HasName("PK_round");
+
+ b.HasIndex("ServerId")
+ .HasDatabaseName("IX_round_server_id");
+
+ b.ToTable("round", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Server", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("server_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.HasKey("Id")
+ .HasName("PK_server");
+
+ b.ToTable("server", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.ServerBan", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("server_ban_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property?>("Address")
+ .HasColumnType("inet")
+ .HasColumnName("address");
+
+ b.Property("BanTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("ban_time");
+
+ b.Property("BanningAdmin")
+ .HasColumnType("uuid")
+ .HasColumnName("banning_admin");
+
+ b.Property("ExpirationTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("expiration_time");
+
+ b.Property("HWId")
+ .HasColumnType("bytea")
+ .HasColumnName("hwid");
+
+ b.Property("Reason")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("reason");
+
+ b.Property("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.HasKey("Id")
+ .HasName("PK_server_ban");
+
+ b.HasIndex("Address");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("server_ban", (string)null);
+
+ b.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address");
+
+ b.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR user_id IS NOT NULL OR hwid IS NOT NULL");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.ServerBanHit", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("server_ban_hit_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("BanId")
+ .HasColumnType("integer")
+ .HasColumnName("ban_id");
+
+ b.Property("ConnectionId")
+ .HasColumnType("integer")
+ .HasColumnName("connection_id");
+
+ b.HasKey("Id")
+ .HasName("PK_server_ban_hit");
+
+ b.HasIndex("BanId")
+ .HasDatabaseName("IX_server_ban_hit_ban_id");
+
+ b.HasIndex("ConnectionId")
+ .HasDatabaseName("IX_server_ban_hit_connection_id");
+
+ b.ToTable("server_ban_hit", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("server_role_ban_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property?>("Address")
+ .HasColumnType("inet")
+ .HasColumnName("address");
+
+ b.Property("BanTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("ban_time");
+
+ b.Property("BanningAdmin")
+ .HasColumnType("uuid")
+ .HasColumnName("banning_admin");
+
+ b.Property("ExpirationTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("expiration_time");
+
+ b.Property("HWId")
+ .HasColumnType("bytea")
+ .HasColumnName("hwid");
+
+ b.Property("Reason")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("reason");
+
+ b.Property("RoleId")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("role_id");
+
+ b.Property("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.HasKey("Id")
+ .HasName("PK_server_role_ban");
+
+ b.HasIndex("Address");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("server_role_ban", (string)null);
+
+ b.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address");
+
+ b.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR user_id IS NOT NULL OR hwid IS NOT NULL");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.ServerRoleUnban", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("role_unban_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("BanId")
+ .HasColumnType("integer")
+ .HasColumnName("ban_id");
+
+ b.Property("UnbanTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("unban_time");
+
+ b.Property("UnbanningAdmin")
+ .HasColumnType("uuid")
+ .HasColumnName("unbanning_admin");
+
+ b.HasKey("Id")
+ .HasName("PK_server_role_unban");
+
+ b.HasIndex("BanId")
+ .IsUnique();
+
+ b.ToTable("server_role_unban", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.ServerUnban", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("unban_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("BanId")
+ .HasColumnType("integer")
+ .HasColumnName("ban_id");
+
+ b.Property("UnbanTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("unban_time");
+
+ b.Property("UnbanningAdmin")
+ .HasColumnType("uuid")
+ .HasColumnName("unbanning_admin");
+
+ b.HasKey("Id")
+ .HasName("PK_server_unban");
+
+ b.HasIndex("BanId")
+ .IsUnique();
+
+ b.ToTable("server_unban", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Sponsor", b =>
+ {
+ b.Property("UserId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.Property("AllowedMarkings")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("allowed_markings");
+
+ b.Property("ExtraSlots")
+ .HasColumnType("integer")
+ .HasColumnName("extra_slots");
+
+ b.Property("HavePriorityJoin")
+ .HasColumnType("boolean")
+ .HasColumnName("have_priority_join");
+
+ b.Property("OOCColor")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("ooccolor");
+
+ b.Property("Tier")
+ .HasColumnType("integer")
+ .HasColumnName("tier");
+
+ b.HasKey("UserId")
+ .HasName("PK_sponsors");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("sponsors", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Trait", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("trait_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("ProfileId")
+ .HasColumnType("integer")
+ .HasColumnName("profile_id");
+
+ b.Property("TraitName")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("trait_name");
+
+ b.HasKey("Id")
+ .HasName("PK_trait");
+
+ b.HasIndex("ProfileId", "TraitName")
+ .IsUnique();
+
+ b.ToTable("trait", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.UploadedResourceLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("uploaded_resource_log_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Data")
+ .IsRequired()
+ .HasColumnType("bytea")
+ .HasColumnName("data");
+
+ b.Property("Date")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("date");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("path");
+
+ b.Property("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.HasKey("Id")
+ .HasName("PK_uploaded_resource_log");
+
+ b.ToTable("uploaded_resource_log", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Whitelist", b =>
+ {
+ b.Property("UserId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.HasKey("UserId")
+ .HasName("PK_whitelist");
+
+ b.ToTable("whitelist", (string)null);
+ });
+
+ modelBuilder.Entity("PlayerRound", b =>
+ {
+ b.Property("PlayersId")
+ .HasColumnType("integer")
+ .HasColumnName("players_id");
+
+ b.Property("RoundsId")
+ .HasColumnType("integer")
+ .HasColumnName("rounds_id");
+
+ b.HasKey("PlayersId", "RoundsId")
+ .HasName("PK_player_round");
+
+ b.HasIndex("RoundsId")
+ .HasDatabaseName("IX_player_round_rounds_id");
+
+ b.ToTable("player_round", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Admin", b =>
+ {
+ b.HasOne("Content.Server.Database.AdminRank", "AdminRank")
+ .WithMany("Admins")
+ .HasForeignKey("AdminRankId")
+ .OnDelete(DeleteBehavior.SetNull)
+ .HasConstraintName("FK_admin_admin_rank_admin_rank_id");
+
+ b.Navigation("AdminRank");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminFlag", b =>
+ {
+ b.HasOne("Content.Server.Database.Admin", "Admin")
+ .WithMany("Flags")
+ .HasForeignKey("AdminId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_admin_flag_admin_admin_id");
+
+ b.Navigation("Admin");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminLog", b =>
+ {
+ b.HasOne("Content.Server.Database.Round", "Round")
+ .WithMany("AdminLogs")
+ .HasForeignKey("RoundId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_admin_log_round_round_id");
+
+ b.Navigation("Round");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b =>
+ {
+ b.HasOne("Content.Server.Database.AdminLog", null)
+ .WithMany("Entities")
+ .HasForeignKey("AdminLogId", "AdminLogRoundId")
+ .HasConstraintName("FK_admin_log_entity_admin_log_admin_log_id_admin_log_round_id");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b =>
+ {
+ b.HasOne("Content.Server.Database.Player", "Player")
+ .WithMany("AdminLogs")
+ .HasForeignKey("PlayerUserId")
+ .HasPrincipalKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_admin_log_player_player_player_user_id");
+
+ b.HasOne("Content.Server.Database.AdminLog", "Log")
+ .WithMany("Players")
+ .HasForeignKey("LogId", "RoundId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_admin_log_player_admin_log_log_id_round_id");
+
+ b.Navigation("Log");
+
+ b.Navigation("Player");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminNote", b =>
+ {
+ b.HasOne("Content.Server.Database.Player", "CreatedBy")
+ .WithMany("AdminNotesCreated")
+ .HasForeignKey("CreatedById")
+ .HasPrincipalKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_admin_notes_player_created_by_id");
+
+ b.HasOne("Content.Server.Database.Player", "DeletedBy")
+ .WithMany("AdminNotesDeleted")
+ .HasForeignKey("DeletedById")
+ .HasPrincipalKey("UserId")
+ .HasConstraintName("FK_admin_notes_player_deleted_by_id");
+
+ b.HasOne("Content.Server.Database.Player", "LastEditedBy")
+ .WithMany("AdminNotesLastEdited")
+ .HasForeignKey("LastEditedById")
+ .HasPrincipalKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_admin_notes_player_last_edited_by_id");
+
+ b.HasOne("Content.Server.Database.Player", "Player")
+ .WithMany("AdminNotesReceived")
+ .HasForeignKey("PlayerUserId")
+ .HasPrincipalKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_admin_notes_player_player_user_id");
+
+ b.HasOne("Content.Server.Database.Round", "Round")
+ .WithMany()
+ .HasForeignKey("RoundId")
+ .HasConstraintName("FK_admin_notes_round_round_id");
+
+ b.Navigation("CreatedBy");
+
+ b.Navigation("DeletedBy");
+
+ b.Navigation("LastEditedBy");
+
+ b.Navigation("Player");
+
+ b.Navigation("Round");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b =>
+ {
+ b.HasOne("Content.Server.Database.AdminRank", "Rank")
+ .WithMany("Flags")
+ .HasForeignKey("AdminRankId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_admin_rank_flag_admin_rank_admin_rank_id");
+
+ b.Navigation("Rank");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Antag", b =>
+ {
+ b.HasOne("Content.Server.Database.Profile", "Profile")
+ .WithMany("Antags")
+ .HasForeignKey("ProfileId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_antag_profile_profile_id");
+
+ b.Navigation("Profile");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Job", b =>
+ {
+ b.HasOne("Content.Server.Database.Profile", "Profile")
+ .WithMany("Jobs")
+ .HasForeignKey("ProfileId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_job_profile_profile_id");
+
+ b.Navigation("Profile");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Profile", b =>
+ {
+ b.HasOne("Content.Server.Database.Preference", "Preference")
+ .WithMany("Profiles")
+ .HasForeignKey("PreferenceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_profile_preference_preference_id");
+
+ b.Navigation("Preference");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Round", b =>
+ {
+ b.HasOne("Content.Server.Database.Server", "Server")
+ .WithMany("Rounds")
+ .HasForeignKey("ServerId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_round_server_server_id");
+
+ b.Navigation("Server");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.ServerBanHit", b =>
+ {
+ b.HasOne("Content.Server.Database.ServerBan", "Ban")
+ .WithMany("BanHits")
+ .HasForeignKey("BanId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_server_ban_hit_server_ban_ban_id");
+
+ b.HasOne("Content.Server.Database.ConnectionLog", "Connection")
+ .WithMany("BanHits")
+ .HasForeignKey("ConnectionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_server_ban_hit_connection_log_connection_id");
+
+ b.Navigation("Ban");
+
+ b.Navigation("Connection");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.ServerRoleUnban", b =>
+ {
+ b.HasOne("Content.Server.Database.ServerRoleBan", "Ban")
+ .WithOne("Unban")
+ .HasForeignKey("Content.Server.Database.ServerRoleUnban", "BanId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_server_role_unban_server_role_ban_ban_id");
+
+ b.Navigation("Ban");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.ServerUnban", b =>
+ {
+ b.HasOne("Content.Server.Database.ServerBan", "Ban")
+ .WithOne("Unban")
+ .HasForeignKey("Content.Server.Database.ServerUnban", "BanId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_server_unban_server_ban_ban_id");
+
+ b.Navigation("Ban");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Trait", b =>
+ {
+ b.HasOne("Content.Server.Database.Profile", "Profile")
+ .WithMany("Traits")
+ .HasForeignKey("ProfileId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_trait_profile_profile_id");
+
+ b.Navigation("Profile");
+ });
+
+ modelBuilder.Entity("PlayerRound", b =>
+ {
+ b.HasOne("Content.Server.Database.Player", null)
+ .WithMany()
+ .HasForeignKey("PlayersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_player_round_player_players_id");
+
+ b.HasOne("Content.Server.Database.Round", null)
+ .WithMany()
+ .HasForeignKey("RoundsId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("FK_player_round_round_rounds_id");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Admin", b =>
+ {
+ b.Navigation("Flags");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminLog", b =>
+ {
+ b.Navigation("Entities");
+
+ b.Navigation("Players");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminRank", b =>
+ {
+ b.Navigation("Admins");
+
+ b.Navigation("Flags");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.ConnectionLog", b =>
+ {
+ b.Navigation("BanHits");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Player", b =>
+ {
+ b.Navigation("AdminLogs");
+
+ b.Navigation("AdminNotesCreated");
+
+ b.Navigation("AdminNotesDeleted");
+
+ b.Navigation("AdminNotesLastEdited");
+
+ b.Navigation("AdminNotesReceived");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Preference", b =>
+ {
+ b.Navigation("Profiles");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Profile", b =>
+ {
+ b.Navigation("Antags");
+
+ b.Navigation("Jobs");
+
+ b.Navigation("Traits");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Round", b =>
+ {
+ b.Navigation("AdminLogs");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.Server", b =>
+ {
+ b.Navigation("Rounds");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.ServerBan", b =>
+ {
+ b.Navigation("BanHits");
+
+ b.Navigation("Unban");
+ });
+
+ modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b =>
+ {
+ b.Navigation("Unban");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Content.Server.Database/Migrations/Postgres/20221128142328_Sponsors.cs b/Content.Server.Database/Migrations/Postgres/20221128142328_Sponsors.cs
new file mode 100644
index 00000000000..b3a9c66ad0d
--- /dev/null
+++ b/Content.Server.Database/Migrations/Postgres/20221128142328_Sponsors.cs
@@ -0,0 +1,43 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Content.Server.Database.Migrations.Postgres
+{
+ public partial class Sponsors : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "sponsors",
+ columns: table => new
+ {
+ user_id = table.Column(type: "uuid", nullable: false),
+ tier = table.Column(type: "integer", nullable: false),
+ ooccolor = table.Column(type: "text", nullable: false),
+ have_priority_join = table.Column(type: "boolean", nullable: false),
+ allowed_markings = table.Column(type: "text", nullable: false),
+ extra_slots = table.Column(type: "integer", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_sponsors", x => x.user_id);
+ });
+
+
+ migrationBuilder.CreateIndex(
+ name: "IX_sponsors_user_id",
+ table: "sponsors",
+ column: "user_id",
+ unique: true);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "sponsors");
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/Content.Server.Database/Migrations/Postgres/20221130091215_AddDateField.Designer.cs b/Content.Server.Database/Migrations/Postgres/20221130091215_AddDateField.Designer.cs
new file mode 100644
index 00000000000..ba1daccf0e6
--- /dev/null
+++ b/Content.Server.Database/Migrations/Postgres/20221130091215_AddDateField.Designer.cs
@@ -0,0 +1,1375 @@
+//
+using System;
+using System.Net;
+using System.Text.Json;
+using Content.Server.Database;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace Content.Server.Database.Migrations.Postgres
+{
+ [DbContext(typeof(PostgresServerDbContext))]
+ [Migration("20221130091215_AddDateField")]
+ partial class AddDateField
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "6.0.5")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("Content.Server.Database.Admin", b =>
+ {
+ b.Property("UserId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.Property("AdminRankId")
+ .HasColumnType("integer")
+ .HasColumnName("admin_rank_id");
+
+ b.Property("Title")
+ .HasColumnType("text")
+ .HasColumnName("title");
+
+ b.HasKey("UserId")
+ .HasName("PK_admin");
+
+ b.HasIndex("AdminRankId")
+ .HasDatabaseName("IX_admin_admin_rank_id");
+
+ b.ToTable("admin", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminFlag", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("admin_flag_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("AdminId")
+ .HasColumnType("uuid")
+ .HasColumnName("admin_id");
+
+ b.Property("Flag")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("flag");
+
+ b.Property("Negative")
+ .HasColumnType("boolean")
+ .HasColumnName("negative");
+
+ b.HasKey("Id")
+ .HasName("PK_admin_flag");
+
+ b.HasIndex("AdminId")
+ .HasDatabaseName("IX_admin_flag_admin_id");
+
+ b.HasIndex("Flag", "AdminId")
+ .IsUnique();
+
+ b.ToTable("admin_flag", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("admin_log_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("RoundId")
+ .HasColumnType("integer")
+ .HasColumnName("round_id");
+
+ b.Property("Date")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("date");
+
+ b.Property("Impact")
+ .HasColumnType("smallint")
+ .HasColumnName("impact");
+
+ b.Property("Json")
+ .IsRequired()
+ .HasColumnType("jsonb")
+ .HasColumnName("json");
+
+ b.Property("Message")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("message");
+
+ b.Property("Type")
+ .HasColumnType("integer")
+ .HasColumnName("type");
+
+ b.HasKey("Id", "RoundId")
+ .HasName("PK_admin_log");
+
+ b.HasIndex("Date");
+
+ b.HasIndex("Message")
+ .HasAnnotation("Npgsql:TsVectorConfig", "english");
+
+ NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("Message"), "GIN");
+
+ b.HasIndex("RoundId")
+ .HasDatabaseName("IX_admin_log_round_id");
+
+ b.HasIndex("Type")
+ .HasDatabaseName("IX_admin_log_type");
+
+ b.ToTable("admin_log", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b =>
+ {
+ b.Property("Uid")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("uid");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Uid"));
+
+ b.Property("AdminLogId")
+ .HasColumnType("integer")
+ .HasColumnName("admin_log_id");
+
+ b.Property("AdminLogRoundId")
+ .HasColumnType("integer")
+ .HasColumnName("admin_log_round_id");
+
+ b.Property("Name")
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.HasKey("Uid")
+ .HasName("PK_admin_log_entity");
+
+ b.HasIndex("AdminLogId", "AdminLogRoundId")
+ .HasDatabaseName("IX_admin_log_entity_admin_log_id_admin_log_round_id");
+
+ b.ToTable("admin_log_entity", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b =>
+ {
+ b.Property("PlayerUserId")
+ .HasColumnType("uuid")
+ .HasColumnName("player_user_id");
+
+ b.Property("LogId")
+ .HasColumnType("integer")
+ .HasColumnName("log_id");
+
+ b.Property("RoundId")
+ .HasColumnType("integer")
+ .HasColumnName("round_id");
+
+ b.HasKey("PlayerUserId", "LogId", "RoundId")
+ .HasName("PK_admin_log_player");
+
+ b.HasIndex("LogId", "RoundId");
+
+ b.ToTable("admin_log_player", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminNote", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("admin_notes_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property("CreatedById")
+ .HasColumnType("uuid")
+ .HasColumnName("created_by_id");
+
+ b.Property("Deleted")
+ .HasColumnType("boolean")
+ .HasColumnName("deleted");
+
+ b.Property("DeletedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("deleted_at");
+
+ b.Property("DeletedById")
+ .HasColumnType("uuid")
+ .HasColumnName("deleted_by_id");
+
+ b.Property("LastEditedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("last_edited_at");
+
+ b.Property("LastEditedById")
+ .HasColumnType("uuid")
+ .HasColumnName("last_edited_by_id");
+
+ b.Property("Message")
+ .IsRequired()
+ .HasMaxLength(4096)
+ .HasColumnType("character varying(4096)")
+ .HasColumnName("message");
+
+ b.Property("PlayerUserId")
+ .HasColumnType("uuid")
+ .HasColumnName("player_user_id");
+
+ b.Property("RoundId")
+ .HasColumnType("integer")
+ .HasColumnName("round_id");
+
+ b.Property("ShownToPlayer")
+ .HasColumnType("boolean")
+ .HasColumnName("shown_to_player");
+
+ b.HasKey("Id")
+ .HasName("PK_admin_notes");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("DeletedById");
+
+ b.HasIndex("LastEditedById");
+
+ b.HasIndex("PlayerUserId")
+ .HasDatabaseName("IX_admin_notes_player_user_id");
+
+ b.HasIndex("RoundId")
+ .HasDatabaseName("IX_admin_notes_round_id");
+
+ b.ToTable("admin_notes", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminRank", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("admin_rank_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.HasKey("Id")
+ .HasName("PK_admin_rank");
+
+ b.ToTable("admin_rank", (string)null);
+ });
+
+ modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("admin_rank_flag_id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("AdminRankId")
+ .HasColumnType("integer")
+ .HasColumnName("admin_rank_id");
+
+ b.Property