forked from team-sg/hero-mark-2
newgrounds login system :)
This commit is contained in:
parent
a205fc3008
commit
644748463c
3 changed files with 215 additions and 4 deletions
|
@ -2,10 +2,19 @@ extends Node
|
||||||
|
|
||||||
|
|
||||||
const GATEWAY_URI: String = "https://newgrounds.io/gateway_v3.php"
|
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 app_id: String = "" # app id on newgrounds
|
||||||
var aes_key := PoolByteArray([]) # AES-128/Base64 encryption key
|
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 keys_loaded: bool = false # whether id and key have been loaded from ini file
|
||||||
|
|
||||||
var http := HTTPRequest.new() # http request node
|
var http := HTTPRequest.new() # http request node
|
||||||
|
@ -27,6 +36,7 @@ func _ready() -> void:
|
||||||
if app_id == "":
|
if app_id == "":
|
||||||
push_error("Failed to load ngio data. Will not be able to access scoreboards.")
|
push_error("Failed to load ngio data. Will not be able to access scoreboards.")
|
||||||
keys_loaded = false
|
keys_loaded = false
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
keys_loaded = true
|
keys_loaded = true
|
||||||
|
|
||||||
|
@ -41,15 +51,77 @@ func _ready() -> void:
|
||||||
|
|
||||||
# initialize rng for encryption
|
# initialize rng for encryption
|
||||||
rng.randomize()
|
rng.randomize()
|
||||||
|
|
||||||
|
# try to load saved session
|
||||||
|
if not yield(load_saved_session(), "completed"):
|
||||||
|
yield(start_new_session(), "completed")
|
||||||
|
|
||||||
|
|
||||||
func _test_http() -> void:
|
## attempts to load a saved newgrounds.io session
|
||||||
print(yield(request_execute("Gateway.getDatetime"), "completed"))
|
## 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 :/
|
## requests the provided component be executed, do not call async :/
|
||||||
# may call with either single or multiple components
|
# 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
|
# build request headers
|
||||||
var headers = [
|
var headers = [
|
||||||
"Content-Type: application/x-www-form-urlencoded",
|
"Content-Type: application/x-www-form-urlencoded",
|
||||||
|
@ -88,7 +160,7 @@ func request_execute(component: String, parameters: Dictionary = {}, session_id:
|
||||||
# compose request body
|
# compose request body
|
||||||
var request = {
|
var request = {
|
||||||
app_id = app_id,
|
app_id = app_id,
|
||||||
session_id = session_id,
|
session_id = session.id,
|
||||||
execute = execute,
|
execute = execute,
|
||||||
}
|
}
|
||||||
var body = "input=" + to_json(request).percent_encode()
|
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")
|
yield(http, "request_completed")
|
||||||
return _response
|
return _response
|
||||||
|
|
||||||
|
|
||||||
## called when the HTTPRequest gets a responce
|
## called when the HTTPRequest gets a responce
|
||||||
func _http_request_completed(result: int, response_code: int, headers: PoolStringArray, body: PoolByteArray) -> void:
|
func _http_request_completed(result: int, response_code: int, headers: PoolStringArray, body: PoolByteArray) -> void:
|
||||||
if response_code == 200:
|
if response_code == 200:
|
||||||
|
|
43
menus/newgrounds_login.gd
Normal file
43
menus/newgrounds_login.gd
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
onready var tab_container: TabContainer = $"%TabContainer"
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
visible = false
|
||||||
|
Fade.fade_out(0.4)
|
||||||
|
yield(Fade, "fade_finished")
|
||||||
|
visible = true
|
||||||
|
yield(get_tree(), "idle_frame")
|
||||||
|
grab_focus()
|
||||||
|
Fade.fade_in(0.4)
|
||||||
|
if not Ngio.keys_loaded:
|
||||||
|
tab_container.current_tab = 2
|
||||||
|
return
|
||||||
|
if Ngio.session.user == null and not Ngio.session.passport_url.empty():
|
||||||
|
var passport_url = Ngio.session.passport_url
|
||||||
|
# try to open in browser
|
||||||
|
OS.shell_open(passport_url)
|
||||||
|
# try to copy to clipboard
|
||||||
|
OS.clipboard = passport_url
|
||||||
|
if OS.has_clipboard():
|
||||||
|
$"%Clipboard".modulate.a = 1.0
|
||||||
|
_await_result()
|
||||||
|
elif Ngio.session.user != null:
|
||||||
|
tab_container.current_tab = 1
|
||||||
|
else:
|
||||||
|
tab_container.current_tab = 2
|
||||||
|
|
||||||
|
func _gui_input(event: InputEvent) -> void:
|
||||||
|
if event.is_action_pressed("ui_cancel"):
|
||||||
|
if tab_container.current_tab == 0:
|
||||||
|
Ngio.request_execute("App.endSession")
|
||||||
|
queue_free()
|
||||||
|
elif event.is_action_pressed("ui_accept") and tab_container.current_tab != 0:
|
||||||
|
queue_free()
|
||||||
|
|
||||||
|
func _await_result() -> void:
|
||||||
|
var success = yield(Ngio.passport_check(), "completed")
|
||||||
|
if success:
|
||||||
|
tab_container.current_tab = 1
|
||||||
|
else:
|
||||||
|
tab_container.current_tab = 2
|
95
menus/newgrounds_login.tscn
Normal file
95
menus/newgrounds_login.tscn
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
[gd_scene load_steps=8 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://shaders/ska_plane.gdshader" type="Shader" id=1]
|
||||||
|
[ext_resource path="res://menus/newgrounds_login.gd" type="Script" id=2]
|
||||||
|
[ext_resource path="res://ui/theme.tres" type="Theme" id=3]
|
||||||
|
[ext_resource path="res://ui/2ndpuberty_scholar_outline.fnt" type="BitmapFont" id=4]
|
||||||
|
[ext_resource path="res://shaders/wibble_wobble.gdshader" type="Shader" id=5]
|
||||||
|
|
||||||
|
[sub_resource type="ShaderMaterial" id=1]
|
||||||
|
shader = ExtResource( 1 )
|
||||||
|
shader_param/color_1 = Color( 1, 0.709804, 0.054902, 1 )
|
||||||
|
shader_param/color_2 = Color( 1, 0.945098, 0.478431, 1 )
|
||||||
|
shader_param/checker_size = Vector2( 24, 12 )
|
||||||
|
shader_param/pan_speed = Vector2( 0, 0 )
|
||||||
|
shader_param/cycle_speed = Vector2( 8, -8 )
|
||||||
|
shader_param/cycle_alternation = Vector2( 0, 1 )
|
||||||
|
shader_param/uv_transform = Transform2D( 1, 1, 1, 1, 0, 0 )
|
||||||
|
|
||||||
|
[sub_resource type="ShaderMaterial" id=2]
|
||||||
|
shader = ExtResource( 5 )
|
||||||
|
shader_param/speed = Vector2( 8, 4 )
|
||||||
|
shader_param/ammount = Vector2( 12, 24 )
|
||||||
|
shader_param/offset = Vector2( 0, 0 )
|
||||||
|
shader_param/delay = Vector2( 0, 0 )
|
||||||
|
|
||||||
|
[node name="NewgroundsLogin" type="Control"]
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
focus_mode = 2
|
||||||
|
script = ExtResource( 2 )
|
||||||
|
|
||||||
|
[node name="Background" type="ColorRect" parent="."]
|
||||||
|
material = SubResource( 1 )
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
|
||||||
|
[node name="CenterContainer" type="CenterContainer" parent="."]
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
theme = ExtResource( 3 )
|
||||||
|
|
||||||
|
[node name="TabContainer" type="TabContainer" parent="CenterContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_left = 23.0
|
||||||
|
margin_top = 43.0
|
||||||
|
margin_right = 233.0
|
||||||
|
margin_bottom = 148.0
|
||||||
|
tabs_visible = false
|
||||||
|
|
||||||
|
[node name="Loading" type="VBoxContainer" parent="CenterContainer/TabContainer"]
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
rect_pivot_offset = Vector2( -174, -77 )
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="CenterContainer/TabContainer/Loading"]
|
||||||
|
margin_right = 210.0
|
||||||
|
margin_bottom = 10.0
|
||||||
|
custom_fonts/font = ExtResource( 4 )
|
||||||
|
text = "Log into newgrounds in browser"
|
||||||
|
align = 1
|
||||||
|
|
||||||
|
[node name="LoadingGraphic" type="Label" parent="CenterContainer/TabContainer/Loading"]
|
||||||
|
material = SubResource( 2 )
|
||||||
|
margin_top = 14.0
|
||||||
|
margin_right = 210.0
|
||||||
|
margin_bottom = 78.0
|
||||||
|
rect_min_size = Vector2( 0, 64 )
|
||||||
|
text = "§"
|
||||||
|
align = 1
|
||||||
|
valign = 1
|
||||||
|
|
||||||
|
[node name="Clipboard" type="Label" parent="CenterContainer/TabContainer/Loading"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
modulate = Color( 1, 1, 1, 0 )
|
||||||
|
margin_top = 82.0
|
||||||
|
margin_right = 210.0
|
||||||
|
margin_bottom = 105.0
|
||||||
|
custom_fonts/font = ExtResource( 4 )
|
||||||
|
text = "If browser didn't open,
|
||||||
|
url copied to clipboard"
|
||||||
|
align = 1
|
||||||
|
|
||||||
|
[node name="Success" type="Label" parent="CenterContainer/TabContainer"]
|
||||||
|
visible = false
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
custom_fonts/font = ExtResource( 4 )
|
||||||
|
text = "Success!"
|
||||||
|
|
||||||
|
[node name="Failure" type="Label" parent="CenterContainer/TabContainer"]
|
||||||
|
visible = false
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
custom_fonts/font = ExtResource( 4 )
|
||||||
|
text = "Failure :("
|
Loading…
Add table
Add a link
Reference in a new issue