К содержимому
Публичный сервер и его расширение
На этой странице

Публичный сервер и его расширение

Что уже есть для публичного сервера Bullet Hero в открытом SDK и что ещё не решено: протокол, API, инструменты модерации

Предупреждение

Кода сервера и протокола пока нет. Ниже - часть SDK, на которой будет работать сервер, и она уже работает. Адресов, формата сообщений и API самого сервера здесь нет, их не существует

SDK работает на сервере

SDK - открытая модель данных игры: модели, сериализация в JSON и в бинарный формат, правила валидации, генераторы. Те же исходники, что компилирует Unity, собираются как обычная библиотека netstandard2.1 без движка. На неё может ссылаться сервер или утилита:

dotnet build -c Release BH.SDK.csproj
dotnet pack  -c Release BH.SDK.csproj

Пакет называется BulletHero.SDK. Код - в github.com/bullet-hero/sdk, под MIT

Версия SDK обычно совпадает с версией игры и пока не обещает стабильности API. Подробнее - Версии и миграции

Клиент и сервер запускают одни и те же проверки над одними и теми же моделями. Уровень, который редактор считает готовым, готов и для сервера. Второго набора правил, который надо держать в согласии, нет

ValidateForPublish

Один вызов отвечает на вопрос "можно ли опубликовать этот уровень здесь":

ValidationFacade.ValidateForPublish(meta, profile, level, now, payload)

Он выполняет три прохода сразу:

  1. декларативные правила над уровнем и его метаданными
  2. проверки графа уровня
  3. собственные условия сервиса из его PublishProfile

Сам уровень передавать не обязательно. metadata.json - отдельный файл, чтобы каталог мог оценить тысячи уровней, не открывая ни одного. Этот дешёвый проход покрывает большую часть политики

Но двум проверкам нужен level.json: ресурсу без записи вообще и способу получения ресурсов. Чистый отчёт только по метаданным значит "в прочитанном ошибок нет". IsReady остаётся false, пока файл уровня не проверен

payload несёт измеренные размеры: каждого ресурса, level.json, metadata.json, всего уровня. Без него ограничения профиля по размеру не проверить

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

Три вердикта

ГруппаЗначениеЧто делает сервер
Errorсервис отказываетотклоняет загрузку (HasErrors)
Warningпубликовать можно, но нужен взгляд человекаставит уровень в очередь модерации (NeedsManualReview)
Adviceотмеченоничего

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

Свой PublishProfile

Политика сервиса - это файл, сериализованная модель SDK. Более строгий или более мягкий сервер - это другой файл, а не форк кода

Уровень, который остаётся на устройстве игрока, не проверяется никак. Профиль важен только в момент, когда уровень предлагают сервису. Как автору подготовить уровень к этому моменту - Готовность к публикации

Пресеты:

ПресетКлючДля чего
CreateOpen()localуровни на устройстве, ничего не требуется
CreateStandard()standardпубличный сервер, политика из Лицензионная политика для пользовательских уровней
CreateStrict()strictсборки из магазинов, без прямых ссылок, хэш у каждого ресурса

Основные поля:

ПолеЧто решает
AllowedLicensesкакие типовые лицензии принимаются, пустой список принимает все
AllowedUriTypesкак можно получать ресурсы, пустой список разрешает все способы
AllowUnknownLicenseможет ли ресурс ничего не сообщать о своих условиях
AllowPermissionInsteadможет ли разрешение правообладателя заменить отклонённую лицензию (всегда отправляется на проверку)
RequireResourceMeta, RequireResourceUrl, RequireAttributionчто должна содержать запись каждого ресурса
RequireAgeRating, RequireLevelAuthors, RequireHashesчто должен объявить уровень
MaxResourceBytes, MaxDataFileBytes, MaxTotalBytesограничения по размеру, ноль значит без ограничения
Sources, UnknownSourceTrustсписок доверенных сайтов и то, как оценивается сайт вне списка

Два публичных пресета:

standardstrict
Прямые ссылки на ресурсыразрешенызапрещены
Указание автора у каждого ресурсане требуетсятребуется
Хэш содержимого в каждой записине требуетсятребуется
Самый большой ресурс64 МБ32 МБ
Самый большой level.json или metadata.json32 МБ16 МБ
Самый большой уровень256 МБ128 МБ
Сайт вне спискаRequiresLicenseCheckRequiresResourceCheck

Все пресеты и поля - Профили публикации

Почему в standard нет GPL

Лицензий семейства GPL в standard нет намеренно. GPL-работа, распространяемая через App Store, конфликтует с условиями Apple. Каталог, который их допускал, потом нельзя было бы отдать на iOS

Интересно

Список доверенных сайтов, который поставляется с SDK, - только отправная точка. Сайты меняют свои условия, поэтому каждый владелец сервера должен переопределить его в своём профиле. Ничто не может рассчитывать, что конкретный сайт в списке есть

Модерация

Что официальный сервер планирует добавить поверх проверки. Публичному серверу это, скорее всего, тоже понадобится:

  • Очередь модерации. Её наполняют находки Warning
  • Жалобы и блокировка уровней и пользователей. Правила Google Play и App Store требуют и то и другое для любого контента, который видят другие люди
  • Удаление по хэшу. Запись ресурса может хранить хэши содержимого его файлов в виде sha256:<hex>. Жалоба называет работу, и с хэшами каждый уровень с ней находится поиском, а не угадыванием по названиям. Редактор записывает хэш при импорте ресурса
  • Условия использования. Они покрывают то, чего не покрывает лицензия: заявление автора, что права у него есть, право владельца сервера удалить уровень, право показывать его название и обложку в списках

Steam Workshop устроен иначе. Файлы хранит Valve. Разработчики могут только проверить их после публикации и решить, что игра загружает

Форматы архивов

Уровень - это папка файлов, а архив делает её переносимой. Что SDK читает и пишет:

ФорматЧтениеЗаписьПримечание
.tar.gzдадапо умолчанию
.zipдадаможно зашифровать по записям AES-256
.tar.gz.gpg, .zip.gpgдадасообщение OpenPGP под паролем, единственная защита, доступная .tar.gz
level.json.gpgдадаодин защищённый файл уровня
.7zнетнетраспознаётся, чтобы отказать с понятным названием

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

tar -xzf, gpg -d и любой zip-архиватор открывают все записываемые форматы. Для распаковки уровня игра не нужна. Подробнее - Архивы и защита

Что не решено

  • протокол между игрой и сервером и будет ли он один для OWS и NOWS
  • API сервера: загрузка, каталог, поиск, аккаунты
  • как указать игре общественный сервер
  • как расширяется сам сервер и на каком языке
  • совместная игра на сервере: транспорт, авторитет, синхронизация уровня и лобби

Для совместной игры продумано только одно: как аватар игрока появляется и исчезает по сетевому сообщению

Публикация уровней в любой сервис появится не раньше обновления после gv 1.0.0. Данные, на которые опирается проверка, должны попасть в уровни до того, как их опубликуют

Лицензия уровней и любой сервер

По умолчанию уровень распространяется под CC BY-NC, и автор может выбрать другую лицензию в метаданных уровня. Разрешение делиться уровнем идёт от его автора напрямую к каждому получателю. Поэтому ни один сервер, официальный или общественный, не может размещать уровень под CC BY-NC коммерчески

Сервер с другим кодом под другой лицензией ничего не меняет в правах на контент. Полные правила для авторов - Лицензионная политика для пользовательских уровней