OverviewFilesCommitsIssuesDocsReleasesPeers

hypergodot commits / 4d9810f

Progress on adding profiles to MultiplayerDemo
4d9810f062b77f1e05eb51cb04e9babcc4206681
by mauve <ranger@mauve.moe> · 2021-10-04T02:54:45.000Z

Changed files (11) +464 -5

project.godot +6 -0
……@@ -34,6 +34,11 @@ _global_script_classes=[ {
3434"language": "GDScript",
3535"path": "res://src/HyperRequest/HyperRequest.gd"
3636}, {
37"base": "Node",
38"class": "HyperUploader",
39"language": "GDScript",
40"path": "res://src/HyperRequest/HyperUploader.gd"
41}, {
3742"base": "Reference",
3843"class": "WAT",
3944"language": "GDScript",
……@@ -50,6 +55,7 @@ _global_script_class_icons={
5055"HyperGateway": "",
5156"HyperGossip": "",
5257"HyperRequest": "",
58"HyperUploader": "",
5359"WAT": "",
5460"WATTest": ""
5561}
src/HTTPEventSource.gd +3 -1
……@@ -135,7 +135,9 @@ func _runRequest(params):
135135 call_deferred("emit_signal", "response_finished")
136136pass
137137
138
139138func _emitEvent(params):
140139 emit_signal("event", params.data, params.name, params.id)
141140 pass
141
142func _exit_tree():
143 cancel_request()
src/HyperGateway/HyperGateway.gd +4 -2
……@@ -33,10 +33,12 @@ var downloadFileRequest = HTTPRequest.new()
3333var downloadingVersion = null
3434var downloadThread = null
3535
36func _exit_tree():
37 cleanupGateway()
38
3639func _notification(what):
3740 if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST:
3841 cleanupGateway()
39 pass
4042
4143# Called when the node enters the scene tree for the first time.
4244func _ready():
……@@ -61,7 +63,7 @@ func cleanupGateway():
6163 print('Gateway already closed ' + str(processPID))
6264 return
6365 print('Cleaning up gateway ' + str(processPID))
64 OS.kill(processPID)
66 return OS.kill(processPID)
6567
6668func setupGateway():
6769 emit_signal("starting_gateway")
src/HyperLoad/HyperLoad.tscn +1 -1
……@@ -87,5 +87,5 @@ __meta__ = {
8787[connection signal="started_gateway" from="HyperGateway" to="StatusLabel" method="setGatewayLoaded"]
8888[connection signal="starting_gateway" from="HyperGateway" to="StatusLabel" method="setGatewayLoading"]
8989[connection signal="loading_data" from="HyperGateway/HyperRequest" to="StatusLabel" method="setLoading"]
90[connection signal="request_completed" from="HyperGateway/HyperRequest" to="StatusLabel" method="_on_HyperLoad_request_completed"]
9190[connection signal="request_completed" from="HyperGateway/HyperRequest" to="ScrollContainer/Output" method="_on_HyperLoad_request_completed"]
91[connection signal="request_completed" from="HyperGateway/HyperRequest" to="StatusLabel" method="_on_HyperLoad_request_completed"]
src/HyperRequest/HyperRequest.gd +13 -0
……@@ -19,3 +19,16 @@ func request(
1919 emit_signal('loading_data', url)
2020
2121 return .request(toLoad, custom_headers, ssl_validate_domain, method, request_data)
22
23# Only available in 3.3
24#func request_raw(
25# url: String,
26# custom_headers : PoolStringArray=PoolStringArray(),
27# ssl_validate_domain: bool =true,
28# method=0,
29# request_data_raw: PoolByteArray=PoolByteArray( )
30#):
31# assert(url.begins_with("hyper://"))
32# var toLoad = url.replace("hyper://", serverPrefix)
33#
34# return .request_raw(toLoad, custom_headers, ssl_validate_domain, method, request_data_raw)
src/HyperRequest/HyperUploader.gd +132 -0
……@@ -0,0 +1,132 @@
1extends Node
2
3class_name HyperUploader
4
5# Final URL of upload along with status code
6signal uploaded(url, status)
7signal error(e)
8
9var URLParser = preload("res://src/utils/URLParser.gd")
10
11export var serverPrefix = "http://127.0.0.1:4973/hyper/"
12
13# TODO: Actually use threads
14# export var use_threads = true
15
16var request: HTTPClient = HTTPClient.new()
17var parser = URLParser.new()
18
19func cancel_request():
20 request.close()
21
22func _connect_to_gateway():
23 var parsed = parser.parse(serverPrefix)
24 var port = parsed.port
25 var host = parsed.host
26 var use_ssl = parsed.ssl
27
28 print('Connecting to gateway for upload: ', host, ":", port)
29 var err = request.connect_to_host(host, port, use_ssl, true)
30
31 if err != OK:
32 return err
33
34 # Wait to establish a connection to the host
35 while request.get_status() == HTTPClient.STATUS_CONNECTING or request.get_status() == HTTPClient.STATUS_RESOLVING:
36 err = request.poll()
37 if err != OK:
38 printerr('Unable to connect to EventSource')
39 return err
40 OS.delay_msec(100)
41
42 return OK
43
44func upload_file(url, filePath):
45 # Connect to gateway
46 _connect_to_gateway()
47 # Open file
48 var file = File.new()
49 var err = file.open(filePath, File.READ)
50
51 if err != OK:
52 printerr('Unable to open file for upload')
53 return _emit_err(err)
54
55 var parsedServer = parser.parse(serverPrefix)
56 var parsedURL = parser.parse(url)
57
58 var final_url = parsedServer.path + parsedURL.host + parsedURL.path
59
60 print('PUT ', final_url, " <- ", filePath)
61 err = _perform_file_upload(final_url, file)
62
63 file.close()
64
65 if err != OK:
66 printerr("Unable to make file upload request")
67 return _emit_err(err)
68
69 err = _wait_for_finish()
70
71 if err != OK:
72 return _emit_err(err)
73
74 var statusCode = request.get_response_code()
75 var headers = request.get_response_headers()
76
77 var regex = RegEx.new()
78 regex.compile("link: <(.+)>")
79 var resolve_url = ''
80
81 for header in headers:
82 var result = regex.search(header)
83 if !result: continue
84 resolve_url = result.get_string(1)
85
86 emit_signal('uploaded', resolve_url, statusCode)
87
88 return OK
89
90func _perform_file_upload(absolute_url, file: File):
91 var length = file.get_len()
92 var buffer = file.get_buffer(length)
93 var headers = []
94
95 return request.request_raw(HTTPClient.METHOD_PUT, absolute_url, headers, buffer)
96
97func _wait_for_finish():
98 print('Waiting to finish upload')
99 # Wait for request to get processed and to get the body
100 while (request.get_status() == HTTPClient.STATUS_REQUESTING):
101 var err = request.poll()
102 if err != OK:
103 printerr('Error getting request from upload')
104 return err
105 OS.delay_msec(100)
106
107 if !request.has_response():
108 printerr('No Response from upload')
109 request.close()
110 return ERR_CANT_OPEN
111
112 print("Loading upload response")
113
114 while request.get_status() == HTTPClient.STATUS_BODY:
115 var err = request.poll()
116 if err != OK:
117 printerr('Error loading body from upload')
118 return err
119 print(request.read_response_body_chunk().get_string_from_utf8())
120 OS.delay_usec(100)
121
122 print('Finished loading upload response')
123
124 return OK
125
126func _exit_tree():
127 cancel_request()
128
129func _emit_err(e):
130 printerr('Error uploadng file: ', e)
131 emit_signal('error', e)
132 return e
src/MultiplayerDemo/LoadProfile.gd +164 -0
……@@ -0,0 +1,164 @@
1extends "res://src/ResizeRoot.gd"
2
3signal profile_ready(url)
4
5export var profile_URL: String = 'hyper://flyballs-profile/'
6export var profile_file: String = 'profile.json'
7export var cache_folder: String = 'user://hyper-file-cache/'
8
9var picture_name = ""
10var picture_path = ""
11
12func _ready():
13 var dir = Directory.new()
14 var err = dir.make_dir_recursive(cache_folder)
15 if err != OK:
16 printerr("Unable to create cache directory ", err)
17
18func hide_loader():
19 $Loader.hide()
20 $Form.show()
21
22func show_loader():
23 $Loader.show()
24 $Form.hide()
25
26func load_url():
27 var url_record = profile_URL + '.well-known/hyper'
28 $LoadURLRequest.request(url_record)
29
30func update_profile(data):
31 var json = JSON.print(data)
32 var info_url = profile_URL + profile_file
33
34 $UpdateProfileRequest.request(info_url, [], true, HTTPClient.METHOD_PUT, json)
35
36func get_username():
37 return $Form/UsernameInput.text
38
39func load_profile():
40 var info_url = profile_URL + profile_file
41 $ListInfoRequest.request(info_url)
42
43func load_image(image: String):
44 print('Loading image')
45 show_loader()
46 var file_name = image.get_file()
47 picture_path = cache_folder + file_name
48 # TODO: Save file_path somewhere?
49 $LoadImageRequest.download_file = picture_path
50 $LoadImageRequest.request(image)
51
52func _on_ImageChooser_pressed():
53 $FileDialog.popup()
54
55func _on_FileDialog_file_selected(path: String):
56 show_loader()
57
58 picture_name = path.get_file()
59 var picture_url = profile_URL + picture_name
60
61 $HyperUploader.upload_file(picture_url, path)
62
63func _on_HyperGateway_started_gateway(_pid):
64 load_profile()
65
66func _on_ListInfoRequest_request_completed(_result, response_code, _headers, body):
67 if response_code != 200:
68 printerr('Cannot load existing profile info: ', response_code)
69 hide_loader()
70 return
71
72 var parsed = JSON.parse(body.get_string_from_utf8())
73 if parsed.error != OK:
74 printerr(parsed.error_string)
75 hide_loader()
76 return
77
78 $Form/StartButton.disabled = false
79
80 $Form/UsernameInput.text = parsed.result.username
81
82 var image = parsed.result.image
83 if image != null:
84 load_image(image)
85 else: hide_loader()
86
87func _on_HyperUploader_uploaded(url, response_code):
88 if response_code != 200:
89 printerr('Unable to upload file ')
90 hide_loader()
91 return
92
93 if !url || (url.length() == 0):
94 printerr("Unable to load Link header for image.")
95 hide_loader()
96 return
97
98 update_profile({
99 "username": get_username(),
100 "image": url
101 })
102
103 load_image(url)
104
105func _on_UploadFileRequest_request_completed(_result, response_code, headers, body):
106 print('Uploaded picture')
107 if response_code != 200:
108 printerr('Unable to upload: ', body.get_string_from_utf8())
109 return
110
111 var regex = RegEx.new()
112 regex.compile("link: <(.+)>")
113 var final_url = ''
114
115 for header in headers:
116 var result = regex.search(header)
117 final_url = result.get_string(1)
118
119 if !final_url || (final_url.size() == 0):
120 printerr("Unable to load Link header for image. ", headers)
121 hide_loader()
122 return
123
124 update_profile({
125 "username": get_username(),
126 "image": final_url
127 })
128
129func _on_LoadImageRequest_request_completed(result, response_code, _headers, body):
130 hide_loader()
131 if result != OK or response_code != 200:
132 printerr('Unable to load image: ', result, ": ", body.get_string_from_utf8())
133 return
134
135 print(result, ' Image got downloaded: ', picture_path)
136
137 var texture = ImageTexture.new()
138 var image = Image.new()
139 image.load(picture_path)
140 texture.create_from_image(image)
141 texture.set_size_override(Vector2(64, 64))
142
143 $Form/ImageChooser.icon = texture
144
145func _on_UpdateProfileRequest_request_completed(_result, _response_code, _headers, _body):
146 hide_loader()
147 $Form/StartButton.disabled = false
148
149func _on_StartButton_pressed():
150 show_loader()
151 load_url()
152
153func _on_LoadURLRequest_request_completed(result, response_code, _headers, body: PoolByteArray):
154 if result != OK or response_code != 200:
155 printerr('Unable to load final profile URL')
156 return
157
158 var lines = body.get_string_from_utf8()
159 var url = lines.split('\n')[0]
160 if !url.ends_with('/'):
161 url += '/'
162 print('Profile ready')
163 print(url)
164 emit_signal('profile_ready', url)
src/MultiplayerDemo/LoadProfile.tscn +108 -0
……@@ -0,0 +1,108 @@
1[gd_scene load_steps=5 format=2]
2
3[ext_resource path="res://src/MultiplayerDemo/LoadProfile.gd" type="Script" id=1]
4[ext_resource path="res://src/HyperGateway/HyperGateway.gd" type="Script" id=2]
5[ext_resource path="res://src/HyperRequest/HyperRequest.gd" type="Script" id=3]
6[ext_resource path="res://src/HyperRequest/HyperUploader.gd" type="Script" id=4]
7
8[node name="LoadProfile" type="VBoxContainer"]
9anchor_right = 1.0
10anchor_bottom = 1.0
11script = ExtResource( 1 )
12__meta__ = {
13"_edit_use_anchors_": false
14}
15
16[node name="Loader" type="CenterContainer" parent="."]
17margin_right = 666.0
18margin_bottom = 331.0
19size_flags_horizontal = 3
20size_flags_vertical = 3
21
22[node name="Label" type="Label" parent="Loader"]
23margin_left = 308.0
24margin_top = 158.0
25margin_right = 357.0
26margin_bottom = 172.0
27text = "Loading"
28
29[node name="Form" type="VBoxContainer" parent="."]
30margin_top = 335.0
31margin_right = 666.0
32margin_bottom = 666.0
33size_flags_vertical = 3
34
35[node name="UsernameLabel" type="Label" parent="Form"]
36margin_right = 666.0
37margin_bottom = 14.0
38text = "Username"
39
40[node name="UsernameInput" type="LineEdit" parent="Form"]
41margin_top = 18.0
42margin_right = 666.0
43margin_bottom = 42.0
44text = "Anon"
45
46[node name="PictureLabel" type="Label" parent="Form"]
47margin_top = 46.0
48margin_right = 666.0
49margin_bottom = 60.0
50text = "Picture"
51
52[node name="ImageChooser" type="Button" parent="Form"]
53margin_top = 64.0
54margin_right = 666.0
55margin_bottom = 84.0
56text = "Choose Image"
57
58[node name="StartButton" type="Button" parent="Form"]
59margin_top = 88.0
60margin_right = 666.0
61margin_bottom = 108.0
62disabled = true
63text = "Start"
64
65[node name="HyperGateway" type="Node" parent="."]
66script = ExtResource( 2 )
67
68[node name="UploadFileRequest" type="HTTPRequest" parent="."]
69script = ExtResource( 3 )
70
71[node name="ListInfoRequest" type="HTTPRequest" parent="."]
72script = ExtResource( 3 )
73
74[node name="LoadImageRequest" type="HTTPRequest" parent="."]
75script = ExtResource( 3 )
76
77[node name="LoadURLRequest" type="HTTPRequest" parent="."]
78script = ExtResource( 3 )
79
80[node name="UpdateProfileRequest" type="HTTPRequest" parent="."]
81script = ExtResource( 3 )
82
83[node name="HyperUploader" type="Node" parent="."]
84script = ExtResource( 4 )
85
86[node name="FileDialog" type="FileDialog" parent="."]
87margin_top = 536.0
88margin_right = 666.0
89margin_bottom = 666.0
90popup_exclusive = true
91window_title = "Open a File"
92resizable = true
93dialog_autowrap = true
94mode = 0
95access = 2
96current_dir = "/home/mauve/programming/godot/hypergodot"
97current_path = "/home/mauve/programming/godot/hypergodot/"
98
99[connection signal="pressed" from="Form/ImageChooser" to="." method="_on_ImageChooser_pressed"]
100[connection signal="pressed" from="Form/StartButton" to="." method="_on_StartButton_pressed"]
101[connection signal="started_gateway" from="HyperGateway" to="." method="_on_HyperGateway_started_gateway"]
102[connection signal="request_completed" from="UploadFileRequest" to="." method="_on_UploadFileRequest_request_completed"]
103[connection signal="request_completed" from="ListInfoRequest" to="." method="_on_ListInfoRequest_request_completed"]
104[connection signal="request_completed" from="LoadImageRequest" to="." method="_on_LoadImageRequest_request_completed"]
105[connection signal="request_completed" from="LoadURLRequest" to="." method="_on_LoadURLRequest_request_completed"]
106[connection signal="request_completed" from="UpdateProfileRequest" to="." method="_on_UpdateProfileRequest_request_completed"]
107[connection signal="uploaded" from="HyperUploader" to="." method="_on_HyperUploader_uploaded"]
108[connection signal="file_selected" from="FileDialog" to="." method="_on_FileDialog_file_selected"]
src/MultiplayerDemo/PlayerSprite.gd +31 -0
……@@ -1,6 +1,37 @@
11extends KinematicBody2D
22
3export var radius: float = 30 setget set_radius
4
5func set_texture(texture):
6 $Sprite.texture = texture
7 $Particles2D.texture = texture
8 set_radius(radius)
9
310func _on_VisibilityNotifier2D_screen_exited():
411 var viewport = get_viewport_rect().size
512 position.x = viewport.x / 2
613 position.y = viewport.y / 2
14
15func set_radius(radius):
16 _set_sprite_radius(radius)
17 _set_colission_radius(radius)
18 _set_visibility_radius(radius)
19
20func _set_sprite_radius(radius):
21 var sprite = $Sprite
22 var rect = sprite.get_rect()
23 var xCurrent = rect.size.x
24 var yCurrent = rect.size.y
25
26 var xScale = (radius * 2) / xCurrent
27 var yScale = (radius * 2) / yCurrent
28
29 sprite.scale.x = xScale
30 sprite.scale.y = yScale
31
32func _set_colission_radius(radius):
33 $CollisionShape2D.shape.radius = radius
34
35func _set_visibility_radius(radius):
36 var rect = Rect2(-radius, -radius, radius*2, radius*2)
37 $VisibilityNotifier2D.rect = rect
src/multiplayer/HyperGossip.gd +1 -0
……@@ -26,6 +26,7 @@ func _ready():
2626 add_child(broadcastRequest)
2727 broadcastRequest.connect("request_completed", self, "_on_broadcast_completed")
2828
29 add_child(eventSource)
2930 eventSource.connect("event", self, "_on_event")
3031 eventSource.connect("response_started", self, "_on_events_started")
3132
src/utils/URLParser.gd +1 -1
……@@ -17,7 +17,7 @@ func parse(url):
1717 var raw_host = parsed.get_string(2)
1818 var path = parsed.get_string(3)
1919 var host = raw_host
20 var port = DEFAULT_PORTS[protocol]
20 var port = DEFAULT_PORTS[protocol] if DEFAULT_PORTS.has(protocol) else 0
2121 var ssl = protocol == "https"
2222
2323 if ":" in raw_host: