diff --git a/.dockerignore b/.dockerignore
index 4a54e2617a..0558f70123 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -21,6 +21,8 @@ build/**
!build/stylecop.json
!build/Version.props
!build/ControlPanelVersion.props
+!build/Common.props
+!build/NugetCommon.props
docs
src/DMAPI
src/Tgstation.Server.Host/ClientApp
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 79ee3f7ac3..bdaf224e68 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -173,6 +173,8 @@ Whenever you make a change to a model schema that must be reflected in the datab
We have a script to do this.
+Warning: You may need to temporarily set valid MySql credentials in [MySqlDesignTimeDbContextFactory.cs](../src/Tgstation.Server.Host/Database/Design/MySqlDesignTimeDbContextFactory.cs) for migrations to generate properly. I have no idea why. Be careful not to commit the change.
+
1. Run `build/GenerateMigrations.sh NameOfMigration` from the project root.
1. You should now have MY/MS/SL/PG migration files generated in `/src/Tgstation.Server.Host/Models/Migrations`. Fix compiler warnings in the generated files. Ensure all classes are in the Tgstation.Server.Host.Database.Migrations namespace.
1. Manually review what each migration does.
diff --git a/build/Common.props b/build/Common.props
new file mode 100644
index 0000000000..95ade51555
--- /dev/null
+++ b/build/Common.props
@@ -0,0 +1,10 @@
+
+
+
+
+ net6.0
+ netstandard2.0
+ latest
+ Full
+
+
diff --git a/build/Dockerfile b/build/Dockerfile
index c5baa2f3ff..716790bada 100644
--- a/build/Dockerfile
+++ b/build/Dockerfile
@@ -25,6 +25,8 @@ RUN npm install -g yarn
# Build web control panel
WORKDIR /repo/build
+COPY build/Common.props Common.props
+COPY build/NugetCommon.props NugetCommon.props
COPY build/Version.props Version.props
COPY build/ControlPanelVersion.props ControlPanelVersion.props
diff --git a/build/NugetCommon.props b/build/NugetCommon.props
new file mode 100644
index 0000000000..d844ff4b1a
--- /dev/null
+++ b/build/NugetCommon.props
@@ -0,0 +1,23 @@
+
+
+
+
+ true
+ Cyberboss/Dominion
+ /tg/station 13
+ https://tgstation.github.io/tgstation-server
+ LICENSE
+ tgs.png
+ Git
+ https://github.com/tgstation/tgstation-server
+ 2018-2023
+ true
+ snupkg
+ enable
+
+
+
+
+
+
+
diff --git a/build/Version.props b/build/Version.props
index 7929f4741d..9fd3893fca 100644
--- a/build/Version.props
+++ b/build/Version.props
@@ -13,6 +13,5 @@
1.2.2
1.2.1
1.0.1
- net6.0
diff --git a/src/Tgstation.Server.Api/Models/Internal/ChatChannelBase.cs b/src/Tgstation.Server.Api/Models/Internal/ChatChannelBase.cs
index 87da5746ae..eee19f244f 100644
--- a/src/Tgstation.Server.Api/Models/Internal/ChatChannelBase.cs
+++ b/src/Tgstation.Server.Api/Models/Internal/ChatChannelBase.cs
@@ -25,6 +25,12 @@ namespace Tgstation.Server.Api.Models.Internal
[Required]
public bool? IsUpdatesChannel { get; set; }
+ ///
+ /// If the received system messages.
+ ///
+ [Required]
+ public bool? IsSystemChannel { get; set; }
+
///
/// A custom tag users can define to group channels together.
///
diff --git a/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj b/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
index 21a2efd47d..cb44534a9c 100644
--- a/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
+++ b/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
@@ -1,29 +1,15 @@
-
+
- netstandard2.0
- Full
+ $(TgsNugetNetVersion)
$(TgsApiLibraryVersion)
- true
- Cyberboss/Dominion
- /tg/station 13
API definitions for tgstation-server.
- https://tgstation.github.io/tgstation-server
- LICENSE
- tgs.png
- Git
- https://github.com/tgstation/tgstation-server
- 2018-2023
json web api tgstation-server tgstation ss13 byond http
Minor documentation correction.
- true
- snupkg
- ../../build/analyzers.ruleset
- latest
- enable
- bin\$(Configuration)\netstandard2.0\Tgstation.Server.Api.xml
true
+ ../../build/analyzers.ruleset
+ bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml
CA1028
@@ -61,7 +47,5 @@
-
-
diff --git a/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj b/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj
index bd1874f5d5..07e99c9dd4 100644
--- a/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj
+++ b/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj
@@ -1,29 +1,15 @@
-
+
- netstandard2.0
- Full
+ $(TgsNugetNetVersion)
$(TgsClientVersion)
- true
- Cyberboss/Dominion
- /tg/station 13
Client library for tgstation-server.
- https://tgstation.github.io/tgstation-server
- LICENSE
- tgs.png
- Git
- https://github.com/tgstation/tgstation-server
- 2018-2023
json web api tgstation-server tgstation ss13 byond client http
Added missing Dispose() call to the StringContents for requests with bodies and added missing ConfigureAwait(false) to async call.
- true
- snupkg
- ../../build/analyzers.ruleset
- latest
- enable
- bin\$(Configuration)\netstandard2.0\Tgstation.Server.Client.xml
true
+ ../../build/analyzers.ruleset
+ bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml
@@ -46,7 +32,5 @@
-
-
diff --git a/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj b/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj
index ad8396a76c..582e4741cc 100644
--- a/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj
+++ b/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj
@@ -1,29 +1,15 @@
-
+
- netstandard2.0
- Full
+ $(TgsNugetNetVersion)
$(TgsCoreVersion)
- true
- Cyberboss/Dominion
- /tg/station 13
Common functions for tgstation-server.
- https://tgstation.github.io/tgstation-server
- LICENSE
- tgs.png
- Git
- https://github.com/tgstation/tgstation-server
- 2018-2023
web tgstation-server tgstation ss13 byond client http
Initial release.
- true
- snupkg
- ../../build/analyzers.ruleset
- latest
- enable
- bin\$(Configuration)\netstandard2.0\Tgstation.Server.Client.xml
true
+ ../../build/analyzers.ruleset
+ bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml
@@ -41,7 +27,5 @@
-
-
diff --git a/src/Tgstation.Server.Host.Common/Tgstation.Server.Host.Common.csproj b/src/Tgstation.Server.Host.Common/Tgstation.Server.Host.Common.csproj
index 35c6319a38..dbe6263f1d 100644
--- a/src/Tgstation.Server.Host.Common/Tgstation.Server.Host.Common.csproj
+++ b/src/Tgstation.Server.Host.Common/Tgstation.Server.Host.Common.csproj
@@ -1,15 +1,13 @@
-
+
netstandard2.0
- Full
$(TgsCoreVersion)
- ../../build/analyzers.ruleset
- latest
false
true
- bin\$(Configuration)\netstandard2.0\Tgstation.Server.Host.Shared.xml
+ ../../build/analyzers.ruleset
+ bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml
diff --git a/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj b/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj
index 045d8ce9eb..4d433b2c54 100644
--- a/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj
+++ b/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj
@@ -1,15 +1,14 @@
-
+
Exe
- net6.0
- Full
+ $(TgsNetVersion)
$(TgsCoreVersion)
- ../../build/analyzers.ruleset
- latest
false
true
+ ../../build/analyzers.ruleset
+ bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml
diff --git a/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj b/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj
index 5499f045f7..6f496e9c5e 100644
--- a/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj
+++ b/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj
@@ -1,16 +1,14 @@
-
+
Exe
net472
win
- Full
$(TgsCoreVersion)
- ../../build/analyzers.ruleset
- 7.3
- bin\Debug\Tgstation.Server.Host.Console.xml
true
+ ../../build/analyzers.ruleset
+ bin/$(Configuration)/$(TargetFramework)/$(RuntimeIdentifier)/$(AssemblyName).xml
diff --git a/src/Tgstation.Server.Host.Watchdog/Tgstation.Server.Host.Watchdog.csproj b/src/Tgstation.Server.Host.Watchdog/Tgstation.Server.Host.Watchdog.csproj
index e8b69ace2b..4fb825d496 100644
--- a/src/Tgstation.Server.Host.Watchdog/Tgstation.Server.Host.Watchdog.csproj
+++ b/src/Tgstation.Server.Host.Watchdog/Tgstation.Server.Host.Watchdog.csproj
@@ -1,16 +1,15 @@
-
+
netstandard2.0
Full
false
$(TgsHostWatchdogVersion)
- ../../build/analyzers.ruleset
- latest
false
true
- bin\$(Configuration)\netstandard2.0\Tgstation.Server.Host.Watchdog.xml
+ ../../build/analyzers.ruleset
+ bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml
diff --git a/src/Tgstation.Server.Host/.config/dotnet-tools.json b/src/Tgstation.Server.Host/.config/dotnet-tools.json
index b8b93fc6c0..5bc20db4c2 100644
--- a/src/Tgstation.Server.Host/.config/dotnet-tools.json
+++ b/src/Tgstation.Server.Host/.config/dotnet-tools.json
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-ef": {
- "version": "6.0.15",
+ "version": "6.0.16",
"commands": [
"dotnet-ef"
]
diff --git a/src/Tgstation.Server.Host/Components/Chat/ChannelMapping.cs b/src/Tgstation.Server.Host/Components/Chat/ChannelMapping.cs
index 333706e796..d7430d7c69 100644
--- a/src/Tgstation.Server.Host/Components/Chat/ChannelMapping.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/ChannelMapping.cs
@@ -30,6 +30,11 @@
///
public bool IsAdminChannel { get; set; }
+ ///
+ /// If the is a system messages channel.
+ ///
+ public bool IsSystemChannel { get; set; }
+
///
/// The with the mapped Id.
///
diff --git a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs
index ddd0aff92b..bb545bec03 100644
--- a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs
@@ -207,6 +207,7 @@ namespace Tgstation.Server.Host.Components.Chat
IrcChannel = apiModel.IrcChannel,
IsAdminChannel = apiModel.IsAdminChannel,
IsUpdatesChannel = apiModel.IsUpdatesChannel,
+ IsSystemChannel = apiModel.IsSystemChannel,
IsWatchdogChannel = apiModel.IsWatchdogChannel,
Tag = apiModel.Tag,
})
@@ -220,6 +221,7 @@ namespace Tgstation.Server.Host.Components.Chat
IsWatchdogChannel = kvp.Key.IsWatchdogChannel == true,
IsUpdatesChannel = kvp.Key.IsUpdatesChannel == true,
IsAdminChannel = kvp.Key.IsAdminChannel == true,
+ IsSystemChannel = kvp.Key.IsSystemChannel == true,
ProviderChannelId = channelRepresentation.RealId,
ProviderId = connectionId,
Channel = channelRepresentation,
@@ -514,7 +516,7 @@ namespace Tgstation.Server.Host.Components.Chat
List wdChannels;
lock (mappedChannels) // so it doesn't change while we're using it
wdChannels = mappedChannels
- .Where(x => !x.Value.Channel.IsPrivateChannel)
+ .Where(x => !x.Value.IsSystemChannel)
.Select(x => x.Key)
.ToList();
diff --git a/src/Tgstation.Server.Host/Components/Session/TopicClientFactory.cs b/src/Tgstation.Server.Host/Components/Session/TopicClientFactory.cs
index 559ffd0400..df0289a380 100644
--- a/src/Tgstation.Server.Host/Components/Session/TopicClientFactory.cs
+++ b/src/Tgstation.Server.Host/Components/Session/TopicClientFactory.cs
@@ -19,7 +19,12 @@ namespace Tgstation.Server.Host.Components.Session
/// The value of .
public TopicClientFactory(ILogger logger)
{
- this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ if (logger == null)
+ throw new ArgumentNullException(nameof(logger));
+
+ // Don't want the debug logs Topic client spits out either, they're too verbose
+ if (logger.IsEnabled(LogLevel.Trace))
+ this.logger = logger;
}
///
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs
index e2b1a6b7dc..96b1a16c03 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs
@@ -387,8 +387,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
using (await SemaphoreSlimContext.Lock(synchronizationSemaphore, ct))
await LaunchNoLock(true, true, true, reattachInfo, ct);
},
- cancellationToken)
- ;
+ cancellationToken);
}
///
diff --git a/src/Tgstation.Server.Host/Controllers/ChatController.cs b/src/Tgstation.Server.Host/Controllers/ChatController.cs
index d6a33f6fe8..804a004313 100644
--- a/src/Tgstation.Server.Host/Controllers/ChatController.cs
+++ b/src/Tgstation.Server.Host/Controllers/ChatController.cs
@@ -71,6 +71,7 @@ namespace Tgstation.Server.Host.Controllers
IsAdminChannel = api.IsAdminChannel ?? false,
IsWatchdogChannel = api.IsWatchdogChannel ?? false,
IsUpdatesChannel = api.IsUpdatesChannel ?? false,
+ IsSystemChannel = api.IsSystemChannel ?? false,
Tag = api.Tag,
};
diff --git a/src/Tgstation.Server.Host/Database/DatabaseContext.cs b/src/Tgstation.Server.Host/Database/DatabaseContext.cs
index bf77cbd332..2614ad2329 100644
--- a/src/Tgstation.Server.Host/Database/DatabaseContext.cs
+++ b/src/Tgstation.Server.Host/Database/DatabaseContext.cs
@@ -379,22 +379,22 @@ namespace Tgstation.Server.Host.Database
///
/// Used by unit tests to remind us to setup the correct MSSQL migration downgrades.
///
- internal static readonly Type MSLatestMigration = typeof(MSAddReattachInfoInitialCompileJob);
+ internal static readonly Type MSLatestMigration = typeof(MSAddSystemChannels);
///
/// Used by unit tests to remind us to setup the correct MYSQL migration downgrades.
///
- internal static readonly Type MYLatestMigration = typeof(MYAddReattachInfoInitialCompileJob);
+ internal static readonly Type MYLatestMigration = typeof(MYAddSystemChannels);
///
/// Used by unit tests to remind us to setup the correct PostgresSQL migration downgrades.
///
- internal static readonly Type PGLatestMigration = typeof(PGAddReattachInfoInitialCompileJob);
+ internal static readonly Type PGLatestMigration = typeof(PGAddSystemChannels);
///
/// Used by unit tests to remind us to setup the correct SQLite migration downgrades.
///
- internal static readonly Type SLLatestMigration = typeof(SLAddReattachInfoInitialCompileJob);
+ internal static readonly Type SLLatestMigration = typeof(SLAddSystemChannels);
///
#pragma warning disable CA1502 // Cyclomatic complexity
@@ -425,6 +425,15 @@ namespace Tgstation.Server.Host.Database
string BadDatabaseType() => throw new ArgumentException($"Invalid DatabaseType: {currentDatabaseType}", nameof(currentDatabaseType));
+ if (targetVersion < new Version(5, 13, 0))
+ targetMigration = currentDatabaseType switch
+ {
+ DatabaseType.MySql => nameof(MYAddReattachInfoInitialCompileJob),
+ DatabaseType.PostgresSql => nameof(PGAddReattachInfoInitialCompileJob),
+ DatabaseType.SqlServer => nameof(MSAddReattachInfoInitialCompileJob),
+ DatabaseType.Sqlite => nameof(SLAddReattachInfoInitialCompileJob),
+ _ => BadDatabaseType(),
+ };
if (targetVersion < new Version(5, 7, 3))
targetMigration = currentDatabaseType switch
{
diff --git a/src/Tgstation.Server.Host/Database/Design/MySqlDesignTimeDbContextFactory.cs b/src/Tgstation.Server.Host/Database/Design/MySqlDesignTimeDbContextFactory.cs
index cf758ef363..f67028efff 100644
--- a/src/Tgstation.Server.Host/Database/Design/MySqlDesignTimeDbContextFactory.cs
+++ b/src/Tgstation.Server.Host/Database/Design/MySqlDesignTimeDbContextFactory.cs
@@ -14,6 +14,6 @@ namespace Tgstation.Server.Host.Database.Design
=> new MySqlDatabaseContext(
DesignTimeDbContextFactoryHelpers.CreateDatabaseContextOptions(
DatabaseType.MariaDB,
- "Server=127.0.0.1;User Id=root;Password=fake;Database=TGS_Design"));
+ "Server=127.0.0.1;User Id=root;Password=zdxfOOTlQFnklwzytzCj;Database=TGS_Design"));
}
}
diff --git a/src/Tgstation.Server.Host/Database/Migrations/20230520203236_MSAddSystemChannels.Designer.cs b/src/Tgstation.Server.Host/Database/Migrations/20230520203236_MSAddSystemChannels.Designer.cs
new file mode 100644
index 0000000000..4fa9364f35
--- /dev/null
+++ b/src/Tgstation.Server.Host/Database/Migrations/20230520203236_MSAddSystemChannels.Designer.cs
@@ -0,0 +1,1069 @@
+//
+using System;
+
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Tgstation.Server.Host.Database.Migrations
+{
+ [DbContext(typeof(SqlServerDatabaseContext))]
+ [Migration("20230520203236_MSAddSystemChannels")]
+ partial class MSAddSystemChannels
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "6.0.16")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("ChannelLimit")
+ .HasColumnType("int");
+
+ b.Property("ConnectionString")
+ .IsRequired()
+ .HasMaxLength(10000)
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Enabled")
+ .HasColumnType("bit");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("Provider")
+ .HasColumnType("int");
+
+ b.Property("ReconnectionInterval")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId", "Name")
+ .IsUnique();
+
+ b.ToTable("ChatBots");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("ChatSettingsId")
+ .HasColumnType("bigint");
+
+ b.Property("DiscordChannelId")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("IrcChannel")
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("IsAdminChannel")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("IsSystemChannel")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("IsUpdatesChannel")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("IsWatchdogChannel")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("Tag")
+ .HasMaxLength(10000)
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ChatSettingsId", "DiscordChannelId")
+ .IsUnique()
+ .HasFilter("[DiscordChannelId] IS NOT NULL");
+
+ b.HasIndex("ChatSettingsId", "IrcChannel")
+ .IsUnique()
+ .HasFilter("[IrcChannel] IS NOT NULL");
+
+ b.ToTable("ChatChannels");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("ByondVersion")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DMApiMajorVersion")
+ .HasColumnType("int");
+
+ b.Property("DMApiMinorVersion")
+ .HasColumnType("int");
+
+ b.Property("DMApiPatchVersion")
+ .HasColumnType("int");
+
+ b.Property("DirectoryName")
+ .IsRequired()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("DmeName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("GitHubDeploymentId")
+ .HasColumnType("int");
+
+ b.Property("GitHubRepoId")
+ .HasColumnType("bigint");
+
+ b.Property("JobId")
+ .HasColumnType("bigint");
+
+ b.Property("MinimumSecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("Output")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RepositoryOrigin")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RevisionInformationId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DirectoryName");
+
+ b.HasIndex("JobId")
+ .IsUnique();
+
+ b.HasIndex("RevisionInformationId");
+
+ b.ToTable("CompileJobs");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("AdditionalParameters")
+ .IsRequired()
+ .HasMaxLength(10000)
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("AllowWebClient")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("AutoStart")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("DumpOnHeartbeatRestart")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("HeartbeatSeconds")
+ .HasColumnType("bigint");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("LogOutput")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("Port")
+ .HasColumnType("int");
+
+ b.Property("SecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("StartProfiler")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("StartupTimeout")
+ .HasColumnType("bigint");
+
+ b.Property("TopicRequestTimeout")
+ .HasColumnType("bigint");
+
+ b.Property("Visibility")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId")
+ .IsUnique();
+
+ b.ToTable("DreamDaemonSettings");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("ApiValidationPort")
+ .HasColumnType("int");
+
+ b.Property("ApiValidationSecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("ProjectName")
+ .HasMaxLength(10000)
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RequireDMApiValidation")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("Timeout")
+ .IsRequired()
+ .HasColumnType("time");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId")
+ .IsUnique();
+
+ b.ToTable("DreamMakerSettings");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("AutoUpdateInterval")
+ .HasColumnType("bigint");
+
+ b.Property("ChatBotLimit")
+ .HasColumnType("int");
+
+ b.Property("ConfigurationType")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("Online")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("SwarmIdentifer")
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Path", "SwarmIdentifer")
+ .IsUnique()
+ .HasFilter("[SwarmIdentifer] IS NOT NULL");
+
+ b.ToTable("Instances");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.InstancePermissionSet", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("ByondRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("ChatBotRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("ConfigurationRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("DreamDaemonRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("DreamMakerRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("InstancePermissionSetRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("PermissionSetId")
+ .HasColumnType("bigint");
+
+ b.Property("RepositoryRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId");
+
+ b.HasIndex("PermissionSetId", "InstanceId")
+ .IsUnique();
+
+ b.ToTable("InstancePermissionSets");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("CancelRight")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("CancelRightsType")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("Cancelled")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("CancelledById")
+ .HasColumnType("bigint");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ErrorCode")
+ .HasColumnType("bigint");
+
+ b.Property("ExceptionDetails")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("StartedAt")
+ .IsRequired()
+ .HasColumnType("datetimeoffset");
+
+ b.Property("StartedById")
+ .HasColumnType("bigint");
+
+ b.Property("StoppedAt")
+ .HasColumnType("datetimeoffset");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CancelledById");
+
+ b.HasIndex("InstanceId");
+
+ b.HasIndex("StartedById");
+
+ b.ToTable("Jobs");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.OAuthConnection", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("ExternalUserId")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("Provider")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("Provider", "ExternalUserId")
+ .IsUnique();
+
+ b.ToTable("OAuthConnections");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.PermissionSet", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("AdministrationRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("GroupId")
+ .HasColumnType("bigint");
+
+ b.Property("InstanceManagerRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("UserId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GroupId")
+ .IsUnique()
+ .HasFilter("[GroupId] IS NOT NULL");
+
+ b.HasIndex("UserId")
+ .IsUnique()
+ .HasFilter("[UserId] IS NOT NULL");
+
+ b.ToTable("PermissionSets");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("AccessIdentifier")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CompileJobId")
+ .HasColumnType("bigint");
+
+ b.Property("InitialCompileJobId")
+ .HasColumnType("bigint");
+
+ b.Property("LaunchSecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("LaunchVisibility")
+ .HasColumnType("int");
+
+ b.Property("Port")
+ .HasColumnType("int");
+
+ b.Property("ProcessId")
+ .HasColumnType("int");
+
+ b.Property("RebootState")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CompileJobId");
+
+ b.HasIndex("InitialCompileJobId");
+
+ b.ToTable("ReattachInformations");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("AccessToken")
+ .HasMaxLength(10000)
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("AccessUser")
+ .HasMaxLength(10000)
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("AutoUpdatesKeepTestMerges")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("AutoUpdatesSynchronize")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("CommitterEmail")
+ .IsRequired()
+ .HasMaxLength(10000)
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CommitterName")
+ .IsRequired()
+ .HasMaxLength(10000)
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreateGitHubDeployments")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("PostTestMergeComment")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("PushTestMergeCommits")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("ShowTestMergeCommitters")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("UpdateSubmodules")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId")
+ .IsUnique();
+
+ b.ToTable("RepositorySettings");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("RevisionInformationId")
+ .HasColumnType("bigint");
+
+ b.Property("TestMergeId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RevisionInformationId");
+
+ b.HasIndex("TestMergeId");
+
+ b.ToTable("RevInfoTestMerges");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("CommitSha")
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("OriginCommitSha")
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)");
+
+ b.Property("Timestamp")
+ .HasColumnType("datetimeoffset");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId", "CommitSha")
+ .IsUnique();
+
+ b.ToTable("RevisionInformations");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("Author")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("BodyAtMerge")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Comment")
+ .HasMaxLength(10000)
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("MergedAt")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("MergedById")
+ .HasColumnType("bigint");
+
+ b.Property("Number")
+ .HasColumnType("int");
+
+ b.Property("PrimaryRevisionInformationId")
+ .IsRequired()
+ .HasColumnType("bigint");
+
+ b.Property("TargetCommitSha")
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)");
+
+ b.Property("TitleAtMerge")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Url")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MergedById");
+
+ b.HasIndex("PrimaryRevisionInformationId")
+ .IsUnique();
+
+ b.ToTable("TestMerges");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("CanonicalName")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("CreatedAt")
+ .IsRequired()
+ .HasColumnType("datetimeoffset");
+
+ b.Property("CreatedById")
+ .HasColumnType("bigint");
+
+ b.Property("Enabled")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("GroupId")
+ .HasColumnType("bigint");
+
+ b.Property("LastPasswordUpdate")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("PasswordHash")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("SystemIdentifier")
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CanonicalName")
+ .IsUnique();
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("GroupId");
+
+ b.HasIndex("SystemIdentifier")
+ .IsUnique()
+ .HasFilter("[SystemIdentifier] IS NOT NULL");
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.UserGroup", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("Groups");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
+ .WithMany("ChatSettings")
+ .HasForeignKey("InstanceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Instance");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings")
+ .WithMany("Channels")
+ .HasForeignKey("ChatSettingsId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("ChatSettings");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.Job", "Job")
+ .WithOne()
+ .HasForeignKey("Tgstation.Server.Host.Models.CompileJob", "JobId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
+ .WithMany("CompileJobs")
+ .HasForeignKey("RevisionInformationId")
+ .OnDelete(DeleteBehavior.ClientNoAction)
+ .IsRequired();
+
+ b.Navigation("Job");
+
+ b.Navigation("RevisionInformation");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
+ .WithOne("DreamDaemonSettings")
+ .HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Instance");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
+ .WithOne("DreamMakerSettings")
+ .HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Instance");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.InstancePermissionSet", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
+ .WithMany("InstancePermissionSets")
+ .HasForeignKey("InstanceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Tgstation.Server.Host.Models.PermissionSet", "PermissionSet")
+ .WithMany("InstancePermissionSets")
+ .HasForeignKey("PermissionSetId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Instance");
+
+ b.Navigation("PermissionSet");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy")
+ .WithMany()
+ .HasForeignKey("CancelledById");
+
+ b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
+ .WithMany("Jobs")
+ .HasForeignKey("InstanceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy")
+ .WithMany()
+ .HasForeignKey("StartedById")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("CancelledBy");
+
+ b.Navigation("Instance");
+
+ b.Navigation("StartedBy");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.OAuthConnection", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.User", "User")
+ .WithMany("OAuthConnections")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.PermissionSet", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.UserGroup", "Group")
+ .WithOne("PermissionSet")
+ .HasForeignKey("Tgstation.Server.Host.Models.PermissionSet", "GroupId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.HasOne("Tgstation.Server.Host.Models.User", "User")
+ .WithOne("PermissionSet")
+ .HasForeignKey("Tgstation.Server.Host.Models.PermissionSet", "UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.Navigation("Group");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob")
+ .WithMany()
+ .HasForeignKey("CompileJobId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Tgstation.Server.Host.Models.CompileJob", "InitialCompileJob")
+ .WithMany()
+ .HasForeignKey("InitialCompileJobId");
+
+ b.Navigation("CompileJob");
+
+ b.Navigation("InitialCompileJob");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
+ .WithOne("RepositorySettings")
+ .HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Instance");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
+ .WithMany("ActiveTestMerges")
+ .HasForeignKey("RevisionInformationId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge")
+ .WithMany("RevisonInformations")
+ .HasForeignKey("TestMergeId")
+ .OnDelete(DeleteBehavior.ClientNoAction)
+ .IsRequired();
+
+ b.Navigation("RevisionInformation");
+
+ b.Navigation("TestMerge");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
+ .WithMany("RevisionInformations")
+ .HasForeignKey("InstanceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Instance");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy")
+ .WithMany("TestMerges")
+ .HasForeignKey("MergedById")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation")
+ .WithOne("PrimaryTestMerge")
+ .HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("MergedBy");
+
+ b.Navigation("PrimaryRevisionInformation");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy")
+ .WithMany("CreatedUsers")
+ .HasForeignKey("CreatedById");
+
+ b.HasOne("Tgstation.Server.Host.Models.UserGroup", "Group")
+ .WithMany("Users")
+ .HasForeignKey("GroupId");
+
+ b.Navigation("CreatedBy");
+
+ b.Navigation("Group");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
+ {
+ b.Navigation("Channels");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
+ {
+ b.Navigation("ChatSettings");
+
+ b.Navigation("DreamDaemonSettings");
+
+ b.Navigation("DreamMakerSettings");
+
+ b.Navigation("InstancePermissionSets");
+
+ b.Navigation("Jobs");
+
+ b.Navigation("RepositorySettings");
+
+ b.Navigation("RevisionInformations");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.PermissionSet", b =>
+ {
+ b.Navigation("InstancePermissionSets");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
+ {
+ b.Navigation("ActiveTestMerges");
+
+ b.Navigation("CompileJobs");
+
+ b.Navigation("PrimaryTestMerge");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
+ {
+ b.Navigation("RevisonInformations");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
+ {
+ b.Navigation("CreatedUsers");
+
+ b.Navigation("OAuthConnections");
+
+ b.Navigation("PermissionSet");
+
+ b.Navigation("TestMerges");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.UserGroup", b =>
+ {
+ b.Navigation("PermissionSet")
+ .IsRequired();
+
+ b.Navigation("Users");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/Tgstation.Server.Host/Database/Migrations/20230520203236_MSAddSystemChannels.cs b/src/Tgstation.Server.Host/Database/Migrations/20230520203236_MSAddSystemChannels.cs
new file mode 100644
index 0000000000..b2ead80c4d
--- /dev/null
+++ b/src/Tgstation.Server.Host/Database/Migrations/20230520203236_MSAddSystemChannels.cs
@@ -0,0 +1,39 @@
+using System;
+
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Tgstation.Server.Host.Database.Migrations
+{
+ ///
+ /// Adds the IsSystemChannel chat channel option for MSSQL.
+ ///
+ public partial class MSAddSystemChannels : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ if (migrationBuilder == null)
+ throw new ArgumentNullException(nameof(migrationBuilder));
+
+ migrationBuilder.AddColumn(
+ name: "IsSystemChannel",
+ table: "ChatChannels",
+ type: "bit",
+ nullable: false,
+ defaultValue: true);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ if (migrationBuilder == null)
+ throw new ArgumentNullException(nameof(migrationBuilder));
+
+ migrationBuilder.DropColumn(
+ name: "IsSystemChannel",
+ table: "ChatChannels");
+ }
+ }
+}
diff --git a/src/Tgstation.Server.Host/Database/Migrations/20230520203305_MYAddSystemChannels.Designer.cs b/src/Tgstation.Server.Host/Database/Migrations/20230520203305_MYAddSystemChannels.Designer.cs
new file mode 100644
index 0000000000..3f1e7b3249
--- /dev/null
+++ b/src/Tgstation.Server.Host/Database/Migrations/20230520203305_MYAddSystemChannels.Designer.cs
@@ -0,0 +1,1102 @@
+//
+using System;
+
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Tgstation.Server.Host.Database.Migrations
+{
+ [DbContext(typeof(MySqlDatabaseContext))]
+ [Migration("20230520203305_MYAddSystemChannels")]
+ partial class MYAddSystemChannels
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "6.0.16")
+ .HasAnnotation("Relational:MaxIdentifierLength", 64);
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("ChannelLimit")
+ .IsRequired()
+ .HasColumnType("smallint unsigned");
+
+ b.Property("ConnectionString")
+ .IsRequired()
+ .HasMaxLength(10000)
+ .HasColumnType("longtext");
+
+ MySqlPropertyBuilderExtensions.HasCharSet(b.Property("ConnectionString"), "utf8mb4");
+
+ b.Property("Enabled")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("varchar(100)");
+
+ b.Property("Provider")
+ .HasColumnType("int");
+
+ b.Property("ReconnectionInterval")
+ .IsRequired()
+ .HasColumnType("int unsigned");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId", "Name")
+ .IsUnique();
+
+ b.ToTable("ChatBots");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("ChatSettingsId")
+ .HasColumnType("bigint");
+
+ b.Property("DiscordChannelId")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("IrcChannel")
+ .HasMaxLength(100)
+ .HasColumnType("varchar(100)");
+
+ MySqlPropertyBuilderExtensions.HasCharSet(b.Property("IrcChannel"), "utf8mb4");
+
+ b.Property("IsAdminChannel")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("IsSystemChannel")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("IsUpdatesChannel")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("IsWatchdogChannel")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Tag")
+ .HasMaxLength(10000)
+ .HasColumnType("longtext");
+
+ MySqlPropertyBuilderExtensions.HasCharSet(b.Property("Tag"), "utf8mb4");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ChatSettingsId", "DiscordChannelId")
+ .IsUnique();
+
+ b.HasIndex("ChatSettingsId", "IrcChannel")
+ .IsUnique();
+
+ b.ToTable("ChatChannels");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("ByondVersion")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ MySqlPropertyBuilderExtensions.HasCharSet(b.Property("ByondVersion"), "utf8mb4");
+
+ b.Property("DMApiMajorVersion")
+ .HasColumnType("int");
+
+ b.Property("DMApiMinorVersion")
+ .HasColumnType("int");
+
+ b.Property("DMApiPatchVersion")
+ .HasColumnType("int");
+
+ b.Property("DirectoryName")
+ .IsRequired()
+ .HasColumnType("char(36)");
+
+ b.Property("DmeName")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ MySqlPropertyBuilderExtensions.HasCharSet(b.Property("DmeName"), "utf8mb4");
+
+ b.Property("GitHubDeploymentId")
+ .HasColumnType("int");
+
+ b.Property("GitHubRepoId")
+ .HasColumnType("bigint");
+
+ b.Property("JobId")
+ .HasColumnType("bigint");
+
+ b.Property("MinimumSecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("Output")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ MySqlPropertyBuilderExtensions.HasCharSet(b.Property("Output"), "utf8mb4");
+
+ b.Property("RepositoryOrigin")
+ .HasColumnType("longtext");
+
+ MySqlPropertyBuilderExtensions.HasCharSet(b.Property("RepositoryOrigin"), "utf8mb4");
+
+ b.Property("RevisionInformationId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DirectoryName");
+
+ b.HasIndex("JobId")
+ .IsUnique();
+
+ b.HasIndex("RevisionInformationId");
+
+ b.ToTable("CompileJobs");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("AdditionalParameters")
+ .IsRequired()
+ .HasMaxLength(10000)
+ .HasColumnType("longtext");
+
+ MySqlPropertyBuilderExtensions.HasCharSet(b.Property("AdditionalParameters"), "utf8mb4");
+
+ b.Property("AllowWebClient")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("AutoStart")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("DumpOnHeartbeatRestart")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("HeartbeatSeconds")
+ .IsRequired()
+ .HasColumnType("int unsigned");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("LogOutput")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Port")
+ .IsRequired()
+ .HasColumnType("smallint unsigned");
+
+ b.Property("SecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("StartProfiler")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("StartupTimeout")
+ .IsRequired()
+ .HasColumnType("int unsigned");
+
+ b.Property("TopicRequestTimeout")
+ .IsRequired()
+ .HasColumnType("int unsigned");
+
+ b.Property("Visibility")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId")
+ .IsUnique();
+
+ b.ToTable("DreamDaemonSettings");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("ApiValidationPort")
+ .IsRequired()
+ .HasColumnType("smallint unsigned");
+
+ b.Property("ApiValidationSecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("ProjectName")
+ .HasMaxLength(10000)
+ .HasColumnType("longtext");
+
+ MySqlPropertyBuilderExtensions.HasCharSet(b.Property("ProjectName"), "utf8mb4");
+
+ b.Property("RequireDMApiValidation")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Timeout")
+ .IsRequired()
+ .HasColumnType("time(6)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId")
+ .IsUnique();
+
+ b.ToTable("DreamMakerSettings");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("AutoUpdateInterval")
+ .IsRequired()
+ .HasColumnType("int unsigned");
+
+ b.Property("ChatBotLimit")
+ .IsRequired()
+ .HasColumnType("smallint unsigned");
+
+ b.Property("ConfigurationType")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("varchar(100)");
+
+ MySqlPropertyBuilderExtensions.HasCharSet(b.Property("Name"), "utf8mb4");
+
+ b.Property("Online")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ MySqlPropertyBuilderExtensions.HasCharSet(b.Property("Path"), "utf8mb4");
+
+ b.Property("SwarmIdentifer")
+ .HasColumnType("varchar(255)");
+
+ MySqlPropertyBuilderExtensions.HasCharSet(b.Property("SwarmIdentifer"), "utf8mb4");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Path", "SwarmIdentifer")
+ .IsUnique();
+
+ b.ToTable("Instances");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.InstancePermissionSet", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("ByondRights")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("ChatBotRights")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("ConfigurationRights")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("DreamDaemonRights")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("DreamMakerRights")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("InstancePermissionSetRights")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("PermissionSetId")
+ .HasColumnType("bigint");
+
+ b.Property