diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..ff692d99b1ee03701c386247ed36b2f42ae150b6 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,46 @@ +# irc mod +Copyright (c) 2013, Diego Martinez (kaeza) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# matrix mod +Copyright (c) 2017, Jon Neverland (joenas) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/callback.lua b/callback.lua new file mode 100644 index 0000000000000000000000000000000000000000..f0b9903813cf37aaf5b6151565328af96cd80814 --- /dev/null +++ b/callback.lua @@ -0,0 +1,38 @@ +-- This file is licensed under the terms of the BSD 2-clause license. +-- See LICENSE.txt for details. + +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + if matrix.connected then --and matrix.config.send_join_part then + matrix.say("*** "..name.." joined the game") + end +end) + +minetest.register_on_leaveplayer(function(player, timed_out) + local name = player:get_player_name() + if matrix.connected then -- and matrix.config.send_join_part then + matrix.say("*** "..name.." left the game".. + (timed_out and " (Timed out)" or "")) + end +end) + +minetest.register_on_chat_message(function(name, message) + if not matrix.connected + or message:sub(1, 1) == "/" + or message:sub(1, 5) == "[off]" + --or not matrix.joined_players[name] # TODO fix in player_part + 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 + matrix.say("<"..name.."> "..message) +end) + + +minetest.register_on_shutdown(function() + matrix.disconnect("Game shutting down.") +end) + diff --git a/config.lua b/config.lua new file mode 100644 index 0000000000000000000000000000000000000000..1c248e508ddef226d0e31c0a573c5029a3224980 --- /dev/null +++ b/config.lua @@ -0,0 +1,33 @@ +-- This file is licensed under the terms of the BSD 2-clause license. +-- See LICENSE.txt for details. + +matrix.config = {} + +local function setting(stype, name, default, required) + local value + if stype == "bool" then + value = minetest.setting_getbool("matrix."..name) + elseif stype == "string" then + value = minetest.setting_get("matrix."..name) + elseif stype == "number" then + value = tonumber(minetest.setting_get("matrix."..name)) + end + if value == nil then + if required then + error("Required configuration option matrix.".. + name.." missing.") + end + value = default + end + matrix.config[name] = value +end + +------------------------- +-- BASIC USER SETTINGS -- +------------------------- + +setting("string", "user", nil, true) -- User name, fe @digbot:matrix.org +setting("string", "server", nil, true) -- Server address to connect to +setting("number", "port", 8448) -- Server port to connect to +setting("string", "channel", nil, true) -- Channel to join (not needed?) +setting("string", "password", nil, true) -- Server password diff --git a/description.txt b/description.txt new file mode 100644 index 0000000000000000000000000000000000000000..d0de424f44ae30a9f4d08b60707cce5fc2822f3d --- /dev/null +++ b/description.txt @@ -0,0 +1 @@ +This mod creates a bridge between (multiple) Matrix channels and in-game chat! diff --git a/init.lua b/init.lua new file mode 100644 index 0000000000000000000000000000000000000000..20d45726a20ea186024990b3415932b7922554c8 --- /dev/null +++ b/init.lua @@ -0,0 +1,143 @@ +-- This file is licensed under the terms of the BSD 2-clause license. +-- See LICENSE.txt for details. + +local modpath = minetest.get_modpath(minetest.get_current_modname()) + +-- Handle mod security if needed +local ie, req_ie = _G, minetest.request_insecure_environment +if req_ie then ie = req_ie() end +if not ie then + error("The Matrix mod requires access to insecure functions in order ".. + "to work. Please add the matrix mod to your secure.trusted_mods ".. + "setting or disable the matrix mod.") +end + +ie.package.path = + modpath.."/lua-matrix/?.lua;" + ..ie.package.path + +matrix = { + version = "0.0.1", + joined_players = {}, + connected = false, + modpath = modpath, + lib = lib, +} + +dofile(modpath.."/config.lua") + +local function eprintf(fmt, ...) + minetest.log("info", fmt:format(...)) +end + +local client = require("matrix").client("https://"..matrix.config.server..":"..matrix.config.port) + +client:login_with_password(matrix.config.user, matrix.config.password, true) + +local running, start_ts = true, os.time() * 1000 + +client:hook("invite", function (client, room) + -- When invited to a room, join it + eprintf("Invited to room %s\n", room) + client:join_room(room) +end):hook("logged-in", function (client) + matrix.connected = true + eprintf("Logged in successfully\n") +end):hook("logged-out", function (client) + eprintf("Logged out... bye!\n") + matrix.connected = false +end):hook("left", function (client, room) + eprintf("Left room %s, active rooms:\n", room) + for room_id, room in pairs(client.rooms) do + assert(room_id == room.room_id) + eprintf(" - %s\n", room) + end +end):hook("joined", function (client, room) + eprintf("Active rooms:\n") + for room_id, room in pairs(client.rooms) do + assert(room_id == room.room_id) + eprintf(" - %s\n", room) + end + + room:send_text("Type “!bot quit” to make the bot exit") + + room:hook("message", function (room, sender, message, event) + if event.origin_server_ts < start_ts then + eprintf("%s: (Skipping message sent before bot startup)\n", room) + return + end + if sender == room.client.user_id then + eprintf("%s: (Skipping message sent by ourselves)\n", room) + return + end + if message.msgtype ~= "m.text" then + eprintf("%s: (Message of type %s ignored)\n", room, message.msgtype) + return + end + + eprintf("%s: <%s> %s\n", room, sender, message.body) + + if message.body == "!bot quit" then + for _, room in pairs(client.rooms) do + room:send_text("(gracefully shutting down)") + end + client:logout() + matrix.connected = false + else + minetest.chat_send_all("<"..sender.."> "..message.body) + end + end) +end) + + +dofile(modpath.."/callback.lua") + +local stepnum = 0 + +minetest.register_globalstep(function(dtime) return matrix.step(dtime) end) + +function matrix.step() + if stepnum == 3 then + matrix.connect() + end + stepnum = stepnum + 1 + + if not matrix.connected then return end + + -- Hooks will manage incoming messages and errors + local good, err = xpcall(function() client:_sync() end, debug.traceback) + if not good then + print(err) + return + end +end + +function matrix.connect() + if matrix.connected then + minetest.log("error", "Matrix: already connected") + return + end + client:login_with_password(matrix.config.user, matrix.config.password, true) + matrix.connected = true + minetest.log("action", "Matrix: Connected!") + minetest.chat_send_all("Matrix: Connected!") +end + + +function matrix.disconnect(message) + if matrix.connected then + --The OnDisconnect hook will clear matrix.connected and print a disconnect message + client:logout() + end +end + +function matrix.say(to, message) + if not message then + message = to + to = matrix.config.channel + end + to = to or matrix.config.channel + for room_id, room in pairs(client.rooms) do + room:send_text(message) + end +end diff --git a/lua-matrix b/lua-matrix new file mode 160000 index 0000000000000000000000000000000000000000..2946b558101a22dd0770a2548f938ada86475256 --- /dev/null +++ b/lua-matrix @@ -0,0 +1 @@ +Subproject commit 2946b558101a22dd0770a2548f938ada86475256 diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000000000000000000000000000000000000..5a6944136de3d08b197f1d9825ad1418cba90cf5 --- /dev/null +++ b/mod.conf @@ -0,0 +1 @@ +name = matrix diff --git a/settingtypes.txt b/settingtypes.txt new file mode 100644 index 0000000000000000000000000000000000000000..7bc98f5aa0c1a682b906a5658303a31ffcda4abb --- /dev/null +++ b/settingtypes.txt @@ -0,0 +1,24 @@ + +[Basic] + +# Bots username. May only contain characters A-Z, 0-9 +# '{', '}', '[', ']', '|', '^', '-', or '_'. +matrix.user (Username) string + +# Server to connect to, include http(s) +matrix.server (Matrix server) string https://matrix.org + +# Server port. +# The standard matrix port is 8448 +matrix.port (Server port) int 8448 + +# Channel the bot joins after connecting. +matrix.channel (Channel to join) string #minetest + +# Matrix user password. +matrix.password (Server password) string + +# Accesstoken for User (not used?) +matrix.access_token (Server password) string + +