+1
gdscript/.import/.gdignore
+1
gdscript/.import/.gdignore
···
1
+
+143
gdscript/mods/AtProto/atproto.gd
+143
gdscript/mods/AtProto/atproto.gd
···
1
+
extends Node
2
+
class_name AtProto
3
+
4
+
# AtProto
5
+
var did
6
+
var pds
7
+
8
+
var accessJwt
9
+
var refreshJwt
10
+
11
+
12
+
# HTTP
13
+
var requester: HTTPRequest
14
+
15
+
func _enter_tree():
16
+
var root = get_tree().get_root()
17
+
var instance = root.get_node("AtProto")
18
+
self.name = "AtProto"
19
+
if instance == null:
20
+
root.add_child(self, true)
21
+
self.requester = HTTPRequest.new()
22
+
self.add_child(self.requester, true)
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 create_record(record):
32
+
33
+
if is_token_expired():
34
+
refresh_token("create_record", record)
35
+
return
36
+
37
+
var payload = {
38
+
repo = did,
39
+
collection = record.at_type,
40
+
record = record
41
+
}
42
+
43
+
var json_payload = JSON.print(payload)
44
+
json_payload = json_payload.replace("at_type", "$type")
45
+
46
+
var req = self.requester
47
+
48
+
var header = [
49
+
"Authorization: Bearer " + self.accessJwt,
50
+
"Content-Type: application/json"
51
+
]
52
+
53
+
req.request(pds + "/xrpc/com.atproto.repo.createRecord", header, true, HTTPClient.METHOD_POST, json_payload)
54
+
55
+
56
+
################
57
+
# LOGIN #
58
+
################
59
+
60
+
func login(handle, password):
61
+
var req = self.requester
62
+
63
+
req.connect("request_completed", self, "after_handle_resolver", [password])
64
+
req.request("https://bsky.social/xrpc/com.atproto.identity.resolveHandle?handle=" + handle)
65
+
66
+
67
+
func after_handle_resolver(_result, _response_code, _headers, body: PoolByteArray, password):
68
+
var req = self.requester
69
+
req.disconnect("request_completed", self, "after_handle_resolver")
70
+
var res = parse_json(body.get_string_from_utf8())
71
+
self.did = res.did
72
+
73
+
req.connect("request_completed", self, "after_get_pds", [password])
74
+
req.request("https://plc.directory/" + self.did)
75
+
76
+
77
+
func after_get_pds(_result, _response_code, _headers, body: PoolByteArray, password):
78
+
var req = self.requester
79
+
req.disconnect("request_completed", self, "after_get_pds")
80
+
81
+
var res = parse_json(body.get_string_from_utf8())
82
+
for x in res.service:
83
+
if x.id == "#atproto_pds":
84
+
self.pds = x.serviceEndpoint
85
+
86
+
var payload = {
87
+
identifier = self.did,
88
+
password = password
89
+
}
90
+
91
+
req.connect("request_completed", self, "after_create_session")
92
+
req.request(pds + "/xrpc/com.atproto.server.createSession", ["Content-Type: application/json"], true, HTTPClient.METHOD_POST, JSON.print(payload))
93
+
94
+
95
+
96
+
func after_create_session(_result, _response_code, _headers, body: PoolByteArray):
97
+
var req = self.requester
98
+
req.disconnect("request_completed", self, "after_create_session")
99
+
100
+
var res = parse_json(body.get_string_from_utf8())
101
+
self.accessJwt = res.accessJwt
102
+
self.refreshJwt = res.refreshJwt
103
+
104
+
#######################
105
+
# REFRESH TOKEN #
106
+
#######################
107
+
func refresh_token(method = "", payload = ""):
108
+
var req = self.requester
109
+
110
+
var headers = [
111
+
"Authorization: Bearer " + self.refreshJwt,
112
+
"Content-Type: application/json"
113
+
]
114
+
req.connect("request_completed", self, "after_refresh_token", [method, payload])
115
+
req.request(pds + "/xrpc/com.atproto.server.refreshSession", headers, true, HTTPClient.METHOD_POST)
116
+
117
+
func after_refresh_token(_result, _response_code, _headers, body: PoolByteArray, method, payload):
118
+
var req = self.requester
119
+
req.disconnect("request_completed", self, "after_refresh_token")
120
+
121
+
var res = parse_json(body.get_string_from_utf8())
122
+
self.accessJwt = res.accessJwt
123
+
self.refreshJwt = res.refreshJwt
124
+
125
+
if method != "":
126
+
self.call(method, payload)
127
+
128
+
129
+
######################
130
+
# STATIC CALLS #
131
+
######################
132
+
133
+
static func catch_fish(node, fish, size, quality):
134
+
# var fish_data = Globals.item_data[fish]["file"]
135
+
# var record = {
136
+
# at_type = "dev.regnault.webfishing.fish",
137
+
# id = fish,
138
+
# name = fish_data.item_name,
139
+
# size = str(size),
140
+
# quality = quality
141
+
# }
142
+
# node.get_tree().get_root().get_node("AtProto").create_record(record)
143
+
pass
+5
gdscript/mods/AtProto/main.gd
+5
gdscript/mods/AtProto/main.gd
+31
gdscript/project.godot
+31
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
+
_global_script_classes=[ {
12
+
"base": "Node",
13
+
"class": "AtProto",
14
+
"language": "GDScript",
15
+
"path": "res://mods/AtProto/atproto.gd"
16
+
} ]
17
+
_global_script_class_icons={
18
+
"AtProto": ""
19
+
}
20
+
21
+
[application]
22
+
23
+
config/name="Webfishing AtProto"
24
+
25
+
[gui]
26
+
27
+
common/drop_mouse_on_gui_input_disabled=true
28
+
29
+
[physics]
30
+
31
+
common/enable_pause_aware_picking=true