Preskoči na glavni sadržaj
Programeri Game SDK

Pokaži što netko igra

Neka tvoja igra javi aplikaciji mssgs što igrač radi. Prijatelji vide „Playing“ ispod njegova imena, otvore detalje i gumbom Join now uđu u istu igru. Tvoja igra može i provjeriti je li igrač u tvojoj zajednici.

Što možeš napraviti

  • Objavi status igranjaIgru, što igrač upravo radi, njegovu ulogu i koliko je ekipa popunjena.
  • Dodaj gumb Join nowPrijatelji jednim pritiskom ulaze u istu igru, server ili lobby.
  • Provjeri članstvoPitaj je li igrač u tvojoj zajednici i s kojim ulogama.
  • Računalo, preglednik ili mobitelNativne igre koriste lokalni most; igre u pregledniku i na mobitelu idu preko tvog backenda.

U aplikaciji

daniPlaying Space Raiders
Space RaidersPlayed by dani
Sector 7
U raidu
3 of 4 in the party · for 12 min
Topnik

Status ispod imena i detalji koje otvara. Igra je objavila jedan JSON blok; sve ostalo radi aplikacija.

Pregled

Aplikacija mssgs za računalo pokreće mali lokalni HTTP most s kojim razgovara igra na istom računalu. Tvoja igra nikad ne razgovara s našim serverima, nikad ne vidi lozinku ni token računa i nikad ne može objavljivati u ime igrača. Razgovara s kopijom mssgs u koju je igrač već prijavljen, a ta kopija odlučuje što će odgovoriti.

Što s njim možeš:

  • Otkriti da je mssgs instaliran i da je netko prijavljen.
  • Pročitati tko je igrač: user_guid, username, avatar.
  • Pitati „je li ovaj igrač u zajednici X?“ i koju ulogu ondje ima.
  • Objaviti status „Playing …“ s gumbom Join now za druge.
  • Primiti podatke za pridruživanje kad netko pritisne taj gumb.

Dva puta

Nativna igra za računalo razgovara s lokalnim mostom; to opisuju sljedeći odjeljci. Igra u pregledniku ili na mobitelu ne može doći do tog mosta. Za takve igre objavljuje tvoj vlastiti backend, za igrače koji su svoj mssgs račun povezali QR kodom ili kodom od osam znakova: vidi Igre u pregledniku i na mobitelu, s CozyCity kao prvim primjerom. Sam status igranja u oba je slučaja isti blok.

Što manje podataka, po zadanim postavkama

Opsezi namjerno nisu jednaki. Ako ti treba samo „je li ova osoba u našoj zajednici“, tražiš membership.query i sam navedeš server_guid: dobiješ da/ne i uloge te osobe ondje, a o ostalim njezinim zajednicama ne saznaš ništa. Cijeli popis skriven je iza zasebnog, višeg opsega koji igrač mora posebno odobriti.

Pronalaženje klijenta

Most sluša samo na 127.0.0.1, na prvom slobodnom portu iz malog raspona. Isprobaj ih redom dok se jedan ne javi: 7440, 7441, 7442, 7443. Razvojne verzije mssgs umjesto toga slušaju na 7540–7543, pa testna verzija nikad ne odgovara na pozive prave igre.

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

Token nije potreban, a odgovor ne govori ništa o igraču, samo da je mssgs tu i je li itko prijavljen.

Odgovor
{
  "product": "mssgs",
  "api": 1,
  "client": "desktop",
  "version": "14.2.20015",
  "platform": "darwin",
  "signed_in": true,
  "scopes": ["identity", "staff", "membership.query", "servers.list", "presence.write"]
}

Provjeri product === "mssgs" i api prije nego što nastaviš. Ako se nijedan od četiri porta ne javi, mssgs nije pokrenut. Tada jednostavno ponudi uobičajeno iskustvo, umjesto da igrač čeka.

Traženje dopuštenja

Sve osim /hello traži token, a token postoji tek kad igrač odobri tvoju igru u dijalogu unutar aplikacije. Traži samo opsege koje stvarno koristiš: igrač vidi svaki zasebno, s objašnjenjem, i može ih pojedinačno odznačiti.

1. Zatraži dopuštenje
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"]
  }'

Dobiješ natrag {"status":"pending","request_id":"…","poll_after_ms":1000}, a igrač vidi dijalog. Zatim provjeravaj (polling) dok ne odgovori (zahtjev istječe nakon 3 minute):

2. Provjeri odgovor
curl http://127.0.0.1:7440/mssgs/v1/authorize/<request_id>

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

Uvijek provjeri što si zapravo dobio

Popis scopes u odgovoru može biti kraći od onoga što si tražio: igrač smije odznačiti pojedine opsege. U gornjem primjeru membership.query je odbijen. Ravnaj se prema onome što piše u odgovoru, a ne prema onome što si tražio, inače ćeš naletjeti na 403 MISSING_SCOPE s kojim nisi računao.

Spremi token i šalji ga kao Authorization: Bearer <token>. Preživljava ponovna pokretanja, pa igrač tvoju igru odobrava jednom, a ne u svakoj sesiji. Ako kasnije ponovno zatražiš autorizaciju s opsezima koji su već odobreni, odmah dobiješ isti token, bez dijaloga.

Opsezi i privatnost

Pet opsega otkriva vrlo različite količine podataka. To nije slučajno; na tome počiva cijeli dizajn. Traži što manje, krećući se ovom tablicom odozgo prema dolje.

Opseg Što dopušta Čega se igrač odriče
presence.write Prikaz onoga što igra Ništa. Ovaj opseg samo zapisuje; ne čita nikakve podatke računa.
identity Tko je igrač user_guid, username, ime za prikaz, URL avatara.
staff Oznake osoblja / moderatora Dvije logičke vrijednosti, uz identity. Zasebno, jer igra koja prikazuje ime nema razloga znati da igrač moderira zajednice.
membership.query Provjera zajednice koju već znaš Za server_guid koji navedeš: da/ne, njezino ime i uloge koje igrač ondje ima. Ništa o bilo kojoj drugoj zajednici.
servers.list Sve zajednice u kojima je Cijeli popis: guidovi, imena, ikone i uloge. Ovo je onaj skupi: traži ga samo ako ti stvarno treba.

Većini igara trebaju dva

identity i presence.write pokrivaju „tko si“ i „pokaži što igraš“, a to je gotovo svaka integracija. Dodaj membership.query ako želiš nagradu vezati uz članstvo u svojoj zajednici. servers.list gotovo nikad ne trebaš, a igrač ga vidi istaknutog crvenom bojom.

Provjera članstva

Ovo je alternativa za „daj mi cijeli popis“. Navedeš server_guid vlastite zajednice (koji već znaš) i dobiješ odgovor samo o njoj.

Jedna zajednica
curl -H "Authorization: Bearer $TOKEN" \
  "http://127.0.0.1:7440/mssgs/v1/membership?server_guid=ca94ecc…f4g02"

# član:
# {"server_guid":"ca94ecc…","member":true,"name":"Acme Fans","is_owner":false,
#  "roles":[{"guid":"0aa32…","name":"Pro"}]}

# nije član, i ništa više:
# {"server_guid":"…","member":false}

„Ne“ znači točno to i ništa više. U jednom pozivu možeš poslati do 10 guidova (ponovi server_guid ili ih odvoji zarezima), i tada dobiješ polje results. Grupa @everyone nikad nije u roles: vrijedi za svakog člana, pa ti ništa ne govori.

Objava statusa igranja

Jedan PUT stavlja redak „Playing …“ ispod imena igrača, svugdje gdje ga vide njegove zajednice.

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" }
}

Obavezno je samo name. Odgovor ti kaže koliko status traje i koliko često slati heartbeat:

Odgovor
{ "ok": true, "expires_in_ms": 90000, "heartbeat_every_ms": 30000 }

Heartbeat, inače status nestaje

Status bez znaka života 90 sekundi automatski se briše. To je namjerno: ako se tvoja igra sruši, igrač ne ostaje satima „u igri“. Šalji POST /mssgs/v1/activity/heartbeat svakih 30 sekundi, a DELETE /mssgs/v1/activity pri urednom gašenju.

Broj igrača i uloga

party.kind određuje koja će se rečenica prikazati, jer ista dva broja ne znače uvijek isto. Ekipa od četvero nije server s četiri igrača.

kind Prikazuje se kao Za
party (zadano)3 of 4 in the partyodred, posada ili grupa
server4/100 playersserver igre (FiveM, server zajednice)
lobby4/100 playerslobby prije početka meča
match4/100 playersmeč ili runda u tijeku

role (do 48 znakova) govori kao tko igrač igra: zanimanje, klasa ili lik. Ima vlastito polje umjesto još jedne rečenice u state, jer se prikazuje kao oznaka pokraj broja igrača.

details i state ograničeni su na po 128 znakova, name na 64. Prijelomi redaka i kontrolni znakovi uklanjaju se. URL ikone namjerno nije podržan: dohvaćao bi ga svaki klijent koji prikazuje taj redak, pa bi status postao svjetionik koji tvom serveru dojavljuje svakog člana svake zajednice u kojoj je igrač.

Gumb Join now

Stavi blok join u svoju aktivnost i drugi članovi dobit će gumb Join now pokraj statusa. Postoje dva načina i možeš ih kombinirati.

1. Tajna (za nativne igre)

Postavi {"join":{"secret":"raid-42"}}. Kad netko pritisne Join now, ta se tajna isporučuje njegovoj vlastitoj kopiji tvoje igre, na njegovu računalu, prema istom game_id. Ne otvara se nikakav URL i ne poziva se nikakav handler sheme. Tvoja igra je preuzima ovako:

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

Provjeravaj s ?since=<cursor> da svaki događaj vidiš samo jednom. Ako igra osobe koja je pritisnula gumb nije pokrenuta, ništa se ne isporučuje, što je dobar razlog da ponudiš i URL.

2. https URL (za web-igre i poveznice na lobby)

Postavi {"join":{"url":"https://play.example.com/s/abc"}} i gumb otvara tu poveznicu. Prihvaća se samo https. Prilagođena shema (steam://, mygame://, file://) se odbija: taj blok završava na zaslonu svakog člana, a takav URL način je da natjeraš tuđe računalo da pokrene lokalni handler s argumentima koje si ti odabrao.

Sve u join je javno

Blok join šalje se svima koji vide status igrača; u tome je cijela svrha gumba Join now. Zato ga tretiraj kao kôd lobbyja, a ne kao vjerodajnicu. Nikad u njega ne stavljaj ništa što mora ostati tajno, i neka tvoji kodovi istječu.

FiveM

FiveM u svom Lua okruženju na strani klijenta nema HTTP, pa resurs s mostom razgovara preko NUI, CEF prikaza koji šalje Origin. Most izričito prihvaća ove vrijednosti zaglavlja Origin: https://cfx-nui-<resource> i stariji nui://<resource>. Obične web-stranice i dalje se odbijaju, a stranica na otvorenom webu ne može lažno tvrditi da ima taj Origin; postavlja ga sam preglednik.

client.lua: zamoli NUI da objavi
-- NUI stranica radi HTTP; Lua joj samo šalje podatke.
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: status istječe nakon 90 s
  end
end)
nui.js
const BASE = 'http://127.0.0.1:7440/mssgs/v1';   // isprobaj 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']          // ovdje ne treba ništa više
    })
  });
  const started = await res.json();
  if (started.status === 'approved') { return started.token; }

  // Igrač sada u mssgs vidi dijalog za dopuštenje.
  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' } // tvoja cfx.re poveznica
    })
  });
});

Rezultat: Playing FiveM · Los Santos Roleplay · 4/100 players · Police, s gumbom Join now koji otvara tvoju cfx.re poveznicu.

Traži samo presence.write

Statusu igranja ne treba ništa drugo: taj opseg ne čita baš ništa. Ako želiš nagradu u igri vezati uz članstvo u svojoj mssgs zajednici, dodaj membership.query i navedi vlastiti server_guid; i dalje ne saznaješ ništa o ostalim zajednicama igrača.

Server na kojem igraš nije automatski pouzdan

Svaki FiveM server može pokretati klijentske resurse, pa svaki server kojem se netko pridruži može tražiti dopuštenje. Upravo je zato između njih dijalog koji navodi ime resursa: odlučuje igrač, a ne server.

Igre u pregledniku i na mobitelu: povezivanje preko tvog backenda

Igra u kartici preglednika ili na mobitelu ne može doći do gore opisanog mosta. Most radi na igračevu računalu, a između stoje tri zida: most odbija svaki zahtjev sa zaglavljem Origin preglednika, Chrome traži dopuštenje prije nego što javna stranica dohvati 127.0.0.1, a Safari to odmah odbija, dok mobitel uopće nema put do loopbacka računala.

Zato se smjer okreće. Tvoj vlastiti backend već zna tko igra, i on to javlja aplikaciji mssgs, za igrače koji su svoj mssgs račun povezali s tvojom igrom. Povezivanje se odobrava u aplikaciji mssgs, nikad u tvojoj igri, i stvara vezu, nikad sesiju: ništa od navedenog u nastavku ne može nikoga prijaviti niti djelovati u ime igrača. Klijent tvoje igre nikad ne vidi ključ i nikad ne razgovara s mss.gs. Prva igra na tom putu je CozyCity, igra gradnje grada koja dolazi kao WebGL stranica i aplikacija za iPhone, bez verzije za računalo; primjeri u nastavku njezini su.

1. Registriraj svoju igru

Registriraj igru na stranici za registraciju Game SDK-a: svoj game_id (na primjer com.deverence.cozycity), ime i ikonu koje igrač vidi u prozoru za odobrenje te nazive hostova svog backenda. Ondje je pregledavamo, a kad je odobrena, na istoj te stranici čeka tvoj ključ backenda, prikazan samo jednom; mi čuvamo samo njegov sažetak (hash). Ključ pripada tvom serveru i nigdje drugdje. Ondje ga možeš rotirati u bilo kojem trenutku, a stari ostaje valjan 24 sata, kako bi deploy mogao proći bez prekida.

Registriraj svoju igru

Ime i ikona u tom prozoru uvijek dolaze iz registracije, nikad iz zahtjeva. Inače bi phishing poveznica mogla zahtjev za povezivanje prerušiti u bilo koju igru. Nazivi hostova ograničavaju kamo smije voditi join.url, vidi u nastavku.

2. Poveži igrača

Igrač u tvojoj igri odabere Connect mssgs. Tvoja igra pita tvoj backend, a tvoj backend pita nas:

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 je tvoj vlastiti stalni ID tog igrača (do 128 znakova), a ne sesije ili meča; player_name (do 64) je ono što prozor prikazuje kao „Player: …“. Klijentu igre predaj samo link_code, qr_url i deep_link. device_code služi tebi za provjeravanje i ostaje na serveru.

Tvoja igra zatim istodobno prikazuje tri stvari, jer igrač može biti bilo gdje:

  • QR kod iz qr_url. Mobitel s mssgs otvara ga izravno u prozoru za odobrenje u aplikaciji. Bez aplikacije završava na stranici na mss.gs koja prikazuje kôd i nudi preuzimanje.
  • Gumb „Open in mssgs“ s deep_link, za preglednik na računalu na kojem radi i aplikacija za računalo. To je jedini vanjski URL koji tvoja igra ikad mora otvoriti.
  • Sam kôd, u dvije skupine po četiri znaka, za upis pod Settings → Game Activity → Link a game. Abeceda nema 0/O ni 1/I, pa se pri upisivanju rijetko pogriješi.

Što igrač vidi u mssgs, u prozoru koji aplikacija gradi iz registracije:

Connect CozyCity to your mssgs account?

CozyCity will be able to show what you are playing as your mssgs status. It will not see your messages, your friends or your servers, and it cannot post as you.
Player: René's city · Connect / Not now

U međuvremenu tvoj backend provjerava svakih interval sekundi (na češće upite odgovor je 429 SLOW_DOWN) dok se status ne promijeni. Kôd vrijedi jednom i istječe nakon deset minuta:

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"}      # igrač je odabrao Not now
# {"status":"expired"}
# {"status":"linked","link_guid":"…","user":{"user_guid":"62e377…"}}

Spremi link_guid uz svog igrača; od sada je to adresa za koju objavljuješ. Odgovor sadrži samo user_guid; username se dodaje samo kad tvoja registracija ima opseg identity.link, i ništa više od toga. Drugo odobrenje za isti player_ref zamjenjuje raniju vezu, pa je jedan igrač tvoje igre jedan mssgs račun. Isti mssgs račun može biti povezan s više igara i s više vrijednosti player_ref jedne igre (obiteljski iPad).

3. Objavi status igranja

Isti blok kao kod mosta, s istim pravilima i istim ograničenjima, samo sada po vezi i s tvojim ključem backenda:

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=…" }
  }
}
Odgovori
200 {"published":true,"changed":true}     # blok se promijenio i poslan je svima
200 {"published":true,"changed":false}    # isti kao spremljeni; osvježen je samo TTL
204                                        # spremljeno, ali igrač trenutačno nije online u mssgs
410 {"error":"LINK_REVOKED"}               # igrač je prekinuo vezu: ukloni je

Odgovore 200 i 204 tretiraj jednako: spremljeno. { "activity": null } briše blok, pošalji to kad igrač ode. Jedna razlika u odnosu na most: host u join.url mora biti jedan od tvojih registriranih backenda (ili njegova poddomena), inače dobiješ 400 INVALID_PAYLOAD. Tako backend ne može na status igrača staviti gumb Join now koji vodi negdje gdje taj igrač nikad nije igrao.

Heartbeat svakih 60 sekundi, TTL 120

Objavljeni status živi 120 sekundi bez nove poruke, a onda sam nestaje. Zato isti blok šalji svakih 60 sekundi; nepromijenjeni blok ne košta ništa i samo osvježava TTL. Ako tvoj heartbeat stane, nestaje i redak „Playing …“, i upravo je to poanta.

Sa stotinama igrača online šalji heartbeat jednim pozivom, do 100 stavki odjednom. Svaka stavka dobiva vlastiti status, pa jedan igrač koji je prekinuo vezu u mssgs nikad ne zaustavlja ostalih devedeset devet:

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 } ] }

Kako se status prikazuje

  • Jednako kao status s mosta: Playing CozyCity · Lantern Hollow · 6/40 players, s Join now kad postoji join.url. Server bloku dodaje oznaku via: "backend", pa klijent može dopisati „Shared by the game's server“.
  • Samo dok je igrač online u mssgs. Bez otvorenog mssgs klijenta račun je offline i takav ostaje; tvoj backend ne može učiniti da netko izgleda prisutno. Time se sprječava i da ovaj put postane dojavljivač „sjedi li René za računalom“.
  • Prednost: igra u aplikaciji > igra preko mosta > tvoj backend. Ako igrač u mssgs sjedne za šah dok tvoj backend i dalje šalje heartbeat, pobjeđuje šah, a ne onaj tko je zadnji pisao.

Prekid veze

Igrač vidi svaku vezu pod Settings → Game Activity → Linked games, s tvojom ikonom i imenom, imenom igrača iz tvoje igre, kad je povezana i kad je zadnji put objavila, te s gumbom Disconnect. Nakon toga tvoja sljedeća objava dobiva odgovor 410 LINK_REVOKED; tako tvoja igra saznaje za to. Ukloni link_guid i ponovno ponudi „Connect mssgs“. Sa svoje strane vezu prekidaš s DELETE /game-sdk/v1/links/{link_guid}.

Ograničenja

Po vezi se promjena računa najviše svake 2 sekunde; nepromijenjeni heartbeat je besplatan. Po ključu je 600 zahtjeva u minuti, a stavke u batch pozivu broje se pojedinačno: heartbeat za 300 igrača svakih 60 sekundi troši 5 od 600.

Referenca endpointa: most

Osnovni URL http://127.0.0.1:<port>. Sve osim prva tri zahtijeva Authorization: Bearer <token>.

Metoda Putanja Scope Što radi
GET /mssgs/v1/hello nema Je li mssgs tu, što podržava i je li itko prijavljen. Jedina ruta kojoj ne treba token, a ne govori ništa o igraču.
POST /mssgs/v1/authorize nema Zatraži dopuštenje od igrača. Otvara dijalog u aplikaciji i vraća request_id za provjeravanje.
GET /mssgs/v1/authorize/:request_id nema pending, approved (s tokenom), denied ili expired.
GET /mssgs/v1/me identity Prijavljeni igrač. Dodaje is_staff / is_moderator samo uz opseg staff.
GET /mssgs/v1/membership membership.query Članstvo u server_guid vrijednostima koje pošalješ (do 10, ponovljene ili odvojene zarezima).
GET /mssgs/v1/servers servers.list Sve zajednice u kojima je igrač, s njegovim ulogama. Izravne poruke nikad nisu uključene.
PUT /mssgs/v1/activity presence.write Objavi blok „Playing …“. Vraća TTL i koliko često slati heartbeat.
POST /mssgs/v1/activity/heartbeat presence.write Održi objavljenu aktivnost živom bez ponovnog slanja.
DELETE /mssgs/v1/activity presence.write Obriši je odmah, za uredno gašenje.
GET /mssgs/v1/events presence.write Podaci za pridruživanje namijenjeni tvojoj igri. Provjeravaj s ?since=<cursor>.
GET /mssgs/v1/session nema Što ovaj token ima: game_id, odobrene opsege, je li itko prijavljen.
DELETE /mssgs/v1/session nema Vrati dopuštenje. Isti učinak kao kad ga igrač opozove u Settings.

Referenca endpointa: povezani backendi

Osnovni URL https://ams1-gateway.mss.gs. Svaka ruta zahtijeva Authorization: Bearer <backend key> i opseg activity.write u tvojoj registraciji; odgovori se šalju s Cache-Control: no-store. Pozivaj ih sa svog servera, nikad iz klijenta igre.

Metoda Putanja Što radi
POST /game-sdk/v1/link/start Pokreni povezivanje za jednog od svojih igrača ({ player_ref, player_name? }). Vraća link_code, device_code, qr_url, deep_link, expires_in i interval.
POST /game-sdk/v1/link/poll { device_code } → pending, denied, expired ili linked s link_guid i user.
DELETE /game-sdk/v1/links/{link_guid} Prekini vezu sa svoje strane. Igrač može učiniti isto u Settings.
PUT /game-sdk/v1/links/{link_guid}/activity Objavi blok „Playing …“ za jednog igrača; { "activity": null } ga briše.
POST /game-sdk/v1/activity/batch Isto, za do 100 igrača u jednom pozivu. Svaka stavka odgovara zasebno.

Kodovi pogrešaka

Pogreške se vraćaju kao {"error":"CODE","message":"…"} s odgovarajućim HTTP statusom.

Kôd Značenje
401 UNAUTHORIZEDToken nedostaje ili je nepoznat; najprije zatraži autorizaciju.
403 MISSING_SCOPEIgrač nije odobrio to dopuštenje. Možda ga je odznačio.
403 ORIGIN_NOT_ALLOWEDZahtjev je nosio Origin preglednika. Vidi „Samo nativne igre“ u nastavku.
409 NOT_SIGNED_INmssgs je pokrenut, ali nitko nije prijavljen.
429 RATE_LIMITEDViše od 120 zahtjeva u minuti od jedne igre.
400 INVALID_GAME_IDgame_id smije sadržavati samo slova, znamenke, točku, crticu ili podvlaku.
400 TOO_MANY_GUIDSNajviše 10 server_guid vrijednosti po pozivu za membership.

Povezani backendi

Rute backenda koriste isti oblik. U batch pozivu status se vraća za svaku stavku zasebno u results, pa jedna prekinuta veza nikad ne obara cijeli poziv.

Kôd Značenje
401 INVALID_BACKEND_KEYNepoznat ključ ili ključ koji je zamijenjen prije više od 24 sata.
403 SCOPE_NOT_GRANTEDTvoja registracija nema opseg koji ta ruta traži.
400 INVALID_PAYLOADNeispravno tijelo zahtjeva, više od 100 stavki u batch pozivu ili join.url čiji host nije jedan od tvojih registriranih backenda.
400 INVALID_ACTIVITYNakon normalizacije nije ostalo upotrebljivo ime.
410 LINK_REVOKEDVeza je prekinuta, s jedne ili druge strane. Ukloni je i ponovno ponudi „Connect mssgs“.
429 SLOW_DOWNProvjeravao si link/poll češće nego što interval dopušta.
429 RATE_LIMITEDPromjena jedne veze unutar 2 sekunde od prethodne ili više od 600 zahtjeva u minuti na tvom ključu.
503 LINK_STORE_UNAVAILABLEPrivremeni problem na našoj strani. Pokušaj ponovno pri sljedećem heartbeatu.

Sigurnost

Samo nativne igre

Zahtjevi koji nose Origin web-stranice odbijaju se s 403 ORIGIN_NOT_ALLOWED. Kad bi bilo koja web-stranica mogla otkriti da koristiš mssgs i otvoriti dijalog za dopuštenje, to bi bila vrata za fingerprinting i phishing, a ne značajka. Nativna igra uopće ne šalje Origin, pa je to ne pogađa, a vlastiti ugrađeni preglednik igre dopušten je poimence, vidi FiveM. Ako radiš igru za preglednik ili mobitel, ne razgovaraš s mostom: tvoj vlastiti backend objavljuje za povezane igrače, vidi Igre u pregledniku i na mobitelu.

Što igrač zadržava u svojim rukama

  • Igrač može isključiti most pod Settings → Game Activity, nakon čega nijedna igra uopće ne vidi mssgs.
  • Svaka odobrena igra ondje je navedena s točno onim dopuštenjima koja ima, s vremenom zadnje aktivnosti i s gumbom Remove. Uklanjanje djeluje odmah: token istog trena prestaje vrijediti.
  • Povezana igra u pregledniku ili na mobitelu navedena je pod Linked games s gumbom Disconnect. I prekid veze djeluje odmah: sljedeća objava tog backenda dobiva 410.
  • Most sluša samo na 127.0.0.1, nikad na mreži.
  • Izravne poruke nikad se ne otkrivaju, čak ni uz servers.list.
  • Svaka igra ima ograničenje od 120 zahtjeva u minuti.

Dobre prakse

  • Traži opsege kad ti zatrebaju, a ne sve odjednom pri prvom pokretanju.
  • Radi i bez mssgs: igrač ga ne mora imati.
  • Obriši svoj status kad igranje završi, umjesto da čekaš TTL.
  • Odbijeni opseg tretiraj kao normalan ishod, a ne kao pogrešku.

Nastavi graditi