Emita eventos.
Receba o caso pronto.
O GameLink liga o seu jogo ao Praetor de duas formas: linke o SDK no seu servidor dedicado ou chame a Web API por HTTPS de qualquer backend. As duas levam os mesmos eventos e dão ao Praetor o mesmo poder. Nos dois casos, sem mudar a arquitetura do jogo e sem downtime.
- 1Conecte o GameLink: linke o SDK com o seu certificado e a sua chave de licença, ou chame a Web API com uma chave de API.
- 2Rode em observação. O Warden calibra a baseline do seu jogo sem punir ninguém.
- 3Defina os limites e escolha o que fica automático e o que vai para revisão humana.
O código abaixo é só uma demonstração de como fica uma integração. Os nomes, endpoints e chaves reais vêm com a sua conta do GameLink.
// dedicated server, one client per process GameLink::GLClient client; client.Startup( iMaxPlayers, nullptr ); client.LoadCertificateFromFile( sCert, sKey ); client.ConnectUsingEndpoint( sEndpoint, sLicenseKey, sVersion, 5000 ); // in the server's main loop client.Tick(); // game events GameLink::Player::SendJoin( &client, iPlayer, sName, ePlatform ); GameLink::Social::SendChatMessage( &client, iSender, eChannel, sText ); client.Shutdown();
/* extern "C" over the same library */ gl_client_t * c = gl_client_create(); gl_client_startup( c, max_players, NULL ); gl_client_connect_endpoint( c, endpoint, license_key, version, 5000 ); /* server loop */ gl_client_tick( c ); gl_client_shutdown( c ); gl_client_destroy( c );
// P/Invoke over the C ABI [DllImport("gamelink")] static extern IntPtr gl_client_create(); [DllImport("gamelink")] static extern int gl_client_tick(IntPtr c); [DllImport("gamelink")] static extern int gl_client_startup(IntPtr c, uint maxPlayers, IntPtr cfg); var c = gl_client_create(); gl_client_startup(c, maxPlayers, IntPtr.Zero); // same pattern in the Unity and Unreal wrappers gl_client_tick(c);
// FFI over the C ABI use std::ffi::{c_int, c_void}; #[link(name = "gamelink")] unsafe extern "C" { fn gl_client_create() -> *mut c_void; fn gl_client_tick(c: *mut c_void) -> c_int; } let c = unsafe { gl_client_create() }; // in the server's main loop unsafe { gl_client_tick(c) };
// cgo over the C ABI /* #cgo LDFLAGS: -lgamelink #include "gamelink.h" */ import "C" c := C.gl_client_create() C.gl_client_startup(c, C.uint32_t(maxPlayers), nil) // in the server's main loop C.gl_client_tick(c)
// FFI over the C ABI (java.lang.foreign) // link() wraps Linker.nativeLinker().downcallHandle(...) try (var arena = Arena.ofConfined()) { var lib = SymbolLookup .libraryLookup("gamelink", arena); var create = link(lib, "gl_client_create", ADDRESS); var tick = link(lib, "gl_client_tick", JAVA_INT, ADDRESS); MemorySegment c = (MemorySegment) create .invoke(); tick.invoke(c); }
# GameLink Web API: events over HTTPS with an API key curl https://api.praetor.example/v1/events \ -H "Authorization: Bearer $PRAETOR_KEY" \ -H "Content-Type: application/json" \ -d '{ "server_id": "eu-west-03", "events": [ { "type": "player.join", "player": "76561198000000042" }, { "type": "combat.hit", "attacker": "76561198000000042", "victim": "76561198000000043" } ] }' # open cases waiting for review curl https://api.praetor.example/v1/cases \ -G -d status=review \ -H "Authorization: Bearer $PRAETOR_KEY"
# any HTTP client works import os, requests API = "https://api.praetor.example/v1" KEY = os.environ["PRAETOR_KEY"] H = { "Authorization": "Bearer " + KEY } requests.post(API + "/events", headers=H, json={ "server_id": "eu-west-03", "events": [ { "type": "chat.message", "player": pid, "text": msg } ] }) cases = requests.get(API + "/cases", headers=H, params={ "status": "review" }).json()
// Node 18+, built-in fetch const API = "https://api.praetor.example/v1"; const headers = { Authorization: `Bearer ${process.env.PRAETOR_KEY}`, "Content-Type": "application/json", }; await fetch(`${API}/events`, { method: "POST", headers, body: JSON.stringify({ server_id: "eu-west-03", events: [ { type: "match.end", match: matchId } ], }), });
Os exemplos HTTP usam um endereço fictício. O endpoint e a chave reais vêm com a sua conta.
Um módulo.
Duas formas de conectar.
O GameLink é como o seu jogo fala com o Praetor, e ele dá ao Praetor poder total sobre os seus servidores nas duas formas. Escolha o SDK ou a Web API pelo jeito como você constrói, não pelo que precisa: todos os módulos funcionam igual nas duas.
| SDK | Web API | |
|---|---|---|
| Canal | persistente, criptografado, aberto pelo seu servidor | uma requisição HTTPS por lote de eventos |
| Autenticação | seu certificado + chave de licença | Chave de API |
| Direção | mão dupla, ao vivo | mão dupla, por HTTPS, mais webhooks |
| Ação no jogo | os comandos do Praetor rodam direto no servidor | os comandos do Praetor voltam por HTTPS e rodam no servidor |
| Dados sensíveis | criptografados no seu servidor, antes de sair | vão pelo HTTPS do seu servidor e são criptografados pelo Praetor quando chegam |
| Carga no seu servidor | não bloqueante, fora da thread do jogo | o que o seu cliente HTTP custar |
| Chat de admin no jogo | sim | sim |
| Replay do Hindsight | quadro a quadro, da visão do jogador | quadro a quadro, da visão do jogador |
| Ideal para | servidores dedicados em C++, Unreal ou Unity | qualquer backend, em qualquer linguagem |
Administre pelo chat.
Sem dar alt-tab.
Com o GameLink, pelo SDK ou pela Web API, os admins digitam comandos direto no chat do jogo. O Praetor intercepta os comandos antes que qualquer outro jogador veja.
- Status do servidor ping, jogadores online, memória, CPU
- Aviso geral para um servidor, para todos ou para o jogo inteiro
- Teleporte até um jogador ou até coordenadas
- Zonas proibidas desenhadas ao vivo, andando até cada canto
Feito para alto desempenho,
sobre o Ethereal.
O Praetor foi projetado para alta vazão e baixa latência, do GameLink ao backend. Muitos dos seus módulos e submódulos rodam sobre o Ethereal, a biblioteca C/C++ em que a Typename Studios constrói os próprios produtos.
Pronto para conectar o GameLink?
Conte qual é a sua engine e como são os seus servidores. A gente manda um plano de integração: os eventos a emitir, onde conectá-los e quanto tempo leva.