+2
-3
.gitignore
+2
-3
.gitignore
+16
-1
Atproto/AtProtoSaveFactory.cs
+16
-1
Atproto/AtProtoSaveFactory.cs
···
13
13
.Named("AtProtoSave")
14
14
.Patching("res://Scenes/Singletons/UserSave/usersave.gdc")
15
15
.AddRule(new TransformationRuleBuilder()
16
+
.Named("ready_slot_condition")
17
+
.Matching(TransformationPatternFactory.CreateGdSnippetPattern("_load_save(last_loaded_slot)", 2))
18
+
.Do(Operation.ReplaceAll)
19
+
.With("""
20
+
var Atproto = $"/root/Atproto"
21
+
if last_loaded_slot != Atproto.ATPROTO_SLOT or Atproto.config.Autoload:
22
+
_load_save(last_loaded_slot)
23
+
else:
24
+
last_loaded_slot = -1
25
+
""", 2)
26
+
)
27
+
.AddRule(new TransformationRuleBuilder()
16
28
.Named("save_file")
17
29
.Matching(TransformationPatternFactory.CreateGdSnippetPattern(
18
30
"\"locked_refs\": PlayerData.locked_refs, \n\t}\n", 2))
19
31
.Do(Operation.Append)
20
-
.With("var atproto = $\"/root/Atproto\"\nif atproto.AtProtoClient.connected() && atproto.save_loaded != null:\n\tatproto.AtProtoClient.save_file()\n", 1)).Build();
32
+
.With("var atproto = $\"/root/Atproto\"\nif atproto.can_save_to_atproto():\n\tatproto.AtProtoClient.save_file()\n", 1)
33
+
)
34
+
35
+
.Build();
21
36
}
22
37
}
+1
-5
Atproto/Atproto.csproj
+1
-5
Atproto/Atproto.csproj
···
4
4
<ImplicitUsings>enable</ImplicitUsings>
5
5
<Nullable>enable</Nullable>
6
6
<AssemblySearchPaths>$(AssemblySearchPaths);$(GDWeavePath)/core</AssemblySearchPaths>
7
-
<Version>1.0.1.0</Version>
7
+
<Version>1.0.2.0</Version>
8
8
<RootNamespace>Atproto</RootNamespace>
9
9
</PropertyGroup>
10
10
11
11
<ItemGroup>
12
12
<Reference Include="GDWeave" Private="false"/>
13
13
<Reference Include="Serilog" Private="false"/>
14
-
</ItemGroup>
15
-
16
-
<ItemGroup>
17
-
<None Include="manifest.json" CopyToOutputDirectory="PreserveNewest"/>
18
14
</ItemGroup>
19
15
20
16
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(GDWeavePath)' != ''">
-14
Atproto/manifest.json
-14
Atproto/manifest.json
···
1
-
{
2
-
"Id": "Atproto",
3
-
"AssemblyPath": "Atproto.dll",
4
-
"Metadata": {
5
-
"Name": "Atproto Webfishing",
6
-
"Author": "Estym",
7
-
"Version": "1.0.1",
8
-
"Description": "A mod that sends data to your AtProto PDS."
9
-
},
10
-
"PackPath": "atproto.pck",
11
-
"Dependencies": [
12
-
"TackleBox"
13
-
]
14
-
}
+7
-1
README.md
+7
-1
README.md
···
1
1
# AtProto Webfishing
2
2
3
3
A Webfishing mod that send data to your PDS
4
-
[Download Link](https://fb.dreamteam.boo/api/public/dl/oMcpvwyP/Webfishing-Atproto.zip)
4
+
5
+
[ThunderStore Link](https://thunderstore.io/c/webfishing/p/EstymMods/Webfishing_Atproto/)
5
6
6
7
# Features
7
8
- Remote save files
···
17
18
After it's done, you can select a save file or create one, then load it !
18
19
19
20
When a file is loaded, the savedata will be synchronized to your PDS each time the game saves.
21
+
22
+
## How to send your save online
23
+
24
+
To send your save on your PDS, simply create a new save and click on "Duplicate Save", it will create a new save on the PDS with the local data you have.
25
+
20
26
21
27
## Credits
22
28
-1
gdscript/.import/.gdignore
-1
gdscript/.import/.gdignore
···
1
-
-264
gdscript/mods/Atproto/assets/at_proto.tres
-264
gdscript/mods/Atproto/assets/at_proto.tres
···
1
-
[gd_resource type="Theme" load_steps=28 format=2]
2
-
3
-
[ext_resource path="res://Assets/Textures/UI/scrollbar.png" type="Texture" id=1]
4
-
[ext_resource path="res://Assets/Themes/main_font.tres" type="DynamicFont" id=2]
5
-
6
-
[sub_resource type="StyleBoxFlat" id=1]
7
-
content_margin_left = 12.0
8
-
content_margin_right = 12.0
9
-
bg_color = Color( 0.415686, 0.266667, 0.12549, 1 )
10
-
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
11
-
corner_radius_top_left = 12
12
-
corner_radius_top_right = 12
13
-
corner_radius_bottom_right = 12
14
-
corner_radius_bottom_left = 12
15
-
corner_detail = 5
16
-
17
-
[sub_resource type="StyleBoxEmpty" id=34]
18
-
19
-
[sub_resource type="StyleBoxFlat" id=30]
20
-
content_margin_left = 12.0
21
-
content_margin_right = 12.0
22
-
bg_color = Color( 0.611765, 0.568627, 0.290196, 1 )
23
-
border_color = Color( 0.835294, 0.666667, 0.45098, 1 )
24
-
corner_radius_top_left = 12
25
-
corner_radius_top_right = 12
26
-
corner_radius_bottom_right = 12
27
-
corner_radius_bottom_left = 12
28
-
corner_detail = 5
29
-
expand_margin_left = 1.0
30
-
expand_margin_right = 1.0
31
-
expand_margin_top = 1.0
32
-
expand_margin_bottom = 1.0
33
-
34
-
[sub_resource type="StyleBoxFlat" id=31]
35
-
content_margin_left = 12.0
36
-
content_margin_right = 12.0
37
-
bg_color = Color( 0.352941, 0.458824, 0.352941, 1 )
38
-
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
39
-
corner_radius_top_left = 12
40
-
corner_radius_top_right = 12
41
-
corner_radius_bottom_right = 12
42
-
corner_radius_bottom_left = 12
43
-
44
-
[sub_resource type="StyleBoxFlat" id=32]
45
-
content_margin_left = 12.0
46
-
content_margin_right = 12.0
47
-
bg_color = Color( 0.352941, 0.458824, 0.352941, 1 )
48
-
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
49
-
corner_radius_top_left = 12
50
-
corner_radius_top_right = 12
51
-
corner_radius_bottom_right = 12
52
-
corner_radius_bottom_left = 12
53
-
corner_detail = 5
54
-
55
-
[sub_resource type="StyleBoxFlat" id=18]
56
-
bg_color = Color( 0.352941, 0.458824, 0.352941, 1 )
57
-
border_width_left = 6
58
-
border_color = Color( 1, 1, 1, 0 )
59
-
corner_radius_top_left = 4
60
-
corner_radius_top_right = 4
61
-
corner_radius_bottom_right = 4
62
-
corner_radius_bottom_left = 4
63
-
64
-
[sub_resource type="StyleBoxFlat" id=15]
65
-
bg_color = Color( 0.611765, 0.568627, 0.290196, 1 )
66
-
border_color = Color( 0.835294, 0.666667, 0.45098, 1 )
67
-
corner_radius_top_left = 12
68
-
corner_radius_top_right = 12
69
-
corner_radius_bottom_right = 12
70
-
corner_radius_bottom_left = 12
71
-
corner_detail = 5
72
-
73
-
[sub_resource type="StyleBoxFlat" id=21]
74
-
bg_color = Color( 0.0627451, 0.109804, 0.192157, 1 )
75
-
draw_center = false
76
-
border_width_left = 16
77
-
border_color = Color( 1, 1, 1, 0 )
78
-
corner_radius_top_left = 4
79
-
corner_radius_top_right = 4
80
-
corner_radius_bottom_right = 4
81
-
corner_radius_bottom_left = 4
82
-
83
-
[sub_resource type="StyleBoxEmpty" id=20]
84
-
85
-
[sub_resource type="StyleBoxFlat" id=35]
86
-
87
-
[sub_resource type="StyleBoxFlat" id=36]
88
-
89
-
[sub_resource type="StyleBoxFlat" id=37]
90
-
bg_color = Color( 0.0627451, 0.109804, 0.192157, 1 )
91
-
corner_radius_top_left = 8
92
-
corner_radius_top_right = 8
93
-
corner_radius_bottom_right = 8
94
-
corner_radius_bottom_left = 8
95
-
expand_margin_top = 3.0
96
-
expand_margin_bottom = 3.0
97
-
98
-
[sub_resource type="StyleBoxFlat" id=33]
99
-
content_margin_left = 12.0
100
-
content_margin_right = 12.0
101
-
bg_color = Color( 0.572549, 0.45098, 0.290196, 1 )
102
-
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
103
-
corner_radius_top_left = 12
104
-
corner_radius_top_right = 12
105
-
corner_radius_bottom_right = 12
106
-
corner_radius_bottom_left = 12
107
-
108
-
[sub_resource type="StyleBoxFlat" id=9]
109
-
bg_color = Color( 1, 0.933333, 0.835294, 1 )
110
-
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
111
-
corner_radius_top_left = 32
112
-
corner_radius_top_right = 32
113
-
corner_radius_bottom_right = 32
114
-
corner_radius_bottom_left = 32
115
-
116
-
[sub_resource type="ImageTexture" id=24]
117
-
118
-
[sub_resource type="StyleBoxFlat" id=25]
119
-
content_margin_left = 4.0
120
-
content_margin_right = 4.0
121
-
bg_color = Color( 0.611765, 0.568627, 0.290196, 1 )
122
-
corner_radius_top_left = 8
123
-
corner_radius_top_right = 8
124
-
corner_radius_bottom_right = 8
125
-
corner_radius_bottom_left = 8
126
-
expand_margin_left = 2.0
127
-
expand_margin_right = 2.0
128
-
expand_margin_top = 2.0
129
-
130
-
[sub_resource type="StyleBoxEmpty" id=26]
131
-
132
-
[sub_resource type="StyleBoxEmpty" id=27]
133
-
134
-
[sub_resource type="StyleBoxFlat" id=28]
135
-
content_margin_left = 8.0
136
-
content_margin_right = 8.0
137
-
bg_color = Color( 0.352941, 0.458824, 0.352941, 1 )
138
-
corner_radius_bottom_right = 12
139
-
corner_radius_bottom_left = 12
140
-
expand_margin_top = 10.0
141
-
expand_margin_bottom = 8.0
142
-
143
-
[sub_resource type="StyleBoxEmpty" id=29]
144
-
145
-
[sub_resource type="StyleBoxFlat" id=4]
146
-
bg_color = Color( 0.352941, 0.458824, 0.352941, 1 )
147
-
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
148
-
corner_radius_top_left = 12
149
-
corner_radius_top_right = 12
150
-
corner_radius_bottom_right = 12
151
-
corner_radius_bottom_left = 12
152
-
expand_margin_left = 2.0
153
-
expand_margin_right = 2.0
154
-
155
-
[sub_resource type="StyleBoxFlat" id=8]
156
-
bg_color = Color( 0.835294, 0.666667, 0.45098, 1 )
157
-
border_width_left = 2
158
-
border_width_top = 2
159
-
border_width_right = 2
160
-
border_width_bottom = 2
161
-
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
162
-
corner_radius_top_left = 6
163
-
corner_radius_top_right = 6
164
-
corner_radius_bottom_right = 6
165
-
corner_radius_bottom_left = 6
166
-
corner_detail = 5
167
-
anti_aliasing = false
168
-
169
-
[sub_resource type="StyleBoxFlat" id=6]
170
-
bg_color = Color( 0.835294, 0.666667, 0.45098, 1 )
171
-
border_width_left = 2
172
-
border_width_top = 2
173
-
border_width_right = 2
174
-
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
175
-
corner_radius_top_left = 6
176
-
corner_radius_top_right = 6
177
-
corner_detail = 5
178
-
anti_aliasing = false
179
-
180
-
[sub_resource type="StyleBoxFlat" id=7]
181
-
bg_color = Color( 0.835294, 0.666667, 0.45098, 1 )
182
-
border_width_left = 2
183
-
border_width_top = 2
184
-
border_width_right = 2
185
-
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
186
-
corner_radius_top_left = 6
187
-
corner_radius_top_right = 6
188
-
corner_detail = 5
189
-
expand_margin_bottom = 2.0
190
-
anti_aliasing = false
191
-
192
-
[sub_resource type="StyleBoxEmpty" id=23]
193
-
194
-
[resource]
195
-
default_font = ExtResource( 2 )
196
-
Button/colors/font_color = Color( 1, 0.933333, 0.835294, 1 )
197
-
Button/colors/font_color_disabled = Color( 0.835294, 0.666667, 0.45098, 1 )
198
-
Button/colors/font_color_focus = Color( 1, 0.933333, 0.835294, 1 )
199
-
Button/colors/font_color_hover = Color( 1, 0.933333, 0.835294, 1 )
200
-
Button/colors/font_color_pressed = Color( 0.835294, 0.666667, 0.45098, 1 )
201
-
Button/styles/disabled = SubResource( 1 )
202
-
Button/styles/focus = SubResource( 34 )
203
-
Button/styles/hover = SubResource( 30 )
204
-
Button/styles/normal = SubResource( 31 )
205
-
Button/styles/pressed = SubResource( 32 )
206
-
HScrollBar/styles/grabber = SubResource( 18 )
207
-
HScrollBar/styles/grabber_highlight = SubResource( 15 )
208
-
HScrollBar/styles/grabber_pressed = SubResource( 15 )
209
-
HScrollBar/styles/scroll = SubResource( 21 )
210
-
HScrollBar/styles/scroll_focus = SubResource( 20 )
211
-
HSlider/icons/grabber = ExtResource( 1 )
212
-
HSlider/icons/grabber_disabled = ExtResource( 1 )
213
-
HSlider/icons/grabber_highlight = ExtResource( 1 )
214
-
HSlider/styles/grabber_area = SubResource( 35 )
215
-
HSlider/styles/grabber_area_highlight = SubResource( 36 )
216
-
HSlider/styles/slider = SubResource( 37 )
217
-
Label/colors/font_color = Color( 0.352941, 0.458824, 0.352941, 1 )
218
-
LineEdit/colors/cursor_color = Color( 1, 0.933333, 0.835294, 1 )
219
-
LineEdit/colors/font_color = Color( 1, 0.933333, 0.835294, 1 )
220
-
LineEdit/colors/font_color_selected = Color( 1, 0.933333, 0.835294, 1 )
221
-
LineEdit/colors/font_color_uneditable = Color( 0.835294, 0.666667, 0.45098, 1 )
222
-
LineEdit/styles/focus = SubResource( 33 )
223
-
LineEdit/styles/normal = SubResource( 33 )
224
-
LineEdit/styles/read_only = SubResource( 33 )
225
-
Panel/styles/panel = SubResource( 9 )
226
-
PopupMenu/colors/font_color = Color( 1, 0.933333, 0.835294, 1 )
227
-
PopupMenu/colors/font_color_hover = Color( 1, 0.933333, 0.835294, 1 )
228
-
PopupMenu/icons/checked = SubResource( 24 )
229
-
PopupMenu/icons/radio_checked = SubResource( 24 )
230
-
PopupMenu/icons/radio_unchecked = SubResource( 24 )
231
-
PopupMenu/icons/submenu = SubResource( 24 )
232
-
PopupMenu/icons/unchecked = SubResource( 24 )
233
-
PopupMenu/styles/hover = SubResource( 25 )
234
-
PopupMenu/styles/labeled_separator_left = SubResource( 26 )
235
-
PopupMenu/styles/labeled_separator_right = SubResource( 27 )
236
-
PopupMenu/styles/panel = SubResource( 28 )
237
-
PopupMenu/styles/panel_disabled = SubResource( 28 )
238
-
PopupMenu/styles/separator = SubResource( 29 )
239
-
ProgressBar/colors/font_color = Color( 1, 0.933333, 0.835294, 1 )
240
-
ProgressBar/styles/bg = SubResource( 1 )
241
-
ProgressBar/styles/fg = SubResource( 4 )
242
-
RichTextLabel/colors/default_color = Color( 0.835294, 0.666667, 0.45098, 1 )
243
-
TabContainer/colors/font_color_bg = Color( 0.415686, 0.266667, 0.12549, 1 )
244
-
TabContainer/colors/font_color_disabled = Color( 0.611765, 0.0784314, 0.0784314, 1 )
245
-
TabContainer/colors/font_color_fg = Color( 1, 0.933333, 0.835294, 1 )
246
-
TabContainer/styles/panel = SubResource( 8 )
247
-
TabContainer/styles/tab_bg = SubResource( 6 )
248
-
TabContainer/styles/tab_disabled = SubResource( 1 )
249
-
TabContainer/styles/tab_fg = SubResource( 7 )
250
-
Tabs/colors/font_color_bg = Color( 0.835294, 0.666667, 0.45098, 1 )
251
-
Tabs/colors/font_color_fg = Color( 0.835294, 0.666667, 0.45098, 1 )
252
-
TextEdit/colors/caret_color = Color( 1, 0.933333, 0.835294, 1 )
253
-
TextEdit/colors/font_color = Color( 0.415686, 0.266667, 0.12549, 1 )
254
-
TextEdit/colors/font_color_readonly = Color( 0.415686, 0.266667, 0.12549, 1 )
255
-
TextEdit/colors/selection_color = Color( 0.352941, 0.458824, 0.352941, 1 )
256
-
TextEdit/styles/completion = SubResource( 23 )
257
-
TextEdit/styles/focus = SubResource( 23 )
258
-
TextEdit/styles/normal = SubResource( 23 )
259
-
TextEdit/styles/read_only = SubResource( 23 )
260
-
VScrollBar/styles/grabber = SubResource( 18 )
261
-
VScrollBar/styles/grabber_highlight = SubResource( 15 )
262
-
VScrollBar/styles/grabber_pressed = SubResource( 15 )
263
-
VScrollBar/styles/scroll = SubResource( 21 )
264
-
VScrollBar/styles/scroll_focus = SubResource( 20 )
-421
gdscript/mods/Atproto/atproto_client.gd
-421
gdscript/mods/Atproto/atproto_client.gd
···
1
-
extends Node
2
-
3
-
# Signals
4
-
signal connection(suceeded)
5
-
6
-
# AtProto
7
-
var did
8
-
var pds
9
-
var accessJwt
10
-
var refreshJwt
11
-
var Atproto
12
-
13
-
# HTTP
14
-
var requester: HTTPRequest
15
-
16
-
func _enter_tree():
17
-
self.requester = HTTPRequest.new()
18
-
Atproto = self.get_parent()
19
-
self.add_child(self.requester, true)
20
-
21
-
func connected() -> bool:
22
-
return accessJwt != null
23
-
24
-
func is_token_expired() -> bool:
25
-
var json = Marshalls.base64_to_utf8(self.accessJwt.split(".")[1])
26
-
var data = parse_json(json)
27
-
var expires = data.exp
28
-
var unix = floor(Time.get_unix_time_from_system())
29
-
return expires < unix
30
-
31
-
func get_header():
32
-
return [
33
-
"Authorization: Bearer " + self.accessJwt,
34
-
"Content-Type: application/json"
35
-
]
36
-
37
-
func create_record(record, callback : FuncRef = null):
38
-
39
-
if is_token_expired():
40
-
refresh_token("create_record", [record])
41
-
return
42
-
43
-
var payload = {
44
-
repo = did,
45
-
collection = record.at_type,
46
-
record = record
47
-
}
48
-
49
-
var json_payload = JSON.print(payload)
50
-
json_payload = json_payload.replace("at_type", "$type")
51
-
52
-
var req = self.requester
53
-
req.request(pds + "/xrpc/com.atproto.repo.createRecord", get_header(), true, HTTPClient.METHOD_POST, json_payload)
54
-
req.connect("request_completed", self, "_create_record_handler", [callback])
55
-
56
-
func _create_record_handler(_result, code, _headers, body: PoolByteArray, callback: FuncRef):
57
-
var req = self.requester
58
-
req.disconnect("request_completed", self, "_create_record_handler")
59
-
if callback == null:
60
-
return
61
-
62
-
var res = parse_json(body.get_string_from_utf8())
63
-
callback.call_func(res)
64
-
65
-
func list_records(callback: FuncRef, collection: String, limit: int = 50, cursor = ""):
66
-
var req = self.requester
67
-
var query_string = "repo=" + did.http_escape()
68
-
query_string += "&collection=" + collection.http_escape()
69
-
query_string += "&limit=" + str(limit).http_escape()
70
-
query_string += "&cursor=" + str(limit).http_escape()
71
-
req.request(pds + "/xrpc/com.atproto.repo.listRecords?" + query_string, get_header(), true, HTTPClient.METHOD_GET)
72
-
req.connect("request_completed", self, "_list_record_handler", [callback])
73
-
74
-
75
-
func _list_record_handler(_result, code, _headers, body: PoolByteArray, callback: FuncRef):
76
-
var req = self.requester
77
-
req.disconnect("request_completed", self, "_list_record_handler")
78
-
var res = parse_json(body.get_string_from_utf8())
79
-
callback.call_func(res.records)
80
-
81
-
func get_record(callback: FuncRef, did: String, collection: String, rkey: String):
82
-
var req = self.requester
83
-
var query_string = "repo=" + did.http_escape()
84
-
query_string += "&collection=" + collection.http_escape()
85
-
query_string += "&rkey=" + rkey.http_escape()
86
-
req.request(pds + "/xrpc/com.atproto.repo.getRecord?" + query_string, get_header(), true, HTTPClient.METHOD_GET)
87
-
req.connect("request_completed", self, "_get_record_handle", [callback])
88
-
89
-
func _get_record_handle(_result, code, _headers, body: PoolByteArray, callback: FuncRef):
90
-
var req = self.requester
91
-
req.disconnect("request_completed", self, "_get_record_handle")
92
-
var res = parse_json(body.get_string_from_utf8())
93
-
callback.call_func(res)
94
-
95
-
func put_record(uri, record):
96
-
if is_token_expired():
97
-
refresh_token("put_record", [uri, record])
98
-
return
99
-
100
-
var splitted_uri = uri.split("/")
101
-
102
-
103
-
var payload = {
104
-
repo = splitted_uri[2],
105
-
collection = splitted_uri[3],
106
-
rkey = splitted_uri[4],
107
-
record = record
108
-
}
109
-
110
-
var json_payload = JSON.print(payload)
111
-
json_payload = json_payload.replace("at_type", "$type")
112
-
113
-
var req = self.requester
114
-
req.request(pds + "/xrpc/com.atproto.repo.putRecord", get_header(), true, HTTPClient.METHOD_POST, json_payload)
115
-
116
-
################
117
-
# LOGIN #
118
-
################
119
-
120
-
func login(handle, password):
121
-
var req = self.requester
122
-
123
-
req.connect("request_completed", self, "after_handle_resolver", [password])
124
-
req.request("https://bsky.social/xrpc/com.atproto.identity.resolveHandle?handle=" + handle)
125
-
126
-
127
-
func after_handle_resolver(_result, code, _headers, body: PoolByteArray, password):
128
-
var req = self.requester
129
-
req.disconnect("request_completed", self, "after_handle_resolver")
130
-
131
-
if code != 200:
132
-
emit_signal("connection", false)
133
-
return
134
-
135
-
var res = parse_json(body.get_string_from_utf8())
136
-
self.did = res.did
137
-
138
-
req.connect("request_completed", self, "after_get_pds", [password])
139
-
req.request("https://plc.directory/" + self.did)
140
-
141
-
142
-
func after_get_pds(_result, code, _headers, body: PoolByteArray, password):
143
-
var req = self.requester
144
-
req.disconnect("request_completed", self, "after_get_pds")
145
-
146
-
if code != 200:
147
-
emit_signal("connection", false)
148
-
return
149
-
150
-
var res = parse_json(body.get_string_from_utf8())
151
-
for x in res.service:
152
-
if x.id == "#atproto_pds":
153
-
self.pds = x.serviceEndpoint
154
-
155
-
var payload = {
156
-
identifier = self.did,
157
-
password = password
158
-
}
159
-
160
-
req.connect("request_completed", self, "after_create_session")
161
-
req.request(pds + "/xrpc/com.atproto.server.createSession", ["Content-Type: application/json"], true, HTTPClient.METHOD_POST, JSON.print(payload))
162
-
163
-
func after_create_session(_result, code, _headers, body: PoolByteArray):
164
-
var req = self.requester
165
-
req.disconnect("request_completed", self, "after_create_session")
166
-
167
-
if code != 200:
168
-
emit_signal("connection", false)
169
-
return
170
-
171
-
var res = parse_json(body.get_string_from_utf8())
172
-
self.accessJwt = res.accessJwt
173
-
self.refreshJwt = res.refreshJwt
174
-
emit_signal("connection", true)
175
-
176
-
#######################
177
-
# REFRESH TOKEN #
178
-
#######################
179
-
func refresh_token(method = "", payload = []):
180
-
var req = self.requester
181
-
182
-
var headers = [
183
-
"Authorization: Bearer " + self.refreshJwt,
184
-
"Content-Type: application/json"
185
-
]
186
-
req.connect("request_completed", self, "after_refresh_token", [method, payload])
187
-
req.request(pds + "/xrpc/com.atproto.server.refreshSession", headers, true, HTTPClient.METHOD_POST)
188
-
189
-
func after_refresh_token(_result, _response_code, _headers, body: PoolByteArray, method, payload):
190
-
var req = self.requester
191
-
req.disconnect("request_completed", self, "after_refresh_token")
192
-
193
-
var res = parse_json(body.get_string_from_utf8())
194
-
self.accessJwt = res.accessJwt
195
-
self.refreshJwt = res.refreshJwt
196
-
197
-
if method != "":
198
-
self.callv(method, payload)
199
-
200
-
201
-
######################
202
-
# Method Calls #
203
-
######################
204
-
205
-
func catch_fish(fish, size, quality):
206
-
var fish_data = Globals.item_data[fish]["file"]
207
-
var record = {
208
-
at_type = "dev.regnault.webfishing.fish",
209
-
id = fish,
210
-
name = fish_data.item_name,
211
-
size = str(size),
212
-
quality = quality
213
-
}
214
-
create_record(record)
215
-
216
-
217
-
# SAVES
218
-
219
-
func create_save_file(uri: String, filename: String, callback: FuncRef = null):
220
-
var record = {
221
-
at_type = "dev.regnault.webfishing.savefile",
222
-
uri = uri,
223
-
name = filename,
224
-
}
225
-
create_record(record, callback)
226
-
pass
227
-
228
-
func get_saves(callback: FuncRef):
229
-
list_records(callback, "dev.regnault.webfishing.savefile")
230
-
231
-
func save_file(callback: FuncRef = null):
232
-
if !connected(): return
233
-
var save_data = {
234
-
"inventory": PlayerData.inventory,
235
-
"hotbar": PlayerData.hotbar,
236
-
"cosmetics_unlocked": PlayerData.cosmetics_unlocked,
237
-
"cosmetics_equipped": PlayerData.cosmetics_equipped,
238
-
"new_cosmetics": [],
239
-
"version": Globals.GAME_VERSION,
240
-
"muted_players": PlayerData.players_muted,
241
-
"hidden_players": PlayerData.players_hidden,
242
-
"recorded_time": PlayerData.last_recorded_time,
243
-
"money": PlayerData.money,
244
-
"bait_inv": PlayerData.bait_inv,
245
-
"bait_selected": PlayerData.bait_selected,
246
-
"bait_unlocked": PlayerData.bait_unlocked,
247
-
"shop": PlayerData.current_shop,
248
-
"journal": PlayerData.journal_logs,
249
-
"quests": PlayerData.current_quests,
250
-
"completed_quests": PlayerData.completed_quests,
251
-
"level": PlayerData.badge_level,
252
-
"xp": PlayerData.badge_xp,
253
-
"max_bait": PlayerData.max_bait,
254
-
"lure_unlocked": PlayerData.lure_unlocked,
255
-
"lure_selected": PlayerData.lure_selected,
256
-
"saved_aqua_fish": PlayerData.saved_aqua_fish,
257
-
"inbound_mail": PlayerData.inbound_mail,
258
-
"rod_power": PlayerData.rod_power_level,
259
-
"rod_speed": PlayerData.rod_speed_level,
260
-
"rod_chance": PlayerData.rod_chance_level,
261
-
"rod_luck": PlayerData.rod_luck_level,
262
-
"saved_tags": PlayerData.saved_tags,
263
-
"loan_level": PlayerData.loan_level,
264
-
"loan_left": PlayerData.loan_left,
265
-
"buddy_level": PlayerData.buddy_level,
266
-
"buddy_speed": PlayerData.buddy_speed,
267
-
"guitar_shapes": PlayerData.guitar_shapes,
268
-
"fish_caught": PlayerData.fish_caught,
269
-
"cash_total": PlayerData.cash_total,
270
-
"voice_pitch": PlayerData.voice_pitch,
271
-
"voice_speed": PlayerData.voice_speed,
272
-
"locked_refs": PlayerData.locked_refs,
273
-
}
274
-
save_data = save_data.duplicate(true)
275
-
276
-
# JOURNAL
277
-
var modified_journal = []
278
-
for area in save_data.journal:
279
-
var area_entry = {
280
-
name = area,
281
-
entries = []
282
-
}
283
-
for entry_name in save_data.journal[area]:
284
-
var entry = save_data.journal[area][entry_name]
285
-
area_entry.entries.append({
286
-
name = entry_name,
287
-
count = entry.count,
288
-
record = str(entry.record),
289
-
quality = entry.quality
290
-
})
291
-
modified_journal.append(area_entry)
292
-
save_data.journal = modified_journal
293
-
294
-
# Quests
295
-
var modified_quests = []
296
-
for quest_id in save_data.quests:
297
-
var entry = save_data.quests[quest_id].duplicate(true)
298
-
entry.id = quest_id
299
-
modified_quests.append(entry)
300
-
save_data.quests = modified_quests
301
-
302
-
# Inventory
303
-
for item in save_data.inventory:
304
-
item.size = str(item.size)
305
-
306
-
307
-
# Version
308
-
save_data.version = str(save_data.version)
309
-
310
-
# Voice Pitch
311
-
save_data.voice_pitch = str(save_data.voice_pitch)
312
-
313
-
# Aqua Fish
314
-
save_data.saved_aqua_fish.size = str(save_data.saved_aqua_fish.size)
315
-
316
-
# Letters
317
-
for letter in save_data.inbound_mail:
318
-
for item in letter.items:
319
-
item.size = str(item.size)
320
-
save_data.at_type = "dev.regnault.webfishing.save"
321
-
322
-
if Atproto.save_loaded:
323
-
put_record(Atproto.save_loaded, save_data)
324
-
else:
325
-
create_record(save_data, callback)
326
-
327
-
func load_save(uri: String):
328
-
var splitted_uri = uri.split("/")
329
-
var did = splitted_uri[2]
330
-
var collection = splitted_uri[3]
331
-
var rkey = splitted_uri[4]
332
-
get_record(funcref(self, "_after_get_save"), did, collection, rkey)
333
-
pass
334
-
335
-
func _after_get_save(save_record):
336
-
var save = save_record.value
337
-
338
-
var modified_journal: Dictionary = {}
339
-
for area in save.journal:
340
-
var area_entries = {}
341
-
for entry in area.entries:
342
-
area_entries[entry.name] = {
343
-
count = entry.count,
344
-
record = float(entry.record),
345
-
quality = entry.quality
346
-
}
347
-
348
-
modified_journal[area.name] = area_entries
349
-
save.journal = modified_journal
350
-
351
-
var modified_quests = {}
352
-
for quest in save.quests:
353
-
var id = quest.id
354
-
modified_quests[quest.id] = quest
355
-
modified_quests[quest.id].erase("id")
356
-
save.quests = modified_quests
357
-
358
-
# Inventory
359
-
for item in save.inventory:
360
-
item.size = float(item.size)
361
-
item.quality = int(item.quality)
362
-
var x = PlayerData.QUALITY_DATA[item.quality]
363
-
364
-
save.version = float(save.version)
365
-
save.saved_aqua_fish.size = float(save.saved_aqua_fish.size)
366
-
for letter in save.inbound_mail:
367
-
for item in letter.items:
368
-
item.size = float(item.size)
369
-
item.quality = int(item.quality)
370
-
var x = PlayerData.QUALITY_DATA[item.quality]
371
-
372
-
var modified_hotbar = {}
373
-
for item in save.hotbar:
374
-
modified_hotbar[int(item)] = save.hotbar[item]
375
-
save.hotbar = modified_hotbar
376
-
377
-
PlayerData.inventory = save.inventory
378
-
PlayerData.hotbar = save.hotbar
379
-
PlayerData.cosmetics_unlocked = save.cosmetics_unlocked
380
-
PlayerData.cosmetics_equipped = save.cosmetics_equipped
381
-
PlayerData.money = save.money
382
-
PlayerData.players_muted = save.muted_players
383
-
PlayerData.players_hidden = save.hidden_players
384
-
PlayerData.bait_inv = save.bait_inv
385
-
PlayerData.bait_selected = save.bait_selected
386
-
PlayerData.bait_unlocked = save.bait_unlocked
387
-
PlayerData.max_bait = save.max_bait
388
-
PlayerData.lure_unlocked = save.lure_unlocked
389
-
PlayerData.lure_selected = save.lure_selected
390
-
PlayerData.journal_logs = save.journal
391
-
PlayerData.current_quests = save.quests
392
-
PlayerData.completed_quests = save.completed_quests
393
-
PlayerData.badge_level = int(save.level)
394
-
PlayerData.badge_xp = int(save.xp)
395
-
PlayerData.saved_aqua_fish = save.saved_aqua_fish
396
-
PlayerData.inbound_mail = save.inbound_mail
397
-
PlayerData.saved_tags = save.saved_tags
398
-
PlayerData.loan_level = int(save.loan_level)
399
-
PlayerData.loan_left = save.loan_left
400
-
PlayerData.rod_power_level = save.rod_power
401
-
PlayerData.rod_speed_level = save.rod_speed
402
-
PlayerData.rod_chance_level = save.rod_chance
403
-
PlayerData.rod_luck_level = save.rod_luck
404
-
PlayerData.buddy_level = save.buddy_level
405
-
PlayerData.buddy_speed = save.buddy_speed
406
-
PlayerData.guitar_shapes = save.guitar_shapes
407
-
PlayerData.fish_caught = save.fish_caught
408
-
PlayerData.cash_total = save.cash_total
409
-
PlayerData.voice_pitch = float(save.voice_pitch)
410
-
PlayerData.voice_speed = save.voice_speed
411
-
PlayerData.locked_refs = save.locked_refs
412
-
PlayerData._validate_guitar_shapes()
413
-
PlayerData._validate_inventory()
414
-
PlayerData._journal_check()
415
-
PlayerData._missing_quest_check()
416
-
PlayerData._unlock_defaults()
417
-
418
-
Atproto.config.Save = save_record.uri
419
-
Atproto.save_loaded = save_record.uri
420
-
PopupMessage._show_popup("AtProto save file loaded")
421
-
-72
gdscript/mods/Atproto/main.gd
-72
gdscript/mods/Atproto/main.gd
···
1
-
extends Node
2
-
3
-
var config: Dictionary
4
-
var save_loaded: String
5
-
var default_config: Dictionary = {}
6
-
7
-
onready var TackleBox := $"/root/TackleBox"
8
-
const AtProtoClient_t := preload("res://mods/Atproto/atproto_client.gd")
9
-
var AtProtoClient: AtProtoClient_t
10
-
11
-
# UI
12
-
const AtProtoMenu := preload("res://mods/Atproto/ui/menus/atproto_config.tscn")
13
-
const AtProtoButton := preload("res://mods/Atproto/ui/buttons/atproto.tscn")
14
-
15
-
var setuped = false
16
-
17
-
func _enter_tree():
18
-
AtProtoClient = AtProtoClient_t.new()
19
-
add_child(AtProtoClient)
20
-
get_tree().connect("node_added", self, "_add_atproto_menu")
21
-
22
-
23
-
func _ready() -> void:
24
-
print("QUOTA:", Steam.getQuota())
25
-
TackleBox.connect("mod_config_updated", self, "_on_config_update")
26
-
27
-
_init_config()
28
-
29
-
func _init_config():
30
-
var saved_config = TackleBox.get_mod_config(name)
31
-
for key in default_config.keys():
32
-
if not saved_config[key]:
33
-
saved_config[key] = default_config[key]
34
-
config = saved_config
35
-
TackleBox.set_mod_config(name, config)
36
-
if config.Autoconnect == true:
37
-
AtProtoClient.login(config.Handle, config.Password)
38
-
39
-
40
-
func _save_config():
41
-
TackleBox.set_mod_config(name, config)
42
-
43
-
func _on_config_update(mod_id: String, new_config: Dictionary) -> void:
44
-
if mod_id != name:
45
-
return
46
-
if config.hash() == new_config.hash():
47
-
return
48
-
config = new_config
49
-
if config.Handle != "" and config.Password != "":
50
-
AtProtoClient.login(config.Handle, config.Password)
51
-
52
-
func _add_atproto_menu(node: Node):
53
-
if node.name == "main_menu":
54
-
var atproto_menu: Node = AtProtoMenu.instance()
55
-
atproto_menu.visible = false
56
-
node.add_child(atproto_menu)
57
-
58
-
var button = AtProtoButton.instance()
59
-
var menu_list: Node = node.get_node("VBoxContainer")
60
-
var settings_button: Node = menu_list.get_node("settings")
61
-
menu_list.add_child(button)
62
-
menu_list.move_child(button, settings_button.get_index() + 1)
63
-
atproto_menu.connect("setup_done", self, "_after_setup")
64
-
pass
65
-
66
-
func _after_setup():
67
-
if setuped:
68
-
return
69
-
setuped = true
70
-
71
-
if config.Save != "" and config.Autoload and AtProtoClient.connected():
72
-
AtProtoClient.load_save(config.Save)
-21
gdscript/project.godot
-21
gdscript/project.godot
···
1
-
; Engine configuration file.
2
-
; It's best edited using the editor UI and not directly,
3
-
; since the parameters that go here are not all obvious.
4
-
;
5
-
; Format:
6
-
; [section] ; section goes between []
7
-
; param=value ; assign values to parameters
8
-
9
-
config_version=4
10
-
11
-
[application]
12
-
13
-
config/name="AtProto Webfishing"
14
-
15
-
[gui]
16
-
17
-
common/drop_mouse_on_gui_input_disabled=true
18
-
19
-
[physics]
20
-
21
-
common/enable_pause_aware_picking=true
icon.png
icon.png
This is a binary file and will not be displayed.
+20
manifestation.toml
+20
manifestation.toml
···
1
+
id = "Atproto"
2
+
name = "Webfishing_Atproto"
3
+
description = "A mod that sends data to your AtProto PDS."
4
+
version = "1.0.4"
5
+
homepage = "https://tangled.org/@regnault.dev/webfishing-atproto"
6
+
author = "Estym"
7
+
8
+
icon = "icon.png"
9
+
readme = "README.md"
10
+
11
+
[project]
12
+
csharp = "./Atproto/Atproto.csproj"
13
+
godot = "./project/project.godot"
14
+
15
+
[[dependencies]]
16
+
thunderstore_version = "NotNet-GDWeave-2.0.12"
17
+
18
+
[[dependencies]]
19
+
id = "TackleBox"
20
+
thunderstore_version = "PuppyGirl-TackleBox-0.5.2"
+264
project/mods/Atproto/assets/at_proto.tres
+264
project/mods/Atproto/assets/at_proto.tres
···
1
+
[gd_resource type="Theme" load_steps=28 format=2]
2
+
3
+
[ext_resource path="res://Assets/Textures/UI/scrollbar.png" type="Texture" id=1]
4
+
[ext_resource path="res://Assets/Themes/main_font.tres" type="DynamicFont" id=2]
5
+
6
+
[sub_resource type="StyleBoxFlat" id=1]
7
+
content_margin_left = 12.0
8
+
content_margin_right = 12.0
9
+
bg_color = Color( 0.415686, 0.266667, 0.12549, 1 )
10
+
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
11
+
corner_radius_top_left = 12
12
+
corner_radius_top_right = 12
13
+
corner_radius_bottom_right = 12
14
+
corner_radius_bottom_left = 12
15
+
corner_detail = 5
16
+
17
+
[sub_resource type="StyleBoxEmpty" id=34]
18
+
19
+
[sub_resource type="StyleBoxFlat" id=30]
20
+
content_margin_left = 12.0
21
+
content_margin_right = 12.0
22
+
bg_color = Color( 0.611765, 0.568627, 0.290196, 1 )
23
+
border_color = Color( 0.835294, 0.666667, 0.45098, 1 )
24
+
corner_radius_top_left = 12
25
+
corner_radius_top_right = 12
26
+
corner_radius_bottom_right = 12
27
+
corner_radius_bottom_left = 12
28
+
corner_detail = 5
29
+
expand_margin_left = 1.0
30
+
expand_margin_right = 1.0
31
+
expand_margin_top = 1.0
32
+
expand_margin_bottom = 1.0
33
+
34
+
[sub_resource type="StyleBoxFlat" id=31]
35
+
content_margin_left = 12.0
36
+
content_margin_right = 12.0
37
+
bg_color = Color( 0.352941, 0.458824, 0.352941, 1 )
38
+
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
39
+
corner_radius_top_left = 12
40
+
corner_radius_top_right = 12
41
+
corner_radius_bottom_right = 12
42
+
corner_radius_bottom_left = 12
43
+
44
+
[sub_resource type="StyleBoxFlat" id=32]
45
+
content_margin_left = 12.0
46
+
content_margin_right = 12.0
47
+
bg_color = Color( 0.352941, 0.458824, 0.352941, 1 )
48
+
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
49
+
corner_radius_top_left = 12
50
+
corner_radius_top_right = 12
51
+
corner_radius_bottom_right = 12
52
+
corner_radius_bottom_left = 12
53
+
corner_detail = 5
54
+
55
+
[sub_resource type="StyleBoxFlat" id=18]
56
+
bg_color = Color( 0.352941, 0.458824, 0.352941, 1 )
57
+
border_width_left = 6
58
+
border_color = Color( 1, 1, 1, 0 )
59
+
corner_radius_top_left = 4
60
+
corner_radius_top_right = 4
61
+
corner_radius_bottom_right = 4
62
+
corner_radius_bottom_left = 4
63
+
64
+
[sub_resource type="StyleBoxFlat" id=15]
65
+
bg_color = Color( 0.611765, 0.568627, 0.290196, 1 )
66
+
border_color = Color( 0.835294, 0.666667, 0.45098, 1 )
67
+
corner_radius_top_left = 12
68
+
corner_radius_top_right = 12
69
+
corner_radius_bottom_right = 12
70
+
corner_radius_bottom_left = 12
71
+
corner_detail = 5
72
+
73
+
[sub_resource type="StyleBoxFlat" id=21]
74
+
bg_color = Color( 0.0627451, 0.109804, 0.192157, 1 )
75
+
draw_center = false
76
+
border_width_left = 16
77
+
border_color = Color( 1, 1, 1, 0 )
78
+
corner_radius_top_left = 4
79
+
corner_radius_top_right = 4
80
+
corner_radius_bottom_right = 4
81
+
corner_radius_bottom_left = 4
82
+
83
+
[sub_resource type="StyleBoxEmpty" id=20]
84
+
85
+
[sub_resource type="StyleBoxFlat" id=35]
86
+
87
+
[sub_resource type="StyleBoxFlat" id=36]
88
+
89
+
[sub_resource type="StyleBoxFlat" id=37]
90
+
bg_color = Color( 0.0627451, 0.109804, 0.192157, 1 )
91
+
corner_radius_top_left = 8
92
+
corner_radius_top_right = 8
93
+
corner_radius_bottom_right = 8
94
+
corner_radius_bottom_left = 8
95
+
expand_margin_top = 3.0
96
+
expand_margin_bottom = 3.0
97
+
98
+
[sub_resource type="StyleBoxFlat" id=33]
99
+
content_margin_left = 12.0
100
+
content_margin_right = 12.0
101
+
bg_color = Color( 0.572549, 0.45098, 0.290196, 1 )
102
+
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
103
+
corner_radius_top_left = 12
104
+
corner_radius_top_right = 12
105
+
corner_radius_bottom_right = 12
106
+
corner_radius_bottom_left = 12
107
+
108
+
[sub_resource type="StyleBoxFlat" id=9]
109
+
bg_color = Color( 1, 0.933333, 0.835294, 1 )
110
+
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
111
+
corner_radius_top_left = 32
112
+
corner_radius_top_right = 32
113
+
corner_radius_bottom_right = 32
114
+
corner_radius_bottom_left = 32
115
+
116
+
[sub_resource type="ImageTexture" id=24]
117
+
118
+
[sub_resource type="StyleBoxFlat" id=25]
119
+
content_margin_left = 4.0
120
+
content_margin_right = 4.0
121
+
bg_color = Color( 0.611765, 0.568627, 0.290196, 1 )
122
+
corner_radius_top_left = 8
123
+
corner_radius_top_right = 8
124
+
corner_radius_bottom_right = 8
125
+
corner_radius_bottom_left = 8
126
+
expand_margin_left = 2.0
127
+
expand_margin_right = 2.0
128
+
expand_margin_top = 2.0
129
+
130
+
[sub_resource type="StyleBoxEmpty" id=26]
131
+
132
+
[sub_resource type="StyleBoxEmpty" id=27]
133
+
134
+
[sub_resource type="StyleBoxFlat" id=28]
135
+
content_margin_left = 8.0
136
+
content_margin_right = 8.0
137
+
bg_color = Color( 0.352941, 0.458824, 0.352941, 1 )
138
+
corner_radius_bottom_right = 12
139
+
corner_radius_bottom_left = 12
140
+
expand_margin_top = 10.0
141
+
expand_margin_bottom = 8.0
142
+
143
+
[sub_resource type="StyleBoxEmpty" id=29]
144
+
145
+
[sub_resource type="StyleBoxFlat" id=4]
146
+
bg_color = Color( 0.352941, 0.458824, 0.352941, 1 )
147
+
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
148
+
corner_radius_top_left = 12
149
+
corner_radius_top_right = 12
150
+
corner_radius_bottom_right = 12
151
+
corner_radius_bottom_left = 12
152
+
expand_margin_left = 2.0
153
+
expand_margin_right = 2.0
154
+
155
+
[sub_resource type="StyleBoxFlat" id=8]
156
+
bg_color = Color( 0.835294, 0.666667, 0.45098, 1 )
157
+
border_width_left = 2
158
+
border_width_top = 2
159
+
border_width_right = 2
160
+
border_width_bottom = 2
161
+
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
162
+
corner_radius_top_left = 6
163
+
corner_radius_top_right = 6
164
+
corner_radius_bottom_right = 6
165
+
corner_radius_bottom_left = 6
166
+
corner_detail = 5
167
+
anti_aliasing = false
168
+
169
+
[sub_resource type="StyleBoxFlat" id=6]
170
+
bg_color = Color( 0.835294, 0.666667, 0.45098, 1 )
171
+
border_width_left = 2
172
+
border_width_top = 2
173
+
border_width_right = 2
174
+
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
175
+
corner_radius_top_left = 6
176
+
corner_radius_top_right = 6
177
+
corner_detail = 5
178
+
anti_aliasing = false
179
+
180
+
[sub_resource type="StyleBoxFlat" id=7]
181
+
bg_color = Color( 0.835294, 0.666667, 0.45098, 1 )
182
+
border_width_left = 2
183
+
border_width_top = 2
184
+
border_width_right = 2
185
+
border_color = Color( 0.415686, 0.266667, 0.12549, 1 )
186
+
corner_radius_top_left = 6
187
+
corner_radius_top_right = 6
188
+
corner_detail = 5
189
+
expand_margin_bottom = 2.0
190
+
anti_aliasing = false
191
+
192
+
[sub_resource type="StyleBoxEmpty" id=23]
193
+
194
+
[resource]
195
+
default_font = ExtResource( 2 )
196
+
Button/colors/font_color = Color( 1, 0.933333, 0.835294, 1 )
197
+
Button/colors/font_color_disabled = Color( 0.835294, 0.666667, 0.45098, 1 )
198
+
Button/colors/font_color_focus = Color( 1, 0.933333, 0.835294, 1 )
199
+
Button/colors/font_color_hover = Color( 1, 0.933333, 0.835294, 1 )
200
+
Button/colors/font_color_pressed = Color( 0.835294, 0.666667, 0.45098, 1 )
201
+
Button/styles/disabled = SubResource( 1 )
202
+
Button/styles/focus = SubResource( 34 )
203
+
Button/styles/hover = SubResource( 30 )
204
+
Button/styles/normal = SubResource( 31 )
205
+
Button/styles/pressed = SubResource( 32 )
206
+
HScrollBar/styles/grabber = SubResource( 18 )
207
+
HScrollBar/styles/grabber_highlight = SubResource( 15 )
208
+
HScrollBar/styles/grabber_pressed = SubResource( 15 )
209
+
HScrollBar/styles/scroll = SubResource( 21 )
210
+
HScrollBar/styles/scroll_focus = SubResource( 20 )
211
+
HSlider/icons/grabber = ExtResource( 1 )
212
+
HSlider/icons/grabber_disabled = ExtResource( 1 )
213
+
HSlider/icons/grabber_highlight = ExtResource( 1 )
214
+
HSlider/styles/grabber_area = SubResource( 35 )
215
+
HSlider/styles/grabber_area_highlight = SubResource( 36 )
216
+
HSlider/styles/slider = SubResource( 37 )
217
+
Label/colors/font_color = Color( 0.352941, 0.458824, 0.352941, 1 )
218
+
LineEdit/colors/cursor_color = Color( 1, 0.933333, 0.835294, 1 )
219
+
LineEdit/colors/font_color = Color( 1, 0.933333, 0.835294, 1 )
220
+
LineEdit/colors/font_color_selected = Color( 1, 0.933333, 0.835294, 1 )
221
+
LineEdit/colors/font_color_uneditable = Color( 0.835294, 0.666667, 0.45098, 1 )
222
+
LineEdit/styles/focus = SubResource( 33 )
223
+
LineEdit/styles/normal = SubResource( 33 )
224
+
LineEdit/styles/read_only = SubResource( 33 )
225
+
Panel/styles/panel = SubResource( 9 )
226
+
PopupMenu/colors/font_color = Color( 1, 0.933333, 0.835294, 1 )
227
+
PopupMenu/colors/font_color_hover = Color( 1, 0.933333, 0.835294, 1 )
228
+
PopupMenu/icons/checked = SubResource( 24 )
229
+
PopupMenu/icons/radio_checked = SubResource( 24 )
230
+
PopupMenu/icons/radio_unchecked = SubResource( 24 )
231
+
PopupMenu/icons/submenu = SubResource( 24 )
232
+
PopupMenu/icons/unchecked = SubResource( 24 )
233
+
PopupMenu/styles/hover = SubResource( 25 )
234
+
PopupMenu/styles/labeled_separator_left = SubResource( 26 )
235
+
PopupMenu/styles/labeled_separator_right = SubResource( 27 )
236
+
PopupMenu/styles/panel = SubResource( 28 )
237
+
PopupMenu/styles/panel_disabled = SubResource( 28 )
238
+
PopupMenu/styles/separator = SubResource( 29 )
239
+
ProgressBar/colors/font_color = Color( 1, 0.933333, 0.835294, 1 )
240
+
ProgressBar/styles/bg = SubResource( 1 )
241
+
ProgressBar/styles/fg = SubResource( 4 )
242
+
RichTextLabel/colors/default_color = Color( 0.835294, 0.666667, 0.45098, 1 )
243
+
TabContainer/colors/font_color_bg = Color( 0.415686, 0.266667, 0.12549, 1 )
244
+
TabContainer/colors/font_color_disabled = Color( 0.611765, 0.0784314, 0.0784314, 1 )
245
+
TabContainer/colors/font_color_fg = Color( 1, 0.933333, 0.835294, 1 )
246
+
TabContainer/styles/panel = SubResource( 8 )
247
+
TabContainer/styles/tab_bg = SubResource( 6 )
248
+
TabContainer/styles/tab_disabled = SubResource( 1 )
249
+
TabContainer/styles/tab_fg = SubResource( 7 )
250
+
Tabs/colors/font_color_bg = Color( 0.835294, 0.666667, 0.45098, 1 )
251
+
Tabs/colors/font_color_fg = Color( 0.835294, 0.666667, 0.45098, 1 )
252
+
TextEdit/colors/caret_color = Color( 1, 0.933333, 0.835294, 1 )
253
+
TextEdit/colors/font_color = Color( 0.415686, 0.266667, 0.12549, 1 )
254
+
TextEdit/colors/font_color_readonly = Color( 0.415686, 0.266667, 0.12549, 1 )
255
+
TextEdit/colors/selection_color = Color( 0.352941, 0.458824, 0.352941, 1 )
256
+
TextEdit/styles/completion = SubResource( 23 )
257
+
TextEdit/styles/focus = SubResource( 23 )
258
+
TextEdit/styles/normal = SubResource( 23 )
259
+
TextEdit/styles/read_only = SubResource( 23 )
260
+
VScrollBar/styles/grabber = SubResource( 18 )
261
+
VScrollBar/styles/grabber_highlight = SubResource( 15 )
262
+
VScrollBar/styles/grabber_pressed = SubResource( 15 )
263
+
VScrollBar/styles/scroll = SubResource( 21 )
264
+
VScrollBar/styles/scroll_focus = SubResource( 20 )
+465
project/mods/Atproto/atproto_client.gd
+465
project/mods/Atproto/atproto_client.gd
···
1
+
extends Node
2
+
3
+
# Signals
4
+
signal connection(suceeded)
5
+
signal savefile_loaded(uri)
6
+
7
+
# State
8
+
var can_save = true
9
+
10
+
# AtProto
11
+
var did
12
+
var pds
13
+
var accessJwt
14
+
var refreshJwt
15
+
var Atproto
16
+
17
+
func _enter_tree():
18
+
Atproto = self.get_parent()
19
+
20
+
func connected() -> bool:
21
+
return accessJwt != null
22
+
23
+
func is_token_expired() -> bool:
24
+
var token_data = self.accessJwt.split(".")[1]
25
+
var data = null
26
+
for x in ["", "=", "=="] :
27
+
var json = Marshalls.base64_to_utf8(token_data + x)
28
+
data = parse_json(json)
29
+
if data != null: break
30
+
var expires = data.exp
31
+
var unix = floor(Time.get_unix_time_from_system())
32
+
return expires < unix
33
+
34
+
func get_header():
35
+
return [
36
+
"Authorization: Bearer " + self.accessJwt,
37
+
"Content-Type: application/json"
38
+
]
39
+
40
+
func create_record(record, callback : FuncRef = null):
41
+
42
+
if is_token_expired():
43
+
refresh_token("create_record", [record])
44
+
return
45
+
46
+
var payload = {
47
+
repo = did,
48
+
collection = record.at_type,
49
+
record = record
50
+
}
51
+
52
+
var json_payload = JSON.print(payload)
53
+
json_payload = json_payload.replace("at_type", "$type")
54
+
55
+
var req = HTTPRequest.new()
56
+
self.add_child(req)
57
+
req.connect("request_completed", self, "_create_record_handler", [req, callback])
58
+
req.request(pds + "/xrpc/com.atproto.repo.createRecord", get_header(), true, HTTPClient.METHOD_POST, json_payload)
59
+
60
+
61
+
func _create_record_handler(_result, code, _headers, body: PoolByteArray, req: HTTPRequest, callback: FuncRef):
62
+
req.queue_free()
63
+
if callback == null:
64
+
return
65
+
66
+
var res = parse_json(body.get_string_from_utf8())
67
+
callback.call_func(res)
68
+
69
+
## LIST RECORDS
70
+
71
+
func list_records(callback: FuncRef, collection: String, limit: int = 50, cursor = ""):
72
+
var query_string = "repo=" + did
73
+
query_string += "&collection=" + collection.http_escape()
74
+
query_string += "&limit=" + str(limit).http_escape()
75
+
query_string += "&cursor=" + str(limit).http_escape()
76
+
var req_str = pds + "/xrpc/com.atproto.repo.listRecords?" + query_string
77
+
78
+
var req = HTTPRequest.new()
79
+
self.add_child(req)
80
+
req.connect("request_completed", self, "_list_record_handler", [req, callback])
81
+
req.request(req_str, get_header(), true, HTTPClient.METHOD_GET)
82
+
83
+
func _list_record_handler(_result, code, _headers, body: PoolByteArray, req: HTTPRequest, callback: FuncRef):
84
+
req.queue_free()
85
+
var b = body.get_string_from_utf8()
86
+
var res = parse_json(b)
87
+
callback.call_func(res.records)
88
+
89
+
90
+
## GET RECORD
91
+
92
+
func get_record(callback: FuncRef, did: String, collection: String, rkey: String):
93
+
var query_string = "repo=" + did.http_escape()
94
+
query_string += "&collection=" + collection.http_escape()
95
+
query_string += "&rkey=" + rkey.http_escape()
96
+
97
+
var req = HTTPRequest.new()
98
+
self.add_child(req)
99
+
req.connect("request_completed", self, "_get_record_handler", [req, callback])
100
+
req.request(pds + "/xrpc/com.atproto.repo.getRecord?" + query_string, get_header(), true, HTTPClient.METHOD_GET)
101
+
102
+
func _get_record_handler(_result, code, _headers, body: PoolByteArray, req: HTTPRequest, callback: FuncRef):
103
+
req.queue_free()
104
+
var res = parse_json(body.get_string_from_utf8())
105
+
callback.call_func(res)
106
+
107
+
108
+
## PUT RECORD
109
+
110
+
func put_record(uri, record, callback: FuncRef = null):
111
+
if is_token_expired():
112
+
refresh_token("put_record", [uri, record])
113
+
return
114
+
115
+
var splitted_uri = uri.split("/")
116
+
117
+
118
+
var payload = {
119
+
repo = splitted_uri[2],
120
+
collection = splitted_uri[3],
121
+
rkey = splitted_uri[4],
122
+
record = record
123
+
}
124
+
125
+
var json_payload = JSON.print(payload)
126
+
json_payload = json_payload.replace("at_type", "$type")
127
+
128
+
var req = HTTPRequest.new()
129
+
self.add_child(req)
130
+
req.connect("request_completed", self, "_put_record_handler", [req, callback])
131
+
req.request(pds + "/xrpc/com.atproto.repo.putRecord", get_header(), true, HTTPClient.METHOD_POST, json_payload)
132
+
133
+
func _put_record_handler(_result, code, _headers, body: PoolByteArray, req: HTTPRequest, callback: FuncRef):
134
+
req.queue_free()
135
+
if callback == null:
136
+
return
137
+
var res = parse_json(body.get_string_from_utf8())
138
+
callback.call_func(res)
139
+
140
+
################
141
+
# LOGIN #
142
+
################
143
+
144
+
func login(handle, password):
145
+
var req = HTTPRequest.new()
146
+
self.add_child(req)
147
+
148
+
req.connect("request_completed", self, "after_handle_resolver", [req, password])
149
+
req.request("https://bsky.social/xrpc/com.atproto.identity.resolveHandle?handle=" + handle)
150
+
151
+
152
+
func after_handle_resolver(_result, code, _headers, body: PoolByteArray, req: HTTPRequest, password):
153
+
req.disconnect("request_completed", self, "after_handle_resolver")
154
+
155
+
if code != 200:
156
+
emit_signal("connection", false)
157
+
return
158
+
159
+
var res = parse_json(body.get_string_from_utf8())
160
+
self.did = res.did
161
+
162
+
req.connect("request_completed", self, "after_get_pds", [req, password])
163
+
req.request("https://plc.directory/" + self.did)
164
+
165
+
166
+
func after_get_pds(_result, code, _headers, body: PoolByteArray,req: HTTPRequest, password):
167
+
req.disconnect("request_completed", self, "after_get_pds")
168
+
169
+
if code != 200:
170
+
emit_signal("connection", false)
171
+
return
172
+
173
+
var res = parse_json(body.get_string_from_utf8())
174
+
for x in res.service:
175
+
if x.id == "#atproto_pds":
176
+
self.pds = x.serviceEndpoint
177
+
178
+
var payload = {
179
+
identifier = self.did,
180
+
password = password
181
+
}
182
+
183
+
req.connect("request_completed", self, "after_create_session", [req])
184
+
req.request(pds + "/xrpc/com.atproto.server.createSession", ["Content-Type: application/json"], true, HTTPClient.METHOD_POST, JSON.print(payload))
185
+
186
+
187
+
func after_create_session(_result, code, _headers, body: PoolByteArray, req: HTTPRequest):
188
+
req.queue_free()
189
+
190
+
if code != 200:
191
+
emit_signal("connection", false)
192
+
return
193
+
194
+
var res = parse_json(body.get_string_from_utf8())
195
+
self.accessJwt = res.accessJwt
196
+
self.refreshJwt = res.refreshJwt
197
+
emit_signal("connection", true)
198
+
199
+
#######################
200
+
# REFRESH TOKEN #
201
+
#######################
202
+
func refresh_token(method = "", payload = []):
203
+
var req = self.requester
204
+
205
+
var headers = [
206
+
"Authorization: Bearer " + self.refreshJwt,
207
+
"Content-Type: application/json"
208
+
]
209
+
req.connect("request_completed", self, "after_refresh_token", [method, payload])
210
+
req.request(pds + "/xrpc/com.atproto.server.refreshSession", headers, true, HTTPClient.METHOD_POST)
211
+
212
+
func after_refresh_token(_result, _response_code, _headers, body: PoolByteArray, method, payload):
213
+
var req = self.requester
214
+
req.disconnect("request_completed", self, "after_refresh_token")
215
+
216
+
var res = parse_json(body.get_string_from_utf8())
217
+
self.accessJwt = res.accessJwt
218
+
self.refreshJwt = res.refreshJwt
219
+
220
+
if method != "":
221
+
self.callv(method, payload)
222
+
223
+
224
+
######################
225
+
# Method Calls #
226
+
######################
227
+
228
+
func catch_fish(fish, size, quality):
229
+
var fish_data = Globals.item_data[fish]["file"]
230
+
var record = {
231
+
at_type = "dev.regnault.webfishing.fish",
232
+
id = fish,
233
+
name = fish_data.item_name,
234
+
size = str(size),
235
+
quality = quality
236
+
}
237
+
create_record(record)
238
+
239
+
240
+
# SAVES
241
+
242
+
func create_save_file(uri: String, filename: String, callback: FuncRef = null):
243
+
var record = {
244
+
at_type = "dev.regnault.webfishing.savefile",
245
+
uri = uri,
246
+
name = filename,
247
+
}
248
+
create_record(record, callback)
249
+
pass
250
+
251
+
func get_saves(callback: FuncRef):
252
+
list_records(callback, "dev.regnault.webfishing.savefile")
253
+
254
+
255
+
func get_save_data():
256
+
var save_data = {
257
+
"inventory": PlayerData.inventory,
258
+
"hotbar": PlayerData.hotbar,
259
+
"cosmetics_unlocked": PlayerData.cosmetics_unlocked,
260
+
"cosmetics_equipped": PlayerData.cosmetics_equipped,
261
+
"new_cosmetics": [],
262
+
"version": Globals.GAME_VERSION,
263
+
"muted_players": PlayerData.players_muted,
264
+
"hidden_players": PlayerData.players_hidden,
265
+
"recorded_time": PlayerData.last_recorded_time,
266
+
"money": PlayerData.money,
267
+
"bait_inv": PlayerData.bait_inv,
268
+
"bait_selected": PlayerData.bait_selected,
269
+
"bait_unlocked": PlayerData.bait_unlocked,
270
+
"shop": PlayerData.current_shop,
271
+
"journal": PlayerData.journal_logs,
272
+
"quests": PlayerData.current_quests,
273
+
"completed_quests": PlayerData.completed_quests,
274
+
"level": PlayerData.badge_level,
275
+
"xp": PlayerData.badge_xp,
276
+
"max_bait": PlayerData.max_bait,
277
+
"lure_unlocked": PlayerData.lure_unlocked,
278
+
"lure_selected": PlayerData.lure_selected,
279
+
"saved_aqua_fish": PlayerData.saved_aqua_fish,
280
+
"inbound_mail": PlayerData.inbound_mail,
281
+
"rod_power": PlayerData.rod_power_level,
282
+
"rod_speed": PlayerData.rod_speed_level,
283
+
"rod_chance": PlayerData.rod_chance_level,
284
+
"rod_luck": PlayerData.rod_luck_level,
285
+
"saved_tags": PlayerData.saved_tags,
286
+
"loan_level": PlayerData.loan_level,
287
+
"loan_left": PlayerData.loan_left,
288
+
"buddy_level": PlayerData.buddy_level,
289
+
"buddy_speed": PlayerData.buddy_speed,
290
+
"guitar_shapes": PlayerData.guitar_shapes,
291
+
"fish_caught": PlayerData.fish_caught,
292
+
"cash_total": PlayerData.cash_total,
293
+
"voice_pitch": PlayerData.voice_pitch,
294
+
"voice_speed": PlayerData.voice_speed,
295
+
"locked_refs": PlayerData.locked_refs,
296
+
}
297
+
save_data = save_data.duplicate(true)
298
+
299
+
# JOURNAL
300
+
var modified_journal = []
301
+
for area in save_data.journal:
302
+
var area_entry = {
303
+
name = area,
304
+
entries = []
305
+
}
306
+
for entry_name in save_data.journal[area]:
307
+
var entry = save_data.journal[area][entry_name]
308
+
area_entry.entries.append({
309
+
name = entry_name,
310
+
count = entry.count,
311
+
record = str(entry.record),
312
+
quality = entry.quality
313
+
})
314
+
modified_journal.append(area_entry)
315
+
save_data.journal = modified_journal
316
+
317
+
# Quests
318
+
var modified_quests = []
319
+
for quest_id in save_data.quests:
320
+
var entry = save_data.quests[quest_id].duplicate(true)
321
+
entry.id = quest_id
322
+
modified_quests.append(entry)
323
+
save_data.quests = modified_quests
324
+
325
+
# Inventory
326
+
for item in save_data.inventory:
327
+
item.size = str(item.size)
328
+
329
+
330
+
# Version
331
+
save_data.version = str(save_data.version)
332
+
333
+
# Voice Pitch
334
+
save_data.voice_pitch = str(save_data.voice_pitch)
335
+
336
+
# Aqua Fish
337
+
save_data.saved_aqua_fish.size = str(save_data.saved_aqua_fish.size)
338
+
339
+
# Letters
340
+
for letter in save_data.inbound_mail:
341
+
for item in letter.items:
342
+
item.size = str(item.size)
343
+
344
+
return save_data
345
+
346
+
func save_file(callback: FuncRef = null, creation = false):
347
+
if UserSave.current_loaded_slot != Atproto.ATPROTO_SLOT:
348
+
return
349
+
if !connected(): return
350
+
351
+
var save_data = get_save_data()
352
+
save_data.at_type = "dev.regnault.webfishing.save"
353
+
354
+
if Atproto.save_loaded != "":
355
+
put_record(Atproto.save_loaded, save_data)
356
+
357
+
func create_save(callback: FuncRef = null):
358
+
if !connected(): return
359
+
var save_data = get_save_data()
360
+
save_data.at_type = "dev.regnault.webfishing.save"
361
+
create_record(save_data, callback)
362
+
363
+
func load_save(uri: String):
364
+
var splitted_uri = uri.split("/")
365
+
var did = splitted_uri[2]
366
+
var collection = splitted_uri[3]
367
+
var rkey = splitted_uri[4]
368
+
get_record(funcref(self, "_after_get_save"), did, collection, rkey)
369
+
pass
370
+
371
+
func _after_get_save(save_record):
372
+
var save = save_record.value
373
+
374
+
UserSave._load_save(Atproto.ATPROTO_SLOT)
375
+
376
+
var modified_journal: Dictionary = {}
377
+
for area in save.journal:
378
+
var area_entries = {}
379
+
for entry in area.entries:
380
+
var new_quality = []
381
+
for x in entry.quality:
382
+
if !new_quality.has(int(x)):
383
+
new_quality.append(int(x))
384
+
area_entries[entry.name] = {
385
+
count = entry.count,
386
+
record = float(entry.record),
387
+
quality = new_quality
388
+
}
389
+
390
+
modified_journal[area.name] = area_entries
391
+
save.journal = modified_journal
392
+
393
+
var modified_quests = {}
394
+
for quest in save.quests:
395
+
var id = quest.id
396
+
modified_quests[quest.id] = quest
397
+
modified_quests[quest.id].erase("id")
398
+
save.quests = modified_quests
399
+
400
+
# Inventory
401
+
for item in save.inventory:
402
+
item.size = float(item.size)
403
+
item.quality = int(item.quality)
404
+
405
+
save.version = float(save.version)
406
+
save.saved_aqua_fish.quality = int(save.saved_aqua_fish.quality)
407
+
save.saved_aqua_fish.size = float(save.saved_aqua_fish.size)
408
+
for letter in save.inbound_mail:
409
+
for item in letter.items:
410
+
item.size = float(item.size)
411
+
item.quality = int(item.quality)
412
+
413
+
var modified_hotbar = {}
414
+
for item in save.hotbar:
415
+
modified_hotbar[int(item)] = save.hotbar[item]
416
+
save.hotbar = modified_hotbar
417
+
418
+
PlayerData.inventory = save.inventory
419
+
PlayerData.hotbar = save.hotbar
420
+
PlayerData.cosmetics_unlocked = save.cosmetics_unlocked
421
+
PlayerData.cosmetics_equipped = save.cosmetics_equipped
422
+
PlayerData.money = save.money
423
+
PlayerData.players_muted = save.muted_players
424
+
PlayerData.players_hidden = save.hidden_players
425
+
PlayerData.bait_inv = save.bait_inv
426
+
PlayerData.bait_selected = save.bait_selected
427
+
PlayerData.bait_unlocked = save.bait_unlocked
428
+
PlayerData.max_bait = save.max_bait
429
+
PlayerData.lure_unlocked = save.lure_unlocked
430
+
PlayerData.lure_selected = save.lure_selected
431
+
PlayerData.journal_logs = save.journal
432
+
PlayerData.current_quests = save.quests
433
+
PlayerData.completed_quests = save.completed_quests
434
+
PlayerData.badge_level = int(save.level)
435
+
PlayerData.badge_xp = int(save.xp)
436
+
PlayerData.saved_aqua_fish = save.saved_aqua_fish
437
+
PlayerData.inbound_mail = save.inbound_mail
438
+
PlayerData.saved_tags = save.saved_tags
439
+
PlayerData.loan_level = int(save.loan_level)
440
+
PlayerData.loan_left = save.loan_left
441
+
PlayerData.rod_power_level = save.rod_power
442
+
PlayerData.rod_speed_level = save.rod_speed
443
+
PlayerData.rod_chance_level = save.rod_chance
444
+
PlayerData.rod_luck_level = save.rod_luck
445
+
PlayerData.buddy_level = save.buddy_level
446
+
PlayerData.buddy_speed = save.buddy_speed
447
+
PlayerData.guitar_shapes = save.guitar_shapes
448
+
PlayerData.fish_caught = save.fish_caught
449
+
PlayerData.cash_total = save.cash_total
450
+
PlayerData.voice_pitch = float(save.voice_pitch)
451
+
PlayerData.voice_speed = save.voice_speed
452
+
PlayerData.locked_refs = save.locked_refs
453
+
PlayerData._validate_guitar_shapes()
454
+
PlayerData._validate_inventory()
455
+
PlayerData._journal_check()
456
+
PlayerData._missing_quest_check()
457
+
PlayerData._unlock_defaults()
458
+
459
+
can_save = false
460
+
UserSave._save_slot(Atproto.ATPROTO_SLOT)
461
+
can_save = true
462
+
463
+
emit_signal("savefile_loaded", save_record.uri)
464
+
465
+
+68
project/mods/Atproto/main.gd
+68
project/mods/Atproto/main.gd
···
1
+
extends Node
2
+
3
+
var config: Dictionary
4
+
5
+
const ATPROTO_SLOT = 99
6
+
var save_loaded: String
7
+
var default_config: Dictionary = {}
8
+
9
+
onready var TackleBox := $"/root/TackleBox"
10
+
const AtProtoClient_t := preload("res://mods/Atproto/atproto_client.gd")
11
+
var AtProtoClient: AtProtoClient_t
12
+
13
+
# UI
14
+
const AtProtoMenu := preload("res://mods/Atproto/ui/menus/atproto_config.tscn")
15
+
const AtProtoButton := preload("res://mods/Atproto/ui/buttons/atproto.tscn")
16
+
17
+
var setuped = false
18
+
19
+
func _enter_tree():
20
+
AtProtoClient = AtProtoClient_t.new()
21
+
add_child(AtProtoClient)
22
+
AtProtoClient.connect("savefile_loaded", self, "set_save_file")
23
+
get_tree().connect("node_added", self, "_add_atproto_menu")
24
+
25
+
26
+
func _ready() -> void:
27
+
_init_config()
28
+
29
+
func _init_config():
30
+
var saved_config = TackleBox.get_mod_config(name)
31
+
for key in default_config.keys():
32
+
if not saved_config[key]:
33
+
saved_config[key] = default_config[key]
34
+
config = saved_config
35
+
TackleBox.set_mod_config(name, config)
36
+
if config.Autoconnect == true:
37
+
AtProtoClient.login(config.Handle, config.Password)
38
+
39
+
func _save_config():
40
+
TackleBox.set_mod_config(name, config)
41
+
42
+
func _add_atproto_menu(node: Node):
43
+
if node.name == "main_menu":
44
+
var atproto_menu: Node = AtProtoMenu.instance()
45
+
atproto_menu.visible = false
46
+
node.add_child(atproto_menu)
47
+
48
+
var button = AtProtoButton.instance()
49
+
var menu_list: Node = node.get_node("VBoxContainer")
50
+
var settings_button: Node = menu_list.get_node("settings")
51
+
menu_list.add_child(button)
52
+
menu_list.move_child(button, settings_button.get_index() + 1)
53
+
atproto_menu.connect("setup_done", self, "_after_setup")
54
+
pass
55
+
56
+
func _after_setup():
57
+
if setuped:
58
+
return
59
+
setuped = true
60
+
61
+
if config.Save != "" and config.Autoload and AtProtoClient.connected():
62
+
AtProtoClient.load_save(config.Save)
63
+
64
+
func can_save_to_atproto():
65
+
return AtProtoClient.can_save && UserSave.current_loaded_slot == ATPROTO_SLOT && AtProtoClient.connected()
66
+
67
+
func set_save_file(save_uri):
68
+
save_loaded = save_uri
+21
project/project.godot
+21
project/project.godot
···
1
+
; Engine configuration file.
2
+
; It's best edited using the editor UI and not directly,
3
+
; since the parameters that go here are not all obvious.
4
+
;
5
+
; Format:
6
+
; [section] ; section goes between []
7
+
; param=value ; assign values to parameters
8
+
9
+
config_version=4
10
+
11
+
[application]
12
+
13
+
config/name="AtProto Webfishing"
14
+
15
+
[gui]
16
+
17
+
common/drop_mouse_on_gui_input_disabled=true
18
+
19
+
[physics]
20
+
21
+
common/enable_pause_aware_picking=true