Code: Select all
--[[
pmprotect.lua by ATAG <[email protected]>
v0.21 @ 2008.09.13
Password Protect for PM
Written in Lua 5.x for BCDC++ and RSX++
(and maybe works on some other CDM clients)
Idea based on SababaDC's "private area protect"
Known bug:
--------------------------------------------------------------
- UserCommand doesn't work on RSX++
Changelog:
--------------------------------------------------------------
v0.21 - 2008.09.13
-fixed: utf8 bug in permament list
-added: hubPM handling (thx to Hungarista)
--------------------------------------------------------------
v0.2 - 2008.09.12
-added: permament exception list
-added: chat commands
-added: UserCommand to lock/unlock a nick
-removed: Lua 5.0 compatibility
--------------------------------------------------------------
v0.1 - 2008.09.12
-first release
--------------------------------------------------------------
]]
-- setup
pmprotect = {}
local password = "" -- leave it empty to generate random password
local warning = "User has been disabled receiving PMs. Use password: %[password] in case of emergency."
-- setup end
-- hub function / UserCommand
dcpp:setListener("connected", "pmprotect",
function(hub)
if hub:getProtocol() ~= "adc" then
hub:injectChat("$UserCommand 1 2 Unlock PM$%[lua:pmprotect.addexception(\"!%!{userNI!}\")]||")
hub:injectChat("$UserCommand 1 2 Lock PM$%[lua:pmprotect.delexception(\"!%!{userNI!}\")]||")
end
end
)
-- chat functions / commands
dcpp:setListener("ownChatOut", "pmprotect",
function(hub, message, ret)
if string.sub(message,1,1) ~= "/" then return nil end
local param = {}
for s in string.gmatch(message, "[^ ]+") do
table.insert(param, s)
end
if param[1] == "/help" then
hub:injectChat( "*** (pmprotect.lua) /unlockpm <nick>, /unlockpm <nick>, /listunlocked, /lockall" )
return nil
elseif param[1] == "/unlockpm" then
if param[2] ~= "" then
if pmprotect.addexception(param[2]) then
hub:injectChat("*** " .. DC():FromUtf8(param[2]) .. " unlocked")
else
hub:injectChat("*** " .. DC():FromUtf8(param[2]) .. " is already unlocked")
end
else
hub:injectChat("*** Usage: /unlockpm <nick>")
end
return 1
elseif param[1] == "/lockpm" then
if param[2] ~= "" then
if pmprotect.delexception(param[2]) then
hub:injectChat("*** " .. DC():FromUtf8(param[2]) .. " locked")
else
hub:injectChat("*** " .. DC():FromUtf8(param[2]) .. " is not unlocked")
end
else
hub:injectChat("*** Usage: /lockpm <nick>")
end
return 1
elseif param[1] == "/listunlocked" then
local buf = {}
for k in pairs(tException) do
table.insert(buf, k)
end
hub:injectChat("*** Permamently unlocked users: " .. table.concat(buf,", "))
return 1
elseif param[1] == "/lockall" then
tException = {}
pmprotect.save()
hub:injectChat("*** All exceptions deleted")
return 1
end
end
)
-- PM function
local handlePM = function( hub, user, msg )
if not user._nick then return nil end -- don't discard PM on lua error
if tPassed[user._nick] or tException[user._nick] then return nil end
local _,_,pass, priv = string.find(msg,"^(%S+)%s*(.*)$")
if pass and pass == password then
tPassed[user._nick] = 1
if priv ~= "" then
DC():InjectHubMessage( hub._id, "$To: "..hub._myNick.." From: "..user._nick.." $<"..user._nick.."> "..priv )
end
else
local message = string.gsub(warning, "%%%[password]", password)
DC():SendHubMessage( hub._id, "$To: "..user._nick.." From: "..hub._myNick.." $<"..hub._myNick.."> "..message.."|" )
end
return 1
end
dcpp:setListener( "pm", "pmprotect", handlePM )
dcpp:setListener( "hubPm", "pmprotect", handlePM )
-- own functions
local GenPass = function(iLength,b1,b2,b3,b4)
-- from PtokaX Remote Administration by Hungarista
math.randomseed(tostring(os.time()):sub(-4))
local tChars, sPass = {}, ""
if b1 then table.insert(tChars,{97,122}) end
if b2 then table.insert(tChars,{65, 90 }) end
if b3 then table.insert(tChars,{48, 57 }) end
if b4 then table.insert(tChars,{{33,47},{58,64}}) end
if #tChars < 1 then return "" end
for i=1,iLength do
local j = math.random(#tChars)
local iFirst,iSecond = tChars[j][1],tChars[j][2]
if type(iFirst) == "table" then
local iGroup = math.random(2)
iFirst,iSecond = tChars[j][iGroup][1],tChars[j][iGroup][2]
end
sPass = sPass..string.char(math.random(iFirst,iSecond))
end
return sPass
end
tPassed = {}
dofile( DC():GetAppPath() .. "/scripts/libsimplepickle.lua" )
pmprotect.addexception = function(nick)
if tException[DC():FromUtf8(nick)] then
DC():PrintDebug("*** " .. nick .. " is already unlocked")
return nil
end
tException[DC():FromUtf8(nick)] = 1
pmprotect.save()
DC():PrintDebug("*** " .. nick .. " unlocked")
return 1
end
pmprotect.delexception = function(nick)
if tException[DC():FromUtf8(nick)] then
tException[DC():FromUtf8(nick)] = nil
pmprotect.save()
DC():PrintDebug("*** " .. nick .. " locked")
return 1
end
DC():PrintDebug("*** " .. nick .. " is not unlocked")
return nil
end
pmprotect.save = function()
pickle.store( DC():GetAppPath() .. "/scripts/pmprotect.txt", { tException = tException } )
end
tException = {}
pmprotect.load = function()
local fname = DC():GetAppPath() .. "/scripts/pmprotect.txt"
local s = loadfile(fname)
if s then
s()
else
local f = io.open(fname,"w+")
if f then f:close() end
end
end
if password == "" then
password = GenPass(8,1,1,1)
end
pmprotect.load()
DC():PrintDebug(" ** Loaded pmprotect.lua ** ")