mirror of
https://github.com/space-wizards/space-station-14.git
synced 2026-02-14 19:29:53 +01:00
Stable to master (#42599)
Ban database refactor (#42495) * Ban DB refactor seems to work at a basic level for PostgreSQL * New ban creation API Supports all the new functionality (multiple players/addresses/hwids/roles/rounds per ban). * Make the migration irreversible * Re-implement ban notifications The server ID check is no longer done as admins may want to place bans spanning multiple rounds irrelevant of the source server. * Fix some split query warnings * Implement migration on SQLite * More comments * Remove required from ban reason SS14.Admin changes would like this * More missing AsSplitQuery() calls * Fix missing ban type filter * Fix old CreateServerBan API with permanent time * Fix department and role ban commands with permanent time * Re-add banhits navigation property Dropped this on accident, SS14.Admin needs it. * More ban API fixes. * Don't fetch ban exemption info for role bans Not relevant, reduces query performance * Regenerate migrations * Fix adminnotes command for players that never connected Would blow up handling null player records. Not a new bug introduced by the refactor, but I ran into it. * Great shame... I accidentally committed submodule update... * Update GDPR scripts * Fix sandbox violation * Fix bans with duplicate info causing DB exceptions Most notably happened with role bans, as multiple departments may include the same role.
This commit is contained in:
committed by
GitHub
parent
facd7da394
commit
29b7fc4463
2125
Content.Server.Database/Migrations/Postgres/20260120200503_BanRefactor.Designer.cs
generated
Normal file
2125
Content.Server.Database/Migrations/Postgres/20260120200503_BanRefactor.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,535 @@
|
||||
using System;
|
||||
using Content.Shared.Database;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using NpgsqlTypes;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Content.Server.Database.Migrations.Postgres
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class BanRefactor : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ban",
|
||||
columns: table => new
|
||||
{
|
||||
ban_id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
type = table.Column<byte>(type: "smallint", nullable: false),
|
||||
playtime_at_note = table.Column<TimeSpan>(type: "interval", nullable: false),
|
||||
ban_time = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
expiration_time = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
reason = table.Column<string>(type: "text", nullable: false),
|
||||
severity = table.Column<int>(type: "integer", nullable: false),
|
||||
banning_admin = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
last_edited_by_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
last_edited_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
exempt_flags = table.Column<int>(type: "integer", nullable: false),
|
||||
auto_delete = table.Column<bool>(type: "boolean", nullable: false),
|
||||
hidden = table.Column<bool>(type: "boolean", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ban", x => x.ban_id);
|
||||
table.CheckConstraint("NoExemptOnRoleBan", "type = 0 OR exempt_flags = 0");
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_player_banning_admin",
|
||||
column: x => x.banning_admin,
|
||||
principalTable: "player",
|
||||
principalColumn: "user_id",
|
||||
onDelete: ReferentialAction.SetNull);
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_player_last_edited_by_id",
|
||||
column: x => x.last_edited_by_id,
|
||||
principalTable: "player",
|
||||
principalColumn: "user_id",
|
||||
onDelete: ReferentialAction.SetNull);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ban_address",
|
||||
columns: table => new
|
||||
{
|
||||
ban_address_id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
address = table.Column<NpgsqlInet>(type: "inet", nullable: false),
|
||||
ban_id = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ban_address", x => x.ban_address_id);
|
||||
table.CheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address");
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_address_ban_ban_id",
|
||||
column: x => x.ban_id,
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ban_hwid",
|
||||
columns: table => new
|
||||
{
|
||||
ban_hwid_id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
hwid = table.Column<byte[]>(type: "bytea", nullable: false),
|
||||
hwid_type = table.Column<int>(type: "integer", nullable: false),
|
||||
ban_id = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ban_hwid", x => x.ban_hwid_id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_hwid_ban_ban_id",
|
||||
column: x => x.ban_id,
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ban_player",
|
||||
columns: table => new
|
||||
{
|
||||
ban_player_id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ban_id = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ban_player", x => x.ban_player_id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_player_ban_ban_id",
|
||||
column: x => x.ban_id,
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ban_role",
|
||||
columns: table => new
|
||||
{
|
||||
ban_role_id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
role_type = table.Column<string>(type: "text", nullable: false),
|
||||
role_id = table.Column<string>(type: "text", nullable: false),
|
||||
ban_id = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ban_role", x => x.ban_role_id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_role_ban_ban_id",
|
||||
column: x => x.ban_id,
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ban_round",
|
||||
columns: table => new
|
||||
{
|
||||
ban_round_id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
ban_id = table.Column<int>(type: "integer", nullable: false),
|
||||
round_id = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ban_round", x => x.ban_round_id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_round_ban_ban_id",
|
||||
column: x => x.ban_id,
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_round_round_round_id",
|
||||
column: x => x.round_id,
|
||||
principalTable: "round",
|
||||
principalColumn: "round_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "unban",
|
||||
columns: table => new
|
||||
{
|
||||
unban_id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
ban_id = table.Column<int>(type: "integer", nullable: false),
|
||||
unbanning_admin = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
unban_time = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_unban", x => x.unban_id);
|
||||
table.ForeignKey(
|
||||
name: "FK_unban_ban_ban_id",
|
||||
column: x => x.ban_id,
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_banning_admin",
|
||||
table: "ban",
|
||||
column: "banning_admin");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_last_edited_by_id",
|
||||
table: "ban",
|
||||
column: "last_edited_by_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_address_ban_id",
|
||||
table: "ban_address",
|
||||
column: "ban_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_hwid_ban_id",
|
||||
table: "ban_hwid",
|
||||
column: "ban_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_player_ban_id",
|
||||
table: "ban_player",
|
||||
column: "ban_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_player_user_id_ban_id",
|
||||
table: "ban_player",
|
||||
columns: new[] { "user_id", "ban_id" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_role_ban_id",
|
||||
table: "ban_role",
|
||||
column: "ban_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_role_role_type_role_id_ban_id",
|
||||
table: "ban_role",
|
||||
columns: new[] { "role_type", "role_id", "ban_id" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_round_ban_id",
|
||||
table: "ban_round",
|
||||
column: "ban_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_round_round_id_ban_id",
|
||||
table: "ban_round",
|
||||
columns: new[] { "round_id", "ban_id" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_unban_ban_id",
|
||||
table: "unban",
|
||||
column: "ban_id",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_server_ban_hit_ban_ban_id",
|
||||
table: "server_ban_hit",
|
||||
column: "ban_id",
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.Sql("""
|
||||
CREATE INDEX "IX_ban_address_address"
|
||||
ON ban_address
|
||||
USING gist
|
||||
(address inet_ops)
|
||||
INCLUDE (ban_id);
|
||||
|
||||
CREATE UNIQUE INDEX "IX_ban_hwid_hwid_ban_id"
|
||||
ON ban_hwid
|
||||
(hwid_type, hwid, ban_id);
|
||||
|
||||
CREATE UNIQUE INDEX "IX_ban_address_address_ban_id"
|
||||
ON ban_address
|
||||
(address, ban_id);
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql($"""
|
||||
-- REMOVE:
|
||||
-- TRUNCATE ban RESTART IDENTITY CASCADE;
|
||||
|
||||
--
|
||||
-- Insert game bans
|
||||
--
|
||||
INSERT INTO
|
||||
ban (ban_id, type, playtime_at_note, ban_time, expiration_time, reason, severity, banning_admin, last_edited_by_id, last_edited_at, exempt_flags, auto_delete, hidden)
|
||||
SELECT
|
||||
server_ban_id, {(int)BanType.Server}, playtime_at_note, ban_time, expiration_time, reason, severity, banning_admin, last_edited_by_id, last_edited_at, exempt_flags, auto_delete, hidden
|
||||
FROM
|
||||
server_ban;
|
||||
|
||||
-- Update ID sequence to be after newly inserted IDs.
|
||||
SELECT setval('ban_ban_id_seq', (SELECT MAX(ban_id) FROM ban));
|
||||
|
||||
-- Insert ban player records.
|
||||
INSERT INTO
|
||||
ban_player (user_id, ban_id)
|
||||
SELECT
|
||||
player_user_id, server_ban_id
|
||||
FROM
|
||||
server_ban
|
||||
WHERE
|
||||
player_user_id IS NOT NULL;
|
||||
|
||||
-- Insert ban address records.
|
||||
INSERT INTO
|
||||
ban_address (address, ban_id)
|
||||
SELECT
|
||||
address, server_ban_id
|
||||
FROM
|
||||
server_ban
|
||||
WHERE
|
||||
address IS NOT NULL;
|
||||
|
||||
-- Insert ban HWID records.
|
||||
INSERT INTO
|
||||
ban_hwid (hwid, hwid_type, ban_id)
|
||||
SELECT
|
||||
hwid, hwid_type, server_ban_id
|
||||
FROM
|
||||
server_ban
|
||||
WHERE
|
||||
hwid IS NOT NULL;
|
||||
|
||||
-- Insert ban unban records.
|
||||
INSERT INTO
|
||||
unban (ban_id, unbanning_admin, unban_time)
|
||||
SELECT
|
||||
ban_id, unbanning_admin, unban_time
|
||||
FROM server_unban;
|
||||
|
||||
|
||||
-- Insert ban round records.
|
||||
INSERT INTO
|
||||
ban_round (round_id, ban_id)
|
||||
SELECT
|
||||
round_id, server_ban_id
|
||||
FROM
|
||||
server_ban
|
||||
WHERE
|
||||
round_id IS NOT NULL;
|
||||
|
||||
--
|
||||
-- Insert role bans
|
||||
-- This shit is a pain in the ass
|
||||
-- > Declarative language
|
||||
-- > Has to write procedural code in it
|
||||
--
|
||||
|
||||
-- Create mapping table from role ban -> server ban.
|
||||
-- We have to manually calculate the new ban IDs by using the sequence.
|
||||
-- We also want to merge role ban records because the game code previously did that in some UI,
|
||||
-- and that code is now gone, expecting the DB to do it.
|
||||
|
||||
-- Create a table to store IDs to merge.
|
||||
CREATE TEMPORARY TABLE /*IF NOT EXISTS*/ _role_ban_import_merge_map (merge_id INTEGER, server_role_ban_id INTEGER UNIQUE) ON COMMIT DROP;
|
||||
-- TRUNCATE _role_ban_import_merge_map;
|
||||
|
||||
-- Create a table to store merged IDs -> new ban IDs
|
||||
CREATE TEMPORARY TABLE /*IF NOT EXISTS*/ _role_ban_import_id_map (ban_id INTEGER UNIQUE, merge_id INTEGER UNIQUE) ON COMMIT DROP;
|
||||
-- TRUNCATE _role_ban_import_id_map;
|
||||
|
||||
-- Calculate merged role bans.
|
||||
INSERT INTO
|
||||
_role_ban_import_merge_map
|
||||
SELECT
|
||||
(
|
||||
SELECT
|
||||
sub.server_role_ban_id
|
||||
FROM
|
||||
server_role_ban AS sub
|
||||
LEFT JOIN server_role_unban AS sub_unban
|
||||
ON sub_unban.ban_id = sub.server_role_ban_id
|
||||
WHERE
|
||||
main.reason IS NOT DISTINCT FROM sub.reason
|
||||
AND main.player_user_id IS NOT DISTINCT FROM sub.player_user_id
|
||||
AND main.address IS NOT DISTINCT FROM sub.address
|
||||
AND main.hwid IS NOT DISTINCT FROM sub.hwid
|
||||
AND main.hwid_type IS NOT DISTINCT FROM sub.hwid_type
|
||||
AND date_trunc('second', main.ban_time, 'utc') = date_trunc('second', sub.ban_time, 'utc')
|
||||
AND (
|
||||
(main.expiration_time IS NULL) = (sub.expiration_time IS NULL)
|
||||
OR date_trunc('minute', main.expiration_time, 'utc') = date_trunc('minute', sub.expiration_time, 'utc')
|
||||
)
|
||||
AND main.round_id IS NOT DISTINCT FROM sub.round_id
|
||||
AND main.severity IS NOT DISTINCT FROM sub.severity
|
||||
AND main.hidden IS NOT DISTINCT FROM sub.hidden
|
||||
AND main.banning_admin IS NOT DISTINCT FROM sub.banning_admin
|
||||
AND (sub_unban.ban_id IS NULL) = (main_unban.ban_id IS NULL)
|
||||
ORDER BY
|
||||
sub.server_role_ban_id ASC
|
||||
LIMIT 1
|
||||
), main.server_role_ban_id
|
||||
FROM
|
||||
server_role_ban AS main
|
||||
LEFT JOIN server_role_unban AS main_unban
|
||||
ON main_unban.ban_id = main.server_role_ban_id;
|
||||
|
||||
-- Assign new ban IDs for merged IDs.
|
||||
INSERT INTO
|
||||
_role_ban_import_id_map
|
||||
SELECT
|
||||
DISTINCT ON (merge_id)
|
||||
nextval('ban_ban_id_seq'),
|
||||
merge_id
|
||||
FROM
|
||||
_role_ban_import_merge_map;
|
||||
|
||||
-- I sure fucking wish CTEs could span multiple queries...
|
||||
|
||||
-- Insert new ban records
|
||||
INSERT INTO
|
||||
ban (ban_id, type, playtime_at_note, ban_time, expiration_time, reason, severity, banning_admin, last_edited_by_id, last_edited_at, exempt_flags, auto_delete, hidden)
|
||||
SELECT
|
||||
im.ban_id, {(int)BanType.Role}, playtime_at_note, ban_time, expiration_time, reason, severity, banning_admin, last_edited_by_id, last_edited_at, 0, FALSE, hidden
|
||||
FROM
|
||||
_role_ban_import_id_map im
|
||||
INNER JOIN _role_ban_import_merge_map mm
|
||||
ON im.merge_id = mm.merge_id
|
||||
INNER JOIN server_role_ban srb
|
||||
ON srb.server_role_ban_id = im.merge_id
|
||||
WHERE mm.merge_id = mm.server_role_ban_id;
|
||||
|
||||
-- Insert role ban player records.
|
||||
INSERT INTO
|
||||
ban_player (user_id, ban_id)
|
||||
SELECT
|
||||
player_user_id, im.ban_id
|
||||
FROM
|
||||
_role_ban_import_id_map im
|
||||
INNER JOIN _role_ban_import_merge_map mm
|
||||
ON im.merge_id = mm.merge_id
|
||||
INNER JOIN server_role_ban srb
|
||||
ON srb.server_role_ban_id = im.merge_id
|
||||
WHERE mm.merge_id = mm.server_role_ban_id
|
||||
AND player_user_id IS NOT NULL;
|
||||
|
||||
-- Insert role ban address records.
|
||||
INSERT INTO
|
||||
ban_address (address, ban_id)
|
||||
SELECT
|
||||
address, im.ban_id
|
||||
FROM
|
||||
_role_ban_import_id_map im
|
||||
INNER JOIN _role_ban_import_merge_map mm
|
||||
ON im.merge_id = mm.merge_id
|
||||
INNER JOIN server_role_ban srb
|
||||
ON srb.server_role_ban_id = im.merge_id
|
||||
WHERE mm.merge_id = mm.server_role_ban_id
|
||||
AND address IS NOT NULL;
|
||||
|
||||
-- Insert role ban HWID records.
|
||||
INSERT INTO
|
||||
ban_hwid (hwid, hwid_type, ban_id)
|
||||
SELECT
|
||||
hwid, hwid_type, im.ban_id
|
||||
FROM
|
||||
_role_ban_import_id_map im
|
||||
INNER JOIN _role_ban_import_merge_map mm
|
||||
ON im.merge_id = mm.merge_id
|
||||
INNER JOIN server_role_ban srb
|
||||
ON srb.server_role_ban_id = im.merge_id
|
||||
WHERE mm.merge_id = mm.server_role_ban_id
|
||||
AND hwid IS NOT NULL;
|
||||
|
||||
-- Insert role ban role records.
|
||||
INSERT INTO
|
||||
ban_role (role_type, role_id, ban_id)
|
||||
SELECT
|
||||
split_part(role_id, ':', 1), split_part(role_id, ':', 2), im.ban_id
|
||||
FROM
|
||||
_role_ban_import_id_map im
|
||||
INNER JOIN _role_ban_import_merge_map mm
|
||||
ON im.merge_id = mm.merge_id
|
||||
INNER JOIN server_role_ban srb
|
||||
ON srb.server_role_ban_id = mm.server_role_ban_id
|
||||
-- Yes, we have some messy ban records which, after merging, end up with duplicate roles.
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- Insert role unban records.
|
||||
INSERT INTO
|
||||
unban (ban_id, unbanning_admin, unban_time)
|
||||
SELECT
|
||||
im.ban_id, unbanning_admin, unban_time
|
||||
FROM server_role_unban sru
|
||||
INNER JOIN _role_ban_import_id_map im
|
||||
ON im.merge_id = sru.ban_id;
|
||||
|
||||
-- Insert role rounds
|
||||
INSERT INTO
|
||||
ban_round (round_id, ban_id)
|
||||
SELECT
|
||||
round_id, im.ban_id
|
||||
FROM
|
||||
_role_ban_import_id_map im
|
||||
INNER JOIN _role_ban_import_merge_map mm
|
||||
ON im.merge_id = mm.merge_id
|
||||
INNER JOIN server_role_ban srb
|
||||
ON srb.server_role_ban_id = im.merge_id
|
||||
WHERE mm.merge_id = mm.server_role_ban_id
|
||||
AND round_id IS NOT NULL;
|
||||
""");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_server_ban_hit_server_ban_ban_id",
|
||||
table: "server_ban_hit");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "server_role_unban");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "server_unban");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "server_role_ban");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "server_ban");
|
||||
|
||||
migrationBuilder.Sql($"""
|
||||
CREATE OR REPLACE FUNCTION send_server_ban_notification()
|
||||
RETURNS trigger AS $$
|
||||
BEGIN
|
||||
PERFORM pg_notify(
|
||||
'ban_notification',
|
||||
json_build_object('ban_id', NEW.ban_id)::text
|
||||
);
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER notify_on_server_ban_insert
|
||||
AFTER INSERT ON ban
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.type = {(int)BanType.Server})
|
||||
EXECUTE FUNCTION send_server_ban_notification();
|
||||
""");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
throw new NotSupportedException("This migration cannot be rolled back");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -519,6 +519,221 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
b.ToTable("assigned_user_id", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Ban", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<bool>("AutoDelete")
|
||||
.HasColumnType("boolean")
|
||||
.HasColumnName("auto_delete");
|
||||
|
||||
b.Property<DateTime>("BanTime")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("ban_time");
|
||||
|
||||
b.Property<Guid?>("BanningAdmin")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("banning_admin");
|
||||
|
||||
b.Property<int>("ExemptFlags")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("exempt_flags");
|
||||
|
||||
b.Property<DateTime?>("ExpirationTime")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("expiration_time");
|
||||
|
||||
b.Property<bool>("Hidden")
|
||||
.HasColumnType("boolean")
|
||||
.HasColumnName("hidden");
|
||||
|
||||
b.Property<DateTime?>("LastEditedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("last_edited_at");
|
||||
|
||||
b.Property<Guid?>("LastEditedById")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("last_edited_by_id");
|
||||
|
||||
b.Property<TimeSpan>("PlaytimeAtNote")
|
||||
.HasColumnType("interval")
|
||||
.HasColumnName("playtime_at_note");
|
||||
|
||||
b.Property<string>("Reason")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("reason");
|
||||
|
||||
b.Property<int>("Severity")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("severity");
|
||||
|
||||
b.Property<byte>("Type")
|
||||
.HasColumnType("smallint")
|
||||
.HasColumnName("type");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_ban");
|
||||
|
||||
b.HasIndex("BanningAdmin");
|
||||
|
||||
b.HasIndex("LastEditedById");
|
||||
|
||||
b.ToTable("ban", null, t =>
|
||||
{
|
||||
t.HasCheckConstraint("NoExemptOnRoleBan", "type = 0 OR exempt_flags = 0");
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanAddress", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_address_id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<NpgsqlInet>("Address")
|
||||
.HasColumnType("inet")
|
||||
.HasColumnName("address");
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_ban_address");
|
||||
|
||||
b.HasIndex("BanId")
|
||||
.HasDatabaseName("IX_ban_address_ban_id");
|
||||
|
||||
b.ToTable("ban_address", null, t =>
|
||||
{
|
||||
t.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address");
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanHwid", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_hwid_id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_ban_hwid");
|
||||
|
||||
b.HasIndex("BanId")
|
||||
.HasDatabaseName("IX_ban_hwid_ban_id");
|
||||
|
||||
b.ToTable("ban_hwid", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanPlayer", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_player_id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("user_id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_ban_player");
|
||||
|
||||
b.HasIndex("BanId")
|
||||
.HasDatabaseName("IX_ban_player_ban_id");
|
||||
|
||||
b.HasIndex("UserId", "BanId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ban_player", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanRole", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_role_id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("role_id");
|
||||
|
||||
b.Property<string>("RoleType")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("role_type");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_ban_role");
|
||||
|
||||
b.HasIndex("BanId")
|
||||
.HasDatabaseName("IX_ban_role_ban_id");
|
||||
|
||||
b.HasIndex("RoleType", "RoleId", "BanId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ban_role", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanRound", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_round_id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.Property<int>("RoundId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("round_id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_ban_round");
|
||||
|
||||
b.HasIndex("BanId")
|
||||
.HasDatabaseName("IX_ban_round_ban_id");
|
||||
|
||||
b.HasIndex("RoundId", "BanId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ban_round", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanTemplate", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -1069,95 +1284,6 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
b.ToTable("server", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ServerBan", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("server_ban_id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<NpgsqlInet?>("Address")
|
||||
.HasColumnType("inet")
|
||||
.HasColumnName("address");
|
||||
|
||||
b.Property<bool>("AutoDelete")
|
||||
.HasColumnType("boolean")
|
||||
.HasColumnName("auto_delete");
|
||||
|
||||
b.Property<DateTime>("BanTime")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("ban_time");
|
||||
|
||||
b.Property<Guid?>("BanningAdmin")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("banning_admin");
|
||||
|
||||
b.Property<int>("ExemptFlags")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("exempt_flags");
|
||||
|
||||
b.Property<DateTime?>("ExpirationTime")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("expiration_time");
|
||||
|
||||
b.Property<bool>("Hidden")
|
||||
.HasColumnType("boolean")
|
||||
.HasColumnName("hidden");
|
||||
|
||||
b.Property<DateTime?>("LastEditedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("last_edited_at");
|
||||
|
||||
b.Property<Guid?>("LastEditedById")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("last_edited_by_id");
|
||||
|
||||
b.Property<Guid?>("PlayerUserId")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("player_user_id");
|
||||
|
||||
b.Property<TimeSpan>("PlaytimeAtNote")
|
||||
.HasColumnType("interval")
|
||||
.HasColumnName("playtime_at_note");
|
||||
|
||||
b.Property<string>("Reason")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("reason");
|
||||
|
||||
b.Property<int?>("RoundId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("round_id");
|
||||
|
||||
b.Property<int>("Severity")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("severity");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_server_ban");
|
||||
|
||||
b.HasIndex("Address");
|
||||
|
||||
b.HasIndex("BanningAdmin");
|
||||
|
||||
b.HasIndex("LastEditedById");
|
||||
|
||||
b.HasIndex("PlayerUserId")
|
||||
.HasDatabaseName("IX_server_ban_player_user_id");
|
||||
|
||||
b.HasIndex("RoundId")
|
||||
.HasDatabaseName("IX_server_ban_round_id");
|
||||
|
||||
b.ToTable("server_ban", null, t =>
|
||||
{
|
||||
t.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address");
|
||||
|
||||
t.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR player_user_id IS NOT NULL OR hwid IS NOT NULL");
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ServerBanExemption", b =>
|
||||
{
|
||||
b.Property<Guid>("UserId")
|
||||
@@ -1207,152 +1333,6 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
b.ToTable("server_ban_hit", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("server_role_ban_id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<NpgsqlInet?>("Address")
|
||||
.HasColumnType("inet")
|
||||
.HasColumnName("address");
|
||||
|
||||
b.Property<DateTime>("BanTime")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("ban_time");
|
||||
|
||||
b.Property<Guid?>("BanningAdmin")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("banning_admin");
|
||||
|
||||
b.Property<DateTime?>("ExpirationTime")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("expiration_time");
|
||||
|
||||
b.Property<bool>("Hidden")
|
||||
.HasColumnType("boolean")
|
||||
.HasColumnName("hidden");
|
||||
|
||||
b.Property<DateTime?>("LastEditedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("last_edited_at");
|
||||
|
||||
b.Property<Guid?>("LastEditedById")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("last_edited_by_id");
|
||||
|
||||
b.Property<Guid?>("PlayerUserId")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("player_user_id");
|
||||
|
||||
b.Property<TimeSpan>("PlaytimeAtNote")
|
||||
.HasColumnType("interval")
|
||||
.HasColumnName("playtime_at_note");
|
||||
|
||||
b.Property<string>("Reason")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("reason");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("role_id");
|
||||
|
||||
b.Property<int?>("RoundId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("round_id");
|
||||
|
||||
b.Property<int>("Severity")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("severity");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_server_role_ban");
|
||||
|
||||
b.HasIndex("Address");
|
||||
|
||||
b.HasIndex("BanningAdmin");
|
||||
|
||||
b.HasIndex("LastEditedById");
|
||||
|
||||
b.HasIndex("PlayerUserId")
|
||||
.HasDatabaseName("IX_server_role_ban_player_user_id");
|
||||
|
||||
b.HasIndex("RoundId")
|
||||
.HasDatabaseName("IX_server_role_ban_round_id");
|
||||
|
||||
b.ToTable("server_role_ban", null, t =>
|
||||
{
|
||||
t.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address");
|
||||
|
||||
t.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR player_user_id IS NOT NULL OR hwid IS NOT NULL");
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ServerRoleUnban", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("role_unban_id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.Property<DateTime>("UnbanTime")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("unban_time");
|
||||
|
||||
b.Property<Guid?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("unban_id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.Property<DateTime>("UnbanTime")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("unban_time");
|
||||
|
||||
b.Property<Guid?>("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.Trait", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -1380,6 +1360,36 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
b.ToTable("trait", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Unban", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("unban_id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.Property<DateTime>("UnbanTime")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("unban_time");
|
||||
|
||||
b.Property<Guid?>("UnbanningAdmin")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("unbanning_admin");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_unban");
|
||||
|
||||
b.HasIndex("BanId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("unban", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.UploadedResourceLog", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -1664,6 +1674,123 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
b.Navigation("Profile");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Ban", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Player", "CreatedBy")
|
||||
.WithMany("AdminServerBansCreated")
|
||||
.HasForeignKey("BanningAdmin")
|
||||
.HasPrincipalKey("UserId")
|
||||
.OnDelete(DeleteBehavior.SetNull)
|
||||
.HasConstraintName("FK_ban_player_banning_admin");
|
||||
|
||||
b.HasOne("Content.Server.Database.Player", "LastEditedBy")
|
||||
.WithMany("AdminServerBansLastEdited")
|
||||
.HasForeignKey("LastEditedById")
|
||||
.HasPrincipalKey("UserId")
|
||||
.OnDelete(DeleteBehavior.SetNull)
|
||||
.HasConstraintName("FK_ban_player_last_edited_by_id");
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("LastEditedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanAddress", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Ban", "Ban")
|
||||
.WithMany("Addresses")
|
||||
.HasForeignKey("BanId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_ban_address_ban_ban_id");
|
||||
|
||||
b.Navigation("Ban");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanHwid", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Ban", "Ban")
|
||||
.WithMany("Hwids")
|
||||
.HasForeignKey("BanId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_ban_hwid_ban_ban_id");
|
||||
|
||||
b.OwnsOne("Content.Server.Database.TypedHwid", "HWId", b1 =>
|
||||
{
|
||||
b1.Property<int>("BanHwidId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("ban_hwid_id");
|
||||
|
||||
b1.Property<byte[]>("Hwid")
|
||||
.IsRequired()
|
||||
.HasColumnType("bytea")
|
||||
.HasColumnName("hwid");
|
||||
|
||||
b1.Property<int>("Type")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("hwid_type");
|
||||
|
||||
b1.HasKey("BanHwidId");
|
||||
|
||||
b1.ToTable("ban_hwid");
|
||||
|
||||
b1.WithOwner()
|
||||
.HasForeignKey("BanHwidId")
|
||||
.HasConstraintName("FK_ban_hwid_ban_hwid_ban_hwid_id");
|
||||
});
|
||||
|
||||
b.Navigation("Ban");
|
||||
|
||||
b.Navigation("HWId")
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanPlayer", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Ban", "Ban")
|
||||
.WithMany("Players")
|
||||
.HasForeignKey("BanId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_ban_player_ban_ban_id");
|
||||
|
||||
b.Navigation("Ban");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanRole", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Ban", "Ban")
|
||||
.WithMany("Roles")
|
||||
.HasForeignKey("BanId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_ban_role_ban_ban_id");
|
||||
|
||||
b.Navigation("Ban");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanRound", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Ban", "Ban")
|
||||
.WithMany("Rounds")
|
||||
.HasForeignKey("BanId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_ban_round_ban_ban_id");
|
||||
|
||||
b.HasOne("Content.Server.Database.Round", "Round")
|
||||
.WithMany()
|
||||
.HasForeignKey("RoundId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_ban_round_round_round_id");
|
||||
|
||||
b.Navigation("Ban");
|
||||
|
||||
b.Navigation("Round");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ConnectionLog", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Server", "Server")
|
||||
@@ -1820,70 +1947,14 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
b.Navigation("Server");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ServerBan", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Player", "CreatedBy")
|
||||
.WithMany("AdminServerBansCreated")
|
||||
.HasForeignKey("BanningAdmin")
|
||||
.HasPrincipalKey("UserId")
|
||||
.OnDelete(DeleteBehavior.SetNull)
|
||||
.HasConstraintName("FK_server_ban_player_banning_admin");
|
||||
|
||||
b.HasOne("Content.Server.Database.Player", "LastEditedBy")
|
||||
.WithMany("AdminServerBansLastEdited")
|
||||
.HasForeignKey("LastEditedById")
|
||||
.HasPrincipalKey("UserId")
|
||||
.OnDelete(DeleteBehavior.SetNull)
|
||||
.HasConstraintName("FK_server_ban_player_last_edited_by_id");
|
||||
|
||||
b.HasOne("Content.Server.Database.Round", "Round")
|
||||
.WithMany()
|
||||
.HasForeignKey("RoundId")
|
||||
.HasConstraintName("FK_server_ban_round_round_id");
|
||||
|
||||
b.OwnsOne("Content.Server.Database.TypedHwid", "HWId", b1 =>
|
||||
{
|
||||
b1.Property<int>("ServerBanId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("server_ban_id");
|
||||
|
||||
b1.Property<byte[]>("Hwid")
|
||||
.IsRequired()
|
||||
.HasColumnType("bytea")
|
||||
.HasColumnName("hwid");
|
||||
|
||||
b1.Property<int>("Type")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasDefaultValue(0)
|
||||
.HasColumnName("hwid_type");
|
||||
|
||||
b1.HasKey("ServerBanId");
|
||||
|
||||
b1.ToTable("server_ban");
|
||||
|
||||
b1.WithOwner()
|
||||
.HasForeignKey("ServerBanId")
|
||||
.HasConstraintName("FK_server_ban_server_ban_server_ban_id");
|
||||
});
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("HWId");
|
||||
|
||||
b.Navigation("LastEditedBy");
|
||||
|
||||
b.Navigation("Round");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ServerBanHit", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.ServerBan", "Ban")
|
||||
b.HasOne("Content.Server.Database.Ban", "Ban")
|
||||
.WithMany("BanHits")
|
||||
.HasForeignKey("BanId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_server_ban_hit_server_ban_ban_id");
|
||||
.HasConstraintName("FK_server_ban_hit_ban_ban_id");
|
||||
|
||||
b.HasOne("Content.Server.Database.ConnectionLog", "Connection")
|
||||
.WithMany("BanHits")
|
||||
@@ -1897,86 +1968,6 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
b.Navigation("Connection");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Player", "CreatedBy")
|
||||
.WithMany("AdminServerRoleBansCreated")
|
||||
.HasForeignKey("BanningAdmin")
|
||||
.HasPrincipalKey("UserId")
|
||||
.OnDelete(DeleteBehavior.SetNull)
|
||||
.HasConstraintName("FK_server_role_ban_player_banning_admin");
|
||||
|
||||
b.HasOne("Content.Server.Database.Player", "LastEditedBy")
|
||||
.WithMany("AdminServerRoleBansLastEdited")
|
||||
.HasForeignKey("LastEditedById")
|
||||
.HasPrincipalKey("UserId")
|
||||
.OnDelete(DeleteBehavior.SetNull)
|
||||
.HasConstraintName("FK_server_role_ban_player_last_edited_by_id");
|
||||
|
||||
b.HasOne("Content.Server.Database.Round", "Round")
|
||||
.WithMany()
|
||||
.HasForeignKey("RoundId")
|
||||
.HasConstraintName("FK_server_role_ban_round_round_id");
|
||||
|
||||
b.OwnsOne("Content.Server.Database.TypedHwid", "HWId", b1 =>
|
||||
{
|
||||
b1.Property<int>("ServerRoleBanId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("server_role_ban_id");
|
||||
|
||||
b1.Property<byte[]>("Hwid")
|
||||
.IsRequired()
|
||||
.HasColumnType("bytea")
|
||||
.HasColumnName("hwid");
|
||||
|
||||
b1.Property<int>("Type")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasDefaultValue(0)
|
||||
.HasColumnName("hwid_type");
|
||||
|
||||
b1.HasKey("ServerRoleBanId");
|
||||
|
||||
b1.ToTable("server_role_ban");
|
||||
|
||||
b1.WithOwner()
|
||||
.HasForeignKey("ServerRoleBanId")
|
||||
.HasConstraintName("FK_server_role_ban_server_role_ban_server_role_ban_id");
|
||||
});
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("HWId");
|
||||
|
||||
b.Navigation("LastEditedBy");
|
||||
|
||||
b.Navigation("Round");
|
||||
});
|
||||
|
||||
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")
|
||||
@@ -1989,6 +1980,18 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
b.Navigation("Profile");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Unban", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Ban", "Ban")
|
||||
.WithOne("Unban")
|
||||
.HasForeignKey("Content.Server.Database.Unban", "BanId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_unban_ban_ban_id");
|
||||
|
||||
b.Navigation("Ban");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PlayerRound", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Player", null)
|
||||
@@ -2023,6 +2026,23 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
b.Navigation("Flags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Ban", b =>
|
||||
{
|
||||
b.Navigation("Addresses");
|
||||
|
||||
b.Navigation("BanHits");
|
||||
|
||||
b.Navigation("Hwids");
|
||||
|
||||
b.Navigation("Players");
|
||||
|
||||
b.Navigation("Roles");
|
||||
|
||||
b.Navigation("Rounds");
|
||||
|
||||
b.Navigation("Unban");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ConnectionLog", b =>
|
||||
{
|
||||
b.Navigation("BanHits");
|
||||
@@ -2052,10 +2072,6 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
|
||||
b.Navigation("AdminServerBansLastEdited");
|
||||
|
||||
b.Navigation("AdminServerRoleBansCreated");
|
||||
|
||||
b.Navigation("AdminServerRoleBansLastEdited");
|
||||
|
||||
b.Navigation("AdminWatchlistsCreated");
|
||||
|
||||
b.Navigation("AdminWatchlistsDeleted");
|
||||
@@ -2104,18 +2120,6 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
2044
Content.Server.Database/Migrations/Sqlite/20260120200455_BanRefactor.Designer.cs
generated
Normal file
2044
Content.Server.Database/Migrations/Sqlite/20260120200455_BanRefactor.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,498 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Content.Server.Database.Migrations.Sqlite
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class BanRefactor : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ban",
|
||||
columns: table => new
|
||||
{
|
||||
ban_id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
type = table.Column<byte>(type: "INTEGER", nullable: false),
|
||||
playtime_at_note = table.Column<TimeSpan>(type: "TEXT", nullable: false),
|
||||
ban_time = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
expiration_time = table.Column<DateTime>(type: "TEXT", nullable: true),
|
||||
reason = table.Column<string>(type: "TEXT", nullable: false),
|
||||
severity = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
banning_admin = table.Column<Guid>(type: "TEXT", nullable: true),
|
||||
last_edited_by_id = table.Column<Guid>(type: "TEXT", nullable: true),
|
||||
last_edited_at = table.Column<DateTime>(type: "TEXT", nullable: true),
|
||||
exempt_flags = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
auto_delete = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
hidden = table.Column<bool>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ban", x => x.ban_id);
|
||||
table.CheckConstraint("NoExemptOnRoleBan", "type = 0 OR exempt_flags = 0");
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_player_banning_admin",
|
||||
column: x => x.banning_admin,
|
||||
principalTable: "player",
|
||||
principalColumn: "user_id",
|
||||
onDelete: ReferentialAction.SetNull);
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_player_last_edited_by_id",
|
||||
column: x => x.last_edited_by_id,
|
||||
principalTable: "player",
|
||||
principalColumn: "user_id",
|
||||
onDelete: ReferentialAction.SetNull);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ban_address",
|
||||
columns: table => new
|
||||
{
|
||||
ban_address_id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
address = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ban_id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ban_address", x => x.ban_address_id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_address_ban_ban_id",
|
||||
column: x => x.ban_id,
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ban_hwid",
|
||||
columns: table => new
|
||||
{
|
||||
ban_hwid_id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
hwid = table.Column<byte[]>(type: "BLOB", nullable: false),
|
||||
hwid_type = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
ban_id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ban_hwid", x => x.ban_hwid_id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_hwid_ban_ban_id",
|
||||
column: x => x.ban_id,
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ban_player",
|
||||
columns: table => new
|
||||
{
|
||||
ban_player_id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
user_id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
ban_id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ban_player", x => x.ban_player_id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_player_ban_ban_id",
|
||||
column: x => x.ban_id,
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ban_role",
|
||||
columns: table => new
|
||||
{
|
||||
ban_role_id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
role_type = table.Column<string>(type: "TEXT", nullable: false),
|
||||
role_id = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ban_id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ban_role", x => x.ban_role_id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_role_ban_ban_id",
|
||||
column: x => x.ban_id,
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ban_round",
|
||||
columns: table => new
|
||||
{
|
||||
ban_round_id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
ban_id = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
round_id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ban_round", x => x.ban_round_id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_round_ban_ban_id",
|
||||
column: x => x.ban_id,
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ban_round_round_round_id",
|
||||
column: x => x.round_id,
|
||||
principalTable: "round",
|
||||
principalColumn: "round_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "unban",
|
||||
columns: table => new
|
||||
{
|
||||
unban_id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
ban_id = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
unbanning_admin = table.Column<Guid>(type: "TEXT", nullable: true),
|
||||
unban_time = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_unban", x => x.unban_id);
|
||||
table.ForeignKey(
|
||||
name: "FK_unban_ban_ban_id",
|
||||
column: x => x.ban_id,
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_banning_admin",
|
||||
table: "ban",
|
||||
column: "banning_admin");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_last_edited_by_id",
|
||||
table: "ban",
|
||||
column: "last_edited_by_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_address_ban_id",
|
||||
table: "ban_address",
|
||||
column: "ban_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_hwid_ban_id",
|
||||
table: "ban_hwid",
|
||||
column: "ban_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_player_ban_id",
|
||||
table: "ban_player",
|
||||
column: "ban_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_player_user_id_ban_id",
|
||||
table: "ban_player",
|
||||
columns: new[] { "user_id", "ban_id" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_role_ban_id",
|
||||
table: "ban_role",
|
||||
column: "ban_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_role_role_type_role_id_ban_id",
|
||||
table: "ban_role",
|
||||
columns: new[] { "role_type", "role_id", "ban_id" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_round_ban_id",
|
||||
table: "ban_round",
|
||||
column: "ban_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ban_round_round_id_ban_id",
|
||||
table: "ban_round",
|
||||
columns: new[] { "round_id", "ban_id" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_unban_ban_id",
|
||||
table: "unban",
|
||||
column: "ban_id",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.Sql("""
|
||||
CREATE UNIQUE INDEX "IX_ban_hwid_hwid_ban_id"
|
||||
ON ban_hwid
|
||||
(hwid_type, hwid, ban_id);
|
||||
|
||||
CREATE UNIQUE INDEX "IX_ban_address_address_ban_id"
|
||||
ON ban_address
|
||||
(address, ban_id);
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql("""
|
||||
--
|
||||
-- Insert game bans
|
||||
--
|
||||
INSERT INTO
|
||||
ban (ban_id, type, playtime_at_note, ban_time, expiration_time, reason, severity, banning_admin, last_edited_by_id, last_edited_at, exempt_flags, auto_delete, hidden)
|
||||
SELECT
|
||||
server_ban_id, 0, playtime_at_note, ban_time, expiration_time, reason, severity, banning_admin, last_edited_by_id, last_edited_at, exempt_flags, auto_delete, hidden
|
||||
FROM
|
||||
server_ban;
|
||||
|
||||
-- Insert ban player records.
|
||||
INSERT INTO
|
||||
ban_player (user_id, ban_id)
|
||||
SELECT
|
||||
player_user_id, server_ban_id
|
||||
FROM
|
||||
server_ban
|
||||
WHERE
|
||||
player_user_id IS NOT NULL;
|
||||
|
||||
-- Insert ban address records.
|
||||
INSERT INTO
|
||||
ban_address (address, ban_id)
|
||||
SELECT
|
||||
address, server_ban_id
|
||||
FROM
|
||||
server_ban
|
||||
WHERE
|
||||
address IS NOT NULL;
|
||||
|
||||
-- Insert ban HWID records.
|
||||
INSERT INTO
|
||||
ban_hwid (hwid, hwid_type, ban_id)
|
||||
SELECT
|
||||
hwid, hwid_type, server_ban_id
|
||||
FROM
|
||||
server_ban
|
||||
WHERE
|
||||
hwid IS NOT NULL;
|
||||
|
||||
-- Insert ban unban records.
|
||||
INSERT INTO
|
||||
unban (ban_id, unbanning_admin, unban_time)
|
||||
SELECT
|
||||
ban_id, unbanning_admin, unban_time
|
||||
FROM server_unban;
|
||||
|
||||
-- Insert ban round records.
|
||||
INSERT INTO
|
||||
ban_round (round_id, ban_id)
|
||||
SELECT
|
||||
round_id, server_ban_id
|
||||
FROM
|
||||
server_ban
|
||||
WHERE
|
||||
round_id IS NOT NULL;
|
||||
|
||||
--
|
||||
-- Insert role bans
|
||||
-- This shit is a pain in the ass
|
||||
-- > Declarative language
|
||||
-- > Has to write procedural code in it
|
||||
--
|
||||
|
||||
-- Create mapping table from role ban -> server ban.
|
||||
-- We have to manually calculate the new ban IDs by using the sequence.
|
||||
-- We also want to merge role ban records because the game code previously did that in some UI,
|
||||
-- and that code is now gone, expecting the DB to do it.
|
||||
|
||||
-- Create a table to store IDs to merge.
|
||||
CREATE TEMPORARY TABLE _role_ban_import_merge_map (merge_id INTEGER, server_role_ban_id INTEGER UNIQUE);
|
||||
|
||||
-- Create a table to store merged IDs -> new ban IDs
|
||||
CREATE TEMPORARY TABLE _role_ban_import_id_map (ban_id INTEGER UNIQUE, merge_id INTEGER UNIQUE);
|
||||
|
||||
-- Calculate merged role bans.
|
||||
INSERT INTO
|
||||
_role_ban_import_merge_map
|
||||
SELECT
|
||||
(
|
||||
SELECT
|
||||
sub.server_role_ban_id
|
||||
FROM
|
||||
server_role_ban AS sub
|
||||
LEFT JOIN server_role_unban AS sub_unban
|
||||
ON sub_unban.ban_id = sub.server_role_ban_id
|
||||
WHERE
|
||||
main.reason IS NOT DISTINCT FROM sub.reason
|
||||
AND main.player_user_id IS NOT DISTINCT FROM sub.player_user_id
|
||||
AND main.address IS NOT DISTINCT FROM sub.address
|
||||
AND main.hwid IS NOT DISTINCT FROM sub.hwid
|
||||
AND main.hwid_type IS NOT DISTINCT FROM sub.hwid_type
|
||||
AND main.ban_time = sub.ban_time
|
||||
AND (
|
||||
(main.expiration_time IS NULL) = (sub.expiration_time IS NULL)
|
||||
OR main.expiration_time = sub.expiration_time
|
||||
)
|
||||
AND main.round_id IS NOT DISTINCT FROM sub.round_id
|
||||
AND main.severity IS NOT DISTINCT FROM sub.severity
|
||||
AND main.hidden IS NOT DISTINCT FROM sub.hidden
|
||||
AND main.banning_admin IS NOT DISTINCT FROM sub.banning_admin
|
||||
AND (sub_unban.ban_id IS NULL) = (main_unban.ban_id IS NULL)
|
||||
ORDER BY
|
||||
sub.server_role_ban_id ASC
|
||||
LIMIT 1
|
||||
), main.server_role_ban_id
|
||||
FROM
|
||||
server_role_ban AS main
|
||||
LEFT JOIN server_role_unban AS main_unban
|
||||
ON main_unban.ban_id = main.server_role_ban_id;
|
||||
|
||||
-- Assign new ban IDs for merged IDs.
|
||||
INSERT OR IGNORE INTO
|
||||
_role_ban_import_id_map
|
||||
SELECT
|
||||
merge_id + (SELECT seq FROM sqlite_sequence WHERE name = 'ban'),
|
||||
merge_id
|
||||
FROM
|
||||
_role_ban_import_merge_map;
|
||||
|
||||
-- I sure fucking wish CTEs could span multiple queries...
|
||||
|
||||
-- Insert new ban records
|
||||
INSERT INTO
|
||||
ban (ban_id, type, playtime_at_note, ban_time, expiration_time, reason, severity, banning_admin, last_edited_by_id, last_edited_at, exempt_flags, auto_delete, hidden)
|
||||
SELECT
|
||||
im.ban_id, 1, playtime_at_note, ban_time, expiration_time, reason, severity, banning_admin, last_edited_by_id, last_edited_at, 0, FALSE, hidden
|
||||
FROM
|
||||
_role_ban_import_id_map im
|
||||
INNER JOIN _role_ban_import_merge_map mm
|
||||
ON im.merge_id = mm.merge_id
|
||||
INNER JOIN server_role_ban srb
|
||||
ON srb.server_role_ban_id = im.merge_id
|
||||
WHERE mm.merge_id = mm.server_role_ban_id;
|
||||
|
||||
-- Insert role ban player records.
|
||||
INSERT INTO
|
||||
ban_player (user_id, ban_id)
|
||||
SELECT
|
||||
player_user_id, im.ban_id
|
||||
FROM
|
||||
_role_ban_import_id_map im
|
||||
INNER JOIN _role_ban_import_merge_map mm
|
||||
ON im.merge_id = mm.merge_id
|
||||
INNER JOIN server_role_ban srb
|
||||
ON srb.server_role_ban_id = im.merge_id
|
||||
WHERE mm.merge_id = mm.server_role_ban_id
|
||||
AND player_user_id IS NOT NULL;
|
||||
|
||||
-- Insert role ban address records.
|
||||
INSERT INTO
|
||||
ban_address (address, ban_id)
|
||||
SELECT
|
||||
address, im.ban_id
|
||||
FROM
|
||||
_role_ban_import_id_map im
|
||||
INNER JOIN _role_ban_import_merge_map mm
|
||||
ON im.merge_id = mm.merge_id
|
||||
INNER JOIN server_role_ban srb
|
||||
ON srb.server_role_ban_id = im.merge_id
|
||||
WHERE mm.merge_id = mm.server_role_ban_id
|
||||
AND address IS NOT NULL;
|
||||
|
||||
-- Insert role ban HWID records.
|
||||
INSERT INTO
|
||||
ban_hwid (hwid, hwid_type, ban_id)
|
||||
SELECT
|
||||
hwid, hwid_type, im.ban_id
|
||||
FROM
|
||||
_role_ban_import_id_map im
|
||||
INNER JOIN _role_ban_import_merge_map mm
|
||||
ON im.merge_id = mm.merge_id
|
||||
INNER JOIN server_role_ban srb
|
||||
ON srb.server_role_ban_id = im.merge_id
|
||||
WHERE mm.merge_id = mm.server_role_ban_id
|
||||
AND hwid IS NOT NULL;
|
||||
|
||||
-- Insert role ban role records.
|
||||
INSERT INTO
|
||||
ban_role (role_type, role_id, ban_id)
|
||||
SELECT
|
||||
substr(role_id, 1, instr(role_id, ':')-1),
|
||||
substr(role_id, instr(role_id, ':')+1),
|
||||
im.ban_id
|
||||
FROM
|
||||
_role_ban_import_id_map im
|
||||
INNER JOIN _role_ban_import_merge_map mm
|
||||
ON im.merge_id = mm.merge_id
|
||||
INNER JOIN server_role_ban srb
|
||||
ON srb.server_role_ban_id = mm.server_role_ban_id
|
||||
-- Yes, we have some messy ban records which, after merging, end up with duplicate roles.
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- Insert role unban records.
|
||||
INSERT INTO
|
||||
unban (ban_id, unbanning_admin, unban_time)
|
||||
SELECT
|
||||
im.ban_id, unbanning_admin, unban_time
|
||||
FROM server_role_unban sru
|
||||
INNER JOIN _role_ban_import_id_map im
|
||||
ON im.merge_id = sru.ban_id;
|
||||
|
||||
-- Insert role rounds
|
||||
INSERT INTO
|
||||
ban_round (round_id, ban_id)
|
||||
SELECT
|
||||
round_id, im.ban_id
|
||||
FROM
|
||||
_role_ban_import_id_map im
|
||||
INNER JOIN _role_ban_import_merge_map mm
|
||||
ON im.merge_id = mm.merge_id
|
||||
INNER JOIN server_role_ban srb
|
||||
ON srb.server_role_ban_id = im.merge_id
|
||||
WHERE mm.merge_id = mm.server_role_ban_id
|
||||
AND round_id IS NOT NULL;
|
||||
""");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_server_ban_hit_ban_ban_id",
|
||||
table: "server_ban_hit",
|
||||
column: "ban_id",
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_server_ban_hit_server_ban_ban_id",
|
||||
table: "server_ban_hit");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "server_role_unban");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "server_unban");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "server_role_ban");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "server_ban");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
throw new NotSupportedException("This migration cannot be rolled back");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -489,6 +489,207 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
b.ToTable("assigned_user_id", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Ban", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.Property<bool>("AutoDelete")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("auto_delete");
|
||||
|
||||
b.Property<DateTime>("BanTime")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("ban_time");
|
||||
|
||||
b.Property<Guid?>("BanningAdmin")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("banning_admin");
|
||||
|
||||
b.Property<int>("ExemptFlags")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("exempt_flags");
|
||||
|
||||
b.Property<DateTime?>("ExpirationTime")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("expiration_time");
|
||||
|
||||
b.Property<bool>("Hidden")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("hidden");
|
||||
|
||||
b.Property<DateTime?>("LastEditedAt")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("last_edited_at");
|
||||
|
||||
b.Property<Guid?>("LastEditedById")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("last_edited_by_id");
|
||||
|
||||
b.Property<TimeSpan>("PlaytimeAtNote")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("playtime_at_note");
|
||||
|
||||
b.Property<string>("Reason")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("reason");
|
||||
|
||||
b.Property<int>("Severity")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("severity");
|
||||
|
||||
b.Property<byte>("Type")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("type");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_ban");
|
||||
|
||||
b.HasIndex("BanningAdmin");
|
||||
|
||||
b.HasIndex("LastEditedById");
|
||||
|
||||
b.ToTable("ban", null, t =>
|
||||
{
|
||||
t.HasCheckConstraint("NoExemptOnRoleBan", "type = 0 OR exempt_flags = 0");
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanAddress", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_address_id");
|
||||
|
||||
b.Property<string>("Address")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("address");
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_ban_address");
|
||||
|
||||
b.HasIndex("BanId")
|
||||
.HasDatabaseName("IX_ban_address_ban_id");
|
||||
|
||||
b.ToTable("ban_address", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanHwid", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_hwid_id");
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_ban_hwid");
|
||||
|
||||
b.HasIndex("BanId")
|
||||
.HasDatabaseName("IX_ban_hwid_ban_id");
|
||||
|
||||
b.ToTable("ban_hwid", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanPlayer", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_player_id");
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("user_id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_ban_player");
|
||||
|
||||
b.HasIndex("BanId")
|
||||
.HasDatabaseName("IX_ban_player_ban_id");
|
||||
|
||||
b.HasIndex("UserId", "BanId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ban_player", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanRole", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_role_id");
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("role_id");
|
||||
|
||||
b.Property<string>("RoleType")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("role_type");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_ban_role");
|
||||
|
||||
b.HasIndex("BanId")
|
||||
.HasDatabaseName("IX_ban_role_ban_id");
|
||||
|
||||
b.HasIndex("RoleType", "RoleId", "BanId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ban_role", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanRound", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_round_id");
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.Property<int>("RoundId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("round_id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_ban_round");
|
||||
|
||||
b.HasIndex("BanId")
|
||||
.HasDatabaseName("IX_ban_round_ban_id");
|
||||
|
||||
b.HasIndex("RoundId", "BanId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ban_round", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanTemplate", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -1010,91 +1211,6 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
b.ToTable("server", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ServerBan", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("server_ban_id");
|
||||
|
||||
b.Property<string>("Address")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("address");
|
||||
|
||||
b.Property<bool>("AutoDelete")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("auto_delete");
|
||||
|
||||
b.Property<DateTime>("BanTime")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("ban_time");
|
||||
|
||||
b.Property<Guid?>("BanningAdmin")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("banning_admin");
|
||||
|
||||
b.Property<int>("ExemptFlags")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("exempt_flags");
|
||||
|
||||
b.Property<DateTime?>("ExpirationTime")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("expiration_time");
|
||||
|
||||
b.Property<bool>("Hidden")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("hidden");
|
||||
|
||||
b.Property<DateTime?>("LastEditedAt")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("last_edited_at");
|
||||
|
||||
b.Property<Guid?>("LastEditedById")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("last_edited_by_id");
|
||||
|
||||
b.Property<Guid?>("PlayerUserId")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("player_user_id");
|
||||
|
||||
b.Property<TimeSpan>("PlaytimeAtNote")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("playtime_at_note");
|
||||
|
||||
b.Property<string>("Reason")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("reason");
|
||||
|
||||
b.Property<int?>("RoundId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("round_id");
|
||||
|
||||
b.Property<int>("Severity")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("severity");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_server_ban");
|
||||
|
||||
b.HasIndex("Address");
|
||||
|
||||
b.HasIndex("BanningAdmin");
|
||||
|
||||
b.HasIndex("LastEditedById");
|
||||
|
||||
b.HasIndex("PlayerUserId")
|
||||
.HasDatabaseName("IX_server_ban_player_user_id");
|
||||
|
||||
b.HasIndex("RoundId")
|
||||
.HasDatabaseName("IX_server_ban_round_id");
|
||||
|
||||
b.ToTable("server_ban", null, t =>
|
||||
{
|
||||
t.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR player_user_id IS NOT NULL OR hwid IS NOT NULL");
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ServerBanExemption", b =>
|
||||
{
|
||||
b.Property<Guid>("UserId")
|
||||
@@ -1142,144 +1258,6 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
b.ToTable("server_ban_hit", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("server_role_ban_id");
|
||||
|
||||
b.Property<string>("Address")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("address");
|
||||
|
||||
b.Property<DateTime>("BanTime")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("ban_time");
|
||||
|
||||
b.Property<Guid?>("BanningAdmin")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("banning_admin");
|
||||
|
||||
b.Property<DateTime?>("ExpirationTime")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("expiration_time");
|
||||
|
||||
b.Property<bool>("Hidden")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("hidden");
|
||||
|
||||
b.Property<DateTime?>("LastEditedAt")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("last_edited_at");
|
||||
|
||||
b.Property<Guid?>("LastEditedById")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("last_edited_by_id");
|
||||
|
||||
b.Property<Guid?>("PlayerUserId")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("player_user_id");
|
||||
|
||||
b.Property<TimeSpan>("PlaytimeAtNote")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("playtime_at_note");
|
||||
|
||||
b.Property<string>("Reason")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("reason");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("role_id");
|
||||
|
||||
b.Property<int?>("RoundId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("round_id");
|
||||
|
||||
b.Property<int>("Severity")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("severity");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_server_role_ban");
|
||||
|
||||
b.HasIndex("Address");
|
||||
|
||||
b.HasIndex("BanningAdmin");
|
||||
|
||||
b.HasIndex("LastEditedById");
|
||||
|
||||
b.HasIndex("PlayerUserId")
|
||||
.HasDatabaseName("IX_server_role_ban_player_user_id");
|
||||
|
||||
b.HasIndex("RoundId")
|
||||
.HasDatabaseName("IX_server_role_ban_round_id");
|
||||
|
||||
b.ToTable("server_role_ban", null, t =>
|
||||
{
|
||||
t.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR player_user_id IS NOT NULL OR hwid IS NOT NULL");
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ServerRoleUnban", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("role_unban_id");
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.Property<DateTime>("UnbanTime")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("unban_time");
|
||||
|
||||
b.Property<Guid?>("UnbanningAdmin")
|
||||
.HasColumnType("TEXT")
|
||||
.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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("unban_id");
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.Property<DateTime>("UnbanTime")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("unban_time");
|
||||
|
||||
b.Property<Guid?>("UnbanningAdmin")
|
||||
.HasColumnType("TEXT")
|
||||
.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.Trait", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -1305,6 +1283,34 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
b.ToTable("trait", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Unban", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("unban_id");
|
||||
|
||||
b.Property<int>("BanId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_id");
|
||||
|
||||
b.Property<DateTime>("UnbanTime")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("unban_time");
|
||||
|
||||
b.Property<Guid?>("UnbanningAdmin")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("unbanning_admin");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_unban");
|
||||
|
||||
b.HasIndex("BanId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("unban", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.UploadedResourceLog", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -1587,6 +1593,123 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
b.Navigation("Profile");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Ban", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Player", "CreatedBy")
|
||||
.WithMany("AdminServerBansCreated")
|
||||
.HasForeignKey("BanningAdmin")
|
||||
.HasPrincipalKey("UserId")
|
||||
.OnDelete(DeleteBehavior.SetNull)
|
||||
.HasConstraintName("FK_ban_player_banning_admin");
|
||||
|
||||
b.HasOne("Content.Server.Database.Player", "LastEditedBy")
|
||||
.WithMany("AdminServerBansLastEdited")
|
||||
.HasForeignKey("LastEditedById")
|
||||
.HasPrincipalKey("UserId")
|
||||
.OnDelete(DeleteBehavior.SetNull)
|
||||
.HasConstraintName("FK_ban_player_last_edited_by_id");
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("LastEditedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanAddress", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Ban", "Ban")
|
||||
.WithMany("Addresses")
|
||||
.HasForeignKey("BanId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_ban_address_ban_ban_id");
|
||||
|
||||
b.Navigation("Ban");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanHwid", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Ban", "Ban")
|
||||
.WithMany("Hwids")
|
||||
.HasForeignKey("BanId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_ban_hwid_ban_ban_id");
|
||||
|
||||
b.OwnsOne("Content.Server.Database.TypedHwid", "HWId", b1 =>
|
||||
{
|
||||
b1.Property<int>("BanHwidId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("ban_hwid_id");
|
||||
|
||||
b1.Property<byte[]>("Hwid")
|
||||
.IsRequired()
|
||||
.HasColumnType("BLOB")
|
||||
.HasColumnName("hwid");
|
||||
|
||||
b1.Property<int>("Type")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("hwid_type");
|
||||
|
||||
b1.HasKey("BanHwidId");
|
||||
|
||||
b1.ToTable("ban_hwid");
|
||||
|
||||
b1.WithOwner()
|
||||
.HasForeignKey("BanHwidId")
|
||||
.HasConstraintName("FK_ban_hwid_ban_hwid_ban_hwid_id");
|
||||
});
|
||||
|
||||
b.Navigation("Ban");
|
||||
|
||||
b.Navigation("HWId")
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanPlayer", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Ban", "Ban")
|
||||
.WithMany("Players")
|
||||
.HasForeignKey("BanId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_ban_player_ban_ban_id");
|
||||
|
||||
b.Navigation("Ban");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanRole", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Ban", "Ban")
|
||||
.WithMany("Roles")
|
||||
.HasForeignKey("BanId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_ban_role_ban_ban_id");
|
||||
|
||||
b.Navigation("Ban");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.BanRound", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Ban", "Ban")
|
||||
.WithMany("Rounds")
|
||||
.HasForeignKey("BanId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_ban_round_ban_ban_id");
|
||||
|
||||
b.HasOne("Content.Server.Database.Round", "Round")
|
||||
.WithMany()
|
||||
.HasForeignKey("RoundId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_ban_round_round_round_id");
|
||||
|
||||
b.Navigation("Ban");
|
||||
|
||||
b.Navigation("Round");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ConnectionLog", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Server", "Server")
|
||||
@@ -1743,70 +1866,14 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
b.Navigation("Server");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ServerBan", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Player", "CreatedBy")
|
||||
.WithMany("AdminServerBansCreated")
|
||||
.HasForeignKey("BanningAdmin")
|
||||
.HasPrincipalKey("UserId")
|
||||
.OnDelete(DeleteBehavior.SetNull)
|
||||
.HasConstraintName("FK_server_ban_player_banning_admin");
|
||||
|
||||
b.HasOne("Content.Server.Database.Player", "LastEditedBy")
|
||||
.WithMany("AdminServerBansLastEdited")
|
||||
.HasForeignKey("LastEditedById")
|
||||
.HasPrincipalKey("UserId")
|
||||
.OnDelete(DeleteBehavior.SetNull)
|
||||
.HasConstraintName("FK_server_ban_player_last_edited_by_id");
|
||||
|
||||
b.HasOne("Content.Server.Database.Round", "Round")
|
||||
.WithMany()
|
||||
.HasForeignKey("RoundId")
|
||||
.HasConstraintName("FK_server_ban_round_round_id");
|
||||
|
||||
b.OwnsOne("Content.Server.Database.TypedHwid", "HWId", b1 =>
|
||||
{
|
||||
b1.Property<int>("ServerBanId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("server_ban_id");
|
||||
|
||||
b1.Property<byte[]>("Hwid")
|
||||
.IsRequired()
|
||||
.HasColumnType("BLOB")
|
||||
.HasColumnName("hwid");
|
||||
|
||||
b1.Property<int>("Type")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(0)
|
||||
.HasColumnName("hwid_type");
|
||||
|
||||
b1.HasKey("ServerBanId");
|
||||
|
||||
b1.ToTable("server_ban");
|
||||
|
||||
b1.WithOwner()
|
||||
.HasForeignKey("ServerBanId")
|
||||
.HasConstraintName("FK_server_ban_server_ban_server_ban_id");
|
||||
});
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("HWId");
|
||||
|
||||
b.Navigation("LastEditedBy");
|
||||
|
||||
b.Navigation("Round");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ServerBanHit", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.ServerBan", "Ban")
|
||||
b.HasOne("Content.Server.Database.Ban", "Ban")
|
||||
.WithMany("BanHits")
|
||||
.HasForeignKey("BanId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_server_ban_hit_server_ban_ban_id");
|
||||
.HasConstraintName("FK_server_ban_hit_ban_ban_id");
|
||||
|
||||
b.HasOne("Content.Server.Database.ConnectionLog", "Connection")
|
||||
.WithMany("BanHits")
|
||||
@@ -1820,86 +1887,6 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
b.Navigation("Connection");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ServerRoleBan", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Player", "CreatedBy")
|
||||
.WithMany("AdminServerRoleBansCreated")
|
||||
.HasForeignKey("BanningAdmin")
|
||||
.HasPrincipalKey("UserId")
|
||||
.OnDelete(DeleteBehavior.SetNull)
|
||||
.HasConstraintName("FK_server_role_ban_player_banning_admin");
|
||||
|
||||
b.HasOne("Content.Server.Database.Player", "LastEditedBy")
|
||||
.WithMany("AdminServerRoleBansLastEdited")
|
||||
.HasForeignKey("LastEditedById")
|
||||
.HasPrincipalKey("UserId")
|
||||
.OnDelete(DeleteBehavior.SetNull)
|
||||
.HasConstraintName("FK_server_role_ban_player_last_edited_by_id");
|
||||
|
||||
b.HasOne("Content.Server.Database.Round", "Round")
|
||||
.WithMany()
|
||||
.HasForeignKey("RoundId")
|
||||
.HasConstraintName("FK_server_role_ban_round_round_id");
|
||||
|
||||
b.OwnsOne("Content.Server.Database.TypedHwid", "HWId", b1 =>
|
||||
{
|
||||
b1.Property<int>("ServerRoleBanId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("server_role_ban_id");
|
||||
|
||||
b1.Property<byte[]>("Hwid")
|
||||
.IsRequired()
|
||||
.HasColumnType("BLOB")
|
||||
.HasColumnName("hwid");
|
||||
|
||||
b1.Property<int>("Type")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(0)
|
||||
.HasColumnName("hwid_type");
|
||||
|
||||
b1.HasKey("ServerRoleBanId");
|
||||
|
||||
b1.ToTable("server_role_ban");
|
||||
|
||||
b1.WithOwner()
|
||||
.HasForeignKey("ServerRoleBanId")
|
||||
.HasConstraintName("FK_server_role_ban_server_role_ban_server_role_ban_id");
|
||||
});
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("HWId");
|
||||
|
||||
b.Navigation("LastEditedBy");
|
||||
|
||||
b.Navigation("Round");
|
||||
});
|
||||
|
||||
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")
|
||||
@@ -1912,6 +1899,18 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
b.Navigation("Profile");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Unban", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Ban", "Ban")
|
||||
.WithOne("Unban")
|
||||
.HasForeignKey("Content.Server.Database.Unban", "BanId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_unban_ban_ban_id");
|
||||
|
||||
b.Navigation("Ban");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PlayerRound", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Player", null)
|
||||
@@ -1946,6 +1945,23 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
b.Navigation("Flags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Ban", b =>
|
||||
{
|
||||
b.Navigation("Addresses");
|
||||
|
||||
b.Navigation("BanHits");
|
||||
|
||||
b.Navigation("Hwids");
|
||||
|
||||
b.Navigation("Players");
|
||||
|
||||
b.Navigation("Roles");
|
||||
|
||||
b.Navigation("Rounds");
|
||||
|
||||
b.Navigation("Unban");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.ConnectionLog", b =>
|
||||
{
|
||||
b.Navigation("BanHits");
|
||||
@@ -1975,10 +1991,6 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
|
||||
b.Navigation("AdminServerBansLastEdited");
|
||||
|
||||
b.Navigation("AdminServerRoleBansCreated");
|
||||
|
||||
b.Navigation("AdminServerRoleBansLastEdited");
|
||||
|
||||
b.Navigation("AdminWatchlistsCreated");
|
||||
|
||||
b.Navigation("AdminWatchlistsDeleted");
|
||||
@@ -2027,18 +2039,6 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
328
Content.Server.Database/Model.Ban.cs
Normal file
328
Content.Server.Database/Model.Ban.cs
Normal file
@@ -0,0 +1,328 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Content.Shared.Database;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NpgsqlTypes;
|
||||
|
||||
// ReSharper disable EntityFramework.ModelValidation.UnlimitedStringLength
|
||||
|
||||
namespace Content.Server.Database;
|
||||
|
||||
//
|
||||
// Contains model definitions primarily related to bans.
|
||||
//
|
||||
|
||||
internal static class ModelBan
|
||||
{
|
||||
public static void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<Ban>()
|
||||
.HasOne(b => b.CreatedBy)
|
||||
.WithMany(pl => pl.AdminServerBansCreated)
|
||||
.HasForeignKey(b => b.BanningAdmin)
|
||||
.HasPrincipalKey(pl => pl.UserId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
modelBuilder.Entity<Ban>()
|
||||
.HasOne(b => b.LastEditedBy)
|
||||
.WithMany(pl => pl.AdminServerBansLastEdited)
|
||||
.HasForeignKey(b => b.LastEditedById)
|
||||
.HasPrincipalKey(pl => pl.UserId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
modelBuilder.Entity<BanPlayer>()
|
||||
.HasIndex(bp => new { bp.UserId, bp.BanId })
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder.Entity<BanHwid>()
|
||||
.OwnsOne(bp => bp.HWId)
|
||||
.Property(hwid => hwid.Hwid)
|
||||
.HasColumnName("hwid");
|
||||
|
||||
modelBuilder.Entity<BanRole>()
|
||||
.HasIndex(bp => new { bp.RoleType, bp.RoleId, bp.BanId })
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder.Entity<BanRound>()
|
||||
.HasIndex(bp => new { bp.RoundId, bp.BanId })
|
||||
.IsUnique();
|
||||
|
||||
// Following indices have to be made manually by migration, due to limitations in EF Core:
|
||||
// https://github.com/dotnet/efcore/issues/11336
|
||||
// https://github.com/npgsql/efcore.pg/issues/2567
|
||||
// modelBuilder.Entity<BanAddress>()
|
||||
// .HasIndex(bp => new { bp.Address, bp.BanId })
|
||||
// .IsUnique();
|
||||
// modelBuilder.Entity<BanHwid>()
|
||||
// .HasIndex(hwid => new { hwid.HWId.Type, hwid.HWId.Hwid, hwid.Hwid })
|
||||
// .IsUnique();
|
||||
// (postgres only)
|
||||
// modelBuilder.Entity<BanAddress>()
|
||||
// .HasIndex(ba => ba.Address)
|
||||
// .IncludeProperties(ba => ba.BanId)
|
||||
// .IsUnique()
|
||||
// .HasMethod("gist")
|
||||
// .HasOperators("inet_ops");
|
||||
|
||||
modelBuilder.Entity<Ban>()
|
||||
.ToTable(t => t.HasCheckConstraint("NoExemptOnRoleBan", $"type = {(int)BanType.Server} OR exempt_flags = 0"));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies a ban of some kind.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Bans come in two types: <see cref="BanType.Server"/> and <see cref="BanType.Role"/>,
|
||||
/// distinguished with <see cref="Type"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Bans have one or more "matching data", these being <see cref="BanAddress"/>, <see cref="BanPlayer"/>,
|
||||
/// and <see cref="BanHwid"/> entities. If a player's connection info matches any of these,
|
||||
/// the ban's effects will apply to that player.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Bans can be set to expire after a certain point in time, or be permanent. They can also be removed manually
|
||||
/// ("unbanned") by an admin, which is stored as an <see cref="Unban"/> entity existing for this ban.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public sealed class Ban
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this is a role or server ban.
|
||||
/// </summary>
|
||||
public required BanType Type { get; set; }
|
||||
|
||||
public TimeSpan PlaytimeAtNote { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The time when the ban was applied by an administrator.
|
||||
/// </summary>
|
||||
public DateTime BanTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The time the ban will expire. If null, the ban is permanent and will not expire naturally.
|
||||
/// </summary>
|
||||
public DateTime? ExpirationTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The administrator-stated reason for applying the ban.
|
||||
/// </summary>
|
||||
public string Reason { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The severity of the incident
|
||||
/// </summary>
|
||||
public NoteSeverity Severity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User ID of the admin that initially applied the ban.
|
||||
/// </summary>
|
||||
[ForeignKey(nameof(CreatedBy))]
|
||||
public Guid? BanningAdmin { get; set; }
|
||||
|
||||
public Player? CreatedBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User ID of the admin that last edited the note
|
||||
/// </summary>
|
||||
[ForeignKey(nameof(LastEditedBy))]
|
||||
public Guid? LastEditedById { get; set; }
|
||||
|
||||
public Player? LastEditedBy { get; set; }
|
||||
public DateTime? LastEditedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional flags that allow adding exemptions to the ban via <see cref="ServerBanExemption"/>.
|
||||
/// </summary>
|
||||
public ServerBanExemptFlags ExemptFlags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this ban should be automatically deleted from the database when it expires.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This isn't done automatically by the game,
|
||||
/// you will need to set up something like a cron job to clear this from your database,
|
||||
/// using a command like this:
|
||||
/// psql -d ss14 -c "DELETE FROM server_ban WHERE auto_delete AND expiration_time < NOW()"
|
||||
/// </remarks>
|
||||
public bool AutoDelete { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to display this ban in the admin remarks (notes) panel
|
||||
/// </summary>
|
||||
public bool Hidden { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If present, an administrator has manually repealed this ban.
|
||||
/// </summary>
|
||||
public Unban? Unban { get; set; }
|
||||
|
||||
public List<BanRound>? Rounds { get; set; }
|
||||
public List<BanPlayer>? Players { get; set; }
|
||||
public List<BanAddress>? Addresses { get; set; }
|
||||
public List<BanHwid>? Hwids { get; set; }
|
||||
public List<BanRole>? Roles { get; set; }
|
||||
public List<ServerBanHit>? BanHits { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base type for entities that specify ban matching data.
|
||||
/// </summary>
|
||||
public interface IBanSelector
|
||||
{
|
||||
int BanId { get; }
|
||||
Ban? Ban { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that a ban was related to a round (e.g. placed on that round).
|
||||
/// </summary>
|
||||
public sealed class BanRound
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the ban to which this round was relevant.
|
||||
/// </summary>
|
||||
[ForeignKey(nameof(Ban))]
|
||||
public int BanId { get; set; }
|
||||
|
||||
public Ban? Ban { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the round to which this ban was relevant to.
|
||||
/// </summary>
|
||||
[ForeignKey(nameof(Round))]
|
||||
public int RoundId { get; set; }
|
||||
|
||||
public Round? Round { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies a player that a <see cref="T:Database.Ban"/> matches.
|
||||
/// </summary>
|
||||
public sealed class BanPlayer : IBanSelector
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The user ID of the banned player.
|
||||
/// </summary>
|
||||
public Guid UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the ban to which this applies.
|
||||
/// </summary>
|
||||
[ForeignKey(nameof(Ban))]
|
||||
public int BanId { get; set; }
|
||||
|
||||
public Ban? Ban { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies an IP address range that a <see cref="T:Database.Ban"/> matches.
|
||||
/// </summary>
|
||||
public sealed class BanAddress : IBanSelector
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The address range being matched.
|
||||
/// </summary>
|
||||
public required NpgsqlInet Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the ban to which this applies.
|
||||
/// </summary>
|
||||
[ForeignKey(nameof(Ban))]
|
||||
public int BanId { get; set; }
|
||||
|
||||
public Ban? Ban { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies a HWID that a <see cref="T:Database.Ban"/> matches.
|
||||
/// </summary>
|
||||
public sealed class BanHwid : IBanSelector
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The HWID being matched.
|
||||
/// </summary>
|
||||
public required TypedHwid HWId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the ban to which this applies.
|
||||
/// </summary>
|
||||
[ForeignKey(nameof(Ban))]
|
||||
public int BanId { get; set; }
|
||||
|
||||
public Ban? Ban { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A single role banned among a greater role ban record.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see cref="Ban"/>s of type <see cref="BanType.Role"/> should have one or more <see cref="BanRole"/>s
|
||||
/// to store which roles are actually banned.
|
||||
/// It is invalid for <see cref="BanType.Server"/> bans to have <see cref="BanRole"/> entities.
|
||||
/// </remarks>
|
||||
public sealed class BanRole
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// What type of role is being banned. For example <c>Job</c> or <c>Antag</c>.
|
||||
/// </summary>
|
||||
public required string RoleType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the role being banned. This is probably something like a prototype.
|
||||
/// </summary>
|
||||
public required string RoleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the ban to which this applies.
|
||||
/// </summary>
|
||||
[ForeignKey(nameof(Ban))]
|
||||
public int BanId { get; set; }
|
||||
|
||||
public Ban? Ban { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An explicit repeal of a <see cref="Ban"/> by an administrator.
|
||||
/// Having an entry for a ban neutralizes it.
|
||||
/// </summary>
|
||||
public sealed class Unban
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of ban that is being repealed.
|
||||
/// </summary>
|
||||
[ForeignKey(nameof(Ban))]
|
||||
public int BanId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ban that is being repealed.
|
||||
/// </summary>
|
||||
public Ban? Ban { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The admin that repealed the ban.
|
||||
/// </summary>
|
||||
public Guid? UnbanningAdmin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The time the ban was repealed.
|
||||
/// </summary>
|
||||
public DateTime UnbanTime { get; set; }
|
||||
}
|
||||
@@ -9,7 +9,6 @@ using System.Net;
|
||||
using System.Text.Json;
|
||||
using Content.Shared.Database;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NpgsqlTypes;
|
||||
|
||||
namespace Content.Server.Database
|
||||
{
|
||||
@@ -31,13 +30,17 @@ namespace Content.Server.Database
|
||||
public DbSet<AdminLogPlayer> AdminLogPlayer { get; set; } = null!;
|
||||
public DbSet<Whitelist> Whitelist { get; set; } = null!;
|
||||
public DbSet<Blacklist> Blacklist { get; set; } = null!;
|
||||
public DbSet<ServerBan> Ban { get; set; } = default!;
|
||||
public DbSet<ServerUnban> Unban { get; set; } = default!;
|
||||
public DbSet<Ban> Ban { get; set; } = default!;
|
||||
public DbSet<BanRound> BanRound { get; set; } = default!;
|
||||
public DbSet<BanPlayer> BanPlayer { get; set; } = default!;
|
||||
public DbSet<BanAddress> BanAddress { get; set; } = default!;
|
||||
public DbSet<BanHwid> BanHwid { get; set; } = default!;
|
||||
public DbSet<BanRole> BanRole { get; set; } = default!;
|
||||
public DbSet<Unban> Unban { get; set; } = default!;
|
||||
public DbSet<ServerBanExemption> BanExemption { get; set; } = default!;
|
||||
public DbSet<ConnectionLog> ConnectionLog { get; set; } = default!;
|
||||
public DbSet<ServerBanHit> ServerBanHit { get; set; } = default!;
|
||||
public DbSet<ServerRoleBan> RoleBan { get; set; } = default!;
|
||||
public DbSet<ServerRoleUnban> RoleUnban { get; set; } = default!;
|
||||
|
||||
public DbSet<PlayTime> PlayTime { get; set; } = default!;
|
||||
public DbSet<UploadedResourceLog> UploadedResourceLog { get; set; } = default!;
|
||||
public DbSet<AdminNote> AdminNotes { get; set; } = null!;
|
||||
@@ -145,43 +148,11 @@ namespace Content.Server.Database
|
||||
modelBuilder.Entity<AdminLogPlayer>()
|
||||
.HasKey(logPlayer => new {logPlayer.RoundId, logPlayer.LogId, logPlayer.PlayerUserId});
|
||||
|
||||
modelBuilder.Entity<ServerBan>()
|
||||
.HasIndex(p => p.PlayerUserId);
|
||||
|
||||
modelBuilder.Entity<ServerBan>()
|
||||
.HasIndex(p => p.Address);
|
||||
|
||||
modelBuilder.Entity<ServerBan>()
|
||||
.HasIndex(p => p.PlayerUserId);
|
||||
|
||||
modelBuilder.Entity<ServerUnban>()
|
||||
.HasIndex(p => p.BanId)
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder.Entity<ServerBan>().ToTable(t =>
|
||||
t.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR player_user_id IS NOT NULL OR hwid IS NOT NULL"));
|
||||
|
||||
// Ban exemption can't have flags 0 since that wouldn't exempt anything.
|
||||
// The row should be removed if setting to 0.
|
||||
modelBuilder.Entity<ServerBanExemption>().ToTable(t =>
|
||||
t.HasCheckConstraint("FlagsNotZero", "flags != 0"));
|
||||
|
||||
modelBuilder.Entity<ServerRoleBan>()
|
||||
.HasIndex(p => p.PlayerUserId);
|
||||
|
||||
modelBuilder.Entity<ServerRoleBan>()
|
||||
.HasIndex(p => p.Address);
|
||||
|
||||
modelBuilder.Entity<ServerRoleBan>()
|
||||
.HasIndex(p => p.PlayerUserId);
|
||||
|
||||
modelBuilder.Entity<ServerRoleUnban>()
|
||||
.HasIndex(p => p.BanId)
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder.Entity<ServerRoleBan>().ToTable(t =>
|
||||
t.HasCheckConstraint("HaveEitherAddressOrUserIdOrHWId", "address IS NOT NULL OR player_user_id IS NOT NULL OR hwid IS NOT NULL"));
|
||||
|
||||
modelBuilder.Entity<Player>()
|
||||
.HasIndex(p => p.UserId)
|
||||
.IsUnique();
|
||||
@@ -296,34 +267,6 @@ namespace Content.Server.Database
|
||||
t.HasCheckConstraint("NotDismissedAndSeen",
|
||||
"NOT dismissed OR seen"));
|
||||
|
||||
modelBuilder.Entity<ServerBan>()
|
||||
.HasOne(ban => ban.CreatedBy)
|
||||
.WithMany(author => author.AdminServerBansCreated)
|
||||
.HasForeignKey(ban => ban.BanningAdmin)
|
||||
.HasPrincipalKey(author => author.UserId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
modelBuilder.Entity<ServerBan>()
|
||||
.HasOne(ban => ban.LastEditedBy)
|
||||
.WithMany(author => author.AdminServerBansLastEdited)
|
||||
.HasForeignKey(ban => ban.LastEditedById)
|
||||
.HasPrincipalKey(author => author.UserId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
modelBuilder.Entity<ServerRoleBan>()
|
||||
.HasOne(ban => ban.CreatedBy)
|
||||
.WithMany(author => author.AdminServerRoleBansCreated)
|
||||
.HasForeignKey(ban => ban.BanningAdmin)
|
||||
.HasPrincipalKey(author => author.UserId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
modelBuilder.Entity<ServerRoleBan>()
|
||||
.HasOne(ban => ban.LastEditedBy)
|
||||
.WithMany(author => author.AdminServerRoleBansLastEdited)
|
||||
.HasForeignKey(ban => ban.LastEditedById)
|
||||
.HasPrincipalKey(author => author.UserId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
modelBuilder.Entity<RoleWhitelist>()
|
||||
.HasOne(w => w.Player)
|
||||
.WithMany(p => p.JobWhitelists)
|
||||
@@ -342,26 +285,6 @@ namespace Content.Server.Database
|
||||
.Property(p => p.Type)
|
||||
.HasDefaultValue(HwidType.Legacy);
|
||||
|
||||
modelBuilder.Entity<ServerBan>()
|
||||
.OwnsOne(p => p.HWId)
|
||||
.Property(p => p.Hwid)
|
||||
.HasColumnName("hwid");
|
||||
|
||||
modelBuilder.Entity<ServerBan>()
|
||||
.OwnsOne(p => p.HWId)
|
||||
.Property(p => p.Type)
|
||||
.HasDefaultValue(HwidType.Legacy);
|
||||
|
||||
modelBuilder.Entity<ServerRoleBan>()
|
||||
.OwnsOne(p => p.HWId)
|
||||
.Property(p => p.Hwid)
|
||||
.HasColumnName("hwid");
|
||||
|
||||
modelBuilder.Entity<ServerRoleBan>()
|
||||
.OwnsOne(p => p.HWId)
|
||||
.Property(p => p.Type)
|
||||
.HasDefaultValue(HwidType.Legacy);
|
||||
|
||||
modelBuilder.Entity<ConnectionLog>()
|
||||
.OwnsOne(p => p.HWId)
|
||||
.Property(p => p.Hwid)
|
||||
@@ -371,6 +294,8 @@ namespace Content.Server.Database
|
||||
.OwnsOne(p => p.HWId)
|
||||
.Property(p => p.Type)
|
||||
.HasDefaultValue(HwidType.Legacy);
|
||||
|
||||
ModelBan.OnModelCreating(modelBuilder);
|
||||
}
|
||||
|
||||
public virtual IQueryable<AdminLog> SearchLogs(IQueryable<AdminLog> query, string searchText)
|
||||
@@ -591,10 +516,8 @@ namespace Content.Server.Database
|
||||
public List<AdminMessage> AdminMessagesCreated { get; set; } = null!;
|
||||
public List<AdminMessage> AdminMessagesLastEdited { get; set; } = null!;
|
||||
public List<AdminMessage> AdminMessagesDeleted { get; set; } = null!;
|
||||
public List<ServerBan> AdminServerBansCreated { get; set; } = null!;
|
||||
public List<ServerBan> AdminServerBansLastEdited { get; set; } = null!;
|
||||
public List<ServerRoleBan> AdminServerRoleBansCreated { get; set; } = null!;
|
||||
public List<ServerRoleBan> AdminServerRoleBansLastEdited { get; set; } = null!;
|
||||
public List<Ban> AdminServerBansCreated { get; set; } = null!;
|
||||
public List<Ban> AdminServerBansLastEdited { get; set; } = null!;
|
||||
public List<RoleWhitelist> JobWhitelists { get; set; } = null!;
|
||||
}
|
||||
|
||||
@@ -724,30 +647,6 @@ namespace Content.Server.Database
|
||||
[ForeignKey("RoundId,LogId")] public AdminLog Log { get; set; } = default!;
|
||||
}
|
||||
|
||||
// Used by SS14.Admin
|
||||
public interface IBanCommon<TUnban> where TUnban : IUnbanCommon
|
||||
{
|
||||
int Id { get; set; }
|
||||
Guid? PlayerUserId { get; set; }
|
||||
NpgsqlInet? Address { get; set; }
|
||||
TypedHwid? HWId { get; set; }
|
||||
DateTime BanTime { get; set; }
|
||||
DateTime? ExpirationTime { get; set; }
|
||||
string Reason { get; set; }
|
||||
NoteSeverity Severity { get; set; }
|
||||
Guid? BanningAdmin { get; set; }
|
||||
TUnban? Unban { get; set; }
|
||||
}
|
||||
|
||||
// Used by SS14.Admin
|
||||
public interface IUnbanCommon
|
||||
{
|
||||
int Id { get; set; }
|
||||
int BanId { get; set; }
|
||||
Guid? UnbanningAdmin { get; set; }
|
||||
DateTime UnbanTime { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flags for use with <see cref="ServerBanExemption"/>.
|
||||
/// </summary>
|
||||
@@ -785,138 +684,6 @@ namespace Content.Server.Database
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A ban from playing on the server.
|
||||
/// If an incoming connection matches any of UserID, IP, or HWID, they will be blocked from joining the server.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// At least one of UserID, IP, or HWID must be given (otherwise the ban would match nothing).
|
||||
/// </remarks>
|
||||
[Table("server_ban"), Index(nameof(PlayerUserId))]
|
||||
public class ServerBan : IBanCommon<ServerUnban>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[ForeignKey("Round")]
|
||||
public int? RoundId { get; set; }
|
||||
public Round? Round { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The user ID of the banned player.
|
||||
/// </summary>
|
||||
public Guid? PlayerUserId { get; set; }
|
||||
[Required] public TimeSpan PlaytimeAtNote { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// CIDR IP address range of the ban. The whole range can match the ban.
|
||||
/// </summary>
|
||||
public NpgsqlInet? Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Hardware ID of the banned player.
|
||||
/// </summary>
|
||||
public TypedHwid? HWId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The time when the ban was applied by an administrator.
|
||||
/// </summary>
|
||||
public DateTime BanTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The time the ban will expire. If null, the ban is permanent and will not expire naturally.
|
||||
/// </summary>
|
||||
public DateTime? ExpirationTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The administrator-stated reason for applying the ban.
|
||||
/// </summary>
|
||||
public string Reason { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The severity of the incident
|
||||
/// </summary>
|
||||
public NoteSeverity Severity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User ID of the admin that applied the ban.
|
||||
/// </summary>
|
||||
[ForeignKey("CreatedBy")]
|
||||
public Guid? BanningAdmin { get; set; }
|
||||
|
||||
public Player? CreatedBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User ID of the admin that last edited the note
|
||||
/// </summary>
|
||||
[ForeignKey("LastEditedBy")]
|
||||
public Guid? LastEditedById { get; set; }
|
||||
|
||||
public Player? LastEditedBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// When the ban was last edited
|
||||
/// </summary>
|
||||
public DateTime? LastEditedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional flags that allow adding exemptions to the ban via <see cref="ServerBanExemption"/>.
|
||||
/// </summary>
|
||||
public ServerBanExemptFlags ExemptFlags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If present, an administrator has manually repealed this ban.
|
||||
/// </summary>
|
||||
public ServerUnban? Unban { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this ban should be automatically deleted from the database when it expires.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This isn't done automatically by the game,
|
||||
/// you will need to set up something like a cron job to clear this from your database,
|
||||
/// using a command like this:
|
||||
/// psql -d ss14 -c "DELETE FROM server_ban WHERE auto_delete AND expiration_time < NOW()"
|
||||
/// </remarks>
|
||||
public bool AutoDelete { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to display this ban in the admin remarks (notes) panel
|
||||
/// </summary>
|
||||
public bool Hidden { get; set; }
|
||||
|
||||
public List<ServerBanHit> BanHits { get; set; } = null!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An explicit repeal of a <see cref="ServerBan"/> by an administrator.
|
||||
/// Having an entry for a ban neutralizes it.
|
||||
/// </summary>
|
||||
[Table("server_unban")]
|
||||
public class ServerUnban : IUnbanCommon
|
||||
{
|
||||
[Column("unban_id")] public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of ban that is being repealed.
|
||||
/// </summary>
|
||||
public int BanId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ban that is being repealed.
|
||||
/// </summary>
|
||||
public ServerBan Ban { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The admin that repealed the ban.
|
||||
/// </summary>
|
||||
public Guid? UnbanningAdmin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The time the ban repealed.
|
||||
/// </summary>
|
||||
public DateTime UnbanTime { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An exemption for a specific user to a certain type of <see cref="ServerBan"/>.
|
||||
/// </summary>
|
||||
@@ -937,7 +704,7 @@ namespace Content.Server.Database
|
||||
|
||||
/// <summary>
|
||||
/// The ban flags to exempt this player from.
|
||||
/// If any bit overlaps <see cref="ServerBan.ExemptFlags"/>, the ban is ignored.
|
||||
/// If any bit overlaps <see cref="Ban.ExemptFlags"/>, the ban is ignored.
|
||||
/// </summary>
|
||||
public ServerBanExemptFlags Flags { get; set; }
|
||||
}
|
||||
@@ -1000,54 +767,10 @@ namespace Content.Server.Database
|
||||
public int BanId { get; set; }
|
||||
public int ConnectionId { get; set; }
|
||||
|
||||
public ServerBan Ban { get; set; } = null!;
|
||||
public Ban Ban { get; set; } = null!;
|
||||
public ConnectionLog Connection { get; set; } = null!;
|
||||
}
|
||||
|
||||
[Table("server_role_ban"), Index(nameof(PlayerUserId))]
|
||||
public sealed class ServerRoleBan : IBanCommon<ServerRoleUnban>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int? RoundId { get; set; }
|
||||
public Round? Round { get; set; }
|
||||
public Guid? PlayerUserId { get; set; }
|
||||
[Required] public TimeSpan PlaytimeAtNote { get; set; }
|
||||
public NpgsqlInet? Address { get; set; }
|
||||
public TypedHwid? HWId { get; set; }
|
||||
|
||||
public DateTime BanTime { get; set; }
|
||||
|
||||
public DateTime? ExpirationTime { get; set; }
|
||||
|
||||
public string Reason { get; set; } = null!;
|
||||
|
||||
public NoteSeverity Severity { get; set; }
|
||||
[ForeignKey("CreatedBy")] public Guid? BanningAdmin { get; set; }
|
||||
public Player? CreatedBy { get; set; }
|
||||
|
||||
[ForeignKey("LastEditedBy")] public Guid? LastEditedById { get; set; }
|
||||
public Player? LastEditedBy { get; set; }
|
||||
public DateTime? LastEditedAt { get; set; }
|
||||
|
||||
public ServerRoleUnban? Unban { get; set; }
|
||||
public bool Hidden { get; set; }
|
||||
|
||||
public string RoleId { get; set; } = null!;
|
||||
}
|
||||
|
||||
[Table("server_role_unban")]
|
||||
public sealed class ServerRoleUnban : IUnbanCommon
|
||||
{
|
||||
[Column("role_unban_id")] public int Id { get; set; }
|
||||
|
||||
public int BanId { get; set; }
|
||||
public ServerRoleBan Ban { get; set; } = null!;
|
||||
|
||||
public Guid? UnbanningAdmin { get; set; }
|
||||
|
||||
public DateTime UnbanTime { get; set; }
|
||||
}
|
||||
|
||||
[Table("play_time")]
|
||||
public sealed class PlayTime
|
||||
{
|
||||
@@ -1247,31 +970,31 @@ namespace Content.Server.Database
|
||||
/// <summary>
|
||||
/// The reason for the ban.
|
||||
/// </summary>
|
||||
/// <seealso cref="ServerBan.Reason"/>
|
||||
/// <seealso cref="Ban.Reason"/>
|
||||
public string Reason { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Exemptions granted to the ban.
|
||||
/// </summary>
|
||||
/// <seealso cref="ServerBan.ExemptFlags"/>
|
||||
/// <seealso cref="Ban.ExemptFlags"/>
|
||||
public ServerBanExemptFlags ExemptFlags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Severity of the ban
|
||||
/// </summary>
|
||||
/// <seealso cref="ServerBan.Severity"/>
|
||||
/// <seealso cref="Ban.Severity"/>
|
||||
public NoteSeverity Severity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ban will be automatically deleted once expired.
|
||||
/// </summary>
|
||||
/// <seealso cref="ServerBan.AutoDelete"/>
|
||||
/// <seealso cref="Ban.AutoDelete"/>
|
||||
public bool AutoDelete { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ban is not visible to players in the remarks menu.
|
||||
/// </summary>
|
||||
/// <seealso cref="ServerBan.Hidden"/>
|
||||
/// <seealso cref="Ban.Hidden"/>
|
||||
public bool Hidden { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -39,10 +39,7 @@ namespace Content.Server.Database
|
||||
// ReSharper disable StringLiteralTypo
|
||||
// Enforce that an address cannot be IPv6-mapped IPv4.
|
||||
// So that IPv4 addresses are consistent between separate-socket and dual-stack socket modes.
|
||||
modelBuilder.Entity<ServerBan>().ToTable(t =>
|
||||
t.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address"));
|
||||
|
||||
modelBuilder.Entity<ServerRoleBan>().ToTable( t =>
|
||||
modelBuilder.Entity<BanAddress>().ToTable(t =>
|
||||
t.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address"));
|
||||
|
||||
modelBuilder.Entity<Player>().ToTable(t =>
|
||||
|
||||
@@ -58,13 +58,7 @@ namespace Content.Server.Database
|
||||
);
|
||||
|
||||
modelBuilder
|
||||
.Entity<ServerBan>()
|
||||
.Property(e => e.Address)
|
||||
.HasColumnType("TEXT")
|
||||
.HasConversion(ipMaskConverter);
|
||||
|
||||
modelBuilder
|
||||
.Entity<ServerRoleBan>()
|
||||
.Entity<BanAddress>()
|
||||
.Property(e => e.Address)
|
||||
.HasColumnType("TEXT")
|
||||
.HasConversion(ipMaskConverter);
|
||||
|
||||
Reference in New Issue
Block a user