forked from minetest-mods/irc_commands
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinit.lua
218 lines (194 loc) · 5.86 KB
/
init.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
local irc_users = {}
local old_chat_send_player = minetest.chat_send_player
minetest.chat_send_player = function(name, message) -- luacheck: ignore
for nick, loggedInAs in pairs(irc_users) do
if name == loggedInAs and not minetest.get_player_by_name(name) then
irc:say(nick, message)
end
end
return old_chat_send_player(name, message)
end
irc.register_hook("NickChange", function(user, newNick)
for nick, player in pairs(irc_users) do
if nick == user.nick then
irc_users[newNick] = irc_users[user.nick]
irc_users[user.nick] = nil
end
end
end)
irc.register_hook("OnPart", function(user, channel, reason)
irc_users[user.nick] = nil
end)
irc.register_hook("OnKick", function(user, channel, target, reason)
irc_users[target] = nil
end)
irc.register_hook("OnQuit", function(user, reason)
irc_users[user.nick] = nil
end)
irc.register_bot_command("login", {
params = "<username> <password>",
description = "Login as a user to run commands",
func = function(user, args)
if args == "" then
return false, "You need a username and password."
end
local playerName, password = args:match("^(%S+)%s(.+)$")
if not playerName then
return false, "Player name and password required."
end
local inChannel = false
local channel = irc.conn.channels[irc.config.channel]
if not channel then
return false, "The server needs to be in its "..
"channel for anyone to log in."
end
for cnick, cuser in pairs(channel.users) do
if user.nick == cnick then
inChannel = true
break
end
end
if not inChannel then
return false, "You need to be in the server's channel to log in."
end
local handler = minetest.get_auth_handler()
local auth = handler.get_auth(playerName)
if auth and minetest.check_password_entry(playerName, auth.password, password) then
minetest.log("action", "User "..user.nick
.." from IRC logs in as "..playerName)
irc_users[user.nick] = playerName
handler.record_login(playerName)
return true, "You are now logged in as "..playerName
else
minetest.log("action", user.nick.."@IRC attempted to log in as "
..playerName.." unsuccessfully")
return false, "Incorrect password or player does not exist."
end
end
})
irc.register_bot_command("logout", {
description = "Logout",
func = function (user, args)
if irc_users[user.nick] then
minetest.log("action", user.nick.."@IRC logs out from "
..irc_users[user.nick])
irc_users[user.nick] = nil
return true, "You are now logged off."
else
return false, "You are not logged in."
end
end,
})
irc.register_bot_command("cmd", {
params = "<command>",
description = "Run a command on the server",
func = function (user, args)
if args == "" then
return false, "You need a command."
end
if not irc_users[user.nick] then
return false, "You are not logged in."
end
local found, _, commandname, params = args:find("^([^%s]+)%s(.+)$")
if not found then
commandname = args
end
local command = minetest.chatcommands[commandname]
if not command then
return false, "Not a valid command."
end
if not minetest.check_player_privs(irc_users[user.nick], command.privs) then
return false, "Your privileges are insufficient."
end
minetest.log("action", user.nick.."@IRC runs "
..args.." as "..irc_users[user.nick])
return command.func(irc_users[user.nick], (params or ""))
end
})
irc.register_bot_command("say", {
params = "message",
description = "Say something",
func = function (user, args)
if args == "" then
return false, "You need a message."
end
if not irc_users[user.nick] then
return false, "You are not logged in."
end
if not minetest.check_player_privs(irc_users[user.nick], {shout=true}) then
minetest.log("action", ("%s@IRC tried to say %q as %s"
.." without the shout privilege.")
:format(user.nick, args, irc_users[user.nick]))
return false, "You can not shout."
end
minetest.log("action", ("%s@IRC says %q as %s.")
:format(user.nick, args, irc_users[user.nick]))
minetest.chat_send_all("<"..irc_users[user.nick].."@IRC> "..args)
return true, "Message sent successfuly."
end
})
local storage = minetest.get_mod_storage()
local function check_host_login(user)
if type(user) ~= "table" then
local whois = irc.conn:whois(user)
user = {
nick = user,
host = whois.userinfo[4]
}
end
local store = minetest.parse_json(storage:get_string("host_logins")) or {}
if user.host and store[user.host] then
local playerName = store[user.host]
local handler = minetest.get_auth_handler()
minetest.log("action", "User " .. user.nick ..
" from IRC logs in as " .. playerName)
irc_users[user.nick] = playerName
handler.record_login(playerName)
end
end
irc:register_hook("OnJoin", function(user, channel)
if irc.config.nick == user.nick then
minetest.after(1, function()
for nick in pairs(irc.conn.channels[irc.config.channel].users) do
check_host_login(nick)
end
end)
else
check_host_login(user)
end
end)
minetest.register_chatcommand("irc_host", {
privs = { password = true },
func = function(name, param)
local pname, host = string.match(param, "^add ([%a%d_-]+) (.+)$")
pname = pname or string.match(param, "^remove (.+)$")
if not pname then
return false, "Usage: add NAME HOST\nor remove NAME or remove HOST"
end
local msg
local store = minetest.parse_json(storage:get_string("host_logins")) or {}
if host then
store[host] = pname
msg = "Added host for " .. pname .. ": '" .. host .. "'"
else
local removed = false
if store[pname] then
store[pname] = nil
removed = true
end
for key, val in pairs(store) do
if val == pname then
store[key] = nil
removed = true
end
end
if removed then
msg = "Removed host mapping matching " .. pname
else
msg = "Unable to find host mapping matching " .. pname
end
end
storage:set_string("host_logins", minetest.write_json(store))
return true, msg
end
})