Skip to content

Commit 8a6ba09

Browse files
authored
feat: add world WebSocket methods (#6)
* feat: sync API surface with asobi backend * feat: add world list/create/join/find_or_create via WebSocket
1 parent bc25036 commit 8a6ba09

File tree

4 files changed

+101
-0
lines changed

4 files changed

+101
-0
lines changed

asobi/api/dm.lua

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
local http_mod = require("asobi.http")
2+
3+
local M = {}
4+
5+
function M.send(client, recipient_id, content, callback)
6+
http_mod.post(client, "/api/v1/dm", {recipient_id = recipient_id, content = content}, callback)
7+
end
8+
9+
function M.history(client, player_id, callback)
10+
http_mod.get(client, "/api/v1/dm/" .. player_id .. "/history", nil, callback)
11+
end
12+
13+
return M

asobi/api/worlds.lua

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
local http_mod = require("asobi.http")
2+
3+
local M = {}
4+
5+
function M.list(client, mode, callback)
6+
local query = nil
7+
if mode then query = {mode = mode} end
8+
http_mod.get(client, "/api/v1/worlds", query, callback)
9+
end
10+
11+
function M.get(client, world_id, callback)
12+
http_mod.get(client, "/api/v1/worlds/" .. world_id, nil, callback)
13+
end
14+
15+
function M.create(client, mode, callback)
16+
http_mod.post(client, "/api/v1/worlds", {mode = mode}, callback)
17+
end
18+
19+
return M

asobi/client.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ local notifications = require("asobi.api.notifications")
1313
local storage = require("asobi.api.storage")
1414
local iap = require("asobi.api.iap")
1515
local votes = require("asobi.api.votes")
16+
local worlds = require("asobi.api.worlds")
17+
local dm = require("asobi.api.dm")
1618

1719
local M = {}
1820

@@ -48,6 +50,8 @@ function M.create(host, port, use_ssl)
4850
client.storage = storage
4951
client.iap = iap
5052
client.votes = votes
53+
client.worlds = worlds
54+
client.dm = dm
5155

5256
realtime_mod.init(client)
5357

asobi/realtime.lua

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ local M = {}
33
M._client = nil
44
M._connection = nil
55
M._cid_counter = 0
6+
M._pending = {}
67
M._callbacks = {
78
on_connected = nil,
89
on_disconnected = nil,
@@ -17,6 +18,9 @@ M._callbacks = {
1718
on_notification = nil,
1819
on_matchmaker_matched = nil,
1920
on_presence_changed = nil,
21+
on_dm_message = nil,
22+
on_world_list = nil,
23+
on_world_joined = nil,
2024
on_error = nil,
2125
}
2226

@@ -92,6 +96,10 @@ function M.cast_veto(vote_id)
9296
M._send("vote.veto", {vote_id = vote_id})
9397
end
9498

99+
function M.send_dm(recipient_id, content)
100+
M._send("dm.send", {recipient_id = recipient_id, content = content})
101+
end
102+
95103
function M.update_presence(status)
96104
M._send("presence.update", {status = status or "online"})
97105
end
@@ -100,6 +108,32 @@ function M.send_heartbeat()
100108
M._send_fire_and_forget("session.heartbeat", {})
101109
end
102110

111+
function M.list_worlds(mode, callback)
112+
local payload = {}
113+
if mode then payload.mode = mode end
114+
M._send_with_callback("world.list", payload, callback)
115+
end
116+
117+
function M.create_world(mode, callback)
118+
M._send_with_callback("world.create", {mode = mode}, callback)
119+
end
120+
121+
function M.join_world(world_id, callback)
122+
M._send_with_callback("world.join", {world_id = world_id}, callback)
123+
end
124+
125+
function M.find_or_create_world(mode, callback)
126+
M._send_with_callback("world.find_or_create", {mode = mode}, callback)
127+
end
128+
129+
function M.send_world_input(input)
130+
M._send_fire_and_forget("world.input", input)
131+
end
132+
133+
function M.leave_world()
134+
M._send("world.leave", {})
135+
end
136+
103137
function M.on(event, callback)
104138
M._callbacks["on_" .. event] = callback
105139
end
@@ -111,6 +145,20 @@ function M._send(msg_type, payload)
111145
websocket.send(M._connection, msg, {type = websocket.DATA_TYPE_TEXT})
112146
end
113147

148+
function M._send_with_callback(msg_type, payload, callback)
149+
if not M._connection then
150+
if callback then callback(nil, "not connected") end
151+
return
152+
end
153+
M._cid_counter = M._cid_counter + 1
154+
local cid = tostring(M._cid_counter)
155+
if callback then
156+
M._pending[cid] = callback
157+
end
158+
local msg = json.encode({type = msg_type, payload = payload, cid = cid})
159+
websocket.send(M._connection, msg, {type = websocket.DATA_TYPE_TEXT})
160+
end
161+
114162
function M._send_fire_and_forget(msg_type, payload)
115163
if not M._connection then return end
116164
local msg = json.encode({type = msg_type, payload = payload})
@@ -123,6 +171,19 @@ function M._handle_message(raw)
123171

124172
local msg_type = msg.type or ""
125173
local payload = msg.payload or {}
174+
local cid = msg.cid
175+
176+
-- Check for pending request-response callbacks
177+
if cid and M._pending[cid] then
178+
local cb = M._pending[cid]
179+
M._pending[cid] = nil
180+
if msg_type == "error" then
181+
cb(nil, payload.reason or "unknown error")
182+
else
183+
cb(payload, nil)
184+
end
185+
return
186+
end
126187

127188
local handlers = {
128189
["session.connected"] = "on_connected",
@@ -137,6 +198,10 @@ function M._handle_message(raw)
137198
["notification.new"] = "on_notification",
138199
["match.matched"] = "on_matchmaker_matched",
139200
["presence.changed"] = "on_presence_changed",
201+
["dm.message"] = "on_dm_message",
202+
["world.list"] = "on_world_list",
203+
["world.joined"] = "on_world_joined",
204+
["world.tick"] = "on_match_state",
140205
["error"] = "on_error",
141206
}
142207

0 commit comments

Comments
 (0)