about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2023-04-13 14:50:27 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2023-04-13 14:50:27 -0400
commitb6b24b10c6fb056bfa297c6f3a6f29a9991f9fa1 (patch)
treeda3931cd6df500e63162ef71d561b553e2e96b22
parent92b1c91d7d40dbb5d301d896c542d03b4b374075 (diff)
downloadlingo-archipelago-b6b24b10c6fb056bfa297c6f3a6f29a9991f9fa1.tar.gz
lingo-archipelago-b6b24b10c6fb056bfa297c6f3a6f29a9991f9fa1.tar.bz2
lingo-archipelago-b6b24b10c6fb056bfa297c6f3a6f29a9991f9fa1.zip
Client authenticates now
-rw-r--r--Archipelago/client.gd47
-rw-r--r--Archipelago/vendor/LICENSE21
-rw-r--r--Archipelago/vendor/uuid.gd195
3 files changed, 263 insertions, 0 deletions
diff --git a/Archipelago/client.gd b/Archipelago/client.gd index 489ec70..62f4d71 100644 --- a/Archipelago/client.gd +++ b/Archipelago/client.gd
@@ -4,6 +4,8 @@ var ap_server = ""
4var ap_user = "" 4var ap_user = ""
5var ap_pass = "" 5var ap_pass = ""
6 6
7const ap_version = {"major": 0, "minor": 4, "build": 0, "class": "Version"}
8
7var _client = WebSocketClient.new() 9var _client = WebSocketClient.new()
8var _last_state = WebSocketPeer.STATE_CLOSED 10var _last_state = WebSocketPeer.STATE_CLOSED
9var _should_process = false 11var _should_process = false
@@ -12,6 +14,15 @@ var _datapackage_checksum = ""
12var _item_name_to_id = {} 14var _item_name_to_id = {}
13var _location_name_to_id = {} 15var _location_name_to_id = {}
14 16
17const uuid_util = preload("user://maps/Archipelago/vendor/uuid.gd")
18
19var _authenticated = false
20var _team = 0
21var _slot = 0
22var _players = []
23var _checked_locations = []
24var _slot_data = {}
25
15 26
16func _init(): 27func _init():
17 global._print("Instantiated APClient") 28 global._print("Instantiated APClient")
@@ -47,6 +58,7 @@ func _ready():
47func _closed(was_clean = false): 58func _closed(was_clean = false):
48 global._print("Closed, clean: " + was_clean) 59 global._print("Closed, clean: " + was_clean)
49 _should_process = false 60 _should_process = false
61 _authenticated = false
50 62
51 63
52func _connected(_proto = ""): 64func _connected(_proto = ""):
@@ -69,6 +81,9 @@ func _on_data():
69 if message["datapackage_checksums"].has("Lingo"): 81 if message["datapackage_checksums"].has("Lingo"):
70 if _datapackage_checksum != message["datapackage_checksums"]["Lingo"]: 82 if _datapackage_checksum != message["datapackage_checksums"]["Lingo"]:
71 requestDatapackage() 83 requestDatapackage()
84 else:
85 connectToRoom()
86
72 elif cmd == "DataPackage": 87 elif cmd == "DataPackage":
73 if message["data"]["games"].has("Lingo"): 88 if message["data"]["games"].has("Lingo"):
74 var lingo_pkg = message["data"]["games"]["Lingo"] 89 var lingo_pkg = message["data"]["games"]["Lingo"]
@@ -77,6 +92,20 @@ func _on_data():
77 _location_name_to_id = lingo_pkg["location_name_to_id"] 92 _location_name_to_id = lingo_pkg["location_name_to_id"]
78 saveSettings() 93 saveSettings()
79 94
95 connectToRoom()
96
97 elif cmd == "Connected":
98 _authenticated = true
99 _team = message["team"]
100 _slot = message["slot"]
101 _players = message["players"]
102 _checked_locations = message["checked_locations"]
103 _slot_data = message["slot_data"]
104
105 elif cmd == "ConnectionRefused":
106 global._print("Connection to AP refused")
107 global._print(message)
108
80 109
81func _process(_delta): 110func _process(_delta):
82 if _should_process: 111 if _should_process:
@@ -119,3 +148,21 @@ func sendMessage(msg):
119 148
120func requestDatapackage(): 149func requestDatapackage():
121 sendMessage([{"cmd": "GetDataPackage", "games": ["Lingo"]}]) 150 sendMessage([{"cmd": "GetDataPackage", "games": ["Lingo"]}])
151
152
153func connectToRoom():
154 sendMessage(
155 [
156 {
157 "cmd": "Connect",
158 "password": ap_pass,
159 "game": "Lingo",
160 "name": ap_user,
161 "uuid": uuid_util.v4(),
162 "version": ap_version,
163 "items_handling": 0b111, # always receive our items
164 "tags": [],
165 "slot_data": true
166 }
167 ]
168 )
diff --git a/Archipelago/vendor/LICENSE b/Archipelago/vendor/LICENSE new file mode 100644 index 0000000..115ba15 --- /dev/null +++ b/Archipelago/vendor/LICENSE
@@ -0,0 +1,21 @@
1MIT License
2
3Copyright (c) 2023 Xavier Sellier
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in all
13copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21SOFTWARE. \ No newline at end of file
diff --git a/Archipelago/vendor/uuid.gd b/Archipelago/vendor/uuid.gd new file mode 100644 index 0000000..b63fa04 --- /dev/null +++ b/Archipelago/vendor/uuid.gd
@@ -0,0 +1,195 @@
1# Note: The code might not be as pretty it could be, since it's written
2# in a way that maximizes performance. Methods are inlined and loops are avoided.
3extends Node
4
5const BYTE_MASK: int = 0b11111111
6
7
8static func uuidbin():
9 randomize()
10 # 16 random bytes with the bytes on index 6 and 8 modified
11 return [
12 randi() & BYTE_MASK,
13 randi() & BYTE_MASK,
14 randi() & BYTE_MASK,
15 randi() & BYTE_MASK,
16 randi() & BYTE_MASK,
17 randi() & BYTE_MASK,
18 ((randi() & BYTE_MASK) & 0x0f) | 0x40,
19 randi() & BYTE_MASK,
20 ((randi() & BYTE_MASK) & 0x3f) | 0x80,
21 randi() & BYTE_MASK,
22 randi() & BYTE_MASK,
23 randi() & BYTE_MASK,
24 randi() & BYTE_MASK,
25 randi() & BYTE_MASK,
26 randi() & BYTE_MASK,
27 randi() & BYTE_MASK,
28 ]
29
30
31static func uuidbinrng(rng: RandomNumberGenerator):
32 rng.randomize()
33 return [
34 rng.randi() & BYTE_MASK,
35 rng.randi() & BYTE_MASK,
36 rng.randi() & BYTE_MASK,
37 rng.randi() & BYTE_MASK,
38 rng.randi() & BYTE_MASK,
39 rng.randi() & BYTE_MASK,
40 ((rng.randi() & BYTE_MASK) & 0x0f) | 0x40,
41 rng.randi() & BYTE_MASK,
42 ((rng.randi() & BYTE_MASK) & 0x3f) | 0x80,
43 rng.randi() & BYTE_MASK,
44 rng.randi() & BYTE_MASK,
45 rng.randi() & BYTE_MASK,
46 rng.randi() & BYTE_MASK,
47 rng.randi() & BYTE_MASK,
48 rng.randi() & BYTE_MASK,
49 rng.randi() & BYTE_MASK,
50 ]
51
52
53static func v4():
54 # 16 random bytes with the bytes on index 6 and 8 modified
55 var b = uuidbin()
56
57 return (
58 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
59 % [
60 # low
61 b[0],
62 b[1],
63 b[2],
64 b[3],
65 # mid
66 b[4],
67 b[5],
68 # hi
69 b[6],
70 b[7],
71 # clock
72 b[8],
73 b[9],
74 # clock
75 b[10],
76 b[11],
77 b[12],
78 b[13],
79 b[14],
80 b[15]
81 ]
82 )
83
84
85static func v4_rng(rng: RandomNumberGenerator):
86 # 16 random bytes with the bytes on index 6 and 8 modified
87 var b = uuidbinrng(rng)
88
89 return (
90 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
91 % [
92 # low
93 b[0],
94 b[1],
95 b[2],
96 b[3],
97 # mid
98 b[4],
99 b[5],
100 # hi
101 b[6],
102 b[7],
103 # clock
104 b[8],
105 b[9],
106 # clock
107 b[10],
108 b[11],
109 b[12],
110 b[13],
111 b[14],
112 b[15]
113 ]
114 )
115
116
117var _uuid: Array
118
119
120func _init(rng := RandomNumberGenerator.new()) -> void:
121 _uuid = uuidbinrng(rng)
122
123
124func as_array() -> Array:
125 return _uuid.duplicate()
126
127
128func as_dict(big_endian := true) -> Dictionary:
129 if big_endian:
130 return {
131 "low": (_uuid[0] << 24) + (_uuid[1] << 16) + (_uuid[2] << 8) + _uuid[3],
132 "mid": (_uuid[4] << 8) + _uuid[5],
133 "hi": (_uuid[6] << 8) + _uuid[7],
134 "clock": (_uuid[8] << 8) + _uuid[9],
135 "node":
136 (
137 (_uuid[10] << 40)
138 + (_uuid[11] << 32)
139 + (_uuid[12] << 24)
140 + (_uuid[13] << 16)
141 + (_uuid[14] << 8)
142 + _uuid[15]
143 )
144 }
145 else:
146 return {
147 "low": _uuid[0] + (_uuid[1] << 8) + (_uuid[2] << 16) + (_uuid[3] << 24),
148 "mid": _uuid[4] + (_uuid[5] << 8),
149 "hi": _uuid[6] + (_uuid[7] << 8),
150 "clock": _uuid[8] + (_uuid[9] << 8),
151 "node":
152 (
153 _uuid[10]
154 + (_uuid[11] << 8)
155 + (_uuid[12] << 16)
156 + (_uuid[13] << 24)
157 + (_uuid[14] << 32)
158 + (_uuid[15] << 40)
159 )
160 }
161
162
163func as_string() -> String:
164 return (
165 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
166 % [
167 # low
168 _uuid[0],
169 _uuid[1],
170 _uuid[2],
171 _uuid[3],
172 # mid
173 _uuid[4],
174 _uuid[5],
175 # hi
176 _uuid[6],
177 _uuid[7],
178 # clock
179 _uuid[8],
180 _uuid[9],
181 # node
182 _uuid[10],
183 _uuid[11],
184 _uuid[12],
185 _uuid[13],
186 _uuid[14],
187 _uuid[15]
188 ]
189 )
190
191
192func is_equal(other) -> bool:
193 # Godot Engine compares Array recursively
194 # There's no need for custom comparison here.
195 return _uuid == other._uuid