Last active
September 25, 2023 11:33
-
-
Save marutypes/13511297c284385157891a9e5d66c642 to your computer and use it in GitHub Desktop.
Godot Lootlocker Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends CanvasLayer | |
@export var leaderboard_line: PackedScene | |
@onready var leaderboard_container = %VBoxContainer | |
@onready var loading_label = %LoadingLabel | |
@onready var return_button = %Button | |
func _ready(): | |
return_button.grab_focus() | |
return_button.pressed.connect(_on_return_button_pressed) | |
if !LootLocker.is_authed(): | |
await LootLocker.authenticate_guest_session() | |
var data = await LootLocker.get_leaderboards() | |
render_leaderboard(data) | |
func render_leaderboard(data): | |
loading_label.visible = false | |
for n in data.items.size(): | |
var item = data.items[n] | |
var line = leaderboard_line.instantiate() | |
line.rank = str(item.rank) | |
line.player_name = item.player.name | |
line.player_id = str(item.player.id) | |
line.score = str(item.score) | |
line.update_label() | |
leaderboard_container.add_child(line) | |
func _on_return_button_pressed(): | |
SceneManager.goto_main_menu() | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# No class_name because we autoload this! | |
extends Node | |
const GAME_KEY = "YOUR_KEY" | |
const GAME_VERSION = "0.0.1" | |
const AUTH_URL = "https://api.lootlocker.io/game/v2/session/guest" | |
const LEADERBOARD_URL = "https://api.lootlocker.io/game/YOUR_LEADERBOARD_KEY/highscores/list?count=10" | |
const SET_NAME_URL = "https://api.lootlocker.io/game/player/name" | |
const SUBMIT_SCORE_URL = "https://api.lootlocker.io/game/YOUR_LEADERBOARD_KEY/highscores/submit" | |
const SILLY_DEFAULT_NAMES = [ | |
"Meowsifer", | |
"Sylvester", | |
"Magical Mr. Mistofolees", | |
"Felix", | |
"Kokusho", | |
"Skye Kitten", | |
"Floopus", | |
"Big Billy", | |
"Billy", | |
"Maru" | |
] | |
@onready var auth_request = $AuthRequest | |
@onready var submit_score_request = $ScoreSubmissionRequest | |
@onready var get_leaderboard_request = $LeaderboardGetRequest | |
@onready var set_name_request = $SetNameRequest | |
var auth_request_ongoing = false | |
var submit_score_ongoing = false | |
var get_leaderboard_ongoing = false | |
var set_name_ongoing = false | |
var leaderboards | |
var token: String | |
var player_id: String | |
var player_name: String = "" | |
func _ready(): | |
player_id = _get_player_id() | |
await authenticate_guest_session() | |
if player_name.length() == 0: | |
player_name = SILLY_DEFAULT_NAMES.pick_random() | |
func is_authed(): | |
return token && token.length() > 0 | |
func authenticate_guest_session(): | |
#print("Authenticating user session...") | |
# If we double requested, cancel the old one | |
if auth_request_ongoing: | |
auth_request.cancel_request() | |
auth_request_ongoing = false | |
# Prepare our HTTP request | |
var header = ["Content-Type: application/json"] | |
var method = HTTPClient.METHOD_POST | |
var request_body = { | |
"game_key": GAME_KEY, | |
"game_version": GAME_VERSION | |
} | |
if player_id: | |
request_body["player_identifier"] = player_id | |
auth_request.request(AUTH_URL, header, method, JSON.stringify(request_body)) | |
auth_request_ongoing = true | |
# Await the result so we can process it | |
var auth_response = await(auth_request.request_completed) | |
auth_request_ongoing = false | |
var code = auth_response[1] | |
if code != 200: | |
#print("LootLocker auth failed, oh no") | |
GameEvents.loot_locker_auth_failed.emit() | |
return | |
var response = auth_response[3] | |
var response_str = response.get_string_from_utf8() | |
var response_json = JSON.new() | |
response_json.parse(response_str) | |
var response_data = response_json.get_data() | |
# Update our data based on the response :0 | |
if "session_token" in response_data: | |
token = response_data["session_token"] | |
if "player_identifier" in response_data: | |
player_id = response_data["player_identifier"] | |
# Notify the game we logged in successfully | |
GameEvents.loot_locker_auth_succeeded.emit() | |
#print("Authentication succeeded!") | |
func get_leaderboards(): | |
if get_leaderboard_ongoing: | |
get_leaderboard_request.cancel() | |
get_leaderboard_ongoing = false | |
#print("Getting leaderboards") | |
var headers = _get_auth_headers() | |
# Send request | |
get_leaderboard_request.request(LEADERBOARD_URL, headers, HTTPClient.METHOD_GET, "") | |
get_leaderboard_ongoing = true | |
var leaderboard_response = await get_leaderboard_request.request_completed | |
get_leaderboard_ongoing = false | |
var code = leaderboard_response[1] | |
if code != 200: | |
#print("Getting leaderboards failed, oh no") | |
return | |
var response = leaderboard_response[3] | |
var response_str = response.get_string_from_utf8() | |
var json = JSON.new() | |
print(response_str) | |
json.parse(response_str) | |
var data = json.get_data() | |
return data | |
func submit_score(score: int): | |
if submit_score_ongoing: | |
submit_score_request.cancel() | |
submit_score_ongoing = false | |
#print("Submitting score") | |
var headers = _get_auth_headers() | |
var payload = JSON.stringify({ "score": str(score) }) | |
# Send request | |
submit_score_request.request(SUBMIT_SCORE_URL, headers, HTTPClient.METHOD_POST, payload) | |
submit_score_ongoing = true | |
var score_response = await submit_score_request.request_completed | |
submit_score_ongoing = false | |
var code = score_response[1] | |
if code != 200: | |
#print("Submitting score failed, oh no") | |
return | |
var response = score_response[3] | |
var response_str = response.get_string_from_utf8() | |
var json = JSON.new() | |
json.parse(response_str) | |
var data = json.get_data() | |
return data | |
func set_player_name(new_name: String): | |
if set_name_ongoing: | |
set_name_request.cancel() | |
set_name_ongoing = false | |
#print("Changing player name") | |
var headers = _get_auth_headers() | |
var payload = JSON.stringify({ "name": new_name }) | |
# Send request | |
set_name_request.request(SET_NAME_URL, headers, HTTPClient.METHOD_PATCH, payload) | |
set_name_ongoing = true | |
var name_response = await set_name_request.request_completed | |
set_name_ongoing = false | |
var code = name_response[1] | |
if code != 200: | |
#print("Setting name failed, oh no") | |
return | |
var response = name_response[3] | |
var response_str = response.get_string_from_utf8() | |
var json = JSON.new() | |
json.parse(response_str) | |
var data = json.get_data() | |
player_name = name | |
return data | |
func _save_player_id(new_id: String): | |
var data = _get_persistent_data() | |
var file = FileAccess.open("user://LootLocker.data", FileAccess.WRITE) | |
data["player_identification"] = new_id | |
var json_string = JSON.stringify(data) | |
file.store_string(json_string) | |
func _get_player_id(): | |
var data = _get_persistent_data() | |
if "player_identification" in data: | |
return data["player_identification"] | |
else: | |
return null | |
func _get_persistent_data(): | |
var file = FileAccess.open("user://LootLocker.data", FileAccess.READ) | |
if file == null: | |
return {} | |
var json = JSON.new() | |
var file_text = file.get_as_text() as String | |
if file_text.length() <= 0: | |
return {} | |
json.parse(file_text) | |
file.close() | |
return json.get_data() | |
func _get_auth_headers(): | |
return ["Content-Type: application/json", "x-session-token:"+token] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends CanvasLayer | |
class_name RunEndScreen | |
const SCORE_STRING = "Your score was: %s" | |
@onready var description_label = %DescriptionLabel | |
@onready var score_label = %ScoreLabel | |
@onready var submit_button: Button = %Button | |
@onready var name_input: LineEdit = %NameInput | |
func _ready(): | |
submit_button.pressed.connect(_on_submit_pressed) | |
name_input.focus_exited.connect(_on_input_focus_exit) | |
name_input.grab_focus() | |
update_labels() | |
func update_labels(): | |
score_label.text = SCORE_STRING % ScoreManager.score | |
name_input.text = LootLocker.player_name | |
func _on_input_focus_exit(): | |
if name_input.text != LootLocker.player_name: | |
await LootLocker.set_player_name(name_input.text) | |
func _on_submit_pressed(): | |
await LootLocker.authenticate_guest_session() | |
if name_input.text != LootLocker.player_name: | |
await LootLocker.set_player_name(name_input.text) | |
submit_button.disabled = true | |
await LootLocker.submit_score(ScoreManager.score) | |
submit_button.disabled = false | |
SceneManager.goto_leaderboard() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment