-
-
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 : 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()
`
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
@samtse: you got this error because most likely the request return no result at all, thus json.result is null.
Your screenshot unfortunately doesn't show the variables so it needs to be confirmed.
Remember when working with network: ALWAYS, always, check results, all the items from top to bottom, here for instance, json not null, then result not null AND a proper array, and so on...
The code you've used is not actually production ready as it is just a sample which need to be completed to work in ALL possible cases.

Any chance of getting this updated to godot 4?