Skip to content

Instantly share code, notes, and snippets.

@JohannesLoot
Created June 10, 2022 06:42
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save JohannesLoot/20290272a91bb785459dd014b8845c8c to your computer and use it in GitHub Desktop.
Save JohannesLoot/20290272a91bb785459dd014b8845c8c to your computer and use it in GitHub Desktop.
extends Node
# Use this game API key if you want to test it with a functioning leaderboard
# "987dbd0b9e5eb3749072acc47a210996eea9feb0"
var game_API_key = "your-game-API-key-here"
var development_mode = true
var leaderboard_key = "leaderboardKey"
var session_token = ""
var score = 0
# HTTP Request node can only handle one call per node
var auth_http = HTTPRequest.new()
var leaderboard_http = HTTPRequest.new()
var submit_score_http = HTTPRequest.new()
func _ready():
_authentication_request()
func _process(_delta):
if(Input.is_action_just_pressed("ui_up")):
score += 1
print("CurrentScore:"+str(score))
if(Input.is_action_just_pressed("ui_down")):
score -= 1
print("CurrentScore:"+str(score))
# Upload score when pressing enter
if(Input.is_action_just_pressed("ui_accept")):
_upload_score(score)
# Get score when pressing spacebar
if(Input.is_action_just_pressed("ui_select")):
_get_leaderboards()
func _authentication_request():
# Check if a player session has been saved
var player_session_exists = false
var file = File.new()
file.open("user://LootLocker.data", File.READ)
var player_identifier = file.get_as_text()
file.close()
if(player_identifier.length() > 1):
player_session_exists = true
## Convert data to json string:
var data = { "game_key": game_API_key, "game_version": "0.0.0.1", "development_mode": true }
# If a player session already exists, send with the player identifier
if(player_session_exists == true):
data = { "game_key": game_API_key, "player_identifier":player_identifier, "game_version": "0.0.0.1", "development_mode": true }
# Add 'Content-Type' header:
var headers = ["Content-Type: application/json"]
# Create a HTTPRequest node for authentication
auth_http = HTTPRequest.new()
add_child(auth_http)
auth_http.connect("request_completed", self, "_on_authentication_request_completed")
# Send request
auth_http.request("https://api.lootlocker.io/game/v2/session/guest", headers, true, HTTPClient.METHOD_POST, to_json(data))
# Print what we're sending, for debugging purposes:
print(data)
func _on_authentication_request_completed(result, response_code, headers, body):
var json = JSON.parse(body.get_string_from_utf8())
# Save player_identifier to file
var file = File.new()
file.open("user://LootLocker.data", File.WRITE)
file.store_string(json.result.player_identifier)
file.close()
# Save session_token to memory
session_token = json.result.session_token
# Print server response
print(json.result)
# Clear node
auth_http.queue_free()
# Get leaderboards
_get_leaderboards()
func _get_leaderboards():
print("Getting leaderboards")
var url = "https://api.lootlocker.io/game/leaderboards/"+leaderboard_key+"/list?count=10"
var headers = ["Content-Type: application/json", "x-session-token:"+session_token]
# Create a request node for getting the highscore
leaderboard_http = HTTPRequest.new()
add_child(leaderboard_http)
leaderboard_http.connect("request_completed", self, "_on_leaderboard_request_completed")
# Send request
leaderboard_http.request(url, headers, true, HTTPClient.METHOD_GET, "")
func _on_leaderboard_request_completed(result, response_code, headers, body):
var json = JSON.parse(body.get_string_from_utf8())
# Print data
print(json.result)
# Formatting as a leaderboard
var leaderboardFormatted = ""
for n in json.result.items.size():
leaderboardFormatted += str(json.result.items[n].rank)+str(". ")
leaderboardFormatted += str(json.result.items[n].player.id)+str(" - ")
leaderboardFormatted += str(json.result.items[n].score)+str("\n")
# Print the formatted leaderboard to the console
print(leaderboardFormatted)
# Clear node
leaderboard_http.queue_free()
func _upload_score(var score):
var data = { "score": str(score) }
var headers = ["Content-Type: application/json", "x-session-token:"+session_token]
submit_score_http = HTTPRequest.new()
add_child(submit_score_http)
submit_score_http.connect("request_completed", self, "_on_upload_score_request_completed")
# Send request
submit_score_http.request("https://api.lootlocker.io/game/leaderboards/"+leaderboard_key+"/submit", headers, true, HTTPClient.METHOD_POST, to_json(data))
# Print what we're sending, for debugging purposes:
print(data)
func _on_upload_score_request_completed(result, response_code, headers, body) :
var json = JSON.parse(body.get_string_from_utf8())
# Print data
print(json.result)
# Clear node
submit_score_http.queue_free()
@josephdevelops
Copy link

Any chance of getting this updated to godot 4?

@Infini-Creation
Copy link

@josephdevelops : here it is, with some little modifications here or there, unfortunately, markdown is really annoying and I don't bother making it looks good here (here is better) updated & tested with v4.1.stable.official [970459615]

`extends Node

Use this game API key if you want to test it with a functioning leaderboard

"987dbd0b9e5eb3749072acc47a210996eea9feb0"

var game_API_key = "your-game-API-key-here"
var development_mode = true
var leaderboard_key = "leaderboardKey"
var session_token = ""
var score = 0

HTTP Request node can only handle one call per node

var auth_http = HTTPRequest.new()
var leaderboard_http = HTTPRequest.new()
var submit_score_http = HTTPRequest.new()

func _ready():
_authentication_request()

func _process(_delta):
if(Input.is_action_just_pressed("ui_up")):
score += 1
print("CurrentScore:"+str(score))

if(Input.is_action_just_pressed("ui_down")):
	score -= 1
	print("CurrentScore:"+str(score))

# Upload score when pressing enter
if(Input.is_action_just_pressed("ui_accept")):
	_upload_score(score)

# Get score when pressing spacebar
if(Input.is_action_just_pressed("ui_select")):
	_get_leaderboards()

func _authentication_request():
var player_identifier : String
# Check if a player session has been saved
var player_session_exists = false
var file = FileAccess.open("user://LootLocker.data", FileAccess.READ)
if file != null:
player_identifier = file.get_as_text()
print("played ID="+player_identifier)
file.close()

if player_identifier != null and player_identifier.length() > 1:
	print("player session exists, id="+player_identifier)
	player_session_exists = true
	
## Convert data to json string:
var data = { "game_key": game_API_key, "game_version": "0.0.0.1", "development_mode": true }

# If a player session already exists, send with the player identifier
if(player_session_exists == true):
	data = { "game_key": game_API_key, "player_identifier":player_identifier, "game_version": "0.0.0.1", "development_mode": true }

# Add 'Content-Type' header:
var headers = ["Content-Type: application/json"]

# Create a HTTPRequest node for authentication
auth_http = HTTPRequest.new()
add_child(auth_http)
auth_http.request_completed.connect(_on_authentication_request_completed)

# Print what we're sending, for debugging purposes:
print(data)

auth_http.request("https://api.lootlocker.io/game/v2/session/guest", headers, HTTPClient.METHOD_POST, JSON.stringify(data))

func _on_authentication_request_completed(result, response_code, headers, body):
var json = JSON.parse_string(body.get_string_from_utf8())
print(json)

# Save player_identifier to file
var file = FileAccess.open("user://LootLocker.data", FileAccess.WRITE)
if file != null:
	print("file open for writing")
	if json.has("player_identifier"):
		print("store played id")
		file.store_string(json["player_identifier"])
		file.close()

		# Save session_token to memory
		print("session token="+json["session_token"])
		session_token = json["session_token"]
	else:
		if json.has("error"):
			print("Error: "+json["error"])


# Clear node
auth_http.queue_free()
# Get leaderboards
_get_leaderboards()

func _get_leaderboards():
print("Getting leaderboards")
var url = "https://api.lootlocker.io/game/leaderboards/"+leaderboard_key+"/list?count=10"
var headers = ["Content-Type: application/json", "x-session-token:"+session_token]

# Create a request node for getting the highscore
leaderboard_http = HTTPRequest.new()
add_child(leaderboard_http)
leaderboard_http.request_completed.connect(_on_leaderboard_request_completed)
# Send request
leaderboard_http.request(url, headers, HTTPClient.METHOD_GET, "")

func _on_leaderboard_request_completed(result, response_code, headers, body):
var json = JSON.parse_string(body.get_string_from_utf8())

print(json)
if json.has("error"):
	print("Error: "+json["error"])
else:
	# Formatting as a leaderboard
	var leaderboardFormatted = ""
	for n in json["items"].size():
		leaderboardFormatted += str(json["items"][n].rank)+str(". ")
		leaderboardFormatted += str(json["items"][n].player.id)+str(" - ")
		leaderboardFormatted += str(json["items"][n].score)
		if json["items"][n].metadata != null:
			print("add meta:"+json["items"][n].metadata)
			leaderboardFormatted += str(" - ")+json["items"][n].metadata
		leaderboardFormatted += str("\n")
	
	# Print the formatted leaderboard to the console
	print(leaderboardFormatted)
	
	# Clear node
	leaderboard_http.queue_free()

func _upload_score(score: int):
var data = { "score": str(score) }
var headers = ["Content-Type: application/json", "x-session-token:"+session_token]
submit_score_http = HTTPRequest.new()
add_child(submit_score_http)
submit_score_http.request_completed.connect(_on_upload_score_request_completed)

# Print what we're sending, for debugging purposes:
print(data)

submit_score_http.request("https://api.lootlocker.io/game/leaderboards/"+leaderboard_key+"/submit", headers, HTTPClient.METHOD_POST, JSON.stringify(data))

func _on_upload_score_request_completed(result, response_code, headers, body):
var json = JSON.parse_string(body.get_string_from_utf8())

# Print data
print("upload score result:"+str(json))

# Clear node
submit_score_http.queue_free()

`

@dudecon
Copy link

dudecon commented Dec 1, 2023

Any chance of getting this updated to godot 4?

I just got it working on Godot Engine v4.1.3
Can't figure out how to PR my fork, so for now my working code is here:
https://gist.github.com/dudecon/48105f960a55eccd77ab0517d15d079f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment