0.1.3 -
Genereret mandag den 11. marts 2024
Har du spørgsmål, fundet en fejl eller idéer til forbedringer? Så er du meget velkommen til at kontakte os:
Immer’s spil bliver aktiveret ved at tilføje et HTML-element og script
-tag til siden eller web-viewet, det skal indlejres i.
I dette eksempel indlejre vi spillet Gitter på en almindelig HTML-side:
<html>
<head>
…
</head>
<body>
<!-- HTML-elementet spillet skal indlejres i -->
<div id="immer-gitter" data-key="DIN_KLIENT_API_NØGLE_HER"></div>
<!-- Henvisning til JavaScript-koden der eksekverer spillet -->
<script src="https://acme.immerspiele.com/games/gitter/gitter.js"></script>
</body>
</html>
Et spil kan konfigureres med forskellige attributter. Disse kan sættes på spillets container-element eller via. en global JavaScript-funktion.
<div id="immer-gitter" data-key="DIN_KLIENT_API_NØGLE_HER"></div>
Funktionen skal hedde immerSetup
og returnere et objekt. Denne funktionen skal defineres
inden selve scriptet til spillet bliver indlæst.
<script>
function immerSetup() {
return {
key: 'DIN_KLIENT_API_NØGLE_HER',
};
}
</script>
<!-- Henvisning til JavaScript-koden der eksekverer spillet -->
<script src="https://acme.immerspiele.com/games/gitter/gitter.js"></script>
Data-attribut | Object-nøgle | Beskrivelse |
---|---|---|
data-key | key | Klient API-nøgle som bruges til at hente og sende data til Immer’s API. |
data-login-url | loginUrl | URL til login-side. Hvis denne ikke er sat, vil spillet sende en udgående handling med ID 1 når brugeren ønsker at logge ind. |
data-proxy | proxy | URL til en server-side proxy, der kan bruges til at skjule klient API-nøglen og spillerens ID. Se Grundlæggende for mere information. |
data-player-id | playerId | Udvekslings-ID for den aktuelle bruger. Denne bruges til at hente og sende data til Immer’s API. |
Når en bruger starter, spiller eller afslutter et spil skal informationen sendes til Immer’s API så sikkert og enkelt som muligt.
Vi vurderer, at denne løsning er den mest sikre og holdbare da ingen oplysninger eksponeres i klienten.
Alle forespørgsler, der sendes til Immer’s API, kører igennem en server-side “proxy”. Denne proxy beriger alle forespørgsler med en API-nøgle og et udvekslings-ID. På denne måde behøver vi ikke afsløre følsomme oplysninger i klienten. Dette giver - potentielt - også en lille hastighedsforøgelse da browseren ikke behøver at sende et ekstra preflight-request pga. CORS.
Når Wørdle starter, laver spillet selv et kald til Immer’s API for at indlæse dagens ord. Hvis brugeren allerede har eller er i gang med at spille, skal dette “state” også genskabes via. API-kaldet.
Eksempel på første forespørgelse i Wørdle hvis brugeren er logget ind:
GET https://acme.immerspiele.com/api/woerdle/latest
# Headers der — som minimum — skal bruges:
Authorization: Bearer tqrnlFGwtXBFRaOALLQiVKVCpi0DCTtyrem8UJ7XuEdUx
X-Immer-Player-ID: 6ac1d26b284a25f733135a5e0eed542b3f6261ec
For at skjule følsomme oplysninger, kan spillet konfigureres til, at kører igennem en proxy:
<div
id="immer-woerdle"
data-proxy="https://www.acme.dk/spil-proxy-endpoint"
>
</div>
<!-- Eller, hvis proxy-adressen er på samme host: -->
<div
id="immer-woerdle"
data-proxy="/spil-proxy-endpoint"
>
</div>
<!-- Alternativt, kan spillet opsættes med en global JavaScript-funktion: -->
<script>
function immerSetup() {
return {
proxy: '/spil-proxy-endpoint',
};
}
</script>
Første forespørgelse i Wørdle vil nu se sådan ud:
GET https://www.acme.dk/spil-proxy-endpoint/woerdle/latest
På server-siden viderestilles forespørgslen til Immer’s API inklusiv API-nøgle og udvekslings-ID (som givetvis findes eller kan fortolkes i et sessions-lag eller via. en cookie):
GET https://www.acme.dk/spil-proxy-endpoint/woerdle/latest
# Headers tilføjet af proxy
Authorization: Bearer tqrnlFGwtXBFRaOALLQiVKVCpi0DCTtyrem8UJ7XuEdUx
X-Immer-Player-ID: 6ac1d26b284a25f733135a5e0eed542b3f6261ec
Andre relevante headers som X-Request-ID
og X-Forwarded-For
kan også medtages ifht. logning og fejlfinding.
For at begrænse eksponering af klient API-nøglen, kan nøglen signeres server-side, så den er unik pr. udvekslings-ID eller sessions-ID og spil.
Der laves en signeret HMAC-værdi med SHA-256 og følgende værdier:
{navn på spil}+{udvekslings-ID eller sessions-ID}
med API-nøglen som den “hemmelige nøgle”. Resultatet præfikses med sign_
.
hashed = hmac(
message: 'wørdle+6ac1d26b284a25f733135a5e0eed542b3f6261ec',
secret: 'tqrnlFGwtXBFRaOALLQiVKVCpi0DCTtyrem8UJ7XuEdUx'
)
=> hashed: 'e9fa3cb0b12770c744976738b55c99732c507f4fa64e5b895c2a47ce75b49c9e'
key = 'sign_' + hashed
=> key: 'sign_e9fa3cb0b12770c744976738b55c99732c507f4fa64e5b895c2a47ce75b49c9e'
Ved opsætning kan værdien nu bruges som API-nøgle:
<div
id="immer-woerdle"
data-key="sign_e9fa3cb0b12770c744976738b55c99732c507f4fa64e5b895c2a47ce75b49c9e"
data-player-id="6ac1d26b284a25f733135a5e0eed542b3f6261ec"
>
</div>
Integrationen til Immer’s API kan også ske via. en klient API-nøgle. Denne løsning er mindre sikker, da API-nøglen og udvekslings-ID’et vil være eksponeret for klienten.
Ved opsætning kan spillet konfigureres med en API-nøgle og et udvekslings-ID (hvis brugeren er logget ind).
<div
id="immer-woerdle"
data-key="dT5ElhVVRmbzPz4yO0rB5yhoPbqSF2fun6Y634iGAqIEBNlVZtj11FgH31nZ0iXB"
data-player-id="6ac1d26b284a25f733135a5e0eed542b3f6261ec"
>
</div>
<!-- Alternativt, kan spillet opsættes med en global JavaScript-funktion: -->
<script>
function immerSetup() {
return {
key: 'dT5ElhVVRmbzPz4yO0rB5yhoPbqSF2fun6Y634iGAqIEBNlVZtj11FgH31nZ0iXB',
playerId: '6ac1d26b284a25f733135a5e0eed542b3f6261ec'
};
}
</script>
Der er flere modal-vinduer i spillene, der kan åbnes programmatisk, så de kan integreres i forskellige kontekst - f.eks. en menu, en mobil-app osv.
Et modal-vindue åbnes ved at afvikle et CustomEvent
med typen
på spillets container-element.showModal
Eventets detail
-egenskab skal indeholde et objekt med modal-vinduets ID.
// Opret event
const helpModalEvent = new CustomEvent('showModal', {
detail: {
id: 1,
},
});
// Find container-elementet, som spillet vises indeni.
// I dette eksempel har elementet klassenavnet "game-container".
const container = document.querySelector('.game-container');
// Afvikl eventet på elementet
container.dispatchEvent(helpModalEvent);
ID | Navn |
---|---|
1 | Hjælp & regler |
2 | Statistik |
3 | Tidligere/gårsdagens løsning |
4 | Ledetråde |
5 | Rang |
6 | Kontakt |
Udvalgte handlinger, der sker udenfor spillets område, kan sendes fra klienten til spillet. Dette kan f.eks. være, at fortælle spillet, at brugeren er logget ind.
Indgående handlinger kan sendes til spillet ved at bruge et CustomEvent
med typen
på spillets container-element.gameAction
Eventets detail
-egenskab skal indeholde et objekt med handlingens ID.
// Opret event
const authenticateEvent = new CustomEvent('gameAction', {
detail: {
id: 1,
},
});
// Find container-elementet, som spillet vises indeni.
// I dette eksempel har elementet klassenavnet "game-container".
const container = document.querySelector('.game-container');
// Afvikl eventet på elementet
container.dispatchEvent(authenticateEvent);
ID | Handling | Beskrivelse |
---|---|---|
1 | Log ind | Brugeren er logget ind og dette skal reflekteres i spillet. |
Udvalgte handlinger, der foretages inde i spillet er tilgængelige for klienten, som spillet indlejres i.
Handlinger sendes fra spillet med et CustomEvent
med typen
på spillets container-element.gameEvent
Eventets detail
-egenskab skal indeholde et objekt med handlingens ID.
// Find container-elementet, som spillet vises indeni.
// I dette eksempel har elementet klassenavnet "game-container".
const container = document.querySelector('.game-container');
// Tilføj event listener til container-elementet
container.addEventListener('gameEvent', (event) => {
const id = event.detail.id;
// Brug handlingens ID…
});
ID | Handling | Beskrivelse |
---|---|---|
1 | Log ind | Brugeren ønsker at logge ind |
2 | Opret bruger | Bruger ønsker at oprette en profil |
3 | Skærmændring | Spillet skifter skærm - f.eks. fra "velkomstskærm" til "spil". |
Visse handlinger indeholder ekstra information.
ID | Handling | Struktur |
---|---|---|
3 | Skærmændring | Se skærm-ID'er |
ID | Navn | Beskrivelse |
---|---|---|
0 | Indlæsning | Vises når spillet indlæses. |
1 | Velkomst | Velkomstskærm. |
2 | Spil | Spilskærm. |
3 | Breaker | Vises i spil, der understøtter "breaker"-skærme (f.eks. Satellit). |
4 | Spil afsluttet | Vises når et spil afsluttes. |