Skip to content

Instantly share code, notes, and snippets.

@marutypes
Last active September 25, 2023 11:33
Show Gist options
  • Save marutypes/13511297c284385157891a9e5d66c642 to your computer and use it in GitHub Desktop.
Save marutypes/13511297c284385157891a9e5d66c642 to your computer and use it in GitHub Desktop.
Godot Lootlocker Example
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()
# 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]
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