Перейти до основного вмісту
Розробникам Game SDK

Показуйте, у що хтось грає

Дозвольте своїй грі повідомляти mssgs, що робить гравець. Друзі бачать «Грає» під його ім’ям, відкривають подробиці й натискають «Приєднатися», щоб потрапити в ту саму гру. Ваша гра також може перевіряти, чи є гравець у вашій спільноті.

Що можна зробити

  • Публікуйте ігровий статусГра, що саме робить гравець, його роль і наскільки заповнена група.
  • Додайте кнопку «Приєднатися»Друзі одним натисканням приєднуються до тієї самої гри, сервера чи лобі.
  • Перевіряйте членствоДізнавайтеся, чи є гравець у вашій спільноті і з якими ролями.
  • Комп’ютер, браузер або телефонНативні ігри використовують локальний міст; браузерні й мобільні ігри працюють через ваш бекенд.

У застосунку

daniГрає в Space Raiders
Space RaidersГрає dani
Sector 7
У рейді
У групі: 3 з 4 · 12 хв
Стрілець

Статус під ім’ям і подробиці, які він відкриває. Гра опублікувала один блок JSON; решту робить застосунок.

Огляд

Настільний застосунок mssgs запускає невеликий локальний HTTP-міст (bridge), з яким спілкується гра на тому самому комп’ютері. Ваша гра ніколи не звертається до наших серверів, ніколи не бачить пароля чи токена облікового запису і ніколи не може дописувати від імені гравця. Вона спілкується з копією mssgs, у яку гравець уже ввійшов, і саме ця копія вирішує, що відповісти.

Що з ним можна робити:

  • Визначити, що mssgs встановлено і хтось у нього ввійшов.
  • Дізнатися, хто гравець: user_guid, ім’я користувача, аватар.
  • Запитати «чи є цей гравець у спільноті X?» і яку роль він там має.
  • Опублікувати статус «Грає …» з кнопкою «Приєднатися» для інших.
  • Отримати передачу приєднання, коли хтось натискає цю кнопку.

Два шляхи

Нативна настільна гра спілкується з локальним мостом; саме це описують наступні розділи. Гра в браузері або на телефоні до цього мосту дістатися не може. Для таких ігор публікує ваш власний бекенд, для гравців, які пов’язали свій обліковий запис mssgs через QR-код або восьмисимвольний код: див. Браузерні й мобільні ігри, де першим прикладом є CozyCity. Сам ігровий статус в обох випадках є тим самим блоком.

Мінімальне розкриття за замовчуванням

Області доступу навмисно нерівноцінні. Якщо вам потрібно лише знати, «чи є ця людина в нашій спільноті», запитуйте membership.query і самі вказуйте server_guid: ви отримаєте «так» чи «ні» плюс ролі гравця там і нічого не дізнаєтеся про решту його спільнот. Повний список захищено окремою, вищою областю доступу, яку гравець має схвалити окремо.

Як знайти клієнт

Міст слухає лише 127.0.0.1, на першому вільному порту з невеликого діапазону. Перебирайте їх по черзі, доки один не відповість: 7440, 7441, 7442, 7443. Збірки mssgs для розробки натомість слухають 7540–7543, тож тестова збірка ніколи не відповідає на виклики справжньої гри.

GET http://127.0.0.1:7440/mssgs/v1/hello

Токен не потрібен, а відповідь нічого не каже про гравця, лише те, що mssgs тут і чи хтось увійшов.

Відповідь
{
  "product": "mssgs",
  "api": 1,
  "client": "desktop",
  "version": "14.2.20015",
  "platform": "darwin",
  "signed_in": true,
  "scopes": ["identity", "staff", "membership.query", "servers.list", "presence.write"]
}

Перш ніж іти далі, перевірте product === "mssgs" та api. Якщо жоден із чотирьох портів не відповідає, mssgs не запущено. Просто запропонуйте звичайний досвід гри, а не змушуйте гравця чекати.

Запит дозволу

Усе, крім /hello, потребує токена, а токен з’являється лише після того, як гравець схвалив вашу гру в діалозі всередині застосунку. Запитуйте лише ті області доступу, якими справді користуєтеся: гравець бачить кожну окремо, з поясненням, і може зняти позначку з будь-якої.

1. Запит дозволу
curl -X POST http://127.0.0.1:7440/mssgs/v1/authorize \
  -H "Content-Type: application/json" \
  -d '{
    "game_id": "com.acme.spacegame",
    "name": "Space Raiders",
    "scopes": ["identity", "membership.query", "presence.write"]
  }'

Ви отримуєте {"status":"pending","request_id":"…","poll_after_ms":1000}, а гравець бачить діалог. Далі опитуйте, доки він не відповість (запит спливає через 3 хвилини):

2. Опитування відповіді
curl http://127.0.0.1:7440/mssgs/v1/authorize/<request_id>

# {"status":"approved","token":"…","scopes":["identity","presence.write"],"game_id":"com.acme.spacegame"}

Завжди перевіряйте, що ви насправді отримали

scopes у відповіді можуть бути коротшими, ніж ви запитували: гравець може зняти позначку з окремих областей. У прикладі вище membership.query було відхилено. Розгалужуйте логіку за тим, що каже відповідь, а не за тим, що ви запитували, інакше натрапите на 403 MISSING_SCOPE, якого не планували.

Збережіть токен і надсилайте його як Authorization: Bearer <token>. Він переживає перезапуски, тож гравець схвалює вашу гру один раз, а не на кожну сесію. Якщо згодом ви повторно авторизуєтеся з уже наданими областями доступу, ви одразу отримаєте той самий токен без діалогу.

Області доступу й приватність

П’ять областей доступу розкривають дуже різні обсяги даних. Це не випадковість, а вся суть задуму. Запитуйте якомога менше, рухаючись цією таблицею згори вниз.

Область доступу Що дозволяє Що віддає гравець
presence.write Показувати, у що грає гравець Нічого. Ця область доступу лише записує; вона взагалі не читає даних облікового запису.
identity Хто гравець user_guid, ім’я користувача, відображуване ім’я, URL аватара.
staff Позначки персоналу та модератора Два булеві значення понад identity. Окремо, бо гра, що показує ім’я, не має жодних підстав знати, що гравець модерує спільноти.
membership.query Перевірити спільноту, яку ви вже знаєте Для вказаного вами server_guid: так чи ні, його назва і ролі, які гравець там має. Нічого про жодну іншу спільноту.
servers.list Усі спільноти гравця Повний список: guid, назви, значки й ролі. Це найдорожча область доступу: запитуйте її, лише якщо вона справді потрібна.

Більшості ігор потрібні дві з них

identity і presence.write покривають «хто ви» і «показати, у що ви граєте», а це майже кожна інтеграція. Додайте membership.query, якщо хочете прив’язати винагороду до членства у вашій спільноті. servers.list вам майже ніколи не потрібна, і гравець бачить її виділеною червоним.

Перевірка членства

Це альтернатива запиту «дайте мені весь список». Ви вказуєте server_guid власної спільноти (який ви й так знаєте) і отримуєте відповідь лише про неї.

Одна спільнота
curl -H "Authorization: Bearer $TOKEN" \
  "http://127.0.0.1:7440/mssgs/v1/membership?server_guid=ca94ecc…f4g02"

# учасник:
# {"server_guid":"ca94ecc…","member":true,"name":"Acme Fans","is_owner":false,
#  "roles":[{"guid":"0aa32…","name":"Pro"}]}

# не учасник, і більше нічого:
# {"server_guid":"…","member":false}

«Ні» означає саме це і нічого більше. За один виклик можна передати до 10 guid (повторіть server_guid або перелічіть через кому), і тоді повертається масив results. Група @everyone ніколи не потрапляє в roles: вона стосується кожного учасника, тож нічого вам не каже.

Публікація ігрового статусу

Один PUT додає рядок «Грає …» під ім’ям гравця всюди, де його бачать його спільноти.

PUT /mssgs/v1/activity
{
  "name":    "Space Raiders",
  "details": "Sector 7",
  "state":   "In a raid",
  "role":    "Gunner",
  "started_at": 1755859200000,
  "party":   { "size": 3, "max": 4, "kind": "party" },
  "join":    { "secret": "raid-42" }
}

Обов’язкове лише поле name. Відповідь каже, скільки живе статус і як часто надсилати heartbeat:

Відповідь
{ "ok": true, "expires_in_ms": 90000, "heartbeat_every_ms": 30000 }

Надсилайте heartbeat, інакше статус зникне

Статус без ознак життя протягом 90 секунд прибирається автоматично. Так задумано: якщо ваша гра аварійно завершиться, гравець не залишиться «у грі» годинами. Надсилайте POST /mssgs/v1/activity/heartbeat кожні 30 секунд і DELETE /mssgs/v1/activity під час коректного завершення.

Кількість гравців і роль

party.kind визначає, яке речення буде показано, бо ті самі два числа означають різне. Загін із чотирьох це не сервер, на якому четверо гравців.

kind Показується як Для
party (типово)3 з 4 у групізагін, команда чи група
server4/100 гравцівігровий сервер (FiveM, сервер спільноти)
lobby4/100 гравцівлобі до початку матчу
match4/100 гравцівматч або раунд, що триває

role (до 48 символів) означає, ким грає гравець: професія, клас чи персонаж. Це окреме поле, а не ще одне речення в state, бо воно показується як мітка поруч із кількістю гравців.

details і state обмежено 128 символами кожне, name 64 символами. Розриви рядків і керівні символи вилучаються. URL значка навмисно не підтримується: його завантажував би кожен клієнт, що показує рядок, і статус перетворився б на маячок, який повідомляє вашому серверу про кожного учасника кожної спільноти, де є гравець.

Кнопка «Приєднатися»

Додайте до своєї активності блок join, і інші учасники побачать поруч зі статусом кнопку «Приєднатися». Є два способи, і їх можна поєднувати.

1. Секрет (для нативних ігор)

Задайте {"join":{"secret":"raid-42"}}. Коли хтось натискає «Приєднатися», цей секрет доставляється в його власну копію вашої гри, на його власному комп’ютері, за тим самим game_id. Жоден URL не відкривається і жоден обробник схеми не викликається. Ваша гра забирає його так:

GET /mssgs/v1/events
{
  "events": [
    { "seq": 1, "type": "join", "secret": "raid-42",
      "from": { "user_guid": "62e377…", "username": "mssgs-test-1" } }
  ],
  "cursor": 1
}

Опитуйте з ?since=<cursor>, щоб бачити кожну подію один раз. Якщо гра того, хто натиснув, не запущена, нічого не доставляється, і це вагома причина також запропонувати URL.

2. URL https (для вебігор і посилань на лобі)

Задайте {"join":{"url":"https://play.example.com/s/abc"}}, і кнопка відкриє це посилання. Приймається лише https. Власна схема (steam://, mygame://, file://) відхиляється: цей блок з’являється на екрані кожного учасника, а такий URL дає змогу змусити чужий комп’ютер викликати локальний обробник з аргументами, які вибрали ви.

Усе в join є публічним

Блок join транслюється кожному, хто бачить статус гравця; у цьому й полягає суть кнопки «Приєднатися». Тож ставтеся до нього як до коду лобі, а не як до облікових даних. Ніколи не кладіть туди нічого, що має лишатися таємним, і обмежуйте строк дії своїх кодів.

FiveM

У клієнтському Lua-середовищі FiveM немає HTTP, тож ресурс спілкується з мостом через NUI, представлення CEF, яке надсилає Origin. Міст явно приймає такі origin: https://cfx-nui-<resource> і старіший nui://<resource>. Звичайні вебсторінки й далі відхиляються, а сторінка з відкритого інтернету не може заявити такий origin: браузер встановлює його сам.

client.lua: попросіть NUI опублікувати
-- HTTP-запити робить сторінка NUI; Lua лише передає їй дані.
CreateThread(function()
  while true do
    SendNUIMessage({
      action  = 'mssgs:publish',
      players = GetActivePlayers and #GetActivePlayers() or 0,
      maxPlayers = GetConvarInt('sv_maxclients', 100),
      job     = exports['qb-core'] and 'Police' or nil
    })
    Wait(30000) -- heartbeat: статус спливає через 90 с
  end
end)
nui.js
const BASE = 'http://127.0.0.1:7440/mssgs/v1';   // пробуємо 7440-7443
let token = null;

async function authorize () {
  const res = await fetch(`${BASE}/authorize`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      game_id: 'fivem.lossantos.rp',
      name: 'Los Santos Roleplay',
      scopes: ['presence.write']          // більше тут нічого не потрібно
    })
  });
  const started = await res.json();
  if (started.status === 'approved') { return started.token; }

  // Тепер гравець бачить діалог дозволу в mssgs.
  for (let i = 0; i < 180; i += 1) {
    await new Promise((r) => { setTimeout(r, 1000); });
    const poll = await (await fetch(`${BASE}/authorize/${started.request_id}`)).json();
    if (poll.status === 'approved') { return poll.token; }
    if (poll.status !== 'pending') { return null; }
  }
  return null;
}

window.addEventListener('message', async (event) => {
  if (event.data.action !== 'mssgs:publish') { return; }
  if (!token) { token = await authorize(); }
  if (!token) { return; }

  await fetch(`${BASE}/activity`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
    body: JSON.stringify({
      name: 'FiveM',
      details: 'Los Santos Roleplay',
      role: event.data.job,                       // "Police"
      party: { size: event.data.players, max: event.data.maxPlayers, kind: 'server' },
      join: { url: 'https://cfx.re/join/abc123' } // ваше посилання cfx.re
    })
  });
});

Результат: Грає FiveM · Los Santos Roleplay · 4/100 гравців · Police, з кнопкою «Приєднатися», що відкриває ваше посилання cfx.re.

Запитуйте лише presence.write

Ігровому статусу більше нічого не потрібно: ця область доступу взагалі нічого не читає. Якщо хочете прив’язати внутрішньоігрову винагороду до членства у вашій спільноті mssgs, додайте membership.query і вкажіть власний server_guid; ви однаково нічого не дізнаєтеся про інші спільноти гравця.

Сервер, на якому ви граєте, не є автоматично довіреним

Будь-який сервер FiveM може запускати клієнтські ресурси, тож будь-який сервер, до якого хтось приєднується, може запитати дозвіл. Саме тому між ними стоїть діалог, що називає ресурс: вирішує гравець, а не сервер.

Браузерні й мобільні ігри: зв’язок через ваш бекенд

Гра у вкладці браузера або на телефоні не може дістатися до описаного вище мосту. Він працює на комп’ютері гравця, і між ними стоять три стіни: міст відхиляє кожен запит із браузерним Origin, Chrome показує запит дозволу, коли публічна сторінка звертається до 127.0.0.1, а Safari одразу відмовляє, і телефон узагалі не має шляху до loopback-інтерфейсу комп’ютера.

Тому напрям змінюється. Ваш власний бекенд уже знає, хто грає, і повідомляє про це mssgs, для гравців, які пов’язали свій обліковий запис mssgs з вашою грою. Зв’язок схвалюється у застосунку mssgs, ніколи не у вашій грі, і він створює зв’язок, а не сесію: ніщо з описаного нижче не може нікого авторизувати чи діяти від імені гравця. Клієнт вашої гри ніколи не бачить ключа і ніколи не звертається до mss.gs. Перша гра на цьому шляху це CozyCity, симулятор будівництва міста, що постачається як WebGL-сторінка та застосунок для iPhone без настільної збірки; приклади нижче взято з неї.

1. Зареєструйте свою гру

Зареєструйте гру на сторінці реєстрації Game SDK: свій game_id (наприклад, com.deverence.cozycity), назву й значок, які гравець бачить на аркуші схвалення, і хости свого бекенда. Ми перевіримо її там, і після схвалення ваш ключ бекенда чекатиме на тій самій сторінці, показаний один раз; ми зберігаємо лише його дайджест. Ключ має бути на вашому сервері й більше ніде. Там само його можна замінити будь-коли, а старий залишається дійсним 24 години, щоб деплой устиг пройти.

Зареєструвати гру

Назва й значок на аркуші завжди беруться з реєстрації, ніколи із запиту. Інакше фішингове посилання могло б видати запит на зв’язок за будь-яку гру. Хости визначають, куди може вказувати join.url, див. нижче.

2. Пов’яжіть гравця

Гравець вибирає у вашій грі «Під’єднати mssgs». Ваша гра звертається до вашого бекенда, а ваш бекенд до нас:

POST /game-sdk/v1/link/start
curl -X POST https://ams1-gateway.mss.gs/game-sdk/v1/link/start \
  -H "Authorization: Bearer $BACKEND_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "player_ref": "player-8812", "player_name": "René\u2019s city" }'

# {"link_code":"K7PQ2XM4","device_code":"…","qr_url":"https://mss.gs/gl/K7PQ2XM4",
#  "deep_link":"mssgs://link-game/K7PQ2XM4","expires_in":600,"interval":5}

player_ref це ваш власний стабільний ID гравця (до 128 символів), а не сесії чи матчу; player_name (до 64) аркуш показує як «Гравець: …». Передавайте клієнту гри лише link_code, qr_url і deep_link. device_code це ваш дескриптор для опитування, і він лишається на сервері.

Далі ваша гра показує одразу три речі, бо гравець може бути будь-де:

  • QR-код з qr_url. Телефон із mssgs відкриває його просто на аркуші схвалення в застосунку. Без застосунку він потрапляє на сторінку mss.gs, яка показує код і пропонує завантаження.
  • Кнопку «Відкрити в mssgs» з deep_link, для настільного браузера поруч із настільним застосунком. Це єдиний зовнішній URL, який вашій грі будь-коли знадобиться відкрити.
  • Сам код, двома групами по чотири символи, щоб ввести його в Налаштування → Ігрова активність → Пов’язати гру. В алфавіті немає 0/O та 1/I, тож помилки під час введення трапляються рідко.

Що гравець бачить у mssgs; застосунок малює це з реєстрації:

Під’єднати CozyCity до вашого облікового запису mssgs?

CozyCity зможе показувати, у що ви граєте, як ваш статус mssgs. Гра не бачитиме ваших повідомлень, друзів чи серверів і не зможе дописувати від вашого імені.
Гравець: René’s city · Під’єднати / Не зараз

Тим часом ваш бекенд опитує кожні interval секунд (на частіші запити приходить 429 SLOW_DOWN), доки статус не зміниться. Код працює один раз і спливає через десять хвилин:

POST /game-sdk/v1/link/poll
curl -X POST https://ams1-gateway.mss.gs/game-sdk/v1/link/poll \
  -H "Authorization: Bearer $BACKEND_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "device_code": "…" }'

# {"status":"pending"}
# {"status":"denied"}      # гравець вибрав «Не зараз»
# {"status":"expired"}
# {"status":"linked","link_guid":"…","user":{"user_guid":"62e377…"}}

Збережіть link_guid для свого гравця; відтепер це адреса, для якої ви публікуєте. Відповідь містить лише user_guid; username додається, тільки якщо ваша реєстрація має область доступу identity.link, і нічого понад це. Повторне схвалення для того самого player_ref замінює попередній зв’язок, тож один гравець вашої гри це один обліковий запис mssgs. Той самий обліковий запис mssgs може бути пов’язаний із кількома іграми та з кількома player_ref однієї гри (сімейний iPad).

3. Опублікуйте ігровий статус

Той самий блок, що й для мосту, з тими самими правилами й обмеженнями, лише тепер для кожного зв’язку окремо та з вашим ключем бекенда:

PUT /game-sdk/v1/links/{link_guid}/activity
{
  "activity": {
    "name":       "CozyCity",
    "details":    "Lantern Hollow",
    "state":      "Day 12 · 34 residents",
    "started_at": 1788901000000,
    "party":      { "size": 6, "max": 40, "kind": "server" },
    "join":       { "url": "https://cozycity.net/game/?share=…" }
  }
}
Відповіді
200 {"published":true,"changed":true}     # блок змінився і його розіслано
200 {"published":true,"changed":false}    # збігається зі збереженим; оновлено лише TTL
204                                        # збережено, але гравець зараз не в мережі в mssgs
410 {"error":"LINK_REVOKED"}               # гравець від’єднався: видаліть зв’язок

Обробляйте 200 і 204 однаково: збережено. { "activity": null } прибирає блок; надсилайте його, коли гравець виходить. Одна відмінність від мосту: хост join.url має бути одним із ваших зареєстрованих бекендів (або його піддоменом), інакше ви отримаєте 400 INVALID_PAYLOAD. Тож бекенд не може додати до статусу гравця кнопку «Приєднатися», що веде туди, де цей гравець ніколи не грав.

Heartbeat кожні 60 секунд, TTL 120

Опублікований статус живе 120 секунд без нового повідомлення, а потім зникає сам. Тож надсилайте той самий блок повторно кожні 60 секунд; незмінений блок нічого не коштує й лише оновлює TTL. Якщо ваш heartbeat припиняється, зникає й рядок «Грає …», і саме в цьому суть.

Коли в мережі сотні гравців, надсилайте heartbeat одним викликом, до 100 елементів за раз. Кожен елемент отримує власний статус, тож один гравець, що від’єднався в mssgs, ніколи не зупиняє решту дев’яносто дев’ять:

POST /game-sdk/v1/activity/batch
{ "items": [ { "link_guid": "…", "activity": { "name": "CozyCity", "details": "Lantern Hollow" } },
             { "link_guid": "…", "activity": null } ] }

// → 200 { "results": [ { "link_guid": "…", "status": 200, "changed": false },
//                      { "link_guid": "…", "status": 410 } ] }

Як показується статус

  • Так само, як статус із мосту: Грає CozyCity · Lantern Hollow · 6/40 гравців, з кнопкою «Приєднатися», коли є join.url. На сервері блок позначається як via: "backend", тож клієнт може додати «Надіслано сервером гри».
  • Лише поки гравець у мережі в mssgs. Якщо жоден клієнт mssgs не відкрито, обліковий запис не в мережі й таким лишається; ваш бекенд не може створити враження, що хтось присутній. Це також не дає цьому шляху стати маячком «чи Рене зараз за комп’ютером».
  • Пріоритет: гра в застосунку > гра через міст > ваш бекенд. Якщо гравець сідає грати в шахи всередині mssgs, поки ваш бекенд і далі надсилає heartbeat, перемагають шахи, а не той, хто писав останнім.

Від’єднання

Гравець бачить кожен зв’язок у Налаштування → Ігрова активність → Пов’язані ігри: з вашим значком і назвою, ім’ям гравця з вашої гри, датою зв’язування й останньої публікації та кнопкою «Від’єднати». Після цього ваша наступна публікація отримує відповідь 410 LINK_REVOKED; так ваша гра про це дізнається. Видаліть link_guid і знову запропонуйте «Під’єднати mssgs». Зі свого боку ви завершуєте зв’язок через DELETE /game-sdk/v1/links/{link_guid}.

Обмеження

Для одного зв’язку зміна зараховується щонайбільше раз на 2 секунди; незмінений heartbeat безкоштовний. На один ключ припадає 600 запитів на хвилину, причому елементи пакета рахуються окремо: heartbeat для 300 гравців кожні 60 секунд витрачає 5 із 600.

Довідник ендпоінтів: міст

Базовий URL http://127.0.0.1:<port>. Усе, крім перших трьох, потребує Authorization: Bearer <token>.

Метод Шлях Scope Що він робить
GET /mssgs/v1/hello немає Чи є тут mssgs, яку версію API він підтримує і чи хтось увійшов. Єдиний маршрут, якому не потрібен токен, і він нічого не каже про гравця.
POST /mssgs/v1/authorize немає Запитує в гравця дозвіл. Відкриває діалог у застосунку й повертає request_id для опитування.
GET /mssgs/v1/authorize/:request_id немає pending, approved (з токеном), denied або expired.
GET /mssgs/v1/me identity Гравець, який увійшов. Додає is_staff / is_moderator лише з областю доступу staff.
GET /mssgs/v1/membership membership.query Членство в спільнотах із переданими значеннями server_guid (до 10, повторено або через кому).
GET /mssgs/v1/servers servers.list Усі спільноти гравця з його ролями. Особисті повідомлення ніколи не включаються.
PUT /mssgs/v1/activity presence.write Публікує блок «Грає …». Повертає TTL і те, як часто надсилати heartbeat.
POST /mssgs/v1/activity/heartbeat presence.write Підтримує опубліковану активність, не надсилаючи її повторно.
DELETE /mssgs/v1/activity presence.write Негайно прибирає її, для коректного завершення.
GET /mssgs/v1/events presence.write Передачі приєднання, адресовані вашій грі. Опитуйте з ?since=<cursor>.
GET /mssgs/v1/session немає Що містить цей токен: game_id, надані області доступу, чи хтось увійшов.
DELETE /mssgs/v1/session немає Повертає дозвіл. Той самий ефект, що й відкликання гравцем у Налаштуваннях.

Довідник ендпоінтів: пов’язані бекенди

Базовий URL https://ams1-gateway.mss.gs. Кожен маршрут потребує Authorization: Bearer <backend key> і області доступу activity.write у вашій реєстрації; відповіді надсилаються з Cache-Control: no-store. Викликайте їх зі свого сервера, ніколи з клієнта гри.

Метод Шлях Що він робить
POST /game-sdk/v1/link/start Починає зв’язок для одного з ваших гравців ({ player_ref, player_name? }). Повертає link_code, device_code, qr_url, deep_link, expires_in та interval.
POST /game-sdk/v1/link/poll { device_code } → pending, denied, expired або linked з link_guid і user.
DELETE /game-sdk/v1/links/{link_guid} Завершує зв’язок з вашого боку. Гравець може зробити те саме в Налаштуваннях.
PUT /game-sdk/v1/links/{link_guid}/activity Публікує блок «Грає …» для одного гравця; { "activity": null } прибирає його.
POST /game-sdk/v1/activity/batch Те саме для до 100 гравців одним викликом. Кожен елемент відповідає окремо.

Коди помилок

Помилки повертаються як {"error":"CODE","message":"…"} з відповідним HTTP-статусом.

Код Значення
401 UNAUTHORIZEDТокен відсутній або невідомий; спершу авторизуйтеся.
403 MISSING_SCOPEГравець не надав цей дозвіл. Можливо, він зняв з нього позначку.
403 ORIGIN_NOT_ALLOWEDЗапит містив браузерний Origin. Див. «Лише нативні ігри» нижче.
409 NOT_SIGNED_INmssgs запущено, але ніхто не ввійшов.
429 RATE_LIMITEDПонад 120 запитів на хвилину від однієї гри.
400 INVALID_GAME_IDgame_id може містити лише літери, цифри, крапку, дефіс або підкреслення.
400 TOO_MANY_GUIDSЩонайбільше 10 значень server_guid за один виклик membership.

Пов’язані бекенди

Маршрути бекенда використовують ту саму форму. У пакеті статус повертається для кожного елемента окремо в results, тож один завершений зв’язок ніколи не зриває весь виклик.

Код Значення
401 INVALID_BACKEND_KEYНевідомий ключ або ключ, ротований понад 24 години тому.
403 SCOPE_NOT_GRANTEDВаша реєстрація не має області доступу, потрібної цьому маршруту.
400 INVALID_PAYLOADНекоректне тіло запиту, понад 100 елементів у пакеті або join.url, хост якого не є одним із ваших зареєстрованих бекендів.
400 INVALID_ACTIVITYПісля нормалізації не лишилося придатного name.
410 LINK_REVOKEDЗв’язок завершено з того чи іншого боку. Видаліть його й знову запропонуйте «Під’єднати mssgs».
429 SLOW_DOWNВи опитували link/poll частіше, ніж дозволяє interval.
429 RATE_LIMITEDЗміна одного зв’язку менш ніж через 2 секунди після попередньої або понад 600 запитів на хвилину з вашим ключем.
503 LINK_STORE_UNAVAILABLEТимчасова проблема на нашому боці. Повторіть під час наступного heartbeat.

Безпека

Лише нативні ігри

Запити з Origin вебсторінки відхиляються з 403 ORIGIN_NOT_ALLOWED. Якби будь-яка вебсторінка могла визначити, що у вас запущено mssgs, і викликати діалог дозволу, це була б поверхня для фінгерпринтингу й фішингу, а не функція. Нативна гра взагалі не надсилає Origin, тож її це не стосується, а вбудований браузер самої гри дозволено за назвою, див. FiveM. Якщо ви створюєте браузерну чи мобільну гру, ви не звертаєтеся до мосту: ваш власний бекенд публікує для пов’язаних гравців, див. Браузерні й мобільні ігри.

Що лишається під контролем гравця

  • Гравець може вимкнути міст у Налаштування → Ігрова активність, і після цього жодна гра взагалі не бачитиме mssgs.
  • Кожна схвалена гра вказана там разом із точними дозволами, які вона має, часом останньої активності та кнопкою «Прибрати». Прибирання діє негайно: токен одразу перестає працювати.
  • Пов’язана браузерна чи мобільна гра вказана в Пов’язані ігри з кнопкою «Від’єднати». Від’єднання теж діє негайно: наступна публікація цього бекенда отримує 410.
  • Міст слухає лише 127.0.0.1, ніколи мережу.
  • Особисті повідомлення ніколи не розкриваються, навіть із servers.list.
  • Для кожної гри діє ліміт 120 запитів на хвилину.

Як бути добрим сусідом

  • Запитуйте області доступу тоді, коли вони потрібні, а не всі одразу під час першого запуску.
  • Працюйте й без mssgs: гравець не зобов’язаний його мати.
  • Прибирайте свій статус, коли гра припиняється, а не чекайте на TTL.
  • Сприймайте відхилену область доступу як звичайний результат, а не як помилку.

Що далі