SDK для Godot 4 (GDScript)
Автозагружаемый (autoload) синглтон-модуль. Использует встроенный HTTPRequest и await — без сторонних плагинов и внешних зависимостей.
Установка
- Сохраните скрипт ниже как
res://bluestudz/BlueStudz.gd. Project Settings → Autoload→ добавьте файл с именем узлаBlueStudz.- Заполните
secret_tokenв инспекторе автозагрузки. - Вызовите
await BlueStudz.init()из вашей стартовой сцены.
Справочник методов GDScript
Исходный код синглтона (GDScript)
BlueStudz.gd
extends Node
## BlueStudz.gd - autoload singleton for Godot 4.
## Project Settings -> Autoload -> add this script as "BlueStudz".
## Reads BLUESTUDZ_API / BLUESTUDZ_GAME_ID / BLUESTUDZ_LAUNCH_TOKEN from the
## environment (set automatically by the BlueStudz Launcher).
signal auth_completed(success: bool)
@export var secret_token: String = ""
var _api_base: String
var _game_id: String
var _user_token: String
var _user_id: String
var is_authenticated: bool = false
func init() -> bool:
_api_base = OS.get_environment("BLUESTUDZ_API")
if _api_base.is_empty():
_api_base = "https://api.bluestudz.ru"
_game_id = OS.get_environment("BLUESTUDZ_GAME_ID")
var launch_token := OS.get_environment("BLUESTUDZ_LAUNCH_TOKEN")
if _game_id.is_empty() or launch_token.is_empty():
push_warning("[BlueStudz] Not launched via BlueStudz Launcher - running unauthenticated.")
return false
var verify_result = await _post_json("/auth/game/verify", {"launchToken": launch_token}, false)
if verify_result == null:
return false
_user_token = verify_result.get("gameToken", "")
_user_id = verify_result.get("user", {}).get("id", "")
var auth_result = await _post_json("/sdk/auth/verify", {
"gameId": _game_id,
"secretToken": secret_token,
"userId": _user_id,
"userToken": _user_token,
}, false)
is_authenticated = auth_result != null and auth_result.get("success", false)
auth_completed.emit(is_authenticated)
return is_authenticated
class Achievements:
static func unlock(achievement_id: String) -> bool:
var result = await Engine.get_main_loop().root.get_node("/root/BlueStudz")._post_json(
"/sdk/achievements/unlock", {"achievementId": achievement_id}, true, true
)
return result != null and result.get("success", false)
class CloudSaves:
## sha256/size_bytes/storage_key come from your own upload of the save
## archive to the presigned URL from POST /storage/presign; this call
## only registers the resulting file with BlueStudz's conflict detection.
static func sync(sha256: String, size_bytes: int, storage_key: String, base_version) -> Dictionary:
var result = await Engine.get_main_loop().root.get_node("/root/BlueStudz")._post_json(
"/sdk/cloudsaves/sync",
{"sha256": sha256, "sizeBytes": size_bytes, "storageKey": storage_key, "baseVersion": base_version},
true
)
return result if result != null else {"success": false}
class Presence:
static func set_status(active: bool) -> bool:
var result = await Engine.get_main_loop().root.get_node("/root/BlueStudz")._post_json(
"/sdk/presence/status", {"active": active}, true
)
return result != null and result.get("success", false)
func _post_json(path: String, body: Dictionary, with_auth: bool, with_secret: bool = false) -> Variant:
var http := HTTPRequest.new()
add_child(http)
var headers := ["Content-Type: application/json"]
if with_auth:
headers.append("Authorization: Bearer %s" % _user_token)
headers.append("x-bs-gameid: %s" % _game_id)
if with_secret:
headers.append("x-bs-secrettoken: %s" % secret_token)
var err := http.request(_api_base + path, headers, HTTPClient.METHOD_POST, JSON.stringify(body))
if err != OK:
http.queue_free()
return null
var response = await http.request_completed
http.queue_free()
var response_code: int = response[1]
var body_bytes: PackedByteArray = response[3]
if response_code < 200 or response_code >= 300:
push_error("[BlueStudz] %s failed with HTTP %d" % [path, response_code])
return null
var json := JSON.new()
if json.parse(body_bytes.get_string_from_utf8()) != OK:
return null
return json.get_data()
Пример использования
gdscript
await BlueStudz.init()
if BlueStudz.is_authenticated:
await BlueStudz.Achievements.unlock("first_blood")
await BlueStudz.Presence.set_status(true)