171 lines
5.1 KiB
Lua
171 lines
5.1 KiB
Lua
|
|
print("Matrix bridge loaded.")
|
|
|
|
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
|
|
|
dofile(modpath.."/config.lua")
|
|
dofile(modpath.."/debug.lua")
|
|
|
|
local http = minetest.request_http_api()
|
|
if http == nil then
|
|
error("Please add matrix_bridge to secure.http_mods")
|
|
end
|
|
|
|
local token = nil
|
|
local txid = 0
|
|
-- used for msync()
|
|
local since = nil
|
|
local last_batch = nil
|
|
|
|
local function mchat(data)
|
|
if data == nil then
|
|
return
|
|
end
|
|
-- lets just get this working
|
|
if data["rooms"] == nil then
|
|
return
|
|
end
|
|
if data["rooms"]["join"] == nil then
|
|
return
|
|
end
|
|
if data["rooms"]["join"][MATRIX_ROOM] == nil then
|
|
return
|
|
end
|
|
if data["rooms"]["join"][MATRIX_ROOM]["timeline"] == nil then
|
|
return
|
|
else
|
|
local events = data["rooms"]["join"][MATRIX_ROOM]["timeline"]["events"]
|
|
if events == nil then
|
|
minetest.log("action", "matrix_bridge - found timeline but no events")
|
|
return
|
|
end
|
|
minetest.log("action", "matrix_bridge - sync'd and found new messages")
|
|
for i, event in ipairs(events) do
|
|
if event.type == "m.room.message"
|
|
and event.sender ~= MATRIX_USERNAME_LONG then
|
|
local message = event.sender .. ": " .. event.content.body
|
|
minetest.chat_send_all(message)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function msync()
|
|
-- optimization note: request more recent instead of unfiltered req
|
|
-- local param1 = '&filter={\"room\":{\"timeline\":{\"limit\":1}}}'
|
|
local param1 = "?access_token=" .. token
|
|
local param2 = "&full_state=false"
|
|
local param3 = "&timeout=30000"
|
|
local u = MATRIX_SERVER.."/_matrix/client/r0/sync" .. param1 .. param2 .. param3
|
|
if since == nil then -- first time sync
|
|
-- do nothing for now
|
|
else -- second time sync -> append since parameter
|
|
u = u .. "&since="..since
|
|
end
|
|
http.fetch({url=u},
|
|
function (res)
|
|
if res == nil then -- received nothing from server
|
|
minetest.log("error", "matrix_bridge - sync response is nil")
|
|
elseif res.code == 0 then
|
|
minetest.log("info", "matrix_bridge - not found / timeout")
|
|
elseif res.code == 404 then
|
|
minetest.log("error", "matrix_bridge - 404")
|
|
else
|
|
local response = minetest.parse_json(res.data)
|
|
if response ~= nil then
|
|
since = response.next_batch
|
|
last_batch = response.prev_batch
|
|
mchat(response)
|
|
end
|
|
end
|
|
end
|
|
)
|
|
end
|
|
|
|
local function mlogin()
|
|
local u = MATRIX_SERVER.."/_matrix/client/r0/login"
|
|
local d = '{"type":"m.login.password","password":"'..MATRIX_PASSWORD..'","identifier":{"type":"m.id.user","user":"'..MATRIX_USERNAME..'"}}'
|
|
local h = {"Content-Type: application/json"}
|
|
http.fetch({url=u, method="POST", extra_headers=h, data=d},
|
|
function(res)
|
|
if res.code == 200 then
|
|
minetest.log("action", res.data)
|
|
local data = minetest.parse_json(res.data)
|
|
token = data.access_token
|
|
minetest.log("action", "Matrix authenticated")
|
|
msync()
|
|
else
|
|
minetest.log("error", to_string(res))
|
|
end
|
|
end
|
|
)
|
|
end
|
|
mlogin()
|
|
|
|
function send_message(msg)
|
|
txid = txid + 1
|
|
http.fetch({
|
|
url = MATRIX_SERVER.."/_matrix/client/r0/rooms/"..MATRIX_ROOM.."/send/m.room.message/"..txid.."?access_token="..token,
|
|
method = "PUT",
|
|
extra_headers = {"Content-Type: application/json"},
|
|
data = minetest.write_json({msgtype="m.text", body=msg})
|
|
}, function(res)
|
|
end)
|
|
end
|
|
|
|
-- http.fetch({
|
|
-- url = MATRIX_SERVER.."/_matrix/client/r0/login",
|
|
-- method = "POST",
|
|
-- extra_headers = {"Content-Type: application/json"},
|
|
-- data = '{"type":"m.login.password","password":"'..MATRIX_PASSWORD..'","identifier":{"type":"m.id.user","user":"'..MATRIX_USERNAME..'"}}'
|
|
-- }, function(res)
|
|
-- if res.code == 200 then
|
|
-- minetest.log("action", res.data)
|
|
-- local data = minetest.parse_json(res.data)
|
|
-- token = data.access_token
|
|
-- minetest.log("action", "Matrix authenticated")
|
|
-- else
|
|
-- minetest.log("error", to_string(res))
|
|
-- end
|
|
-- end)
|
|
|
|
local GLOBAL_STEPS = 0
|
|
minetest.register_globalstep(function(dtine)
|
|
-- print(GLOBAL_STEPS)
|
|
if GLOBAL_STEPS == 4 then
|
|
msync()
|
|
end
|
|
GLOBAL_STEPS = (GLOBAL_STEPS + 1) % 5
|
|
end)
|
|
|
|
minetest.register_on_joinplayer(function(player)
|
|
local name = player:get_player_name()
|
|
if token then
|
|
send_message("*** "..name.." joined the game")
|
|
end
|
|
end)
|
|
|
|
minetest.register_on_leaveplayer(function(player, timed_out)
|
|
local name = player:get_player_name()
|
|
if token then
|
|
send_message("*** "..name.." left the game"..
|
|
(timed_out and " (Timed out)" or ""))
|
|
end
|
|
end)
|
|
|
|
minetest.register_on_chat_message(function(name, message)
|
|
if token == nil
|
|
or message:sub(1, 1) == "/"
|
|
or message:sub(1, 5) == "[off]"
|
|
or (not minetest.check_player_privs(name, {shout=true})) then
|
|
return
|
|
end
|
|
local nl = message:find("\n", 1, true)
|
|
if nl then
|
|
message = message:sub(1, nl - 1)
|
|
end
|
|
send_message("<"..name.."> "..message)
|
|
end)
|
|
|
|
|