Ugrás a fő tartalomra
Fejlesztők Game SDK

Mutasd meg, mivel játszik valaki

A játékod elmondhatja az mssgs-nek, mit csinál éppen egy játékos. A barátai a neve alatt a „Playing” sort látják, megnyitják a részleteket, és a Join now gombbal beszállnak ugyanabba a játékba. A játékod azt is ellenőrizheti, hogy a játékos tagja-e a közösségednek.

Mire használhatod

  • Játékstátusz közzétételeA játék, hogy mit csinál éppen a játékos, a szerepe, és mennyire telt meg a csapat.
  • Join now gomb hozzáadásaA barátok egyetlen gombnyomással csatlakoznak ugyanahhoz a játékhoz, szerverhez vagy lobbyhoz.
  • Tagság ellenőrzéseKérdezd meg, hogy a játékos tagja-e a közösségednek, és ha igen, milyen szerepekkel.
  • Asztali gép, böngésző vagy telefonA natív játékok a helyi hidat használják, a böngészős és telefonos játékok a backendeden keresztül mennek.

Az alkalmazásban

daniPlaying Space Raiders
Space RaidersPlayed by dani
Sector 7
Raidben
3 of 4 in the party · for 12 min
Lövész

A státusz egy név alatt, és a részletek, amelyeket megnyit. A játék egyetlen JSON-blokkot tett közzé, a többi az alkalmazás dolga.

Áttekintés

Az mssgs asztali alkalmazása egy kis helyi HTTP-hidat futtat, amellyel az ugyanazon a gépen futó játék kommunikál. A játékod soha nem beszél a szervereinkkel, soha nem lát fiókjelszót vagy tokent, és soha nem küldhet üzenetet a játékos nevében. Az mssgs azon példányával beszél, amelyben a játékos már be van jelentkezve, és ez a példány dönti el, mit válaszol.

Ezt teheted vele:

  • Észlelheted, hogy az mssgs telepítve van, és valaki be van jelentkezve.
  • Kiolvashatod, ki a játékos: user_guid, username, avatar.
  • Megkérdezheted: „tagja ez a játékos az X közösségnek?”, és hogy milyen szerepe van ott.
  • Közzétehetsz egy „Playing …” státuszt egy Join now gombbal a többieknek.
  • Megkapod a csatlakozáshoz szükséges adatot, amikor valaki megnyomja ezt a gombot.

Két út

Egy natív asztali játék a helyi híddal kommunikál; erről szólnak a következő részek. Egy böngészőben vagy telefonon futó játék nem éri el ezt a hidat. Ilyenkor a saját backended teszi közzé a státuszt azoknak a játékosoknak, akik QR-kóddal vagy nyolckarakteres kóddal összekapcsolták az mssgs-fiókjukat: lásd Böngészős és telefonos játékok; az első példa a CozyCity. Maga a játékstátusz mindkét esetben ugyanaz a blokk.

Alapból minimális adatközlés

A hatókörök szándékosan nem egyenértékűek. Ha csak arra vagy kíváncsi, hogy „ez a személy tagja-e a közösségünknek”, a membership.query hatókört kéred, és te magad adod meg a server_guid értékét: igen/nem választ kapsz, plusz a játékos ottani szerepeit, és semmit nem tudsz meg a többi közösségéről. A teljes lista egy külön, magasabb hatókör mögött van, amelyet a játékosnak külön kell jóváhagynia.

A kliens megtalálása

A híd kizárólag a 127.0.0.1 címen figyel, egy kis tartomány első szabad portján. Próbáld végig őket sorban, amíg valamelyik válaszol: 7440, 7441, 7442, 7443. Az mssgs fejlesztői buildjei helyette a 7540–7543 portokon figyelnek, így egy tesztbuild soha nem válaszol egy valódi játék hívásaira.

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

Nem kell hozzá token, és a válasz semmit nem árul el a játékosról, csak azt, hogy az mssgs itt van, és be van-e jelentkezve valaki.

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

Mielőtt továbblépsz, ellenőrizd a product === "mssgs" és az api értéket. Ha a négy port egyike sem válaszol, az mssgs nem fut. Ilyenkor egyszerűen kínáld a megszokott élményt, ahelyett hogy várakoztatnád a játékost.

Engedélykérés

A /hello kivételével mindenhez token kell, token pedig csak akkor létezik, ha a játékos jóváhagyta a játékodat egy párbeszédablakban az alkalmazáson belül. Csak azokat a hatóköröket kérd, amelyeket ténylegesen használsz: a játékos mindegyiket külön, magyarázattal látja, és bármelyikből kiveheti a pipát.

1. Engedély kérése
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"]
  }'

Ezt kapod vissza: {"status":"pending","request_id":"…","poll_after_ms":1000}, a játékos pedig látja a párbeszédablakot. Ezután kérdezd le újra és újra, amíg nem válaszol (a kérés 3 perc után lejár):

2. A válasz lekérdezése
curl http://127.0.0.1:7440/mssgs/v1/authorize/<request_id>

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

Mindig ellenőrizd, mit kaptál valójában

A válaszban szereplő scopes rövidebb lehet annál, amit kértél: a játékos szabadon kiveheti a pipát egyes hatókörökből. A fenti példában a membership.query hatókört elutasította. A válasz alapján ágazz el, ne aszerint, amit kértél, különben egy nem várt 403 MISSING_SCOPE hibába futsz.

Tárold el a tokent, és küldd Authorization: Bearer <token> fejlécként. Túléli az újraindításokat, így a játékos egyszer hagyja jóvá a játékodat, nem minden munkamenetben. Ha később olyan hatókörökkel engedélyezel újra, amelyeket már megkaptál, azonnal ugyanazt a tokent kapod vissza, párbeszédablak nélkül.

Hatókörök és adatvédelem

Az öt hatókör nagyon eltérő mennyiségű adatot ad ki. Ez nem véletlen, ez maga a koncepció. Kérj minél kevesebbet, a táblázatban fentről lefelé haladva.

Hatókör Mit tesz lehetővé Mit ad fel a játékos
presence.write Mutasd, mivel játszik Semmit. Ez a hatókör csak ír; semmilyen fiókadatot nem olvas.
identity Ki a játékos user_guid, username, megjelenített név, az avatar URL-je.
staff Személyzeti / moderátori jelzők Két logikai érték az identity mellett. Külön van, mert egy nevet megjelenítő játéknak semmi köze ahhoz, hogy a játékos közösségeket moderál.
membership.query Egy már ismert közösség ellenőrzése Az általad megadott server_guid esetén: igen/nem, a közösség neve és a játékos ottani szerepei. Semmi más közösségről.
servers.list Minden közösség, amelynek tagja A teljes lista: guidok, nevek, ikonok és szerepek. Ez a drága hatókör: csak akkor kérd, ha tényleg szükséged van rá.

A legtöbb játéknak kettő elég

Az identity és a presence.write lefedi a „ki vagy” és a „mutasd, mivel játszol” kérdést, vagyis szinte minden integrációt. Add hozzá a membership.query hatókört, ha egy jutalmat a közösséged tagságához akarsz kötni. A servers.list hatókörre szinte soha nincs szükséged, és a játékos pirossal kiemelve látja.

Tagság ellenőrzése

Ez az alternatívája annak, hogy „add ide a teljes listát”. Megadod a saját közösséged server_guid értékét (amit már ismersz), és csak arról az egy közösségről kapsz választ.

Egy közösség
curl -H "Authorization: Bearer $TOKEN" \
  "http://127.0.0.1:7440/mssgs/v1/membership?server_guid=ca94ecc…f4g02"

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

# nem tag, és semmi más:
# {"server_guid":"…","member":false}

A „nem” pontosan ennyit jelent, és semmi többet. Egy hívásban legfeljebb 10 guidot adhatsz meg (ismételd a server_guid paramétert, vagy válaszd el őket vesszővel), ilyenkor egy results tömböt kapsz vissza. Az @everyone csoport soha nem szerepel a roles között: minden tagra igaz, így semmit nem árul el.

Játékstátusz közzététele

Egyetlen PUT kérés kiteszi a „Playing …” sort a játékos neve alá, mindenhol, ahol a közösségei látják.

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

Csak a name kötelező. A válaszból kiderül, meddig él a státusz, és milyen gyakran kell heartbeatet küldeni:

Válasz
{ "ok": true, "expires_in_ms": 90000, "heartbeat_every_ms": 30000 }

Heartbeat, különben eltűnik a státusz

Ha egy státusz 90 másodpercig nem ad életjelet, automatikusan törlődik. Ez szándékos: ha a játékod összeomlik, a játékos nem marad órákig „játszó” állapotban. Küldj POST /mssgs/v1/activity/heartbeat kérést 30 másodpercenként, rendes leálláskor pedig DELETE /mssgs/v1/activity kérést.

Játékosszám és szerep

A party.kind dönti el, melyik mondat jelenik meg, mert ugyanaz a két szám nem mindig ugyanazt jelenti. Egy négyfős osztag nem egy szerver négy játékossal.

kind Így jelenik meg Mire való
party (alapértelmezett)3 of 4 in the partyosztag, csapat vagy csoport
server4/100 playersjátékszerver (FiveM, közösségi szerver)
lobby4/100 playerslobby a meccs kezdete előtt
match4/100 playersfolyamatban lévő meccs vagy kör

A role (legfeljebb 48 karakter) azt mondja meg, kiként játszik a játékos: foglalkozás, kaszt vagy karakter. Saját mezőt kap, nem egy újabb mondatot a state mezőben, mert címkeként jelenik meg a játékosszám mellett.

A details és a state legfeljebb 128 karakter lehet, a name legfeljebb 64. A sortörések és a vezérlőkarakterek törlődnek. Ikon URL-t szándékosan nem támogatunk: azt minden kliens letöltené, amely megjeleníti a sort, így a státusz jeladóvá válna, amely a játékos összes közösségének minden tagját jelentené a szerverednek.

A Join now gomb

Ha a státuszba egy join blokkot teszel, a többi tag egy Join now gombot lát mellette. Két módja van, és kombinálhatod is őket.

1. Titok (natív játékokhoz)

Állítsd be: {"join":{"secret":"raid-42"}}. Amikor valaki megnyomja a Join now gombot, ez a titok a játékod az ő saját példányához jut el, az ő gépén, ugyanazzal a game_id értékkel párosítva. Nem nyílik meg URL, és nem indul el sémakezelő. A játékod így veszi át:

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

Kérdezd le a ?since=<cursor> paraméterrel, így minden eseményt csak egyszer látsz. Ha a gombot megnyomó játékos játéka nem fut, semmi nem érkezik meg, és ez jó ok arra, hogy URL-t is adj meg.

2. https URL (webes játékokhoz és lobbylinkekhez)

Állítsd be: {"join":{"url":"https://play.example.com/s/abc"}}, és a gomb ezt a linket nyitja meg. Csak a https elfogadott. Egyéni sémát (steam://, mygame://, file://) elutasítunk: ez a blokk minden tag képernyőjére kikerül, és egy ilyen URL-lel rá lehetne venni valaki más gépét, hogy egy helyi kezelőt az általad választott argumentumokkal indítson el.

A join tartalma teljesen nyilvános

A join blokk mindenkihez eljut, aki látja a játékos státuszát; pont ez a Join now gomb lényege. Kezeld tehát lobbykódként, ne hitelesítő adatként. Soha ne tegyél bele semmit, aminek titokban kell maradnia, és adj lejárati időt a kódjaidnak.

FiveM

A FiveM kliensoldali Lua-futtatókörnyezetében nincs HTTP, ezért egy erőforrás (resource) a NUI révén beszél a híddal: ez egy CEF-nézet, amely Origin fejlécet küld. A híd kifejezetten elfogadja ezeket az originöket: https://cfx-nui-<resource> és a régebbi nui://<resource>. A hétköznapi weboldalakat továbbra is elutasítja, és egy oldal a nyílt weben nem adhatja ki magát ennek az originnek, mert azt maga a böngésző állítja be.

client.lua: kérd meg a NUI-t a közzétételre
-- A HTTP-t a NUI-oldal intézi; a Lua csak átadja neki az adatokat.
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: a státusz 90 mp után lejár
  end
end)
nui.js
const BASE = 'http://127.0.0.1:7440/mssgs/v1';   // próbáld sorban: 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']          // ide ennél több nem kell
    })
  });
  const started = await res.json();
  if (started.status === 'approved') { return started.token; }

  // A játékos most látja az engedélykérő ablakot az mssgs-ben.
  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' } // a cfx.re linked
    })
  });
});

Az eredmény: Playing FiveM · Los Santos Roleplay · 4/100 players · Police, egy Join now gombbal, amely a cfx.re linkedet nyitja meg.

Csak a presence.write hatókört kérd

Egy játékstátuszhoz semmi más nem kell: ez a hatókör semmit sem olvas. Ha egy játékbeli jutalmat az mssgs-közösséged tagságához akarsz kötni, add hozzá a membership.query hatókört, és a saját server_guid értékedet add meg; a játékos többi közösségéről így sem tudsz meg semmit.

Egy szerver, amelyen játszol, nem automatikusan megbízható

Bármelyik FiveM-szerver futtathat kliensoldali erőforrásokat, így bármelyik szerver, amelyhez valaki csatlakozik, kérhet engedélyt. Pontosan ezért áll közöttük egy párbeszédablak, amely megnevezi az erőforrást: a játékos dönt, nem a szerver.

Böngészős és telefonos játékok: összekapcsolás a backendeden keresztül

Egy böngészőlapon vagy telefonon futó játék nem éri el a fenti hidat. A híd a játékos asztali gépén fut, és három fal áll közöttük: a híd minden olyan kérést elutasít, amely böngészős Origin fejlécet hordoz, a Chrome engedélykérést tesz elé, ha egy nyilvános oldal a 127.0.0.1 címről kér le adatot, a Safari egyenesen megtagadja, egy telefon pedig egyáltalán nem éri el egy asztali gép loopback címét.

Ezért megfordul az irány. A saját backended már tudja, ki játszik, és ő szól az mssgs-nek, azoknál a játékosoknál, akik összekapcsolták az mssgs-fiókjukat a játékoddal. Az összekapcsolást az mssgs alkalmazásban hagyják jóvá, soha nem a játékodban, és ez kapcsolatot hoz létre, soha nem munkamenetet: az alábbiak közül semmi nem tud senkit bejelentkeztetni, és nem tud a játékos nevében eljárni. A játékkliensed soha nem lát kulcsot, és soha nem fordul az mss.gs felé. Az első játék ezen az úton a CozyCity, egy városépítő játék, amely WebGL-oldalként és iPhone-appként érhető el, asztali változat nélkül; az alábbi példák tőle származnak.

1. Regisztráld a játékodat

Regisztráld a játékot a Game SDK regisztrációs oldalán: add meg a game_id azonosítódat (például com.deverence.cozycity), a nevet és az ikont, amelyet a játékos a jóváhagyó lapon lát, valamint a backended hosztneveit. Ott átnézzük, és amint jóváhagytuk, ugyanazon az oldalon vár rád a backendkulcsod, egyetlen alkalommal megjelenítve; mi csak egy kivonatot tárolunk belőle. A kulcs helye a szervereden van, sehol máshol. Bármikor lecserélheted ott, a régi pedig 24 óráig érvényes marad, hogy egy telepítés zökkenőmentesen végigmehessen.

Regisztráld a játékodat

A lapon megjelenő név és ikon mindig a regisztrációból származik, soha nem a kérésből. Különben egy adathalász link bármilyen játéknak álcázhatna egy összekapcsolási kérést. A hosztnevek határozzák meg, hová mutathat egy join.url, lásd lent.

2. Kapcsolj össze egy játékost

A játékos a játékodban a Connect mssgs lehetőséget választja. A játékod megkérdezi a backendedet, a backended pedig minket:

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}

A player_ref a saját, állandó azonosítód az adott játékoshoz (legfeljebb 128 karakter), nem egy munkamenethez vagy meccshez; a player_name (legfeljebb 64) az, amit a lap „Player: …” formában mutat. A játékkliensednek csak a link_code, a qr_url és a deep_link értéket add át. A device_code a lekérdezéshez kell, és a szerveren marad.

A játékod ezután egyszerre három dolgot mutat, mert a játékos bárhol lehet:

  • A QR-kódot a qr_url értékből. Egy telefon, amelyen ott az mssgs, egyenesen az alkalmazás jóváhagyó lapján nyitja meg. Alkalmazás nélkül egy mss.gs-oldalra érkezik, amely megmutatja a kódot, és felajánlja a letöltést.
  • Egy „Open in mssgs” gombot a deep_link értékkel, az asztali alkalmazás mellett futó asztali böngészőhöz. Ez az egyetlen külső URL, amelyet a játékodnak valaha meg kell nyitnia.
  • Magát a kódot, két négyes csoportban, hogy be lehessen írni a Settings → Game Activity → Link a game menüpontban. Az ábécéből hiányzik a 0/O és az 1/I, így a begépelés ritkán megy félre.

Ezt látja a játékos az mssgs-ben; a lapot az alkalmazás rajzolja meg a regisztráció alapján:

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

Közben a backended interval másodpercenként lekérdez (a gyakoribb kérésekre 429 SLOW_DOWN a válasz), amíg az állapot meg nem változik. Egy kód egyszer használható, és tíz perc után lejár:

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"}      # a játékos a Not now gombot választotta
# {"status":"expired"}
# {"status":"linked","link_guid":"…","user":{"user_guid":"62e377…"}}

Mentsd el a link_guid értéket a játékosod adatai mellé; mostantól ez a cím, amelyre közzéteszel. A válasz csak a user_guid értéket tartalmazza; username csak akkor kerül bele, ha a regisztrációd rendelkezik az identity.link hatókörrel, és ezen túl semmi. Ugyanarra a player_ref értékre adott második jóváhagyás lecseréli a korábbi kapcsolatot, így a játékod egy játékosa egy mssgs-fiók. Ugyanaz az mssgs-fiók több játékhoz, és egy játék több player_ref azonosítójához is kapcsolódhat (egy családi iPad).

3. Tedd közzé a játékstátuszt

Ugyanaz a blokk, mint a hídnál, ugyanazokkal a szabályokkal és korlátokkal, csak most kapcsolatonként és a backendkulcsoddal:

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=…" }
  }
}
Válaszok
200 {"published":true,"changed":true}     # a blokk megváltozott, és szétküldtük
200 {"published":true,"changed":false}    # azonos a tárolttal; csak a TTL frissült
204                                        # eltároltuk, de a játékos most nincs online az mssgs-ben
410 {"error":"LINK_REVOKED"}               # a játékos megszüntette a kapcsolatot: töröld a linket

A 200 és a 204 ugyanazt jelenti: eltárolva. A { "activity": null } törli a blokkot, ezt küldd, amikor a játékos kilép. Egy különbség a hídhoz képest: a join.url hosztjának a regisztrált backendjeid egyikének (vagy annak egy aldomainjének) kell lennie, különben 400 INVALID_PAYLOAD választ kapsz. Így egy backend nem tehet a játékos státuszára olyan Join now gombot, amely oda vezet, ahol az a játékos soha nem játszott.

Heartbeat 60 másodpercenként, TTL 120

Egy közzétett státusz új üzenet nélkül 120 másodpercig él, aztán magától eltűnik. Ezért küldd el ugyanazt a blokkot 60 másodpercenként; egy változatlan blokk semmibe sem kerül, csak a TTL-t frissíti. Ha a heartbeat leáll, a „Playing …” sor is eltűnik, és pontosan ez a cél.

Több száz online játékosnál egyetlen hívással küldj heartbeatet, egyszerre legfeljebb 100 elemmel. Minden elem saját állapotot kap, így egy játékos, aki az mssgs-ben megszüntette a kapcsolatot, soha nem állítja meg a másik kilencvenkilencet:

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

Hogyan jelenik meg a státusz

  • Ugyanúgy, mint egy hídon keresztüli státusz: Playing CozyCity · Lantern Hollow · 6/40 players, Join now gombbal, ha van join.url. A szerver a blokkot via: "backend" jelöléssel látja el, így egy kliens hozzáírhatja: „Shared by the game's server”.
  • Csak amíg a játékos online van az mssgs-ben. Ha nincs nyitva mssgs-kliens, a fiók offline, és az is marad; a backended senkit nem tud jelenlévőnek feltüntetni. Ez azt is megakadályozza, hogy ez az út „ül-e René a gépénél” jeladóvá váljon.
  • Elsőbbség: alkalmazáson belüli játék > hídon keresztüli játék > a backended. Ha a játékos leül sakkozni az mssgs-ben, miközben a backended tovább küldi a heartbeatet, a sakk nyer, nem az, aki utoljára írt.

A kapcsolat bontása

A játékos minden kapcsolatot lát a Settings → Game Activity → Linked games alatt, a játékod ikonjával és nevével, a játékodból származó játékosnévvel, azzal, hogy mikor kapcsolták össze és mikor tett közzé utoljára, valamint egy Disconnect gombbal. Ezután a következő közzétételedre 410 LINK_REVOKED a válasz; a játékod így értesül róla. Töröld a link_guid értéket, és ajánld fel újra a „Connect mssgs” lehetőséget. A te oldaladról a DELETE /game-sdk/v1/links/{link_guid} hívással szüntethetsz meg egy kapcsolatot.

Korlátok

Kapcsolatonként egy változás legfeljebb 2 másodpercenként számít; a változatlan heartbeat ingyenes. Kulcsonként percenként 600 kérés jár, a kötegelt elemeket egyenként számolva: 300 játékos heartbeatje 60 másodpercenként 5-öt használ el a 600-ból.

Végpont-referencia: a híd

Alap-URL: http://127.0.0.1:<port>. Az első hármon kívül mindenhez Authorization: Bearer <token> kell.

Metódus Útvonal Scope Mit csinál
GET /mssgs/v1/hello nincs Itt van-e az mssgs, milyen API-t beszél, és be van-e jelentkezve valaki. Az egyetlen útvonal, amelyhez nem kell token, és semmit nem árul el a játékosról.
POST /mssgs/v1/authorize nincs Engedély kérése a játékostól. Párbeszédablakot nyit az alkalmazásban, és egy lekérdezhető request_id-t ad vissza.
GET /mssgs/v1/authorize/:request_id nincs pending, approved (a tokennel), denied vagy expired.
GET /mssgs/v1/me identity A bejelentkezett játékos. Az is_staff / is_moderator mezőt csak a staff hatókörrel adja hozzá.
GET /mssgs/v1/membership membership.query Tagság a megadott server_guid értékekben (legfeljebb 10, ismételve vagy vesszővel elválasztva).
GET /mssgs/v1/servers servers.list Minden közösség, amelynek a játékos tagja, a szerepeivel együtt. Privát üzenetek soha nincsenek benne.
PUT /mssgs/v1/activity presence.write A „Playing …” blokk közzététele. Visszaadja a TTL-t, és hogy milyen gyakran kell heartbeatet küldeni.
POST /mssgs/v1/activity/heartbeat presence.write Életben tartja a közzétett státuszt újraküldés nélkül.
DELETE /mssgs/v1/activity presence.write Azonnal törli, rendes leálláskor.
GET /mssgs/v1/events presence.write A játékodnak szóló csatlakozási adatok. Kérdezd le a ?since=<cursor> paraméterrel.
GET /mssgs/v1/session nincs Mit tartalmaz ez a token: game_id, megadott hatókörök, be van-e jelentkezve valaki.
DELETE /mssgs/v1/session nincs Az engedély visszaadása. Ugyanaz a hatása, mintha a játékos vonná vissza a Settings menüben.

Végpont-referencia: összekapcsolt backendek

Alap-URL: https://ams1-gateway.mss.gs. Minden útvonalhoz Authorization: Bearer <backend key> és a regisztrációdon az activity.write hatókör szükséges; a válaszok Cache-Control: no-store fejléccel mennek ki. Ezeket a szerveredről hívd, soha ne a játékkliensből.

Metódus Útvonal Mit csinál
POST /game-sdk/v1/link/start Kapcsolat indítása az egyik játékosodhoz ({ player_ref, player_name? }). Visszaadja: link_code, device_code, qr_url, deep_link, expires_in és interval.
POST /game-sdk/v1/link/poll { device_code } → pending, denied, expired, vagy linked a link_guid és a user értékkel.
DELETE /game-sdk/v1/links/{link_guid} Kapcsolat megszüntetése a te oldaladról. A játékos ugyanezt megteheti a Settings menüben.
PUT /game-sdk/v1/links/{link_guid}/activity A „Playing …” blokk közzététele egy játékosnak; a { "activity": null } törli.
POST /game-sdk/v1/activity/batch Ugyanez legfeljebb 100 játékosnak egyetlen hívásban. Minden elem külön válaszol.

Hibakódok

A hibák {"error":"CODE","message":"…"} formában érkeznek, a megfelelő HTTP-állapotkóddal.

Kód Jelentés
401 UNAUTHORIZEDHiányzó vagy ismeretlen token; előbb kérj engedélyt.
403 MISSING_SCOPEA játékos nem adta meg ezt az engedélyt. Lehet, hogy kivette a pipát.
403 ORIGIN_NOT_ALLOWEDA kérés böngészős Origin fejlécet hordozott. Lásd lent: „Csak natív játékok”.
409 NOT_SIGNED_INAz mssgs fut, de senki nincs bejelentkezve.
429 RATE_LIMITEDTöbb mint 120 kérés egy perc alatt egyetlen játéktól.
400 INVALID_GAME_IDA game_id csak betűket, számjegyeket, pontot, kötőjelet vagy aláhúzásjelet tartalmazhat.
400 TOO_MANY_GUIDSTagsági hívásonként legfeljebb 10 server_guid érték.

Összekapcsolt backendek

A backend útvonalai ugyanezt a formát használják. Egy kötegen belül az állapot elemenként érkezik vissza a results tömbben, így egy megszűnt kapcsolat soha nem buktatja el az egész hívást.

Kód Jelentés
401 INVALID_BACKEND_KEYIsmeretlen kulcs, vagy olyan, amelyet több mint 24 órája lecseréltek.
403 SCOPE_NOT_GRANTEDA regisztrációd nem rendelkezik az útvonalhoz szükséges hatókörrel.
400 INVALID_PAYLOADHibás törzs, több mint 100 elem egy kötegben, vagy olyan join.url, amelynek a hosztja nem tartozik a regisztrált backendjeid közé.
400 INVALID_ACTIVITYA normalizálás után nem maradt használható név.
410 LINK_REVOKEDA kapcsolat megszűnt, bármelyik oldalon. Töröld, és ajánld fel újra a „Connect mssgs” lehetőséget.
429 SLOW_DOWNAz interval értéknél gyakrabban kérdezted le a link/poll végpontot.
429 RATE_LIMITEDEgy kapcsolat módosítása 2 másodpercen belül az előző után, vagy több mint 600 kérés egy perc alatt a kulcsodon.
503 LINK_STORE_UNAVAILABLEÁtmeneti hiba a mi oldalunkon. Próbáld újra a következő heartbeatnél.

Biztonság

Csak natív játékok

A weboldalról érkező, Origin fejlécet hordozó kéréseket 403 ORIGIN_NOT_ALLOWED hibával elutasítjuk. Ha bármely weboldal észlelhetné, hogy az mssgs-t használod, és engedélykérő ablakot dobhatna fel, az ujjlenyomat-alapú azonosításnak és adathalászatnak nyitna kaput, nem funkció lenne. Egy natív játék egyáltalán nem küld Origin fejlécet, így ez nem érinti, egy játék saját beágyazott böngészője pedig név szerint engedélyezett, lásd FiveM. Ha böngészős vagy telefonos játékot építesz, nem a híddal kommunikálsz: a saját backended tesz közzé az összekapcsolt játékosoknak, lásd Böngészős és telefonos játékok.

Ami a játékos kezében marad

  • A játékos kikapcsolhatja a hidat a Settings → Game Activity alatt, és ezután egyetlen játék sem látja az mssgs-t.
  • Minden jóváhagyott játék ott szerepel, pontosan azokkal az engedélyekkel, amelyekkel rendelkezik, azzal, hogy mikor volt utoljára aktív, és egy Remove gombbal. Az eltávolítás azonnali: a token rögtön érvényét veszti.
  • Egy összekapcsolt böngészős vagy telefonos játék a Linked games alatt szerepel, egy Disconnect gombbal. A kapcsolat bontása is azonnali: az adott backend következő közzététele 410 választ kap.
  • A híd csak a 127.0.0.1 címen figyel, soha nem a hálózaton.
  • A privát üzenetek soha nem kerülnek ki, még a servers.list hatókörrel sem.
  • Játékonként percenként 120 kérés a keret.

Jó gyakorlatok

  • Akkor kérj hatóköröket, amikor szükséged van rájuk, ne mindet egyszerre az első indításkor.
  • Működj mssgs nélkül is: a játékosnak nem kötelező használnia.
  • Töröld a státuszt, amikor a játék véget ér, ahelyett hogy a TTL lejártára várnál.
  • Kezeld az elutasított hatókört normális kimenetként, ne hibaként.

Építs tovább