newgrounds login system :)

This commit is contained in:
Haze Weathers 2023-10-13 16:20:53 -04:00
parent a205fc3008
commit 644748463c
3 changed files with 215 additions and 4 deletions

View file

@ -2,10 +2,19 @@ extends Node
const GATEWAY_URI: String = "https://newgrounds.io/gateway_v3.php"
const SESSION_FILE: String = "user://ngio.pr"
const EMPTY_SESSION: Dictionary = {
expired = true,
id = "",
passport_url = "",
remember = false,
user = null,
}
var app_id: String = "" # app id on newgrounds
var aes_key := PoolByteArray([]) # AES-128/Base64 encryption key
var session: Dictionary = EMPTY_SESSION
var keys_loaded: bool = false # whether id and key have been loaded from ini file
var http := HTTPRequest.new() # http request node
@ -27,6 +36,7 @@ func _ready() -> void:
if app_id == "":
push_error("Failed to load ngio data. Will not be able to access scoreboards.")
keys_loaded = false
return
else:
keys_loaded = true
@ -41,15 +51,77 @@ func _ready() -> void:
# initialize rng for encryption
rng.randomize()
# try to load saved session
if not yield(load_saved_session(), "completed"):
yield(start_new_session(), "completed")
func _test_http() -> void:
print(yield(request_execute("Gateway.getDatetime"), "completed"))
## attempts to load a saved newgrounds.io session
## returns true if the loaded session is valid
func load_saved_session() -> bool:
var ini = ConfigFile.new()
var err = ini.load(SESSION_FILE)
# fail if can't load ngio.pr
if err != OK:
session = EMPTY_SESSION
session.id = ini.get_value("ngio", "session_id", "")
# check session is valid
var response = yield(request_execute("App.checkSession"), "completed")
if has_result(response):
var result = response.result
if result.data.success and not result.data.session.expired:
session = result.data.session
return true
session = EMPTY_SESSION
ini.set_value("ngio", "session_id", "")
ini.save(SESSION_FILE)
return false
## start new session
func start_new_session() -> bool:
var response = yield(request_execute("App.startSession"), "completed")
if has_result(response):
var result = response.result
if result.data.success and not result.data.session.expired:
session = result.data.session
return true
session = EMPTY_SESSION
return false
## repeatedly checks session until it is logged in or cancelled
func passport_check() -> bool:
# attempt for maximum of 5 minutes
var attempts = 60
while attempts > 0:
attempts -= 1
yield(get_tree().create_timer(5.0), "timeout")
var response = yield(request_execute("App.checkSession"), "completed")
if has_result(response):
var result = response.result
if result.data.success:
if result.data.session.user:
session = result.data.session
if session.remember:
var ini = ConfigFile.new()
ini.set_value("ngio", "session_id", session.id)
ini.save(SESSION_FILE)
return true
else:
return false
return false
## checks if a response is valid and succeeded
func has_result(response: Dictionary) -> bool:
return "success" in response and response.success
## requests the provided component be executed, do not call async :/
# may call with either single or multiple components
func request_execute(component: String, parameters: Dictionary = {}, session_id: String = "", echo: String = "", encrypt: bool = false) -> Dictionary:
func request_execute(component: String, parameters: Dictionary = {}, echo: String = "", encrypt: bool = false) -> Dictionary:
# build request headers
var headers = [
"Content-Type: application/x-www-form-urlencoded",
@ -88,7 +160,7 @@ func request_execute(component: String, parameters: Dictionary = {}, session_id:
# compose request body
var request = {
app_id = app_id,
session_id = session_id,
session_id = session.id,
execute = execute,
}
var body = "input=" + to_json(request).percent_encode()
@ -98,6 +170,7 @@ func request_execute(component: String, parameters: Dictionary = {}, session_id:
yield(http, "request_completed")
return _response
## called when the HTTPRequest gets a responce
func _http_request_completed(result: int, response_code: int, headers: PoolStringArray, body: PoolByteArray) -> void:
if response_code == 200: