Обсуждение участника:WikiHampter/Разработка:Структура базы данных

Обсуждение страницы Участник:WikiHampter/Разработка:Структура базы данных

База данных Space Station 14 (DeadSpace)

Проект: Content.Server.Database
ORM: Entity Framework Core
Движок: PostgreSQL 16 (production) / SQLite (dev)
Соглашение об именах: Все имена таблиц, колонок, индексов и ограничений записываются в snake_case автоматически через кастомный конвеншен.

База данных — общая для игрового сервера и админ-панели. Всего 41 таблица, охватывающая игроков, персонажей, наказания, администрирование, логи и форковые расширения DeadSpace.

Список таблиц

  1. preference — Настройки игрока
  2. profile — Профиль персонажа
  3. job — Предпочтения по работе
  4. antag — Предпочтения по антагонистам
  5. trait — Черты характера
  6. profile_role_loadout — Экипировка по ролям
  7. profile_loadout_group — Группа экипировки
  8. profile_loadout — Конкретный предмет экипировки
  9. assigned_user_id — Привязка никнейма к UUID
  10. player — Зарегистрированные игроки
  11. whitelist — Вайтлист (допуск на сервер)
  12. blacklist — Блэклист (блокировка на сервер)
  13. admin — Администраторы
  14. admin_flag — Индивидуальные флаги прав админов
  15. admin_rank — Ранги/группы админов
  16. admin_rank_flag — Флаги прав, привязанные к рангу
  17. server — Игровые серверы
  18. round — Игровые раунды
  19. player_round — Связь игроков с раундами (M:N)
  20. admin_log — Логи действий администраторов
  21. admin_log_player — Привязка логов админов к игрокам
  22. ban — Баны (серверные и ролевые в одной таблице)
  23. ban_address — IP-адреса, попадающие под бан
  24. ban_hwid — HWID (железо), попадающие под бан
  25. ban_player — Игроки (по UserId), попадающие под бан
  26. ban_role — Роли, попадающие под ролевой бан
  27. ban_round — Привязка бана к раунду, в котором он выдан
  28. unban — Снятие бана (кто и когда снял)
  29. server_ban_exemption — Исключения из банов для конкретных игроков
  30. connection_log — История подключений к серверу
  31. server_ban_hit — Срабатывания бана (кто был заблокирован при попытке зайти)
  32. play_time — Наигранное время по ролям
  33. uploaded_resource_log — Аудит загрузки ресурсов на сервер
  34. admin_notes — Заметки администраторов на игроков
  35. admin_watchlists — Вотчлисты (список наблюдения)
  36. admin_messages — Сообщения администраторов игрокам
  37. role_whitelists — Вайтлист на конкретные роли
  38. ban_template — Шаблоны банов для админ-панели
  39. ipintel_cache — Кэш результатов IPIntel (определение VPN/прокси)
  40. bi_stats — Статистика раундов (форк DeadSpace)
  41. information_topics — Информационные страницы (форк DeadSpace)

1. preference

Таблица хранит настройки игрового профиля пользователя. Каждому зарегистрированному пользователю соответствует ровно одна запись. Создаётся автоматически при первом входе на сервер.

Колонка Тип Ограничения Описание
preference_id int PK, автоинкремент Уникальный идентификатор записи настроек
user_id Guid Unique Уникальный идентификатор пользователя (SS14 Central). Связывает таблицу с внешними системами аутентификации
selected_character_slot int Номер выбранного слата персонажа (0-5). Определяет, какой персонаж будет загружен при входе в раунд
admin_ooc_color string Цвет текста в OOC-чате для администраторов. Позволяет настроить отображение сообщений в чате
construction_favorites string[] Список избранных конструкций (для быстрого строительства). Хранится как массив строк

2. profile

Профиль персонажа игрока. Каждый пользователь может иметь до 6 персонажей (слоты 0-5). Содержит полную информацию о внешности, имени и настройках персонажа.

Колонка Тип Ограничения Описание
profile_id int PK, автоинкремент Уникальный идентификатор профиля
slot int Номер слота (0-5). Определяет позицию персонажа в списке выбора
char_name string Имя персонажа, отображаемое в игре
flavor_text string Описание внешности и характера персонажа. Видно другим игрокам при осмотре
age int Возраст персонажа (игровая роль, не настоящий возраст игрока)
sex string Пол персонажа (Male/Female)
gender string Грамматический род (он/она/они) для корректного отображения в чате
species string Раса персонажа (Human, IPC, Diona, Vox, Slime и т.д.)
voice string Тип голоса для TTS (Text-To-Speech). Добавлено в форке Corvax
markings jsonb (PG) / blob (SQLite) Nullable Список татуировок, шрамов и других отметок на теле персонажа в JSON-формате
hair_name string Название причёски
hair_color string Цвет волос (HEX-код)
facial_hair_name string Название растительности на лице
facial_hair_color string Цвет растительности на лице (HEX-код)
eye_color string Цвет глаз (HEX-код)
skin_color string Цвет кожи (HEX-код)
spawn_priority int Default 0 Приоритет появления. Определяет, какой персонаж будет загружен, если подходят несколько
pref_unavailable int 0=StayInLobby, 1=SpawnAsOverflow Поведение, если любимая работа недоступна: остаться в лобби или зайти за overflow-роль
preference_id int FK → preference(preference_id) Ссылка на запись настроек пользователя, которому принадлежит этот персонаж

Уникальный индекс: (slot, preference_id) — гарантирует, что у одного пользователя не будет двух персонажей в одном слоте.


3. job

Предпочтения по работе (роли) для конкретного персонажа. Игрок указывает, кем хочет играть, и приоритет каждой роли.

Колонка Тип Ограничения Описание
job_id int PK, автоинкремент Уникальный идентификатор предпочтения
profile_id int FK → profile(profile_id) Ссылка на профиль персонажа
job_name string Название работы (прототип: StationEngineer, MedicalDoctor, SecurityOfficer...)
priority int 0=Never, 1=Low, 2=Medium, 3=High Приоритет: Never — никогда не спауниться за эту роль, High — хочу больше всего

Уникальный индекс: (profile_id, job_name) — у одного персонажа не может быть двух настроек для одной работы.
Фильтрованный индекс: IX_job_one_high_priority WHERE priority = 3 — гарантирует, что только одна работа может иметь приоритет High (чтобы SS14 мог автоматически определить "любимую" работу).


4. antag

Список антагонистов, которых игрок хочет (или не хочет) получать.

Колонка Тип Ограничения Описание
antag_id int PK, автоинкремент Уникальный идентификатор
profile_id int FK → profile(profile_id) Ссылка на профиль персонажа
antag_name string Название антагониста (Traitor, Changeling, NukeOps и т.д.)

Уникальный индекс: (profile_id, antag_name) — один персонаж не может иметь дублирующихся настроек по одному антагонисту. Отсутствие записи = настройка по умолчанию (разрешено).


5. trait

Черты характера персонажа. Позволяют добавить персонажу особые свойства (положительные или отрицательные), влияющие на геймплей.

Колонка Тип Ограничения Описание
trait_id int PK, автоинкремент Уникальный идентификатор
profile_id int FK → profile(profile_id) Ссылка на профиль персонажа
trait_name string Название черты (LightweightDrunk, Paracusia, Liar, Spacer...)

Уникальный индекс: (profile_id, trait_name) — персонаж не может взять одну черту дважды.


6. profile_role_loadout

Привязка набора экипировки (loadout) к конкретной роли для персонажа. Позволяет настроить, с какими предметами персонаж появляется, если зашёл за определённую роль.

Колонка Тип Ограничения Описание
profile_role_loadout_id int PK, автоинкремент Уникальный идентификатор
profile_id int FK → profile(profile_id) Ссылка на профиль персонажа
role_name string Название роли, для которой применяется этот набор (например, JobStationEngineer)
entity_name string(256) Nullable Название предмета-прототипа, который будет выдан (например, ClothingBackpackDuffelEngineering)

7. profile_loadout_group

Группа предметов внутри набора экипировки для роли. Позволяет разделить loadout на категории (например, "Рюкзаки", "Обувь", "Головные уборы").

Колонка Тип Ограничения Описание
profile_loadout_group_id int PK, автоинкремент Уникальный идентификатор группы
profile_role_loadout_id int FK → profile_role_loadout(profile_role_loadout_id) Ссылка на набор экипировки для роли
group_name string Название группы предметов (Backpack, Shoes, Head, Uniform...)

8. profile_loadout

Конкретный предмет внутри группы экипировки.

Колонка Тип Ограничения Описание
profile_loadout_id int PK, автоинкремент Уникальный идентификатор
profile_loadout_group_id int FK → profile_loadout_group(profile_loadout_group_id) Ссылка на группу экипировки
loadout_name string Название прототипа предмета (ClothingBackpackDuffelEngineering, ClothingHandsGlovesInsulated...)

9. assigned_user_id

Сервисная таблица, которая хранит привязку никнейма игрока к его UUID (GUID пользователя в SS14 Central). Используется для быстрого поиска по имени и обратного поиска.

Колонка Тип Ограничения Описание
assigned_user_id_id int PK, автоинкремент Уникальный идентификатор
user_name string Unique Имя пользователя (никнейм)
user_id Guid Unique Уникальный идентификатор пользователя в SS14 Central

10. player

Основная таблица игроков. Содержит запись о каждом игроке, который хотя бы раз подключался к серверу. Является центром связей: большинство других таблиц (баны, заметки, логи) ссылаются на player.user_id.

Колонка Тип Ограничения Описание
player_id int PK, автоинкремент Внутренний числовой идентификатор
user_id Guid Unique (Alternate Key) Глобальный идентификатор игрока в SS14 Central. Используется как внешний ключ во всех связанных таблицах
first_seen_time DateTime Дата и время первого подключения игрока к серверу
last_seen_user_name string Indexed Последний известный никнейм игрока
last_seen_time DateTime Дата и время последнего подключения
last_seen_address inet (IPAddress) Последний известный IP-адрес игрока
last_seen_hwid byte[] Nullable, Owned Последний известный HWID (аппаратный идентификатор) — часть TypedHwid
last_seen_hwid_type int Default=Legacy(0) Тип HWID (для совместимости с разными методами снятия отпечатка)
last_read_rules DateTime Nullable Дата, когда игрок последний раз прочитал правила сервера

11. whitelist

Список игроков, допущенных на сервер (белый список). Если на сервере включён вайтлист, только пользователи из этой таблицы могут подключиться.

Колонка Тип Ограничения Описание
user_id Guid PK Уникальный идентификатор пользователя, допущенного на сервер

12. blacklist

Список игроков, которым навсегда запрещён вход на сервер (чёрный список). Проверяется до вайтлиста — если игрок в блэклисте, он не сможет зайти, даже если он в вайтлисте.

Колонка Тип Ограничения Описание
user_id Guid PK Уникальный идентификатор заблокированного пользователя

13. admin

Таблица администраторов сервера. Содержит учётные записи людей, имеющих доступ к админ-инструментам.

Колонка Тип Ограничения Описание
user_id Guid PK Уникальный идентификатор пользователя (должен совпадать с player.user_id)
title string Nullable Должность/звание администратора (например, "Главный администратор", "Модератор")
deadminned bool Флаг временного снятия админ-прав. Если true — администратор не может использовать админ-инструменты до повторной активации
suspended bool Флаг отстранения. Если true — администратор отстранён от должности вышестоящим админом
admin_rank_id int Nullable, FK → admin_rank(admin_rank_id), ON DELETE SET NULL Ссылка на ранг администратора. SET NULL при удалении ранга

14. admin_flag

Индивидуальные флаги прав для конкретного администратора. Позволяют точечно выдавать или забирать права, не создавая отдельный ранг.

Колонка Тип Ограничения Описание
admin_flag_id int PK, автоинкремент Уникальный идентификатор
flag string Название флага (Admin, Ban, Notes, ServerControl, Debug...)
negative bool Если true — флаг работает в отрицание (забирает право). Если false — добавляет право
admin_id Guid FK → admin(user_id) Ссылка на администратора

Уникальный индекс: (flag, admin_id) — один флаг не может быть назначен админу дважды.


15. admin_rank

Ранги/группы администраторов. Позволяют группировать несколько флагов прав в одну роль (например, "Модератор", "Старший администратор", "Хост").

Колонка Тип Ограничения Описание
admin_rank_id int PK, автоинкремент Уникальный идентификатор ранга
name string Название ранга (Moderator, SeniorAdmin, Host...)

16. admin_rank_flag

Флаги прав, привязанные к рангу. Когда администратору назначается ранг, он автоматически получает все флаги этого ранга.

Колонка Тип Ограничения Описание
admin_rank_flag_id int PK, автоинкремент Уникальный идентификатор
flag string Название флага права
admin_rank_id int FK → admin_rank(admin_rank_id) Ссылка на ранг

Уникальный индекс: (flag, admin_rank_id) — флаг не может быть назначен рангу дважды.


17. server

Справочная таблица игровых серверов. Позволяет одному игровому процессу (SS14) управлять несколькими серверами (например, "Основной", "Тестовый", "Событийный") и разграничивать данные между ними.

Колонка Тип Ограничения Описание
server_id int PK, автоинкремент Уникальный идентификатор сервера
name string Название сервера (DeadSpace, DeadSpace-Test, DeadSpace-Event...)

18. round

Таблица игровых раундов. Каждый запуск новой игровой сессии создаёт новую запись в этой таблице. Раунд начинается, когда на сервере запускается новый раунд, и заканчивается при его завершении.

Колонка Тип Ограничения Описание
round_id int PK, автоинкремент Уникальный номер раунда
start_date DateTime Nullable, Indexed Дата и время начала раунда
server_id int FK → server(server_id) Сервер, на котором прошёл раунд

19. player_round

Промежуточная таблица для связи "многие-ко-многим" между игроками и раундами. Показывает, какие игроки участвовали в каких раундах.

Колонка Тип Ограничения Описание
players_id int Composite PK, FK → player(player_id) Идентификатор игрока
rounds_id int Composite PK, FK → round(round_id) Идентификатор раунда

Составной первичный ключ: (players_id, rounds_id) — один игрок может быть отмечен в раунде только один раз.


20. admin_log

Журнал действий администраторов. Фиксирует все значимые действия: баны, кики, телепортации, спавн предметов и другие админ-команды.

Колонка Тип Ограничения Описание
round_id int Composite PK, FK → round(round_id) Номер раунда, в котором было совершено действие
admin_log_id int Composite PK Номер лога в рамках раунда (нумерация своя для каждого раунда)
type int Indexed Тип действия (103 типа: AdminMessage, Ban, Kick, Teleport, Spawn, Smoke...)
impact sbyte Степень воздействия на сервер/игроков (Extreme, High, Medium, Low)
date DateTime Indexed Дата и время действия
message string GIN index (tsvector) Текстовое описание действия для полнотекстового поиска
json jsonb JSON-данные с деталями действия (сохраняет параметры команды)

Составной PK: (round_id, admin_log_id). Каждый раунд начинает нумерацию логов с 1. Это сделано для того, чтобы логи оставались читаемыми даже при архивации старых раундов.


21. admin_log_player

Связывает логи администраторов с игроками, которых эти логи касаются. Позволяет найти все админ-действия по конкретному игроку.

Колонка Тип Ограничения Описание
round_id int Composite PK Номер раунда
log_id int Composite PK Номер лога
player_user_id Guid Composite PK, FK → player(user_id) Идентификатор игрока, которого касается это админ-действие

Составной PK: (round_id, log_id, player_user_id)
Внешний ключ: (round_id, log_id) → admin_log(round_id, admin_log_id)
Внешний ключ: player_user_id → player(user_id)


22. ban

Основная таблица наказаний: баны и ролевые баны. Раньше было две отдельные таблицы (server_ban и server_role_ban), но их объединили в одну с полем-дискриминатором type.

Логика работы бана:

  1. Серверный бан (type=0) — запрещает вход на сервер полностью. Проверяется по трём критериям одновременно: IP, HWID, UserId (все три должны совпадать, чтобы бан считался "попаданием")
  2. Ролевой бан (type=1) — запрещает играть за конкретную роль (работу или антагониста). Не проверяет IP/HWID.
Колонка Тип Ограничения Описание
ban_id int PK, автоинкремент Уникальный идентификатор бана
type byte 0=Server, 1=Role Тип бана: серверный или ролевой
playtime_at_note TimeSpan Наигранное время игрока на момент выдачи бана (для контекста)
ban_time DateTime Дата и время выдачи бана
expiration_time DateTime Nullable Дата и время истечения бана. Если null — бан перманентный
reason string Причина бана, введённая администратором
severity int Серьёзность нарушения (лёгкое, среднее, тяжёлое)
banning_admin Guid Nullable, FK → player(user_id), ON DELETE SET NULL Администратор, выдавший бан. SET NULL при удалении админа (GDPR)
last_edited_by_id Guid Nullable, FK → player(user_id), ON DELETE SET NULL Кто последний раз редактировал бан
last_edited_at DateTime Nullable Когда бан был последний раз отредактирован
exempt_flags int Флаги исключений, применённые к бану (например, игрок в датацентре)
auto_delete bool Флаг автоматического удаления по истечении срока
hidden bool Флаг скрытого бана (не показывается в публичных списках, виден только админам)

Проверка: NoExemptOnRoleBan: type = 0 OR exempt_flags = 0 — для ролевых банов запрещено указывать флаги исключений.


23. ban_address

IP-адреса, которые попадают под бан. Когда админ банит игрока, текущий IP-адрес нарушителя сохраняется в эту таблицу. При попытке подключения сервер проверяет IP по этой таблице.

Колонка Тип Ограничения Описание
ban_address_id int PK, автоинкремент Уникальный идентификатор
address inet (PG) / string (SQLite) GiST index (PG) IP-адрес или подсеть под баном (например: 192.168.1.5 или 192.168.0.0/16)
ban_id int FK → ban(ban_id) Ссылка на бан

Уникальный индекс: (address, ban_id) — один адрес не может быть дважды привязан к одному бану.
Проверка (PG): AddressNotIPv6MappedIPv4 — запрещает сохранение IPv4-адресов в формате IPv6-mapped (::ffff:192.168.1.1).


24. ban_hwid

Аппаратные идентификаторы (HWID), которые попадают под бан. HWID — это уникальный отпечаток железа игрока, позволяющий идентифицировать его даже при смене IP или аккаунта.

Колонка Тип Ограничения Описание
ban_hwid_id int PK, автоинкремент Уникальный идентификатор
hwid byte[] Owned (TypedHwid) Массив байт — отпечаток аппаратного обеспечения
hwid_type int Owned, Default=Legacy(0) Тип HWID (на будущее, для разных алгоритмов снятия отпечатка)
ban_id int FK → ban(ban_id) Ссылка на бан

Уникальный индекс: (hwid_type, hwid, ban_id) — один HWID не может быть дважды привязан к одному бану.


25. ban_player

Игроки (по UserId), которые попадают под бан. Это основной идентификатор для проверки бана — проверяется, находится ли UserId подключающегося игрока в этой таблице.

Колонка Тип Ограничения Описание
ban_player_id int PK, автоинкремент Уникальный идентификатор
user_id Guid Идентификатор забаненного игрока
ban_id int FK → ban(ban_id) Ссылка на бан

Уникальный индекс: (user_id, ban_id) — один игрок не может быть дважды привязан к одному бану.


26. ban_role

Роли, которые попадают под ролевой бан (type=1). Например, бан на роль "Captain" запрещает игроку заходить за капитана.

Колонка Тип Ограничения Описание
ban_role_id int PK, автоинкремент Уникальный идентификатор
role_type string Тип роли: "Job" (работа) или "Antag" (антагонист)
role_id string Идентификатор прототипа роли (например, "Captain", "Traitor", "Warden")
ban_id int FK → ban(ban_id) Ссылка на бан

Уникальный индекс: (role_type, role_id, ban_id) — одна роль не может быть дважды привязана к одному бану.


27. ban_round

Связывает бан с раундом, в котором он был выдан. Носит информационный характер — позволяет понять, в каком раунде произошло нарушение.

Колонка Тип Ограничения Описание
ban_round_id int PK, автоинкремент Уникальный идентификатор
ban_id int FK → ban(ban_id) Ссылка на бан
round_id int FK → round(round_id) Ссылка на раунд

Уникальный индекс: (round_id, ban_id) — бан не может быть привязан к одному раунду дважды.


28. unban

Запись о снятии бана. Когда администратор разбанивает игрока, создаётся запись в этой таблице, а сам бан помечается как снятый (через наличие unban-записи). Важно: бан физически не удаляется из БД, а лишь деактивируется.

Колонка Тип Ограничения Описание
unban_id int PK, автоинкремент Уникальный идентификатор снятия бана
ban_id int Unique, FK → ban(ban_id) Ссылка на бан, который был снят (One-to-One: один бан может быть снят только один раз)
unbanning_admin Guid Nullable Администратор, снявший бан. Null возможен, если бан истёк автоматически (auto_delete)
unban_time DateTime Дата и время снятия бана

29. server_ban_exemption

Исключения из проверки банов для конкретных игроков. Позволяет игроку подключаться, даже если его IP или HWID попадает под автоматический бан (например, для датацентров или VPN).

Колонка Тип Ограничения Описание
user_id Guid PK Игрок, которому выдано исключение
flags int Битовая маска флагов исключения: None=0, Datacenter=1, IP=2, BlacklistedRange=4, All=int.MaxValue

Проверка: FlagsNotZero: flags != 0 — исключение должно иметь хотя бы один флаг (бессмысленная пустая запись запрещена).


30. connection_log

Журнал всех попыток подключения к серверу. Записывается каждая попытка войти на сервер — удачная или неудачная. Основной инструмент для расследования нарушений (поиск по IP, HWID, времени).

Колонка Тип Ограничения Описание
connection_log_id int PK, автоинкремент Уникальный идентификатор подключения
user_id Guid Indexed Идентификатор игрока, пытавшегося подключиться
user_name string Никнейм игрока на момент подключения
time DateTime Indexed Дата и время попытки подключения
address inet (IPAddress) IP-адрес, с которого подключался игрок
hwid byte[] Nullable, Owned (TypedHwid) HWID игрока (аппаратный отпечаток)
hwid_type int Default=Legacy(0) Тип HWID
denied byte Nullable (ConnectionDenyReason) Причина отказа, если подключение было отклонено: 0=Ban, 1=Whitelist, 2=Full, 3=Panic, 4=BabyJail, 5=IPChecks, 6=NoHwid
server_id int Default=0, FK → server(server_id), ON DELETE SET NULL Сервер, на который пытались подключиться
trust float Уровень доверия к подключению (на основе IPIntel или других проверок). 0 = не доверяем (VPN), 1 = доверяем

Проверка (PG): AddressNotIPv6MappedIPv4 — запрет IPv6-mapped формата.


31. server_ban_hit

Журнал "попаданий" бана. Когда игрок пытается подключиться, его данные проверяются по активным банам, и если найдено совпадение — запись об этом попадает сюда. Носит статистический характер.

Колонка Тип Ограничения Описание
server_ban_hit_id int PK, автоинкремент Уникальный идентификатор
ban_id int FK → ban(ban_id) Бан, по которому было попадание
connection_id int FK → connection_log(connection_log_id) Попытка подключения, которая вызвала срабатывание

32. play_time

Наигранное время игрока по каждому трекеру (роли). Используется для систем, требующих минимального наигранного времени (например, ролевой вайтлист на капитана требует N часов за инженера).

Колонка Тип Ограничения Описание
play_time_id int PK, автоинкремент Уникальный идентификатор
player_id Guid Идентификатор игрока
tracker string Название трекера — роль или категория (например, "JobStationEngineer", "Overall", "Antag")
time_spent TimeSpan Общее время, проведённое за эту роль

Уникальный индекс: (player_id, tracker) — у одного игрока может быть только одна запись времени по каждому трекеру.


33. uploaded_resource_log

Журнал загрузки пользовательских ресурсов на сервер. Фиксирует, кто, когда и какой файл загрузил. Используется для модерации контента.

Колонка Тип Ограничения Описание
uploaded_resource_log_id int PK, автоинкремент Уникальный идентификатор
date DateTime Дата и время загрузки
user_id Guid Идентификатор загрузившего игрока
path string Путь к файлу на сервере
data byte[] Содержимое загруженного файла (бинарные данные)

34. admin_notes

Система заметок на игроков. Администраторы могут оставлять заметки о нарушениях, предупреждениях или любой другой информации, связанной с игроком. Поддерживает мягкое удаление (пометка deleted вместо физического удаления).

Отличия от бана: нота — это запись, которая не блокирует игрока. Она служит для информирования других администраторов.

Колонка Тип Ограничения Описание
admin_notes_id int PK, автоинкремент Уникальный идентификатор заметки
round_id int Nullable, FK → round(round_id) Раунд, в котором была сделана заметка
player_user_id Guid Nullable, FK → player(user_id), CASCADE Игрок, на которого написана заметка. CASCADE — удаление игрока удалит заметку
playtime_at_note TimeSpan Время игрока на момент создания заметки
message string(4096) Текст заметки (до 4096 символов)
severity int Серьёзность нарушения
created_by_id Guid Nullable, FK → player(user_id), SET NULL Администратор, создавший заметку
created_at DateTime Дата создания заметки
last_edited_by_id Guid Nullable, FK → player(user_id), SET NULL Кто последний раз редактировал
last_edited_at DateTime Дата последнего редактирования
expiration_time DateTime Nullable Дата автоматического удаления (null = бессрочно)
deleted bool Флаг мягкого удаления (true = заметка скрыта)
deleted_by_id Guid Nullable, FK → player(user_id), SET NULL Кто удалил заметку
deleted_at DateTime Nullable Дата удаления
secret bool Флаг секретности: если true — заметка видна только администраторам с особыми правами

Индекс: player_user_id — для быстрого поиска всех заметок по игроку.


35. admin_watchlists

Список наблюдения за игроками. Отличается от заметок тем, что вотчлист сигнализирует администраторам "обрати внимание на этого игрока" при его подключении или действиях.

Колонка Тип Ограничения Описание
admin_watchlists_id int PK, автоинкремент Уникальный идентификатор записи в вотчлисте
round_id int Nullable, FK → round(round_id) Раунд, в котором игрок был добавлен в вотчлист
player_user_id Guid Nullable, FK → player(user_id), CASCADE Игрок, за которым ведётся наблюдение
playtime_at_note TimeSpan Время игрока на момент добавления в список
message string(4096) Причина наблюдения и что отслеживать
created_by_id Guid Nullable, FK → player(user_id), SET NULL Администратор, добавивший игрока
created_at DateTime Дата добавления в вотчлист
last_edited_by_id Guid Nullable, FK → player(user_id), SET NULL Кто последний раз редактировал запись
last_edited_at DateTime Дата последнего редактирования
expiration_time DateTime Nullable Дата истечения наблюдения
deleted bool Флаг мягкого удаления
deleted_by_id Guid Nullable, FK → player(user_id), SET NULL Кто убрал из списка наблюдения
deleted_at DateTime Nullable Дата удаления

Индекс: player_user_id


36. admin_messages

Сообщения от администраторов игрокам. Позволяет отправлять игрокам сообщения, которые они видят при следующем входе на сервер. В отличие от бана, сообщение не блокирует доступ — оно просто информирует.

Жизненный цикл сообщения:

  1. Администратор создаёт сообщение
  2. При подключении игрока сервер показывает сообщение
  3. Игрок помечает его как seen (просмотрено)
  4. Администратор может пометить сообщение как dismissed (закрыто)
Колонка Тип Ограничения Описание
admin_messages_id int PK, автоинкремент Уникальный идентификатор сообщения
round_id int Nullable, FK → round(round_id) Раунд, в котором было отправлено сообщение
player_user_id Guid Nullable, FK → player(user_id), CASCADE Игрок-получатель сообщения
playtime_at_note TimeSpan Время игрока на момент отправки
message string(4096) Текст сообщения
created_by_id Guid Nullable, FK → player(user_id), SET NULL Администратор, отправивший сообщение
created_at DateTime Дата отправки
last_edited_by_id Guid Nullable, FK → player(user_id), SET NULL Кто редактировал сообщение
last_edited_at DateTime Nullable Дата редактирования
expiration_time DateTime Nullable Дата истечения (сообщение автоматически скрывается)
deleted bool Флаг мягкого удаления
deleted_by_id Guid Nullable, FK → player(user_id), SET NULL Кто удалил сообщение
deleted_at DateTime Nullable Дата удаления
seen bool Флаг: игрок прочитал сообщение
dismissed bool Флаг: сообщение закрыто/архивировано

Индекс: player_user_id
Проверка: NotDismissedAndSeen: NOT dismissed OR seen — нельзя закрыть сообщение, не прочитав его.


37. role_whitelists

Вайтлист на конкретные игровые роли. Позволяет ограничить доступ к определённым работам или антагонистам, выдавая разрешение только проверенным игрокам.

Колонка Тип Ограничения Описание
player_user_id Guid Composite PK, FK → player(user_id) Игрок, которому разрешена роль
role_id string Composite PK Идентификатор роли (например, "Captain", "Warden", "HeadOfSecurity")

Составной PK: (player_user_id, role_id) — игрок может иметь доступ к каждой роли только один раз.


38. ban_template

Шаблоны банов, предназначенные для использования в админ-панели. Позволяют администраторам быстро создавать баны, выбирая стандартную причину и длительность из предустановленного списка.

Колонка Тип Ограничения Описание
ban_template_id int PK, автоинкремент Уникальный идентификатор шаблона
title string Краткое название шаблона (например, "Гриферство", "Оскорбления", "Использование багов")
length TimeSpan Длительность бана по умолчанию
reason string Текст причины (будет подставлен в бан)
exempt_flags int Флаги исключений по умолчанию
severity int Серьёзность по умолчанию
auto_delete bool Авто-удаление по умолчанию
hidden bool Скрытый бан по умолчанию

39. ipintel_cache

Кэш результатов IPIntel (сервис определения VPN/прокси). Позволяет не дёргать внешний API повторно при проверке одного и того же IP.

Колонка Тип Ограничения Описание
ipintel_cache_id int PK, автоинкремент Уникальный идентификатор
address IPAddress Unique IP-адрес, который проверяли
time DateTime Время проверки
score float Результат проверки: 0 — точно не прокси, 1 — точно прокси/VPN

40. bi_stats

Форк DeadSpace. Таблица статистики раундов. Содержит информацию о режиме игры и победителе каждого раунда. Создана для BI-отчётности и дашбордов. Связь с round осуществляется по дате (±2 минуты), так как прямого внешнего ключа нет.

Колонка Тип Ограничения Описание
bi_stats_id int PK, автоинкремент Уникальный идентификатор
game_mode string(128) Indexed Название игрового режима (Extended, Secret, Traitor, NukeOps, Revolution...)
winner byte 0=Crew, 1=Antagonist Победитель раунда: экипаж станции или антагонисты
date DateTime Indexed Дата и время окончания раунда

41. information_topics

Форк DeadSpace. Таблица для создания и публикации информационных страниц прямо в игре и/или админ-панели. Позволяет создавать страницы правил, гайдов, объявлений и т.д.

Колонка Тип Ограничения Описание
information_topics_id int PK, автоинкремент Уникальный идентификатор страницы
title string(256) Заголовок информационной страницы
content_markdown string Содержимое страницы в формате Markdown (для редактирования)
content_html string Содержимое страницы в формате HTML (сгенерировано из Markdown для отображения)
author_id Guid Идентификатор автора
author_name string(128) Имя автора (дублируется здесь для быстрого отображения без JOIN)
created_at DateTime Indexed Дата создания
updated_at DateTime Nullable Дата последнего обновления
category string(64) Nullable, Indexed Категория (например, "Правила", "Гайды", "Объявления")
is_pinned bool Indexed Флаг закрепления (показывать вверху списка)
is_visible bool Default=true Видимость страницы (false — черновик)
view_count int Default=0 Счётчик просмотров

Вспомогательный тип: TypedHwid

Embedded (owned) тип, используемый повторно в нескольких таблицах (player, connection_log, ban_hwid). Хранит HWID вместе с его типом для обратной совместимости.

Поле Тип Описание
Hwid byte[] Аппаратный отпечаток (хэш компонентов ПК игрока)
Type int Тип HWID (сейчас только Legacy=0, зарезервировано под будущие форматы)

Перечисляемые типы (Enum)

DbJobPriority

Приоритет работы в предпочтениях персонажа.

Значение Имя Описание
0 Never Никогда не спауниться за эту роль
1 Low Низкий приоритет
2 Medium Средний приоритет
3 High Высокий приоритет (любимая работа)

DbPreferenceUnavailableMode

Поведение, если любимая работа недоступна.

Значение Имя Описание
0 StayInLobby Остаться в лобби и ждать
1 SpawnAsOverflow Появиться на станции за assistant/overflow

ConnectionDenyReason (byte)

Причина отклонения подключения к серверу.

Значение Имя Описание
0 Ban Забанен
1 Whitelist Не в вайтлисте
2 Full Сервер заполнен
3 Panic Режим паники (сервер закрыт для всех)
4 BabyJail Сервер для новичков (достигнут лимит по времени)
5 IPChecks Провалена проверка IP (прокси/VPN)
6 NoHwid Отсутствует HWID (подозрение на бота/читера)

ServerBanExemptFlags (Flags)

Флаги исключений из банов. Битовая маска — можно комбинировать.

Значение Имя Описание
0 None Нет исключений
1 Datacenter Исключение для датацентров (игроки с облачных IP не блокируются)
2 IP Исключение по IP
4 BlacklistedRange Исключение для заブラックлистованных диапазонов
int.MaxValue All Полное исключение от всех автоматических банов

BanType (byte)

Тип бана (дискриминатор в таблице ban).

Значение Имя Описание
0 Server Серверный бан (полный запрет входа)
1 Role Ролевой бан (запрет на конкретные роли)

BiStatWinner (byte) — DeadSpace

Победитель раунда (форк DeadSpace).

Значение Имя Описание
0 Crew Победил экипаж станции
1 Antagonist Победили антагонисты

Схема связей (ERD)

Preference 1──* Profile 1──* Job
                        1──* Antag
                        1──* Trait
                        1──* ProfileRoleLoadout 1──* ProfileLoadoutGroup 1──* ProfileLoadout

Player *──* Round  (через player_round)
Player *──* AdminLog  (через admin_log_player)
Player 1──* AdminNote (как получатель, создатель, редактор, удалитель)
Player 1──* AdminWatchlist (те же роли)
Player 1──* AdminMessage (те же роли)
Player 1──* RoleWhitelist
Player 1──* Ban (как создатель, редактор)

Ban 1──* BanPlayer
Ban 1──* BanAddress
Ban 1──* BanHwid
Ban 1──* BanRole
Ban 1──* BanRound *──1 Round
Ban 1──0..1 Unban
Ban 1──* ServerBanHit *──1 ConnectionLog

ConnectionLog 1──* ServerBanHit
ConnectionLog *──1 Server

Server 1──* Round
Admin 0..1 AdminRank 1──* AdminRankFlag
Admin 1──* AdminFlag

Round 1──* AdminLog 1──* AdminLogPlayer *──1 Player

Ключевые особенности

  1. player.user_id (Guid) — сквозной идентификатор. Почти все таблицы ссылаются на player.user_id, а не на player_id. Это сделано для совместимости с SS14 Central.
  2. ban — единая таблица для серверных и ролевых банов. Раньше были две отдельные таблицы (server_ban, server_role_ban).
  3. admin_notes, admin_watchlists, admin_messages — три типа административных записей с одинаковой структурой (created/deleted/edited). Все поддерживают мягкое удаление и SET NULL для GDPR.
  4. GDPR-совместимость: внешние ключи на админов используют ON DELETE SET NULL, чтобы при удалении аккаунта игрока его данные в административных записях обнулялись, а не удаляли сами записи.
  5. DateTime всегда UTC — PostgreSQL использует timestamp with time zone для всех временных полей.
  6. SnakeCase — все имена таблиц, колонок, индексов и ограничений автоматически приводятся к snake_case.
  7. DeadSpace-форк: добавил таблицы bi_stats (статистика раундов) и information_topics (информационные страницы).
  8. BanTemplate — единственная таблица, созданная исключительно для нужд админ-панели (а не игрового сервера).