/* СТИЛИ */

[#DCBEELINEKZ] БИЛАЙН ХАБЫ КАЗАХСТАН

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » [#DCBEELINEKZ] БИЛАЙН ХАБЫ КАЗАХСТАН » DIRECT CONNECT » СКРИПТЫ


СКРИПТЫ

Сообщений 1 страница 26 из 26

1

2

История чата с сохранением в файл

Название скрипта: ShortChatHistory
Версия скрипта: 3.2 (2016-01-12)
Описание: Показывает последние сообщения чата по команде и при входе в хаб.
Хабсофт: PtokaX 0.4.1.1 и выше (под более ранними не проверялось)
Версия Lua: 5.1/5.3
Автор: Alexey

Код:
local tCfg = {
	-- ник бота, оставьте "" для использования имени бота хаба
	sBot = "",
	-- отправлять меню при входе в хаб, 1 или 0
	bMenuOnEntry = 1,
	-- сохранять +me сообщения, 1 или 0
	bLogMeCmds = 1,
	-- укорачивать сообщения в истории чата до этого количества символов
	-- оставьте 0, если укорачивать не требуется
	iMaxLen = 0,
	-- максимальное количество сохраняемых в истории чата сообщений
	iMaxMsgs = 100,
	-- количество сообщений при входе в хаб
	iMsgsOnEntry = 12,
	-- корректировка времени, секунд
	iTimeOffset = 0,
	-- интервал автосохранения истории, минут
	iAutoSave = 1,
	-- формат времени написания сообщений в истории чата
	sTimeStamp = "[%H:%M:%S] ",
	-- относительный путь к файлу сохранения истории
	sFile	= "Chat.dat",
	iMenuDefaultContext = 3,
}
local tCmdsConf = { -- настройки команд: название команды; профили с доступом к команде;
-- использовать ли указанные профили при формировании пула профилей-получателей отчётов;
-- создавать меню для команды; показывать команду в справке; очерёдность в меню и в справке;
-- правила создания меню (контекст, родительское меню, название строки с переводом дополнительных параметров,
-- сырые дополнительные параметры меню, разделитель над меню); параметры команды для справки
	tScriptHelp    = { "histhelp",    {0,1,2,3,4,-1},    0, 1, 1, 90,
            {3,"","","",1} },
	tGlobalHelp    = { "help",    	{0,1,2,3,4,-1},    0, 0, 0, 99 },

	tGetChatHistory	= { "history",    {0,1,2,3,4,-1},    0, 1, 1, 10,
            {3, "", "sMenuShowParams"},	" <count>"},
	tDelMsgByString	= { "chdelstr",    {0,1,2},    	1, 1, 1, 20,
            {3, "", "sMenuDMBSParams"},	" <text>"},
	tDelMsgFromNick	= { "chdelnick",	{0,1,2},    	1, 1, 1, 30,
            {	{3,"","sMenuDMBNParams"}, {2,"",""," %[nick]"},	},	" <nick>"},
	tDelMsg    	= { "chdelmsg", 	{0,1,2},    	1, 1, 1, 40,
            {3, "", "sMenuDMParams"},    " <number>[ <number>]"},
	tDelChatHistory	= { "chdelete", 	{0,1},        1, 1, 1, 50,
            {3, "", "sMenuDCHParams"} },
}
local tExceptions = {	-- шаблоны, сообщения с которыми обрезаться не будут
	"magnet:%?xt=urn:tree:tiger:[a-zA-Z%d]+&xl=%-?%d+&dn=%S+",	-- магнет-ссылки
	"https?://%S+",	-- веб-ссылки
	"www%.%S+",    -- веб-ссылки
	"ftp[:.]%S+",	-- фтп-ссылки
	"dchub://%S+",	-- хаб-ссылки
}
-- соответствие страны пользователя языку получаемых им сообщений от скрипта
local tLangs = {
	Status	= "Russian",	-- Рассылка операторам
}

local tMsgs = {}
tMsgs["Russian"] = {
	sBadBotName	= "Имя бота содержит запрещённые символы ($ или | или пробел). Они были заменены на их коды.",
	sCHEmpty	= "История чата пуста.",
	sCHLong    = "Последние [COUNT] сообщений в чате:\n [MSGS]\n",
	sCHShort	= "Предыдущие сообщения в чате:",
	sCHCleared	= "%s очистил историю чата.",
	sDelMsg    = "%s удалил из истории чата %s сообщений: %s",
	sDelMsgNick	= "%s удалил из истории чата %s сообщений от ника '%s'.",
	sDelMsgPat	= "%s удалил из истории чата %s сообщений, содержащих строку '%s'.",
	sHelpHeader	= "Вам доступны следующие команды:\n",
	sMsgNotFound	= "%s\n\tСообщение #%s не найдено.",
	sNickNotFound	= "В истории чата не найдено сообщений от ника '%s'.",
	sNoArg    = "Не найден необходимый параметр команды.",
	sFileError	= "Не удалось открыть файл",
	sPatternNotFound = "В истории чата не найдено сообщений, содержащих строку '%s'.",
	sRegBotFail    = "Не удалось зарегистрировать бота '%s'.",
	sSubMenu    = "История чата",
	sMenuDCHParams    = "Вы действительно хотите удалить все сообщения в истории чата?",
	sMenuDMBNParams    = "Введите ник",
	sMenuDMBSParams    = "Введите образец строки для удаления",
	sMenuDMParams    = "Введите номера удаляемых сообщений (через пробел)",
	sMenuShowParams    = "Сколько сообщений показать?",

	sHelpDelChatHistory	= "очистить историю чата",
	sHelpDelMsg    	= "удалить сообщения с указанными номерами (нумерация от новейшего сообщения)",
	sHelpDelMsgByString = "удалить сообщения, содержащие указанный образец текста",
	sHelpDelMsgFromNick = "удалить сообщения от указанного ника",
	sHelpGetChatHistory = "показать последние <count> сообщений в истории чата (без параметра - все сообщения)",
	sHelpScriptHelp    = "эта справка по командам",
	sMenuDelChatHistory	= "Очистить",
	sMenuDelMsg    	= "Удалить по номеру",
	sMenuDelMsgByString = "Удалить по образцу",
	sMenuDelMsgFromNick = "Удалить сообщения ника",
	sMenuDelMsgFromNick2 = "Удалить сообщения этого юзера",
	sMenuGetChatHistory	= "Показать",
	sMenuScriptHelp    = "Справка",
}


------------------------------------------------------------

local tCmds, tChat, sChatHistory
local tUC, tHelp = {}, {}
local bToSave, bChanges = true, true

function OnError(sErrMsg)
	Core.SendToOps("<"..Core.GetHubSecAlias().."> Error "..sErrMsg)
	return true
end

function OnStartup()
	tCfg.sBot = tCfg.sBot and tCfg.sBot ~= "" and tCfg.sBot
    or SetMan.GetString( SetMan.tStrings and SetMan.tStrings.HubBotNick or 21 )
	for i,v in pairs(tCfg) do
    if i:byte(1) == 98 then -- b
    	tCfg[i] = v == 1
    end
	end
	tCfg.bTruncateMsgs = tCfg.iMaxLen ~= 0

	local sPrefixes = SetMan.GetString( SetMan.tStrings and SetMan.tStrings.ChatCommandsPrefixes or 29 )
	if not sPrefixes or #sPrefixes == 0 then sPrefixes = "!" end
	local sPrefix = sPrefixes:sub(1,1)
	sPrefixes = sPrefixes:gsub("[%^%%%.%[%]%-]","%%%1")
	tCfg.sMcPattern = "^<[^ |$]+> %s*(["..sPrefixes.."]%S+)"
	tCfg.sPmPattern = "^$To:%s+([^ ]+)%s+From:%s+[^ ]+%s+$<[^ |$]+>( %s*["..sPrefixes.."](%S+).*)|$"
	local sUC = "$UserCommand 1 [CONTEXT] [MENU]$<%[mynick]> [COMMAND][PARAMS]||"

	if not tLangs.Status	then tLangs.Status	= next(tMsgs) end
	if not tLangs.Other    then tLangs.Other	= tLangs.Status end
	if not tLangs.NoIP2C	then tLangs.NoIP2C	= tLangs.Status end
	local t = {}
	for i,v in pairs(tLangs) do
    if not tMsgs[v] then
    	table.insert(t, i)
    end
	end
	for i,v in ipairs(t) do tLangs[v] = nil end

	for sLangName, tLangMsgs in pairs(tMsgs) do
    t = {}
    for i,v in pairs(tLangMsgs) do
    	if (i:sub(1,5) == "sMenu" or i:sub(1,5) == "sHelp") and #v == 0 then
        table.insert(t, i)
    	end
    end
    for i,v in ipairs(t) do tLangMsgs[v] = nil end
	end

	local tTempStrings, tTempUC, tTempHelp, tReportToProfs = {}, {}, {}, {}
	for k,tComConf in pairs(tCmdsConf) do
    tTempStrings[k] = {}
    for sLangName, tLangMsgs in pairs(tMsgs) do
    	tTempStrings[k][sLangName] = {}
    	local tTempStringsLang = tTempStrings[k][sLangName]
    	if tComConf[4] == 1 then
        if tComConf[7] and tComConf[7][1] and type(tComConf[7][1]) == 'table' then
        	for i,v in ipairs(tComConf[7]) do
            local sSubMenu = tLangMsgs['sSubMenu'..(v[2] or "")]
            if v[5] then
            	tTempStringsLang[1] = (tTempStringsLang[1] or "").."$UserCommand 0 "..(v[1] or tCfg.iMenuDefaultContext).." |"
            end
            tTempStringsLang[1] = (tTempStringsLang[1] or "")..(sUC:gsub("%[([A-Z]+)%]", {
            	CONTEXT	= v[1] or tCfg.iMenuDefaultContext,
            	MENU	= (sSubMenu and #sSubMenu ~= 0 and sSubMenu.."\\" or "")
                ..(tLangMsgs["sMenu"..k:sub(2)..i] or tLangMsgs["sMenu"..k:sub(2)] or k:sub(2)),
            	COMMAND = sPrefix..tComConf[1],
            	PARAMS	=
                  (v[3] and #v[3] ~= 0 and (" %%[line:%s]"):format(tLangMsgs[ v[3] ]) or "")
                ..(v[4] and #v[4] ~= 0 and v[4]  or ""),
            }))
        	end
        else
        	local sSubMenu = tLangMsgs['sSubMenu'..(tComConf[7] and tComConf[7][2] or "")]
        	if tComConf[7] and tComConf[7][5] then
            tTempStringsLang[1] = "$UserCommand 0 "..(tComConf[7][1] or tCfg.iMenuDefaultContext).." |"
        	end
        	tTempStringsLang[1] = (tTempStringsLang[1] or "")..(sUC:gsub("%[([A-Z]+)%]", {
            CONTEXT	= tComConf[7] and tComConf[7][1] or tCfg.iMenuDefaultContext,
            MENU	= (sSubMenu and #sSubMenu ~= 0 and sSubMenu.."\\" or "")
            	..(tLangMsgs["sMenu"..k:sub(2)] or k:sub(2)),
            COMMAND = sPrefix..tComConf[1],
            PARAMS	= (
            	tComConf[7] and tComConf[7][3] and #tComConf[7][3] ~= 0
            	and (" %%[line:%s]"):format(tLangMsgs[ tComConf[7][3] ]) or ""
            ) .. (
            	tComConf[7] and tComConf[7][4] and #tComConf[7][4] ~= 0
            	and tComConf[7][4] or ""
            ),
        	}))
        end
    	else
        tTempStringsLang[1] = ""
    	end
    	table.insert(tTempStringsLang, tComConf[5] == 1 and ("\n\t%s%s%s - %s."):format(
        sPrefix, tComConf[1], tComConf[8] or "", tLangMsgs["sHelp"..k:sub(2)] or "not described yet") or "")
    end

    local tPerms = {}
    for _,iProf in ipairs(tComConf[2]) do
    	tPerms[iProf] = true

    	if tComConf[3] == 1 then
        tReportToProfs[iProf] = true
    	end

    	if tComConf[4] == 1 then
        if not tTempUC[iProf] then tTempUC[iProf] = {} end
        table.insert(tTempUC[iProf], k)
    	end
    	if tComConf[5] == 1 then
        if not tTempHelp[iProf] then tTempHelp[iProf] = {} end
        table.insert(tTempHelp[iProf], k)
    	end
    end
    if tCmds[tComConf[1]] then
    	table.insert(tCmds[tComConf[1]], tPerms)
    end
	end

	for iProf,tComs in pairs(tTempUC) do
    table.sort(tComs, function(a,b) return tCmdsConf[a][6] < tCmdsConf[b][6] end)
    for _,sCmdsConfIdx in ipairs(tComs) do
    	for sLangName, tLangUC in pairs(tTempStrings[sCmdsConfIdx]) do
        if not tUC[sLangName] then tUC[sLangName] = {} end
        tUC[sLangName][iProf] = (tUC[sLangName][iProf] or "")..tLangUC[1]
    	end
    end
	end
	for iProf,tComs in pairs(tTempHelp) do
    table.sort(tComs, function(a,b) return tCmdsConf[a][6] < tCmdsConf[b][6] end)
    for _,sCmdsConfIdx in ipairs(tComs) do
    	for sLangName, tLangHelp in pairs(tTempStrings[sCmdsConfIdx]) do
        if not tHelp[sLangName] then tHelp[sLangName] = {} end
        tHelp[sLangName][iProf] = (tHelp[sLangName][iProf] or "")..tLangHelp[2]
    	end
    end
	end

	local tReportTo = {}
	for i in pairs(tReportToProfs) do
    table.insert(tReportTo, i)
	end
	if #tReportTo == 0 then table.insert(tReportTo, 0) end
	Report = function(sMsg)
    if SetMan.GetBool( SetMan.tBooleans and SetMan.tBooleans.SendStatusMessagesAsPm or 30 ) then
    	local sMsg = "*** "..tostring(sMsg)
    	for i,v in ipairs(tReportTo) do
        Core.SendPmToProfile(v, tCfg.sBot, sMsg)
    	end
    else
    	local sMsg = "<"..tCfg.sBot.."> *** "..tostring(sMsg)
    	for i,v in ipairs(tReportTo) do
        Core.SendToProfile(v, sMsg)
    	end
    end
	end

	local bBotExists
	if tCfg.sBot == SetMan.GetString( SetMan.tStrings and SetMan.tStrings.HubBotNick or 21 ) then
    bBotExists = true
	else
    for i,v in ipairs(Core.GetBots()) do
    	if v.sName == tCfg.sBot then
        bBotExists = true
        break
    	end
    end
	end
	if not bBotExists then
    if tCfg.sBot:find"[|$ ]" then
    	tCfg.sBot = tCfg.sBot:gsub("[|$ ]", function(s) return('\\'..string.byte(s)) end)
    	Report(tMsgs[tLangs.Status].sBadBotName)
    end
    if not Core.RegBot(tCfg.sBot,"","",true) then
    	Report(tMsgs[tLangs.Status].sRegBotFail:format(tCfg.sBot))
    end
	end

	tCfg.sFile = Core.GetPtokaXPath().."scripts/"..tCfg.sFile
	local Ret = loadfile(tCfg.sFile)
	if Ret then Ret() end

	tChat = _G.tChat or {}
	while #tChat > tCfg.iMaxMsgs do
    table.remove(tChat, 1)
	end
	tCfg.iAutoSave = tCfg.iAutoSave * 60 * 1000
	TmrMan.AddTimer(tCfg.iAutoSave, 'OnExit')
	OnExit()
end

function Serialize(tTable, sTableName, hFile, sTab)
	sTab = sTab or ''
	hFile:write(sTab..sTableName.." = {\n")
	for k, v in pairs(tTable) do
    if type(v) ~= "function" then
    	local sKey = type(k) == "string" and ("[%q]"):format(k) or ("[%d]"):format(k)
    	if type(v) == "table" then
        Serialize(v, sKey, hFile, sTab..'\t')
    	else
        local sValue = type(v) == "string" and ("%q"):format(v) or tostring(v)
        hFile:write(sTab..'\t'..sKey.." = "..sValue)
    	end
    	hFile:write(",\n")
    end
	end
	hFile:write(sTab.."}")
end

function SaveTable(sFile, tTable, sTableName)
	local hFile, sErr = io.open(sFile, "w+")
	if hFile then
    Serialize(tTable, sTableName, hFile)
    hFile:flush()
    hFile:close()
    return true
	end
	error( ("%s %s\n%s"):format(tMsgs[tLangs.Status].sFileError, sFile, sErr), 0 )
end

function OnExit()
	if bToSave then
    bToSave = false
    SaveTable(tCfg.sFile, tChat, "tChat")
	end
end

function ChatArrival(tUser, sData)
	sData = sData:sub(1,-2)
	local sCmdOrNick = sData:match(tCfg.sMcPattern)
	if sCmdOrNick then
    local sCmd = sCmdOrNick:sub(2):lower()
    if tCmds[sCmd] and tCmds[sCmd][2][tUser.iProfile] then
--    	local sLang = tLangs[IP2Country.GetCountryCode(tUser.sIP) or "NoIP2C"] or tLangs.Other
    	local sLang = tLangs[Core.GetUserValue(tUser, 26) or "NoIP2C"] or tLangs.Other
    	local bRet, sResult = tCmds[sCmd][1](tUser, sLang, sData:sub(#tUser.sNick + 3))
    	if sResult and type(sResult) == "string" then
        Core.SendToUser(tUser, "<"..tCfg.sBot.."> "..sResult)
    	end
    	return bRet
    elseif Core.GetUser(sCmdOrNick) or Core.GetUser(sCmdOrNick:sub(1,-2)) then
    	sCmdOrNick = nil
    else
    	sCmdOrNick = sCmdOrNick:match("^.(%a%w+)$")
    end
	end
	if not sData:find"is kicking" and (not sCmdOrNick or (tCfg.bLogMeCmds and sCmdOrNick == "me")) then
    if sCmdOrNick then
    	sData = "* "..tUser.sNick..sData:sub(#tUser.sNick + 7)
    end
    if tCfg.bTruncateMsgs then
    	local bTrimMsg = true
    	local iLen = #sData - #tUser.sNick - 3
    	for i,v in ipairs(tExceptions) do
        if sData:find(v) then
        	bTrimMsg = false
        	break
        end
    	end
    	if bTrimMsg and iLen > tCfg.iMaxLen then
        sData = sData:sub(1, tCfg.iMaxLen - iLen - 1).."[…]"
    	end
    end
    if not bToSave then bToSave = true end
    bChanges = true
    table.insert(tChat, os.date(tCfg.sTimeStamp, os.time() + tCfg.iTimeOffset)..sData)
    while #tChat > tCfg.iMaxMsgs do
    	table.remove(tChat, 1)
    end
	end
end

function ToArrival(tUser, sData)
	local sTo, sMsg, sCmd = sData:match(tCfg.sPmPattern)
	if sTo and sTo == tCfg.sBot and tCmds[sCmd:lower()] and tCmds[sCmd:lower()][2][tUser.iProfile] then
--    local sLang = tLangs[IP2Country.GetCountryCode(tUser.sIP) or "NoIP2C"] or tLangs.Other
    local sLang = tLangs[Core.GetUserValue(tUser, 26) or "NoIP2C"] or tLangs.Other
    local bRet, sResult = tCmds[sCmd:lower()][1](tUser, sLang, sMsg, true)
    if sResult and type(sResult) == "string" then
    	Core.SendPmToUser(tUser, tCfg.sBot, sResult)
    end
    return bRet
	end
end

function UserConnected(tUser)
--	local sLang = tLangs[IP2Country.GetCountryCode(tUser.sIP) or "NoIP2C"] or tLangs.Other
	local sLang = tLangs[Core.GetUserValue(tUser, 26) or "NoIP2C"] or tLangs.Other
	if tCfg.bMenuOnEntry and Core.GetUserValue(tUser, 12) and tUC[sLang] and tUC[sLang][tUser.iProfile] then
    Core.SendToUser(tUser, tUC[sLang][tUser.iProfile])
	end
	if bChanges then
    if #tChat ~= 0 then
    	bChanges = false
    	sChatHistory = ("\n\173%s\n"):format(table.concat(
        tChat, "\n\173", #tChat - math.min(tCfg.iMsgsOnEntry, #tChat) + 1))
    else
    	Core.SendToUser(tUser, "<"..tCfg.sBot.."> "..tMsgs[sLang].sCHEmpty)
    	return
    end
	end
	Core.SendToUser(tUser, ("<%s> %s %s"):format(tCfg.sBot, tMsgs[sLang].sCHShort, sChatHistory) )
end
RegConnected, OpConnected = UserConnected, UserConnected

tCmds = {
	[tCmdsConf.tScriptHelp[1]] = {function(tUser, sLang)
    return true, tMsgs[sLang].sHelpHeader..tHelp[sLang][tUser.iProfile]
	end},
	[tCmdsConf.tGlobalHelp[1]] = {function(tUser, sLang, _, bPM)
    if not bPM and SetMan.GetBool( SetMan.tBooleans and SetMan.tBooleans.ReplyToHubCommandsAsPm or 36 ) then
    	Core.SendPmToUser(tUser, tCfg.sBot, tMsgs[sLang].sHelpHeader..tHelp[sLang][tUser.iProfile])
    	return false
    end
    return false, tMsgs[sLang].sHelpHeader..tHelp[sLang][tUser.iProfile]
	end},

	[tCmdsConf.tGetChatHistory[1]] = {function(tUser, sLang, sData)
    if #tChat == 0 then
    	return true, tMsgs[sLang].sCHEmpty
    end

    local iMsgs = sData:match"^%s+[^ ]+%s+(%d+)"
    iMsgs = math.min(tonumber(iMsgs) or #tChat, #tChat)
    return true, tMsgs[sLang].sCHLong:gsub("%[([A-Z]+)%]", {
    	COUNT = iMsgs,
    	MSGS  = table.concat(tChat, "\n ", #tChat - iMsgs + 1),
    })
	end},
	[tCmdsConf.tDelChatHistory[1]] = {function(tUser)
    tChat = {}
    bToSave = true
    bChanges = true
    Report(tMsgs[tLangs.Status].sCHCleared:format(tUser.sNick))
    return true
	end},
	[tCmdsConf.tDelMsgByString[1]] = {function(tUser, sLang, sData)
    local sPattern = sData:match"^%s+[^ ]+%s+(.*)"
    if not sPattern or sPattern == "" then
    	return true, tMsgs[sLang].sNoArg
    end

    local t = {}
    for i,v in ipairs(tChat) do
    	if v:find(sPattern,1,true) then
        table.insert(t,i)
    	end
    end
    if #t == 0 then
    	return true, tMsgs[sLang].sPatternNotFound:format(sPattern)
    end

    table.sort(t)
    for i=#t,1,-1 do
    	table.remove(tChat, t[i])
    end
    bToSave = true
    bChanges = true
    Report(tMsgs[tLangs.Status].sDelMsgPat:format(tUser.sNick, #t, sPattern))
    return true
	end},
	[tCmdsConf.tDelMsgFromNick[1]] = {function(tUser, sLang, sData)
    local sNick = sData:match"^%s+[^ ]+%s+([^ ]+)"
    if not sNick then
    	return true, tMsgs[sLang].sNoArg
    end

    local sTS = (tCfg.sTimeStamp:gsub("[%^%$%(%)%%%.%[%]%*%+%-%?]","%%%1")):gsub("%%%%[a-zA-Z]","%[%%da-zA-Z%]+")
    local sNickP = sNick:gsub("[%^%$%(%)%%%.%[%]%*%+%-%?]","%%%1")
    local sPattern1 = "^"..sTS.."<"	..sNickP..">"
    local sPattern2 = "^"..sTS.."%* "..sNickP
    local t = {}
    for i,v in ipairs(tChat) do
    	if v:find(sPattern1) or v:find(sPattern2) then
        table.insert(t,i)
    	end
    end
    if #t == 0 then
    	return true, tMsgs[sLang].sNickNotFound:format(sNick)
    end

    table.sort(t)
    for i=#t,1,-1 do
    	table.remove(tChat, t[i])
    end
    bToSave = true
    bChanges = true
    Report(tMsgs[tLangs.Status].sDelMsgNick:format(tUser.sNick, #t, sNick))
    return true
	end},
	[tCmdsConf.tDelMsg[1]] = {function(tUser, sLang, sData)
    local t = {}
    for n in sData:gmatch" (%d+)" do
    	table.insert(t, tonumber(n))
    end
    if #t == 0 then
    	return true, tMsgs[sLang].sNoArg
    end

    local iChat, iCounter, sRet = #tChat, 0, ""
    table.sort(t)
    for i=1,#t do
    	local sMsg = table.remove(tChat, iChat - t[i] + 1)
    	if sMsg then
        iCounter = iCounter + 1
        sRet = ("%s\n\t%s: %s"):format(sRet, t[i], sMsg)
    	else
        sRet = tMsgs[sLang].sMsgNotFound:format(sRet, t[i])
    	end
    end
    if iCounter == 0 then
    	return true, sRet
    end

    bToSave = true
    bChanges = true
    Report(tMsgs[tLangs.Status].sDelMsg:format(tUser.sNick, iCounter, sRet))
    return true
	end},
}

Особенности:

Команды: просмотра истории чата, удаления сообщений по образцу, удаления сообщений по нику автора, удаления сообщений по номеру, полной очистки истории чата и справки по командам.
Меню для команд.
Возможность логирования сообщений от третьего лица (команд +me).
Возможность при сохранении обреза́ть длинные сообщения (при этом не обрезает сообщения с ссылками).
Не сохраняет сообщения кика (is kicking Spamer because: spam).
Не сохраняет сообщения, похожие на команды.
Возможность установить корректировку времени сохраняемых сообщений (если время на сервере отличается от реального).
Сохранение в файл при выключении скрипта (или хаба) и по таймеру (по умолчанию, каждую минуту, если были новые сообщения).
Возможность использовать разный язык сообщений скрипта в зависимости от страны пользователя (по IP).

0

3

FAQ СКРИПТ ОТ ХАБА DCBEELINEKZ

Код:
local sBot = "DCBEELINEKZ"

local sMsg=[[	ЧАСТЫЕ ВОПРОСЫ
  
  
  СКАЧАЙ: magnet:?xt=urn:tree:tiger:L4EJPCQQNVVHARMQU77FDSQNX5ZTOU32ZLWJTOA&xl=28235518&dn=!%D0%9B%D0%A3%D0%A7%D0%A8%D0%98%D0%99+FAQ+%D0%9F%D0%9E+%D0%A5%D0%90%D0%91%D0%90%D0%9C+DC%2B%2B+%5BDCBEELINEKZ%5D+Full.chm
  НАСТРОЙКИ СО СКРИНШОТАМИ
 
 КАК РАСШАРИТЬ СВОИ ФАЙЛЫ
  Файл > Настройки > Шара, выберите папки, которые вы хотите расшарить.
  После того, как закончится хэширование файлов, они появятся в списке ваших файлов.
 
 КАК ПОСМОТРЕТЬ СВОЮ ШАРУ
  Файл > Открыть свой список файлов. Или комбинация клавиш CTRL+SHIFT+L

 КУДА СКАЧИВАЮТСЯ ФАЙЛЫ
  Файл > Папка для скачивания
  Файл > Настройки > Скачивание, в поле Папка для скачиваний по умолчанию 


 КАК ОТМЕНИТЬ СКАЧИВАНИЕ
  Для отмены загрузки файла не достаточно простого нажатия в нижнем
  окне и выборе в меню [Закрыть соединение] Открываем Очередь скачивания,
  через панель Передачи > Очередь скачивания или нажатием CTRL+D,
  по файлу пр.мышью [Удалить] или поставить Установить приоритет > [Пауза]


 КАК ОБНОВИТЬ СВОЙ СПИСОК ФАЙЛОВ
  По мне, в чате вбить команду /refresh, и [Enter] 
  Или: 
  Файл > Обновить свой список файлов, либо зажать CTRL+E.
  Когда в нижнем правом углу процесс хеширования завершиться
  Затем: 
  Файл > Очистить базу данных ТТН от "мертвых" записей.
  Это для того чтобы не презаходить на хаб!


 КАК ПОЛЬЗОВАТЬСЯ ПОИСКОМ
  Зажать Ctrl + S (или значок с простой лупой), или выбрать Вид > Поиск,
  вбить в Поиск...то, что хотите найти, и нажать на [Поиск] 
  Обратите внимание на строчку [Тип файла]. Если вы ищете, например,
  фильм, то указывайте, что вам нужен именно Видео это облегчает поиск.
  Маленький секрет. Поиск иногда помогает ускорить возобновление прерванной скачки.
  Если прерванная скачка не продолжается автоматически
  (хотя все условия есть: источник, расшаренный файл и т.п.),
  нужно набрать имя скачиваемого файла (или часть имени) в Поиске и нажать [Enter].
  Скачка должна продолжиться.
  

 КАК СДЕЛАТЬ ССЫЛКУ НА ФАЙЛ (МАГНЕТ-ССЫЛКА)
  Необходимо открыть ваш список файлов Файл > Открыть свой список файлов, 
  либо зажать CTRL+SHIFT+L, выбрать необходимую папку где хранятся ваши файлы,
  и на необходимом файле(или файлах, при удержание CTRL, более актуально для сериалов, 
  чтобы не выбирать по одному файлу) Пр.мышки Копировать > Копировать магнет-ссылку,
  после чего, смело вставляем содержимое из буфера обмена.

--------------------------------------------------------------------
http://DCBEELINEKZ.1bb.ru МОРЕ ИНФОРМАЦИИ
http://DCBEELINEKZ.do.am САЙТ БИЛАЙН ХАБЫ КАЗАХСТАН
]]
------------------------------------------------------------------------------------------------
local sMsg2 = [[	ОСНОВНЫЕ КОМАНДЫ
 
 
  +myip - Твой IP
  /clear - Отчистить главный чат
  /close - закрытие активного окна
  /help - Вывести список встроенных в DC команд
  /flylinkdc++ - Информация о DC и ссылка где можно скачать DC++
  /fav или /favorite - Добавить активный хаб в избраное.
  /removefavorite - Удалить активный хаб из списка избранных
  /w или /winamp - Отображает какая у вас сейчас песня играет в винампе
  /refresh - Обновить ваш список файлов
  /rebuild - Перехэшировать файлы, то есть переделать шаринг заново
  /connection - Показать ваш IP адрес и порты, которые использует DC для работы

 ГОРЯЧИЕ КЛАВИШИ

  Ctrl + 1 - Включить/выключить панель управления
  Ctrl + 2 - Включить/выключить статусную строку
  Ctrl + 3 - Включить/выключить панель передачи файлов
  Ctrl + C - Копировать выделенный текст
  Ctrl + D - Открыть список файлов в очереди
  Ctrl + E - Обновить ваш список файлов
  Ctrl + F - Открыть избранные хабы.
  Ctrl + N - Открыть блокнот
  Ctrl + L - Открыть список файлов
  Ctrl + P - Открыть публичные хабы
  Ctrl + Q - Быстрое подключение к хабу
  Ctrl + R - Переподелючиться к хабу
  Ctrl + S - Открыть поиск
  Ctrl + T - Следовать последнему перенаправлению
  Ctrl + U - Открыть список избранных пользователей
  Ctrl + V - Вставить скопированный текст
  Ctrl + X - Вырезать выделенный текст

--------------------------------------------------------------------
http://DCBEELINEKZ.1bb.ru МОРЕ ИНФОРМАЦИИ
http://DCBEELINEKZ.do.am САЙТ БИЛАЙН ХАБЫ КАЗАХСТАН
]]
------------------------------------------------------------------------------------------------
local sMsg3 = [[	ЕСЛИ НЕ КАЧАЕТ
  

Если вы видите список пользователей, но не можете ничего с них скачать и получить список файлов, то оборудование и/или 
программное обеспечение блокирует прохождение пакетов к программе.

ПРИЧИНЫ ПОЧЕМУ НЕ КАЧАЕТ:
     Firewall (Брандмауэр Windows, антивирус, отдельный файрволл)
     Роутер (маршрутизатор)
     Другое (Ограничение по слотам, Бан по шаре, полный хард)

FIREWALL
  Программные средства защиты компьютера, в частности Kaspersky Internet Security, Eset Smart Security и прочие.   
  Проблема решается путем добавления клиента DC++ в доверенные приложения firewall-а, а также снижением уровня защиты до среднего и ниже.

РОУТЕР
  Если у вас роутер (белая коробочка), вам необходимо настроить переадресацию портов. Это связанно с тем, что прямой   
  доступ в Интернет имеет сам роутер, позволяя компьютерам и устройствам внутренней домашней сети пользоваться своим соединением.
  Поэтому «снаружи» «видно» только роутер. Чтобы получить из внешнего мира доступ к сервисам внутренней сети (в нашем случае к DC-клиенту FlyLink) нужно, чтобы роутер переадресовывал IP-пакеты на нужный внутренний адрес и порт.
  С точки зрения рядового пользователя, настройка этого устройства представляет наибольшую сложность по сравнению с предыдущими, однако разобраться в этом не так долго, как может показаться на первый взгляд.
 НАСТРОЙКА РОУТЕРОВ ТУТ http://vk.com/topic-49673700_27695244

 ДРУГОЕ 
  Отсутствуют свободные слоты, нужно подождать.
  Ваш хард переполнен, нужно почистить жезтянку, именно в какой диск идет скачка!
  Пользователь удалил файл из шары. и пока не обновилась его шара.
  Пользователь запретил вам скачивать, забанил вас лично или бан за малый размер вашей шары ( BAN for Share < 20 Gb)
  
 НЕДОСТАТКИ ПАССИВНОГО РЕЖИМА
  Пользователь в "Пассивном режиме" не может скачивать файлы с другого пользователя, находящегося тоже в "пассивном режиме". Пользователей в пассивном режиме на хабе в среднем 1/3, поэтому ВЫ теряете 33% источников если находитесь в ПАССИВНОМ режиме!
  Падение скорости у пользователей в режиме "Пассив" гораздо сильнее (в sp2). В конце обычно приводит к разрыву связи и потере слота.
  При поиске ответы от юзеров в пассивном режиме проходят через хаб, в активном - идут напрямую. Хаб не транслирует ответы с неполными источниками (если файл не докачан), поэтому, при появлении нового файла (фильма), активный юзер увидит много источников для скачки (всех, кто подключился к скачке и что-то успел скачать), а пассивный - только тех, кто скачал файл полностью и расшарил.
"Пассивов" можно узнать по кирпичной стене напротив ника в списке пользователей: 

Я настоятельно рекомендую настроить соединение и перейти на "актив" для повышения эффективности системы в ваших же интересах!

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: http://dcbeelinekz.1bb.ru

--------------------------------------------------------------------
http://DCBEELINEKZ.1bb.ru МОРЕ ИНФОРМАЦИИ
http://DCBEELINEKZ.do.am САЙТ БИЛАЙН ХАБЫ КАЗАХСТАН
]]
------------------------------------------------------------------------------------------------
local sMsg4 = [[	СПИСОК  ХАБОВ. ЛЕТО 17-ГО
  ВСЕГДА СВЕЖИЙ СПИСОК ТУТ:
 http://dcbeelinekz.do.am/hubs.html

1. dchub://10.24.9.2 + ВНЕШКА dchub://prosto-host.ru
2. dchub://10.90.66.46 (ЧАСТО МЕНЯЕТСЯ IP)
3. dchub://10.16.89.44 (ЖДЕМ ЗАПУСК)

--------------------------------------------------------------------
http://DCBEELINEKZ.1bb.ru МОРЕ ИНФОРМАЦИИ
http://DCBEELINEKZ.do.am САЙТ БИЛАЙН ХАБЫ КАЗАХСТАН
]]
------------------------------------------------------------------------------------------------
local sMsg5 = [[  
.   Прокси-сервер для пользователей
.   Адрес:  10.24.2.9  Порт: 3128
.   Бесплатный:  1 МБит/сек.
.   Платный:  от 4 до 8 МБит/сек.
.   Стоимость платного:  500 тг.

 ТАК ЖЕ НАСКАНЕННЫЕ ПРОКСИ СЕРВЕРЫ ЮЗЕРАМИ ХАБА:
 magnet:?xt=urn:tree:tiger:HDIRP2A343LGXW26WDJQQFAJQMCDNBWZFQYMCYQ&xl=732890&dn=!+%D0%A1%D0%9A%D0%90%D0%9D%D0%95%D0%A0+%D0%9F%D0%A0%D0%9E%D0%9A%D0%A1%D0%98+2017+%5BDCBEELINEKZ%5D.rar

 10.50.18.95 3128 (ЧАСТО РАБОТАЕТ ВЕЧЕРОМ)
 10.87.71.85 3128 (НОВЫЙ)

 ДЛЯ РАБОТЫ С ПРОКСИ
 magnet:?xt=urn:tree:tiger:CENKXFBKP3D7P2T5N5VDRCAIDW54RHJDM4THOGY&xl=5958238&dn=Proxifier+%5BDCBEELINEKZ%5D.rar
 magnet:?xt=urn:tree:tiger:PXN2PWO7SZOMUYNI4UFEY6SDOC27VMWK27J4VRY&xl=1511&dn=Proxifier+%D0%B8%D1%81%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5+%D0%BB%D0%BE%D0%BA%D0%B0%D0%BB%D0%BA%D0%B8+DCBEELINEKZ.ppx
]]
------------------------------------------------------------------------------------------------
function UserConnected(tUser)
  Core.SendToUser(tUser,"$UserCommand 1 3 ТЕХ.ПОДДЕРЖКА\\ ЧАСТЫЕ ВОПРОСЫ$<%[mynick]> !rf1|")
  Core.SendToUser(tUser,"$UserCommand 1 3 ТЕХ.ПОДДЕРЖКА\\ ОСНОВНЫЕ КОМАНДЫ$<%[mynick]> !rf2|")
  Core.SendToUser(tUser,"$UserCommand 1 3 ТЕХ.ПОДДЕРЖКА\\ ЕСЛИ НЕ КАЧАЕТ$<%[mynick]> !rf3|")
  Core.SendToUser(tUser,"$UserCommand 1 3 ТЕХ.ПОДДЕРЖКА\\ СПИСОК ХАБОВ$<%[mynick]> !rf4|")
  Core.SendToUser(tUser,"$UserCommand 1 3 ТЕХ.ПОДДЕРЖКА\\ ПРОКСИ$<%[mynick]> !rafa|")
end
RegConnected=UserConnected
OpConnected=UserConnected
function ChatArrival(tUser,sData)
  sData=sData:sub(tUser.sNick:len()+4,-2)
  if sData=="!rf1" then
    Core.SendPmToUser(tUser,sBot,sMsg)
    return true
  elseif sData=="!rf2" then
    Core.SendPmToUser(tUser,sBot,sMsg2)
    return true
  elseif sData=="!rf3" then
    Core.SendPmToUser(tUser,sBot,sMsg3)
    return true
  elseif sData=="!rf4" then
    Core.SendPmToUser(tUser,sBot,sMsg4)
    return true
  elseif sData=="!rafa" then
    Core.SendPmToUser(tUser,sBot,sMsg5)
    return true
  end
end

0

4

БОТ ИНФОРМАЦИЯ В СПИСКЕ ЮЗЕРОВ

Код:
--[[
	Для оформления фраз из таблицы tFormat[i]["tPhrases"] можно использовать:
	------------------------------------------------------------------------------------------------------------------
    HOURS    -	часы
    MINUTES    -	минуты
    SECONDS    -	секунды
    DAY    	-	число
    WEEK    -	неделя
    MONTH    -	месяц
    YEAR    -	год
    HUB    	-	название хаба
    SHARE    -	шара хаба
    USERS    -	кол-во юзеров на хабе
	------------------------------------------------------------------------------------------------------------------
]]--
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Конфиг бота:
	
	-- Таблица с названиями месяцев
	tMonths = {".01.", ".02.", ".03.", ".04.", ".05.", ".06.", ".07.", ".08.", ".09.", ".10.", ".11.", ".12."}
	
	 -- Часовые пояса, 1 параметр здесь служит приставкой для времени и даты, первый параметр - смещение относительно текущего времени:
	tTimeZones = {
    {0, "MSK"},
	}
	
	-- Таблица с названиями дней недели
	tWeeks = {"Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье"}

	-- Таблица с названиями едениц измерения шар
	tShareUnits = {"Б", "КБ", "МБ", "ГБ", "ТБ", "ПБ"}

	-- Таблица с блоками информации:
	-- (каждый блок состоит из: ["iInteval"] = время_в_секундах_для_смены_информации, ["sWhatBeforeInfo"] = символ_перед_инфомацией, ["tPhrases"] = таблица_с_инфомацией)
	tFormat = {
    [1] = {
    	["iInteval"] = 10,
    	["sWhatBeforeInfo"] = "[",
    	["tPhrases"] = {
        "Хаб сети Билайн KZ]",
        "Админ хаба: MarkDark]",
        "Время: HOURS:MINUTES]",
        "Дата: DAYMONTHYEARг.]",
        "Юзеров на хабе: USERS]",
        "Шара хаба: SHARE]",
    	},
    },
	}
	
botDesc = "Информация о хабе" --Описание бота
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function OnStartup()
	for i,v in ipairs(tTimeZones) do
    v[1] = v[1] * 3600
	end
	sBot = SetMan.GetString(21)
	sHub = SetMan.GetString(0)
	tNeedToSend = {}
	AddTempToTable()
	TmrMan.AddTimer(1000)
end 

function OnExit()
	for i, v in pairs(tFormat) do
    Core.SendToAll("$Quit "..v["sInformation"])
	end
end
OnError = OnExit

function UserConnected(curUser)
	table.insert(tNeedToSend, curUser.sNick)
end
OpConnected = UserConnected
RegConnected = UserConnected

function GetNickListArrival(curUser,sData)
	table.insert(tNeedToSend, curUser.sNick)
end

function OnTimer()
	for i, v in pairs(tFormat) do
    tFormat[i]["iTimer"] = v["iTimer"] + 1
    if tFormat[i]["iTimer"] > v["iInteval"] then
    	tFormat[i]["iTimer"] = 1
    	tFormat[i]["iStatus"] = v["iStatus"] + 1
    	if v["iStatus"] > #v["tPhrases"] then
        tFormat[i]["iStatus"] = 1
    	end
    	Core.SendToAll("$Quit "..tFormat[i]["sInformation"])
    	tFormat[i]["sInformation"] = v["sWhatBeforeInfo"]..DoGsub(v["tPhrases"][v["iStatus"]])
    	Core.SendToAll("$OpList "..tFormat[i]["sInformation"])
    end
	end
	if tNeedToSend ~= {} then
    SendBotToNewUsers()
    tNeedToSend = {}
	end
end

function AddTempToTable()
	for i, v in pairs(tFormat) do
    tFormat[i]["iStatus"] = 1
    tFormat[i]["iTimer"] = 1
    tFormat[i]["sInformation"] = v["sWhatBeforeInfo"]..DoGsub(v["tPhrases"][1])
    Core.SendToAll("$OpList "..tFormat[i]["sInformation"])
	end
end

function DoGsub(sMsg)
	for _, t in ipairs(tTimeZones) do
    local iTime = os.time() + t[1]
    sMsg = sMsg:gsub(t[2].."HOURS", tonumber(os.date("%H", iTime)))
    sMsg = sMsg:gsub(t[2].."MINUTES", os.date("%M", iTime))
    sMsg = sMsg:gsub(t[2].."SECONDS", os.date("%S", iTime))
    sMsg = sMsg:gsub(t[2].."DAY", tonumber(os.date("%d", iTime)))
    sMsg = sMsg:gsub(t[2].."WEEK", tWeeks[tonumber(os.date("%w", iTime))] or tWeeks[7])
    sMsg = sMsg:gsub(t[2].."MONTH", tMonths[tonumber(os.date("%m", iTime))])
    sMsg = sMsg:gsub(t[2].."YEAR", (os.date("%Y", iTime)))
	end
	sMsg = sMsg:gsub("HOURS", tonumber(os.date("%H")))
	sMsg = sMsg:gsub("MINUTES", os.date("%M"))
	sMsg = sMsg:gsub("SECONDS", os.date("%S"))
	sMsg = sMsg:gsub("DAY", tonumber(os.date("%d")))
	sMsg = sMsg:gsub("WEEK", tWeeks[tonumber(os.date("%w"))] or tWeeks[7])
	sMsg = sMsg:gsub("MONTH", tMonths[tonumber(os.date("%m"))])
	sMsg = sMsg:gsub("YEAR", (os.date("%Y")))
	sMsg = sMsg:gsub("HUB", sHub)
	sMsg = sMsg:gsub("SHARE", DoShareUnits())
	sMsg = sMsg:gsub("USERS", Core.GetUsersCount())
	return sMsg
end

function SendBotToNewUsers()
	for i , v in pairs(tNeedToSend) do
    local sUser = Core.GetUser(v)
    if sUser then
    	for k, y in pairs(tFormat) do
        Core.SendToUser(sUser,"$OpList "..y["sInformation"])
    	end
    end
	end
end

function DoShareUnits()
	local iSize = Core.GetCurrentSharedSize()
	local stSize = #tShareUnits
	local iSize = tonumber(iSize)
	local sUserNits = ""
	for index = 1, stSize do
    if iSize < 1024 then
    	sUserNits = tShareUnits[index]
    	break
    elseif index == stSize then
    	sUserNits = tShareUnits[stSize]
    else
    	iSize = iSize / 1024
    end
	end
	return string.gsub(string.format("%0.2f %s", iSize, sUserNits), "%.", ",")
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

0

5

Скрипт для периодической отправки в чат динамической информации, прочитываемой из файла

Название: MsgToChatFromFile.lua
Платформа: PtokaX
API: API 2
Автор: Ksan

http://mydc.ru/topic5767.html

Для работы скрипта нужно наличие папки MsgToChatFromFile в папке скриптов. В этой папке должен лежать файл с текстом, отправляемым в чат. В предлагаемом архиве папка с файлом уже присутствует, надо только положить куда надо (не забудьте поправить текст на нужный).

Описание: При старте скрипт проверяет наличие файла, если его нет, сообщает админу, чей ник прописан в настройках скрипта, и остаётся в рабочем режиме. При наступлении времени отправки информации в чат (сработал таймер №2 - (1 час, изменить можно в настройках) проверяется файл, считывается текст (админ может в любое время изменить текст в файле) и отправляется в чат (либо как есть, либо от имени бота хаба (в скрипте представлены оба варианта отправки, один вариант закомментен)). При отсутствии же файла с информацией (либо файл есть, но внутри нет текста) скрипт запускает таймер (№1) ожидания файла с информацией (проверяется каждые 55 секунд, но вы можете сами выставить нужный период в настройках), и при появлении информации сразу же отправляет его в чат, и таймер (№1) отключается.. Дальше - в обычном режиме - отправка по таймеру (№2).
Примечание: Срабатывание короткого таймера (появление файла и последующая отправка информации в чат) может произойти в произвольное время (зависит от того, когда вы положите файл в папку), так что возможно одноразовое сокращённое время вывода в чат.

0

6

Информер

Код:
--###################################################################################
--	InformEr 1.02 by alex82
--	PtokaX 0.3.6./0.4.0/0.4.1, LUA 5.1
--	http://mydc.ru/topic1209.html
--###################################################################################

--###################################################################################
--ОСНОВНЫЕ НАСТРОЙКИ

sConfigFile = "InformEr.tbl"	--Файл базы данных
AdminMenu = "Admin\\InformEr\\"	--Название меню
FAQMenu = "Справка\\"
SaveIP = true	--Метод сохранения количества рассылок. false - сохранять по нику; true - сохранять по IP

sSettingsFolder = ""	--Папка для сохранения файла настроек. Если не указано, используется папка "scripts".
sTextFolder = ""	--Папка для текстовых файлов. Если не указано, используется папка "scripts".

--###################################################################################
--НАСТРОЙКИ АНТИФЛУДА

bDeflood = true	--Включить антифлуд. Если включено, автоматический вывод информации в чат будет приостановлен при отсутствии сообщений пользователей, и возобновлён при их появлении.
iDefloodTimer = 1	--Время отправки первого сообщения после выхода из режима антифлуда (минут).

sCmdPrefix = "!"	--Префикс команд, используемых на хабе
--sCmdPrefix = "[!%+%-%*]"

sCmdPattern = "%w+"	--Шаблон команд, используемых на хабе
--sCmdPattern = "%S+"	--Раскомментируйте эту строку, если на хабе используются команды, содержащие символы кириллицы.

--###################################################################################
--НАСТРОЙКИ СПРАВКИ

bEnableFAQ = true	--Включить справку (true - да, false - нет)
bFaqToPM = true	--Отправлять справку в личку (true - да, false - нет)

--###################################################################################
--НАСТРОЙКИ ПРАВ ДОСТУПА

tControl = {	--Профили, имеющие доступ к настройкам
	[0] = 1,    -- =[Master]=
	[1] = 0,    -- =[OP]=
	[2] = 0,    -- =[ViP]=
	[3] = 0,    -- =[Reg]=
	[4] = 0,    -- =[LidShare]=
	[5] = 0,    -- =[LidNov]=
   [-1] = 0,   	-- =[UnReg]=
}

tSend = {    --Профили, имеющие доступ к рассылке сообщений
	[0] = 1,    -- =[Master]=
	[1] = 1,    -- =[OP]=
	[2] = 0,    -- =[ViP]=
	[3] = 0,    -- =[Reg]=
	[4] = 0,    -- =[LidShare]=
	[5] = 0,    -- =[LidNov]=
   [-1] = 0,   	-- =[UnReg]=
}

--###################################################################################
--НАСТРОЙКИ КОМАНД

prefix = "!"	--Префикс команд
info = "info"	--Включение/выключение рассылки сообщений
timeinfo = "timeinfo"	--Установка времени рассылки
impinfo = "impinfo"	--Включение/выключение рассылки важных сообщений (в личку)
showallinfo = "showallinfo"	--Показать все
manual = "manualinfo"	--Вручную
addinfo = "addinfo"	--Добавить сообщение
delinfo = "delinfo"	--Удалить сообщение
addimpinfo = "addimpinfo"	--Добавить важное сообщение
delimpinfo = "delimpinfo"	--Удалить важное сообщение
send = "send"	--Рассылка сообщения
sendpm = "sendpm"	--Рассылка сообщения в личку
faq = "faq"	--Вызов справки
showfaq = "showfaq"	--Показать все разделы
addfaq = "addfaq"	--Добавить раздел справки
delfaq = "delfaq"	--Удалить раздел справки
--###################################################################################
--###################################################################################
tConfig={Auto = 1, Timer = 15, ImpMsg = 1}
tMessage={}
tImpMessage={}
tImpData={}
tFAQ = {}

SaveCount = 0

function Main()
	if Core then
    NewAPI = true
    stop = true
    _,_,ver,subver = string.find(Core.Version,"^%d+%.(%d+)%.(%d+)")
    if (tonumber(ver) >=4 and tonumber(subver) >=1) or tonumber(ver) > 4 then
    	local path = "scripts/"
    	if sSettingsFolder == "" then
        sSettingsFolder = path..sSettingsFolder
    	end
    	if sTextFolder == "" then
        sTextFolder = path..sTextFolder
    	end
    end
    bot = SetMan.GetString(21)
	else
    NewAPI = false
    stop = 1
    bot = frmHub:GetHubBotName()
	end
	if loadfile(sSettingsFolder..sConfigFile) then dofile(sSettingsFolder..sConfigFile) end
	if tConfig.Auto==1 then
    StartTmr()
	end
end

OnStartup = Main

function StartTmr()
	if NewAPI then
    TimerID = TmrMan.AddTimer(tConfig.Timer*60*1000,"OnTimer")
	else
    SetTimer (tConfig.Timer*60*1000)
    StartTimer()
	end
	bDefloodPause = false
end

function StartTmr2()
	if NewAPI then
    TimerID = TmrMan.AddTimer(iDefloodTimer*60*1000,"OnTimer")
	else
    SetTimer (iDefloodTimer*60*1000)
    StartTimer()
	end
end

function StopTmr()
	if NewAPI then
    TmrMan.RemoveTimer(TimerID)
	else
    StopTimer()
	end
end

function OnExit()
	Save()
end

function OnTimer()
	if bMessage or not bDeflood then
    if bDefloodPause then
    	StopTmr()
    	StartTmr()
    end
    bMessage = false
    SendInfo()
	else
    bDefloodPause = true
    StopTmr()
	end
end

function NewUserConnected(user)
	if bEnableFAQ and next(tFAQ) then
    for i,v in ipairs(tFAQ) do
    	SendFAQMenu(user, v[1].."$<%[mynick]> "..prefix..faq.." "..i)
    end
	end
	if tControl[user.iProfile] == 1 then
    SendMenu(user, "Показать все$<%[mynick]> "..prefix..showallinfo.." ")
    SendMenu(user, "Настройки\\Вывод информации в чат\\Включить$<%[mynick]> "..prefix..info.." 1")
    SendMenu(user, "Настройки\\Вывод информации в чат\\Отключить$<%[mynick]> "..prefix..info.." 0")
    SendMenu(user, "Настройки\\Время вывода информации в чат$<%[mynick]> "..prefix..timeinfo.." %[line:Укажите время (в минутах)]")
    SendMenu(user, "Настройки\\Рассылка важной информации в личку\\Включить$<%[mynick]> "..prefix..impinfo.." 1")
    SendMenu(user, "Настройки\\Рассылка важной информации в личку\\Отключить$<%[mynick]> "..prefix..impinfo.." 0")
    SendMenu(user, "Информация\\Добавить сообщение$<%[mynick]> "..prefix..addinfo.." %[line:Введите текст]")
    SendMenu(user, "Информация\\Удалить сообщение$<%[mynick]> "..prefix..delinfo.." %[line:Введите номер]")
    SendMenu(user, "Важная информация\\Добавить сообщение$<%[mynick]> "..prefix..addimpinfo.." %[line:Введите текст] %[line:Укажите количество отправок]")
    SendMenu(user, "Важная информация\\Удалить сообщение$<%[mynick]> "..prefix..delimpinfo.." %[line:Введите номер]")
    if bEnableFAQ then
    	SendMenu(user, "Справка\\Показать все разделы$<%[mynick]> "..prefix..showfaq)
    	SendMenu(user, "Справка\\Добавить раздел$<%[mynick]> "..prefix..addfaq.." name:%[line:Введите имя раздела] text:%[line:Введите текст]")
    	SendMenu(user, "Справка\\Удалить раздел$<%[mynick]> "..prefix..delfaq.." %[line:Введите номер]")
    end
	end
	if tSend[user.iProfile] == 1 then
    SendMenu(user, "Разослать сообщение$<%[mynick]> "..prefix..send.." %[line:Введите текст]")
    SendMenu(user, "Разослать сообщение в личку$<%[mynick]> "..prefix..sendpm.." %[line:Введите текст]")
	end
	for i in pairs(tImpMessage) do
    nick = user.sNick or user.sName
    local id = ""
    if SaveIP then
    	id = user.sIP
    else
    	id = nick
    end
    if not(tImpMessage[i][3][id]) then
    	tImpMessage[i][3][id] = 1
    end
    if tImpMessage[i][3][id] <= tImpMessage[i][2] or tImpMessage[i][2] == 0 then
    	local s,e,file = string.find(tImpMessage[i][1],"^file:(.+)$")
    	local msg = ""
    	if file then
        msg = ReadFile(sTextFolder,file)
    	else
        msg = tImpMessage[i][1]
    	end
    	if msg then
        msg = string.gsub(msg,"%[USER%]",nick)
        SendPM(user,msg)
        tImpMessage[i][3][id] = tImpMessage[i][3][id]+1
        SaveCount = SaveCount+1
        if SaveCount >=10 then
        	SaveCount = 0
        	Save()
        end
    	end
    end
	end
end

UserConnected = NewUserConnected
OpConnected = NewUserConnected
RegConnected = NewUserConnected

function ChatArrival(user, data)
	local data = data:sub(1,-2)
	if tConfig.Auto==1 and not data:find("^%b<>%s+"..sCmdPrefix..sCmdPattern) then
    if bDefloodPause and not bMessage then
    	StartTmr2()
    end
    bMessage = true
	end
	if tControl[user.iProfile] == 1 or tSend[user.iProfile] == 1 or bEnableFAQ then
    local pre,cmd = data:match("^%b<>%s+(%p)(%S+)")
    if pre and cmd and pre==prefix then
    	local tdata = data:match("^%b<>%s+%S+%s(.+)$")
    	if bEnableFAQ then
        if cmd == faq then
        	FAQ(user,tdata)
        	return stop
        end
    	end
    	if tControl[user.iProfile] == 1 and tControlCmd[cmd] then
        local result = tControlCmd[cmd](user,tdata)
        if result then SendMsg(user,result) end
        return stop
    	end
    	if tSend[user.iProfile] == 1 and (cmd == send or cmd == sendpm) then
        local pm = false
        if cmd == sendpm then pm = true end
        if tdata == nil or tdata == "" then
        	return "Ошибка: Вы должны ввести текст"
        else
        	Send(tdata,pm)
        end
        return stop
    	end
    end
	end
end

function ToArrival(user, data)
	local data = data:sub(1,-2)
	if tControl[user.iProfile] == 1 or tSend[user.iProfile] == 1 or bEnableFAQ then
    local to = data:match("^%$To:%s(%S+)%s")
    if to == bot then
    	local pre,cmd = data:match("^%$To:%s%S+%sFrom:%s%S+%s%$%b<>%s+(%p)(%S+)")
    	if pre and cmd and pre==prefix then
        local tdata = data:match("^%$To:%s%S+%sFrom:%s%S+%s%$%b<>%s+%p%S+%s+(.+)$")
        if bEnableFAQ then
        	if cmd == faq then
            FAQ(user,tdata)
            return stop
        	end
        end
        if tControl[user.iProfile] == 1 and tControlCmd[cmd] then
        	local result = tControlCmd[cmd](user,tdata)
        	if result then SendPM(user,result) end
        	return stop
        end
        if tSend[user.iProfile] == 1 and (cmd == send or cmd == sendpm) then
        	local pm = false
        	if cmd == sendpm then pm = true end
        	if tdata == nil or tdata == "" then
            return "Ошибка: Вы должны ввести текст"
        	else
            Send(tdata,pm)
        	end
        	return stop
        end
    	end
    end
	end
end

function FAQ(user,tdata)
	tdata = tonumber(tdata)
	if tdata then
    if tFAQ[tdata] then
    	local file = string.match(tFAQ[tdata][2],"^file:(.+)$")
    	if file then
        msg = ReadFile(sTextFolder,file)
    	else
        msg = tFAQ[tdata][2]
    	end
    	if msg then
        msg = string.gsub(msg,"%[USER%]",user.sName or user.sNick)
        SendFAQ(user, tFAQ[tdata][1].."\n"..msg)
    	else
        SendFAQ(user,"Произошла ошибка при отправке раздела. Обратитесь к администратору хаба.")
    	end
    else
    	SendFAQ(user,"Ошибка: не найден указанный раздел справки")
    end
	else
    if next(tFAQ) then
    	local msg = "\r\n\t::: ::: ::: Разделы справки ::: ::: :::\r\n"
    	for i,v in pairs(tFAQ) do
        msg = msg.."\t"..i..". "..v[1].."\r\n"
    	end
    	msg = msg.."Чтобы выбрать раздел, введите "..prefix..faq.." <номер раздела>"
    	SendFAQ(user, msg)
    else
    	SendFAQ(user, "Нет ни одного раздела справки")
    end
	end
end

tControlCmd = {
	[addfaq] = function(user,tdata)
    tdata = tdata or ""
    local s,e,name,text = string.find(tdata, "^name:(.+)%s+text:(.+)$")
    if name and text then
    	local tTemp = {name,text}
    	table.insert(tFAQ,tTemp)
    	Save()
    	return "Раздел сохранен в базе под номером "..table.maxn(tFAQ)
    else
    	return "Ошибка синтаксиса. Синтаксис: "..prefix..addfaq.." name:<имя раздела> text:<текст>"
    end
	end,
	[delfaq] = function(user,tdata)
    if tdata == nil or tdata == "" then
    	return  "Ошибка: Вы должны ввести номер"
    else
    	tdata  = tonumber(tdata)
    	if tFAQ[tdata] then
        table.remove(tFAQ,tdata)
        Save()
        return "Раздел № "..tdata.." успешно удален из базы"
    	else
        return "Ошибка: Раздел с номером "..tdata.." не существует в базе"
    	end
    end
	end,
	[showfaq] = function(user,tdata)
    local msg = "\r\n::: ::: ::: Разделы справки ::: ::: :::\r\n"
    if next(tFAQ) then
    	for i in ipairs(tFAQ) do
        local s,e,file = string.find(tFAQ[i][2],"^file:(.+)$")
        local msg2 = ""
        if file then
        	msg2 = "*Содержимое файла "..file.."*"
        	if not(CheckFile(sTextFolder,file)) then
            msg2 = msg2.." (ошибка)"
        	end
        else
        	msg2 = tFAQ[i][2]
        end
        msg = msg.."\r\n\t"..i..".  "..tFAQ[i][1]..": "..msg2.."\r\n"
    	end
    else
    	msg = msg.."\r\n\tРазделы отсутствуют\r\n"
    end
    SendPM(user, msg)
	end,
	[showallinfo] = function(user,tdata)
    local msg = "\r\n::: ::: ::: Настройки ::: ::: :::\r\n"
    local state = "включен"
    if tConfig["Auto"]==0 then
    	state = "отключен"
    end
    msg = msg.."\r\n\tВывод информации в чат: "..state.."\r\n"
    msg = msg.."\r\n\tВремя отправки сообщений: "..tConfig["Timer"].." мин.\r\n"
    state = "включена"
    if tConfig["ImpMsg"]==0 then
    	state = "отключена"
    end
    msg = msg.."\r\n\tРассылка важной информации в личку: "..state.."\r\n"
    msg = msg.."\r\n::: ::: ::: Информация ::: ::: :::\r\n"
    if next(tMessage) then
    	for i in ipairs(tMessage) do
        local s,e,file = string.find(tMessage[i],"^file:(.+)$")
        local msg2 = ""
        if file then
        	msg2 = "*Содержимое файла "..file.."*"
        	if not(CheckFile(sTextFolder,file)) then
            msg2 = msg2.." (ошибка)"
        	end
        else
        	msg2 = tMessage[i]
        end
        msg = msg.."\r\n\t"..i..".  "..msg2.."\r\n"
    	end
    else
    	msg = msg.."\r\n\tСообщения отсутствуют\r\n"
    end
    msg = msg.."\r\n::: ::: ::: Важная информация ::: ::: :::\r\n"
    if next(tImpMessage) then
    	for i in ipairs(tImpMessage) do
        local s,e,file = string.find(tImpMessage[i][1],"^file:(.+)$")
        local msg2 = ""
        if file then
        	msg2 = "*Содержимое файла "..file.."*"
        	if not(CheckFile(sTextFolder,file)) then
            msg2 = msg2.." (ошибка)"
        	end
        else
        	msg2 = tImpMessage[i][1]
        end
        msg3 = ""
        if tImpMessage[i][2] > 0 then
        	msg3 = " (Отправлять "..tImpMessage[i][2].." раз(а))"
        end
        msg = msg.."\r\n\t"..i..".  "..msg2..msg3.."\r\n"
    	end
    else
    	msg = msg.."\r\n\tСообщения отсутствуют\r\n"
    end
    SendPM(user, msg)
	end,
	[info] = function(user,tdata)
    if not tdata or tdata == "" then
    	return "Ошибка"
    else
    	tdata = tonumber(tdata)
    	if tdata == 0 then
        if tConfig.Auto == 1 then
        	StopTmr()
        end
        tConfig.Auto = 0
        Save()
        return "Вывод информации в чат отключен"
    	else
        if tConfig.Auto == 0 then
        	StartTmr()
        end
        tConfig.Auto = 1
        Save()
        return "Вывод информации в чат включен"
    	end
    end
	end,
	[timeinfo] = function(user,tdata)
    if not tdata or tdata == "" then
    	return "Ошибка"
    else
    	tdata = tonumber(tdata)
    	if tdata > 0 then
        tConfig.Timer = tdata
        Save()
        if tConfig.Auto == 1 then
        	StopTmr()
        	StartTmr()
        end
        return "Установлено время отправки сообщений в чат - "..tConfig.Timer.." мин."
    	else
        return "Ошибка"
    	end
    end
	end,
	[impinfo] = function(user,tdata)
    if not tdata or tdata == "" then
    	return "Ошибка"
    else
    	tdata = tonumber(tdata)
    	if tdata == 0 then
        tConfig.ImpMsg = 0
        Save()
        return "Рассылка важной информации в личку отключена" 
    	else
        tConfig.ImpMsg = 1
        Save()
        return "Рассылка важной информации в личку включена"
    	end
    end
	end,
	[addinfo] = function(user,tdata)
    if tdata == nil or tdata == "" then
    	return "Ошибка: Вы должны ввести текст"
    else
    	table.insert(tMessage,tdata)
    	Save()
    	return "Сообщение успешно сохранено в базе под номером "..table.maxn(tMessage)
    end
	end,
	[delinfo] = function(user,tdata)
    if tdata == nil or tdata == "" then
    	return "Ошибка: Вы должны ввести номер"
    else
    	tdata  = tonumber(tdata)
    	if tMessage[tdata] then
        table.remove(tMessage,tdata)
        Save()
        return "Сообщение № "..tdata.." успешно удалено из базы"
    	else
        return "Ошибка: Сообщение с номером "..tdata.." не существует в базе"
    	end
    end
	end,
	[addimpinfo] = function(user,tdata)
    local s,e,smsg, num = string.find(tdata, "^(.+)%s(%d+)$")
    num = tonumber(num)
    if smsg == nil or smsg == "" then
    	return "Ошибка: Вы должны ввести текст сообщения и указать количество отправок сообщения каждому пользователю. Введите 0 чтобы рассылка никогда не заканчивалась."
    else
    	local index=table.maxn(tImpMessage)+1
    	tImpMessage[index] = {[1] = smsg, [2] = num, [3] = {}}
    	Save()
    	return "Сообщение успешно сохранено в базе под номером "..index
    end
	end,
	[delimpinfo] = function(user,tdata)
    if tdata == nil or tdata == "" then
    	SendMsg(user, "Ошибка: Вы должны ввести номер")
    else
    	tdata  = tonumber(tdata)
    	if tImpMessage[tdata] then
        table.remove(tImpMessage,tdata)
        Save()
        return "Сообщение № "..tdata.." успешно удалёно из базы"
    	else
        return "Ошибка: Сообщение с номером "..tdata.." не существует в базе"
    	end
    end
	end
}

function SendInfo()
	if table.maxn(tMessage) > 0 then
    local temp = tMessage[math.random(1,table.getn(tMessage))]
    Send(temp,false)
	end
end

function Send(data,pm)
	local s,e,file = string.find(data,"^file:(.+)$")
	local msg = ""
	if file then
    msg = ReadFile(sTextFolder,file)
	else
    msg = data
	end
	if msg then
    local temp = string.find(msg,"%[USER%]")
    if temp then
    	local OnlineTab = {}
    	if NewAPI then
        OnlineTab = Core.GetOnlineUsers(true)
    	else
        OnlineTab = frmHub:GetOnlineUsers()
    	end
    	for i, v in pairs(OnlineTab) do
        local nick = v.sNick or v.sName
        local msg2 = string.gsub(msg,"%[USER%]",nick)
        if pm then
        	SendPM(v,msg2)
        else
        	SendMsg(v,msg2)
        end
    	end
    else
    	if pm then
        SendPMToAll(msg)
    	else
        SendMsgToAll(msg)
    	end
    end
	end
end

--Функции работы с файлами
function CheckFile(folder,file)
	local f = io.open( folder..file, "r" )
	local result = false
	if f then
    f:close()
    result = true
	end
	return result
end

function ReadFile(folder,file)
	local f = io.open( folder..file, "r" )
	local content = nil
	if f then
    content = f:read("*all")
    f:close()
	else
    SendMsgToOps("Ошибка при отправке сообщения: невозможно прочитать файл "..file)
	end
	return content
end

--Функции отправки сообщений
function SendMsg(user, msg)
	if NewAPI then
    Core.SendToUser(user,"<"..bot.."> "..msg)
	else
    user:SendData(bot, msg)
	end
end

function SendPM(user, msg)
	if NewAPI then
    Core.SendPmToUser(user,bot,msg)
	else
    user:SendPM(bot, msg)
	end
end

function SendFAQ(user, msg)
	if bFaqToPM then
    SendPM(user, msg)
	else
    SendMsg(user, msg)
	end
end

function SendMsgToAll(msg)
	if NewAPI then
    Core.SendToAll("<"..bot.."> "..msg)
	else
    SendToAll(bot, msg)
	end
end

function SendPMToAll(msg)
	if NewAPI then
    Core.SendPmToAll(bot, msg)
	else
    SendPmToAll(bot, msg)
	end
end

function SendMsgToOps(msg)
	if NewAPI then
    Core.SendToOps("<"..bot.."> "..msg)
	else
    SendToOps(bot, msg)
	end
end

function SendMenu(user, menu)
	if NewAPI then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu..menu.."|")
	else
    user:SendData("$UserCommand 1 3 "..AdminMenu..menu.."|")
	end
end

function SendFAQMenu(user, menu)
	if NewAPI then
    Core.SendToUser(user,"$UserCommand 1 3 "..FAQMenu..menu.."|")
	else
    user:SendData("$UserCommand 1 3 "..FAQMenu..menu.."|")
	end
end

function SendSpacer(user, menu)
	if NewAPI then
    Core.SendToUser(user,"$UserCommand 0 3")
	else
    user:SendData("$UserCommand 0 3")
	end
end

--Функции сохранения
function Save()
	local hFile = io.open(sSettingsFolder..sConfigFile, "w+")
	Serialize(tConfig, "tConfig", hFile)
	Serialize(tMessage, "tMessage", hFile)
	Serialize(tImpMessage, "tImpMessage", hFile)
	Serialize(tFAQ, "tFAQ", hFile)
	hFile:close()
end

function Serialize(tTable, sTableName, hFile, sTab)
	sTab = sTab or "";
	hFile:write(sTab..sTableName.." = {\n");
	for key, value in pairs(tTable) do
    if (type(value) ~= "function") then
    	local sKey = (type(key) == "string") and string.format("[%q]", key) or string.format("[%d]", key);
    	if(type(value) == "table") then
        Serialize(value, sKey, hFile, sTab.."\t");
    	else
        local sValue = (type(value) == "string") and string.format("%q", value) or tostring(value);
        hFile:write(sTab.."\t"..sKey.." = "..sValue);
    	end
    	hFile:write(",\n");
    end
	end
	hFile:write(sTab.."}");
end

0

7

Код:
bot = "MAINBOT"
taimer = 180 -- в минутах

messarray={ 
[[Мы рады приветствовать вас на нашем хабе! Посетите наши веб ресурсы:
Сайт: http://core.pvt.454.ru
Форум: http://core.pvt.454.ru/forum]],
}

function OnStartup()
    tmr = TmrMan.AddTimer (taimer*60*1000)
end

function OnTimer(tmr)
    Core.SendToAll("<"..bot.."> "..messarray[math.random(1,#messarray)])
end

0

8

Код:
---------------------------------------------------------------------------------------------------------------------------------------------------------------  
--  Скрипт "Информер v1.1" by Wariner под API 2  
--  Для портала администраторов хаба http://mydc.ru
--  Доработал Damaks (http://ddd-dc.ru)
----------------------------------------------------------------------------------------------------------------------------------------------------------------

local gBot = "Информер"
local gTaimer = 5 --  время в минутах через которое будуи выходить сообщение в интервале заданных часов
local tDays = {
   ["Monday"] = "Понедельник",
   ["Tuesday"] = "Вторник",
   ["Wednesday"] = "Среда",
   ["Thursday"] = "Четверг", 
   ["Friday"] = "Пятница",
   ["Saturday"] = "Суббота",
   ["Sunday"] = "Воскресенье", 
}

local msg = {
'Сообщение для понедельника',
'Сообщение для вторника',
'Сообщение для среды',
'Сообщение для четверга',
'Сообщение для пятницы',
'Сообщение для субботы',
'Сообщение для воскресенья',
}

function OnStartup()
	tmr = TmrMan.AddTimer (gTaimer*60*1000)
end

function OnTimer(tmr)
	local day = os.date("%A")
	local hour = os.date("%H")
	local min = os.date("%M")
	for i,v in pairs(tDays) do
        day = string.gsub(day,i,v)
    end
	
	if (day == "Понедельник") then
	    if (tonumber(hour) >= 18) and (tonumber(hour) < 19) and (tonumber(min) >= 1) and (tonumber(min) < 5) then    -- hour - часы, от и до;	min - минуты, от и до.	 Интервал минут лучше ставить в количестве gTaimer-1
    	Core.SendToAll("<"..gBot.."> "..msg[1])
     end
   end
	if (day == "Вторник") then
	    if (tonumber(hour) >= 18) and (tonumber(hour) < 19) and (tonumber(min) >= 1) and (tonumber(min) < 5) then
    	Core.SendToAll("<"..gBot.."> "..msg[2])
     end
   end
	if (day == "Среда") then
	    if (tonumber(hour) >= 18) and (tonumber(hour) < 19) and (tonumber(min) >= 1) and (tonumber(min) < 5) then
    	Core.SendToAll("<"..gBot.."> "..msg[3])
     end
   end
	if (day == "Четверг") then
	    if (tonumber(hour) >= 18) and (tonumber(hour) < 19) and (tonumber(min) >= 1) and (tonumber(min) < 5) then
    	Core.SendToAll("<"..gBot.."> "..msg[4])
     end
   end
	if (day == "Пятница") then
	    if (tonumber(hour) >= 18) and (tonumber(hour) < 19) and (tonumber(min) >= 1) and (tonumber(min) < 5) then
    	Core.SendToAll("<"..gBot.."> "..msg[5])
     end
   end
	if (day == "Суббота") then
	    if (tonumber(hour) >= 18) and (tonumber(hour) < 19) and (tonumber(min) >= 1) and (tonumber(min) < 5) then
    	Core.SendToAll("<"..gBot.."> "..msg[6])
    end
	end
	if (day == "Воскресенье") then
	    if (tonumber(hour) >= 18) and (tonumber(hour) < 19) and (tonumber(min) >= 1) and (tonumber(min) < 5) then
    	Core.SendToAll("<"..gBot.."> "..msg[7])
     end
   end

end

0

9

Скрипт предназначен для перенаправления юзеров, упорно пытающихся войти на хаб
несколько раз под одним ником. Используется при слиянии крупных хабов.

Алгоритм работы следующий: При первой попытке входа клона, запоминаем время
сего знаменательного события, а затем, при каждой последующей попытке, смотрим,
прошло ли с момента первой попытки входа iTime минут. Если да, перенаправляем
юзера. Сделано это для того, чтобы избежать перенаправления тех юзеров, что
отвалились от хаба из-за проблем с сетью, и теперь не могут войти по той причине,
что их ник по-прежнему висит в списке юзеров. Если в промежутке между iTime и
iDelTime юзер не предпринял ни одной попытки входа, то предполагаем, что юзер
таки заметил неладное и сменил ник (или его просто заебало ломиться в закрытую
дверь :D) , и удаляем его из списка ожидающих перенаправления.

Clone Redirect

iTime = 20 -- Таймаут перенаправления, минут
iDelTime = 30 -- Таймаут удаления юзера из списка, минут
sRedirAddr = "bceti.com" -- Адрес перенаправления

sLog = Core.GetPtokaXPath().."logs/clone_redirect.log"

--###################################################################################

tClone = {}

function OnStartup()
TmrMan.AddTimer(60000,"MainTimer")
end

function ValidateDenideArrival(user,nick)
    if tClone[nick] then
    if tClone[nick]+iTime*60 < os.time() then
    Core.SendToUser(user,"$ForceMove "..sRedirAddr)
    tClone[nick] = nil
    Report("Юзер "..nick.." был перенаправлен на резервный хаб, поскольку на хабе уже есть юзер с таким ником")
    end
else
    tClone[nick] = os.time()
    Report("Юзер "..nick.." был добавлен в список ожидающих перенаправления")
end
end

function UserConnected(user)
if tClone[user.sNick] then
    tClone[user.sNick] = nil
    Report("Юзер "..user.sNick.." был удален из списка дублирующихся юзеров, поскольку успешно вошел на хаб.")
end
end
OpConnected = UserConnected
RegConnected = UserConnected

function MainTimer()
for i,v in pairs(tClone) do
    if v+iDelTime*60 < os.time() then
    tClone[i] = nil
    Report("Юзер "..i.." был удален из списка дублирующихся юзеров, поскольку прекратил попытки входа.")
    end
end
end

function Report(msg)
local f = io.open(sLog,"a")
if f then
    f:write(os.date("[%Y-%m-%d %H:%M:%S] "),msg,"\n")
    f:close()
end
end

0

10

Если Вы переходите на данную версию с более новой, хранящей настройки и список скриптов в файлах .pxt, то Вам будет полезен конвертер

Скрипт предназначен для конвертирования настроек и списка скриптов из текстового
формата обратно в XML. Скрипт используется в том случае, если Вы желаете откатиться
с PtokaX 0.5.2.1 mod (или более новой) на PtokaX 0.5.0.1 mod (или более старую).

ВНИМАНИЕ!
Скрипт не умеет парсить файлы настроек, он получает данные из памяти PtokaX при
помощи API Lua. Следовательно, необходимо запускать его непосредственно на хабе,
использующем новый формат настроек.

Скрипт

tSetBool = {
    "AntiMoGlo",
    "AutoStart",
    "RedirectAll",
    "RedirectWhenHubFull",
    "AutoRegister",
    "RegOnly",
    "RegOnlyRedir",
    "ShareLimitRedir",
    "SlotsLimitRedir",
    "HubSlotRatioRedir",
    "MaxHubsLimitRedir",
    "ModeToMyINFO",
    "ModeToDescription",
    "StripDescription",
    "StripTag",
    "StripConnection",
    "StripEmail",
    "RegBot",
    "UseBotNickAsHubSec",
    "RegOpChat",
    "TempBanRedir",
    "PermBanRedir",
    "EnableScripting",
    "KeepSlowUsers",
    "CheckNewReleases",
    "EnableTrayIcon",
    "StartMinimized",
    "FilterKickMessages",
    "SendKickMessagesToOps",
    "SendStatusMessages",
    "SendStatusMessagesAsPm",
    "EnableTextFiles",
    "SendTextFilesAsPm",
    "StopScriptOnError",
    "MOTDAsPm",
    "DefloodReport",
    "ReplyToHubCommandsAsPm",
    "DisableMOTD",
    "DontAllowPingers",
    "ReportPingers",
    "Report3xBadPass",
    "AdvancedPassProtection",
    "BindOnlySingleIp",
    "ResolveToIp",
    "NickLimitRedir",
"SendUserIP2ToUserOnLogin",
    "BanMessageShowIp",
    "BanMessageShowRange",
    "BanMessageShowNick",
    "BanMessageShowReason",
    "BanMessageShowBy",
    "ReportSuspiciousTag",
"AcceptUnknownTag",
"CheckIpInCommands",
"PopupScriptsWindow",
    "LogScriptErrors",
    "NoQuackSupports",
"ShowWelcome",
"BlockUnknownCmd",
"CheckKeys",
"UseCompression",
"ScriptErrorsToOps",
"ScriptStackTraceback",
"KeepMagicByte",
"LockDelayed",
};

tSetNumber = {
    "MaxUsers",
    "MinShareLimit",
    "MinShareUnits",
    "MaxShareLimit",
    "MaxShareUnits",
    "MinSlotsLimit",
    "MaxSlotsLimit",
    "HubSlotRatioHubs",
    "HubSlotRatioSlots",
    "MaxHubsLimit",
    "NoTagOption",
    "FullMyINFOOption",
    "MaxChatLen",
    "MaxChatLines",
    "MaxPmLen",
    "MaxPmLines",
    "DefaultTempBanTime",
    "MaxPassiveSr",
    "MyINFODelay",
    "MainChatMessages",
    "MainChatTime",
    "MainChatAction",
    "SameMainChatMessages",
    "SameMainChatTime",
    "SameMainChatAction",
    "SameMultiMainChatMessages",
    "SameMultiMainChatLines",
    "SameMultiMainChatAction",
    "PmMessages",
    "PmTime",
    "PmAction",
    "SamePmMessages",
    "SamePmTime",
    "SamePmAction",
    "SameMultiPmMessages",
    "SameMultiPmLines",
    "SameMultiPmAction",
    "SearchMessages",
    "SearchTime",
    "SearchAction",
    "SameSearchMessages",
    "SameSearchTime",
    "SameSearchAction",
    "MyINFOMessages",
    "MyINFOTime",
    "MyINFOAction",
    "GetNickListMessages",
    "GetNickListTime",
    "GetNickListAction",
    "NewConnectionsCount",
    "NewConnectionsTime",
    "DefloodWarningCount",
    "DefloodWarningAction",
    "DefloodTempBanTime",
    "GlobalMainChatMessages",
    "GlobalMainChatTime",
    "GlobalMainChatTimeOut",
    "GlobalMainChatAction",
    "MinSearchLen",
    "MaxSearchLen",
    "MinNickLen",
    "MaxNickLen",
    "BruteForcePassProtectBanType",
    "BruteForcePassProtectTempBanTime",
    "MaxPmCountToUser",
    "MaxSimultaneousLogins",
    "MainChatMessages2",
    "MainChatTime2",
    "MainChatAction2",
    "PmMessages2",
    "PmTime2",
    "PmAction2",
    "SearchMessages2",
    "SearchTime2",
    "SearchAction2",
    "MyINFOMessages2",
    "MyINFOTime2",
    "MyINFOAction2",
    "MaxMyINFOLen",
    "CTMMessages",
    "CTMTime",
    "CTMAction",
    "CTMMessages2",
    "CTMTime2",
    "CTMAction2",
    "RCTMMessages",
    "RCTMTime",
    "RCTMAction",
    "RCTMMessages2",
    "RCTMTime2",
    "RCTMAction2",
    "MaxCTMLen",
    "MaxRCTMLen",
    "SRMessages",
    "SRTime",
    "SRAction",
    "SRMessages2",
    "SRTime2",
    "SRAction2",
    "MaxSRLen",
    "MaxDownAction",
    "MaxDownKb",
    "MaxDownTime",
    "MaxDownAction2",
    "MaxDownKb2",
    "MaxDownTime2",
    "ChatIntervalMessages",
    "ChatIntervalTime",
    "PMIntervalMessages",
    "PMIntervalTime",
    "SearchIntervalMessages",
    "SearchIntervalTime",
    "MaxConnSameIP",
    "MinReConnTime",
"MaxTempBanTimeDays",
"ServiceLoopInterval",
    "MaxUsersPeak",
};

tSetStr = {
    "HubName",
    "AdminNick",
    "HubAddress",
    "TCPPorts",
    "UDPPort",
    "HubDescription",
    "RedirectAddress",
    "RegisterServers",
    "RegOnlyMessage",
    "RegOnlyRedirAddress",
    "HubTopic",
    "ShareLimitMessage",
    "ShareLimitRedirAddress",
    "SlotsLimitMessage",
    "SlotsLimitRedirAddress",
    "HubSlotRatioMessage",
    "HubSlotRatioRedirAddress",
    "MaxHubsLimitMessage",
    "MaxHubsLimitRedirAddress",
    "NoTagMessage",
    "NoTagRedirAddress",
    "BotNick",
    "BotDescription",
    "BotEmail",
    "OpChatNick",
    "OpChatDescription",
    "OpChatEmail",
    "TempBanRedirAddress",
    "PermBanRedirAddress",
    "ChatCommandsPrefixes",
    "HubOwnerEmail",
    "NickLimitMessage",
    "NickLimitRedirAddress",
    "MessageToAddToBanMessage",
    "Language",
    "IPv4Address",
    "IPv6Address",
"LocaleWin",
"LocaleNix",
};

function OnStartup()
function XMLEscape(str)
    str=str:gsub("&","&amp;")
    for i,v in pairs({["'"] = "&apos;", ["\""] = "&quot;", ["<"] = "&lt;", [">"] = "&gt;", }) do
    str=str:gsub(i,v)
    end
    return str
end

local f = io.open(Core.GetPtokaXPath().."cfg/Settings.xml", "wb")
if f then
    f:write('<?xml version="1.0" encoding="windows-1251" standalone="yes" ?>\n<PtokaX Version="0.5.0.1 mod 11">\n    <Booleans>\n')
    for i, v in ipairs(tSetBool) do
    f:write('\t\t<Bool Name="', v, '">', (SetMan.GetBool(i-1) and '1' or '0'), '</Bool>\n')
    end
   
    f:write("\t</Booleans>\n\t<Integers>\n")
    for i, v in ipairs(tSetNumber) do
    f:write('\t\t<Integer Name="', v, '">', SetMan.GetNumber(i-1), '</Integer>\n')
    end
   
    f:write("\t</Integers>\n\t<Strings>\n")
    for i, v in ipairs(tSetStr) do
    f:write('\t\t<String Name="', v, '">', XMLEscape(SetMan.GetString(i-1) or ""), '</String>\n')
    end
   
    f:write("\t</Strings>\n</PtokaX>\n")
   
    f:close()
end

f = io.open(Core.GetPtokaXPath().."cfg/Scripts.xml", "wb")

if f then
    f:write('<?xml version="1.0" encoding="windows-1251" standalone="yes" ?>\n<Scripts>\n')
    for i, v in ipairs(ScriptMan.GetScripts()) do
    f:write('\t<Script>\n\t\t<Name>', XMLEscape(v.sName), '</Name>\n\t\t<Enabled>', v.sName == 'settings_back.lua' and '0' or (v.bEnabled and '1' or '0'), '</Enabled>\n\t</Script>\n')
    end
   
    f:write('</Scripts>\n')

    f:close()
end

print("Settings and scripts was saved in old format.")
ScriptMan.StopScript('settings_back.lua')
end

0

11

Скрипт для конвертирования бинарной базы обратно в XML

Скрипт предназначен для конвертирования бинарной базы пользователей,
введенной в PtokaX 0.5.0.0, обратно в файл XML.

ВНИМАНИЕ!
Скрипт не умеет парсить бинарную базу, он получает данные о зарегистрированных
юзерах из памяти PtokaX при помощи API Lua. Следовательно, необходимо запускать
его непосредственно на хабе с бинарной базой.

Скрипт

--[[##################################################################################

Скрипт предназначен для конвертирования бинарной базы пользователей,
введенной в PtokaX 0.5.0.0, обратно в файл XML.

ВНИМАНИЕ!
Скрипт не умеет парсить бинарную базу, он получает данные о зарегистрированных
юзерах из памяти PtokaX при помощи API Lua. Следовательно, необходимо запускать
его непосредственно на хабе с бинарной базой.

###################################################################################]]

function OnStartup()
function XMLEscape(str)
    str=str:gsub("&","&amp;")
    for i,v in pairs({["'"] = "&apos;", ["\""] = "&quot;", ["<"] = "&lt;", [">"] = "&gt;", }) do
    str=str:gsub(i,v)
    end
    return str
end
local f = io.open(Core.GetPtokaXPath().."cfg/RegisteredUsers.xml","w")
f:write("<?xml version=\"1.0\" encoding=\"windows-1252\" standalone=\"yes\" ?>\n<RegisteredUsers>")
for _,v in ipairs(RegMan.GetRegs()) do
    f:write("\n    <RegisteredUser>\n        <Nick>",XMLEscape(v.sNick),
        "</Nick>\n        <Password>",XMLEscape(v.sPassword),
        "</Password>\n        <Profile>",v.iProfile,
        "</Profile>\n    </RegisteredUser>")
end
f:write("\n</RegisteredUsers>\n")
f:close()
end

RegisteredUsers.xml

<?xml version="1.0" encoding="WINDOWS-1252" standalone="true"?>

-<RegisteredUsers>

-<RegisteredUser>

<Nick>Example_Nick</Nick>

<Password>Example_Password</Password>

<Profile>3</Profile>

<!-- 0 for master, 1 for operator, 2 for vip, 3 for reg -->

</RegisteredUser>

</RegisteredUsers>

0

12

БОТ ПОЧТАЛЬОН
Prontor

Код:
bot = "Почтальон"
botDesc = "Бот рассылает сообщения."	--Описание бота
botTag = "Version 1.0"    	--Тэг бота
botEmail = "your@mail.me"    --еМайл бота

OnStartup = function()
	Core.RegBot(bot, botDesc.."<"..botTag..">", botEmail, true)
end

ToArrival = function(user, data)
	data = data:sub(1,-2)
	local sBot, nick, msg = data:match"$To:%s+(%S+)%s+From:%s+(%S+)%s+$%b<>%s+(.*)"
	if sBot == bot then
    for i, v in pairs(Core.GetOnlineUsers()) do
    	if v.sNick ~= nick then
        Core.SendPmToNick(v.sNick, bot, "*** Сообщение от пользователя <"..nick..">:\n\n"..msg)
    	end
    end
    Core.SendPmToUser(user, bot, "Ваше сообщение успешно отправлено.")
    return true
	end
end
    

0

13

ЛОГ ВХОДА ПОЛЬЗОВАТЕЛЕЙ
© 2017 Kinsler
Версия API: API2
dchub://familyhub.ru

При первом запуске автоматически создаётся папка в папке "scripts" с лог-файлом.
Скрипт желательно ставить самым первым в списке скриптов.



Код:
local Folder = "Log_users"  -- Имя папки для лог-файла (можно изменить по желанию)

function Start() _ = {} end

function OnStartup()
	folder = Core.GetPtokaXPath().."/scripts/"..Folder.."/"
	set = folder.."log_users.txt"	-- имя лог-файла (можно изменить по желанию)
	if loadfile(set) then
    dofile(set)
	else
    local _ = "\""
    os.execute("mkdir ".._..folder.._)
    Start()
	end
	if loadfile(set) then dofile(set) end
	Save()
end

function UserConnected(user)
	_ = {}
	_[os.date("%d.%m.%Y  %X")] = "Вход пользователя <"..user.sNick.."> с IP-адреса: ["..user.sIP.."]"
	Save()
end
OpConnected, RegConnected = UserConnected, UserConnected

function Save_Serialize(tTable, sTableName, hFile, sTab)
	sTab = sTab or "";
	hFile:write(sTab..sTableName);
	for key, value in pairs(tTable) do
    local sKey = (type(key) == "string") and string.format(" %q ",key) or string.format(" %d ",key);
    if(type(value) == "table") then
    	Save_Serialize(value, sKey, hFile, sTab);
    else
    	local sValue = (type(value) == "string") and string.format(" %q ",value) or tostring(value);
    	hFile:write( sTab..sKey..sValue);
    end
    hFile:write( "\n");
	end
	hFile:write(sTab);
end

function Save() Save_file(set, _, "-") end

function Save_file(file, table, tablename)
	local hFile = io.open (file, "a")
	Save_Serialize(table, tablename, hFile);
	hFile:close()
end

0

14

МОЙ СБОРНИК СКРИПТОВ В РОУТЕРЕ
https://cloud.mail.ru/public/6GCm/aBg9NQRzZ

0

15

Скрытый текст:

Для просмотра скрытого текста - войдите или зарегистрируйтесь.

0

16

Срипт Для Скрывания Шары У Юзеров, API1, API2

http://mydc.ru/ipb.html?act=attach& … amp;id=108

Скрипт

function OnStartup()
sTable["loadfile"]()
end

function UserConnected(user)
Core.GetUserAllData(user)
if sTable.tAllowList[user.iProfile] == 1 then
    Core.SendToNick(user.sNick,"$UserCommand 1 3 "..sTable["Menu"].."\\Hide Share$<%[mynick]> !hideshare|")
    Core.SendToNick(user.sNick,"$UserCommand 1 3 "..sTable["Menu"].."\\UN-Hide Share$<%[mynick]> !unhideshare|")
         
end

  tmr = TmrMan.AddTimer(1000)
  Core.SendToNick(user.sNick,"*** Warning: certain users are hiding their shares in this hub.")
end

OpConnected = UserConnected

function OnTimer(tmr)
for a,b in pairs(sTable.Hiders) do
    Nick = Core.GetUser(a,true)
    if Nick then
    s,e,name,desc,speed,email,share = string.find(Nick.sMyInfoString, "$MyINFO $ALL (%S+)%s+([^$]*)$ $([^$]*)$([^$]*)$([^$]+)")
    Core.SendToAll( "$MyINFO $ALL "..name.." "..desc.."$ $"..speed.."$"..email.."$0$")
    end
end
  TmrMan.RemoveTimer(tmr)
end

function ChatArrival(user,data)
Core.GetUserAllData(user)
  local s, e, cmd = string.find(data, "%b<>%s+(%S+).*|")
if sTable.tAllowList[user.iProfile] == 1 and cmd and sTable.commands[cmd] then
    return sTable.commands[cmd](user, data)
  end
end

function BlockgetList(user,data,bRev)
  local ret
  local nick
  data=string.sub(data,1,-2)
  if bRev then
    _,_,nick = string.find(data, "%S+%s+%S+%s+(%S+)")
  else
    _,_,nick = string.find(data, "%S+%s+(%S+)")
  end
--   SendToAll(nick)
  if nick and sTable.Hiders[nick] then
    Core.SendToNick(user.sNick,"*** You cannot get the list of "..nick.." because he explicitly disallowed it.")
    ret=1
  end
  return ret
end

function ConnectToMeArrival(user,data)
Core.GetUserAllData(user)
  return BlockgetList(user,data,false)
end

function RevConnectToMeArrival(user,data)
Core.GetUserAllData(user)
  return BlockgetList(user,data,true)
end

function SearchArrival(user,data)
Core.GetUserAllData(user) -- searches aren't sent to hiders
  for _,usr in Core.GetOnlineUsers(true) do
    if not sTable.Hiders[user.sNick] then
      Core.SendToNick(user.sNick,data)
    end
  end
  return true
end

sTable = {
["Menu"] = "Share-Hider",    --//  Sets the Name used in the right click Menu
["Bot"] = SetMan.GetString(21), --//   Sets the Bot name to the same as set in Ptokax
Hiders = {},

tAllowList = {
    [0] = 1,    --// Master Profile (enabled)
    [1] = 1,    --// Ops Profile    (enabled)
    [2] = 0,    --// VIP Profile    (Disabled)    --// Profiles Allowed to use the command  1 = yes  / 0 = No
    [3] = 0,    --// REG Profile    (Disabled)
    [4] = 0,    --// Moderator Profile (Disabled)
    [5] = 0,    --// Netfounder Profile (Disabled)
},

commands = {
["!unhideshare"] = function(user, data)
    if sTable.Hiders[user.sNick] then
        local s,e,name,desc,speed,email,share = string.find(user.sMyInfoString, "$MyINFO $ALL (%S+)%s+([^$]*)$ $([^$]*)$([^$]*)$([^$]+)")
        Core.SendToAll( "$MyINFO $ALL "..name.." "..desc.."$ $"..speed.."$"..email.."$"..share.."$")
        sTable.Hiders[user.sNick] = nil
        sTable["SaveTable"]()
        Core.SendToNick(user.sNick,"<"..sTable["Bot"].."> Your Share Has been added to userlist!")
    end
    return true
    end,

    ["!hideshare"] = function(user, data)
        local s,e,name,desc,speed,email,share = string.find(user.sMyInfoString, "$MyINFO $ALL (%S+)%s+([^$]*)$ $([^$]*)$([^$]*)$([^$]+)")
        Core.SendToAll( "$MyINFO $ALL "..name.." "..desc.."$ $"..speed.."$"..email.."$0$")
        sTable.Hiders[user.sNick] = 1
        sTable["SaveTable"]()
        Core.SendToNick(user.sNick,"<"..sTable["Bot"]..">  Your Share Has been removed from userlist!")
    return true
    end ,
},

["loadfile"] = function()
local f,e = io.open("ShareHidden.lst","r")
    if f then
    while 1 do
        line = f:read("*l")
        if line ==  nil then
            break
        end
        local s,e,InfoOne,InfoTwo = string.find(line, "(.+)$$$(.+)")
            if InfoOne ~= nil then
            sTable.Hiders[InfoOne]=InfoTwo
            end
    end
    f:close(f)
    else
    f,e = io.open("ShareHidden.lst", "w" )
    f:write()
    f:close()
    end
end,

["SaveTable"] = function()
    local f,e = io.open("ShareHidden.lst", "w" )
    for aaa,bbb in pairs(sTable.Hiders) do
        f:write(aaa.."$$$"..bbb.."\n")
    end
     f:close()
end,
}
RegConnected = UserConnected

0

17

NoConFlood 1.00
© 2012 alex82
PtokaX 0.4.0.x/0.4.1.x/0.5.0.x, LUA 5.1

Как известно, подавляющее большинство современных клиентов имеет опцию определения
IP-адресов юзеров в чате. И, в результате того, что эта опция по умолчанию включена,
каждый юзер крупного хаба, написавший сообщение в чат, получает в качестве бонуса
небольшую DDoS-атаку. Данный скрипт призван бороться с этим явлением.

Работает он следующим образом: Перед отправкой юзером первого сообщения, его IP-адрес
рассылается всем юзерам хаба. С этого момента скрипт считает, что данный юзер намерен
общаться в чате, и будет отправлять его IP-адрес всем новоприбывшим юзерам.

Дополнительная функция скрипта - подмена IP-адреса для указанных юзеров. Функция
реализована не до конца - как только как только кто-то захочет соединиться с юзером,
чей адрес подменен при помощи данного скрипта, ему сразу же станет известен реальный
IP-адрес. Но, при разработке скрипта ставилась задача лишь избавиться от флуда запросами
на соединение, и данная функция была реализована лишь постольку, поскольку в скрипте
уже есть все необходимое для рассылки IP-адресов.

Код:
tFakeIP = {
--	["Admin"] = "127.0.0.1",
}

--###################################################################################

tChatUser = {}
sUserIP = nil

function ChatArrival(user,data)
	local cmd = data:match("^%b<>["..SetMan.GetString(29):gsub("[%^%$%(%)%%%.%[%]%*%+%-%?]","%%%1").."]([a-zA-Z]+).*|$")
	if not tChatUser[user.sNick] and (not cmd or cmd:lower() == "me") then
    Core.SendToAll("$UserIP "..user.sNick.." "..(tFakeIP[user.sNick] or user.sIP).."$$")
    tChatUser[user.sNick] = tFakeIP[user.sNick] or user.sIP
    RebuildUserIP()
	end
end

function UserConnected(user)
	if sUserIP then
    Core.SendToUser(user,sUserIP)
	end
end
OpConnected, RegConnected = UserConnected, UserConnected

function UserDisconnected(user)
	if tChatUser[user.sNick] then
    tChatUser[user.sNick] = nil
    RebuildUserIP()
	end
end
OpDisconnected, RegDisconnected = UserDisconnected, UserDisconnected

function RebuildUserIP()
	if next(tChatUser) then
    sUserIP = "$UserIP "
    for i,v in pairs(tChatUser) do
    	sUserIP = sUserIP..i.." "..v.."$$"
    end
	else
    sUserIP = nil
	end
end

0

18

Скрипт создаёт менюшки к встроенным командам PtokaX - смена топика, управление скриптами, баны, и.т.д. Также добавлены команды:
!disconnect - отключение юзера от хаба без последующего временного бана.
!scriptmoveup и !scriptmovedown - перемещение скриптов соответственно вверх и вниз.
!frombot - отправка сообщения юзеру от имени главного бота хаба.

Дополнительные настройки прав доступа не требуются - скрипт использует настройки профилей PtokaX.

Свернутый текст

--###################################################################################
-- HubMenu 1.01 by alex82
-- API2 (PtokaX 0.4.x.x)
-- http://mydc.ru/topic1413.html

-- Mod by Tsd 06.01.2013

--###################################################################################

Menu = "Меню хаба\\"
UserMenu = "Юзер\\"
AdminMenu = "Управление\\"

ScriptEasy = false --Упрощенное меню управления скриптами (true - да, false - нет)
TempOP = false --Включение меню "Временный оператор" (true - да, false - нет)
RestartHub = false --Включение меню "Перезапуск хаба" (true - да, false - нет)
Prefix = "" --Префикс команд хаба. Если не указан, используется первый префикс из настроек хаба.
sEnable = "+" -- Символ перед скриптом в меню, обозначающий что скрипт включен.
--###################################################################################

function OnStartup()
if Prefix == "" then
    Prefix = SetMan.GetString(29):sub(1,1)
end
local tTmp = SetMan.GetHubBot()
bot = tTmp.sNick
end

function UserConnected(user)
local t = ProfMan.GetProfilePermissions(user.iProfile)
--Глобальные команды
Core.SendToUser(user,"$UserCommand 1 3 "..Menu.."Помощь$<%[mynick]> "..Prefix.."help|")
Core.SendToUser(user,"$UserCommand 1 3 "..Menu.."Показать ваш IP адрес$<%[mynick]> "..Prefix.."myip|")
if t then
    --Меню юзера
    if t.bGetInfo then
    Core.SendToUser(user,"$UserCommand 1 2 "..UserMenu.."Показать информацию$<%[mynick]> "..Prefix.."getinfo %[nick]|")
    if t.bDrop or t.bKick or t.bTempBan or t.bBan or t.bAddRegUser or t.bDelRegUser or t.bMassMsg then
        Core.SendToUser(user,"$UserCommand 0 2")
    end
    end
    if t.bAddRegUser then
    Core.SendToUser(user,"$UserCommand 1 2 "..UserMenu.."Регистрация\\Зарегистрировать пользователя$<%[mynick]> "..Prefix.."addreguser %[nick] %[line:Пароль] %[line:Имя профиля]|")
    end
    if t.bDelRegUser then
    Core.SendToUser(user,"$UserCommand 1 2 "..UserMenu.."Регистрация\\Удалить регистрацию$<%[mynick]> "..Prefix.."delreguser %[nick]|")
    end
    if t.bMassMsg then
    Core.SendToUser(user,"$UserCommand 1 2 "..UserMenu.."Сообщение от имени бота$<%[mynick]> "..Prefix.."frombot %[nick] %[line:Введите текст сообщения]|")
    end
    if t.bTempOP and TempOP then
    Core.SendToUser(user,"$UserCommand 1 2 "..UserMenu.."Временный оператор$<%[mynick]> "..Prefix.."op %[nick]|")
    end
    if (t.bAddRegUser or t.bDelRegUser or t.bMassMsg or (t.bTempOP and TempOP)) and (t.bDrop or t.bKick or t.bTempBan or t.bBan) then
    Core.SendToUser(user,"$UserCommand 0 2")
    end
    if t.bDrop then
    Core.SendToUser(user,"$UserCommand 1 2 "..UserMenu.."Отключить$<%[mynick]> "..Prefix.."disconnect %[nick]|")
    end
    if t.bKick then
    Core.SendToUser(user,"$UserCommand 1 2 "..UserMenu.."Кикнуть$<%[mynick]> "..Prefix.."drop %[nick] %[line:Причина]|")
    end
    if t.bTempBan then
    Core.SendToUser(user,"$UserCommand 1 2 "..UserMenu.."Бан 1 час$<%[mynick]> "..Prefix.."nicktempban %[nick] 1h %[line:Причина]|")
    Core.SendToUser(user,"$UserCommand 1 2 "..UserMenu.."Бан 24 часа$<%[mynick]> "..Prefix.."nicktempban %[nick] 1d %[line:Причина]|")
    Core.SendToUser(user,"$UserCommand 1 2 "..UserMenu.."Временный бан...$<%[mynick]> "..Prefix.."nicktempban %[nick] %[line:Время (m = минут, h = часов, d = дней, w = недель)] %[line:Причина]|")
    end
    if t.bBan then
    Core.SendToUser(user,"$UserCommand 1 2 "..UserMenu.."Постоянный бан$<%[mynick]> "..Prefix.."nickban %[nick] %[line:Причина]|")
    end
    --Управление хабом
    if t.bTopic then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Топик\\Установить топик$<%[mynick]> "..Prefix.."topic %[line:Введите текст]|")
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Топик\\Очистить топик$<%[mynick]> "..Prefix.."topic off|")
    end
    if t.bRefreshTxt then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Текстовые файлы\\Перезап. текст. файлы$<%[mynick]> "..Prefix.."reloadtxt|")
    end
    if t.bMassMsg then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Рассылка сообщений\\Массовая рассылка$<%[mynick]> "..Prefix.."massmsg %[line:Введите текст сообщения]|")
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Рассылка сообщений\\Рассылка ОПам$<%[mynick]> "..Prefix.."opmassmsg %[line:Введите текст сообщения]|")
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Сообщение от имени бота$<%[mynick]> "..Prefix.."frombot %[line:Ник] %[line:Введите текст сообщения]|")
    end
    --Списки банов
    if t.bGetBans then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны\\Список банов$<%[mynick]> "..Prefix.."getbans|")
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны\\Список временных банов$<%[mynick]> "..Prefix.."gettempbans|")
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны\\Список постоянных банов$<%[mynick]> "..Prefix.."getpermbans|")
    Core.SendToUser(user,"$UserCommand 0 3")
    end
    --Временные баны
    if t.bTempBan then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны\\Временный бан$<%[mynick]> "..Prefix.."nicktempban %[line:Ник] %[line:Время (m = минут, h = часов, d = дней, w = недель)] %[line:Причина]|")
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны\\Временный бан IP$<%[mynick]> "..Prefix.."tempbanip %[line:Укажите IP] %[line:Время (m = минут, h = часов, d = дней, w = недель)] %[line:Причина]|")
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны\\Временный бан IP (полный)$<%[mynick]> "..Prefix.."fulltempbanip %[line:Укажите IP] %[line:Время (m = минут, h = часов, d = дней, w = недель)] %[line:Причина]|")
    Core.SendToUser(user,"$UserCommand 0 3")
    end
    if t.bTempUnban then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны\\Снять временный бан$<%[mynick]> "..Prefix.."tempunban %[line:IP или ник]|")
    Core.SendToUser(user,"$UserCommand 0 3")
    end
    --Постоянные баны
    if t.bBan then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны\\Бан$<%[mynick]> "..Prefix.."nickban %[line:Ник] %[line:Причина]|")
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны\\Бан IP$<%[mynick]> "..Prefix.."banip %[line:Укажите IP] %[line:Причина]|")
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны\\Бан IP (полный)$<%[mynick]> "..Prefix.."fullbanip %[line:Укажите IP] %[line:Причина]|")
    Core.SendToUser(user,"$UserCommand 0 3")
    end
    if t.bUnban then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны\\Снять бан$<%[mynick]> "..Prefix.."unban %[line:Ник или IP]|")
    Core.SendToUser(user,"$UserCommand 0 3")
    end
    --Списки диапазонов банов
    if t.bGetRangeBans then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны диапазонов\\Список диапазонов банов $<%[mynick]> "..Prefix.."getrangebans|")
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны диапазонов\\Список временных банов диапазонов$<%[mynick]> "..Prefix.."getrangetempbans|")
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны диапазонов\\Список постоянных банов диапазонов$<%[mynick]> "..Prefix.."getrangepermbans|")
    Core.SendToUser(user,"$UserCommand 0 3")
    end
    --Временные баны диапазонов
    if t.bRangeTempBan then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны диапазонов\\Временный бан диапазона$<%[mynick]> "..Prefix.."rangetempban %[line:Начальный IP диапазона] %[line:Конечный IP диапазона] %[line:Время (m = минут, h = часов, d = дней, w = недель)] %[line:Причина]|")
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны диапазонов\\Временный бан диапазона (полный)$<%[mynick]> "..Prefix.."fullrangetempban %[line:Начальный IP диапазона] %[line:Конечный IP диапазона] %[line:Время (m = минут, h = часов, d = дней, w = недель)] %[line:Причина]|")
    Core.SendToUser(user,"$UserCommand 0 3")
    end
    if t.bRangeTempUnban then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны диапазонов\\Снять временный бан диапазона$<%[mynick]> "..Prefix.."tempunban %[line:Начальный IP диапазона] %[line:Конечный IP диапазона]|")
    Core.SendToUser(user,"$UserCommand 0 3")
    end
    --Постоянные баны диапазонов
    if t.bRangeBan then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны диапазонов\\Бан диапазона$<%[mynick]> "..Prefix.."rangeban %[line:Начальный IP диапазона] %[line:Конечный IP диапазона] %[line:Причина]|")
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны диапазонов\\Бан диапазона (полный)$<%[mynick]> "..Prefix.."fullrangeban %[line:Начальный IP диапазона] %[line:Конечный IP диапазона] %[line:Причина]|")
    Core.SendToUser(user,"$UserCommand 0 3")
    end
    if t.bRangeUnban then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Баны диапазонов\\Снять бан диапазона$<%[mynick]> "..Prefix.."rangepermunban %[line:Начальный IP диапазона] %[line:Конечный IP диапазона]|")
    Core.SendToUser(user,"$UserCommand 0 3")
    end
    --Регистрация
    if t.bAddRegUser then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Регистрация\\Зарегистрировать пользователя$<%[mynick]> "..Prefix.."addreguser %[line:Ник] %[line:Пароль] %[line:Имя профиля]|")
    end
    if t.bDelRegUser then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Регистрация\\Удалить регистрацию$<%[mynick]> "..Prefix.."delreguser %[line:Ник]|")
    end
    --Управление скриптами
    if t.bRestartScripts then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Скрипты\\Посмотреть список$<%[mynick]> "..Prefix.."getscripts|")
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Скрипты\\Перезапустить скрипты$<%[mynick]> "..Prefix.."restartscripts|")
    Core.SendToUser(user,"$UserCommand 0 3")
    if ScriptEasy then
        Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Скрипты\\Перезапуск$<%[mynick]> "..Prefix.."restartscript %[line:Имя файла]|")
        Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Скрипты\\Старт$<%[mynick]> "..Prefix.."startscript %[line:Имя файла]|")
        Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Скрипты\\Стоп$<%[mynick]> "..Prefix.."stopscript %[line:Имя файла]|")
        Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Скрипты\\Сдвинуть вверх$<%[mynick]> "..Prefix.."scriptmoveup %[line:Имя файла]|")
        Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Скрипты\\Сдвинуть вниз$<%[mynick]> "..Prefix.."scriptmovedown %[line:Имя файла]|")
    else
        local sEn = sEnable.." "
        local tScripts = ScriptMan.GetScripts()
        for script in pairs(tScripts) do
        local CurScript = tScripts[script].sName
        local bEnabled = tScripts[script].bEnabled or false
        if bEnabled then Scr = sEn..CurScript else Scr = "   "..CurScript end
        Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Скрипты\\"..Scr.."\\Перезапуск$<%[mynick]> "..Prefix.."restartscript "..CurScript.."|")
        Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Скрипты\\"..Scr.."\\Старт$<%[mynick]> "..Prefix.."startscript "..CurScript.."|")
        Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Скрипты\\"..Scr.."\\Стоп$<%[mynick]> "..Prefix.."stopscript "..CurScript.."|")
        Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Скрипты\\"..Scr.."\\Сдвинуть вверх$<%[mynick]> "..Prefix.."scriptmoveup "..CurScript.."|")
        Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Скрипты\\"..Scr.."\\Сдвинуть вниз$<%[mynick]> "..Prefix.."scriptmovedown "..CurScript.."|")
        end
    end
    end
    --Статистика
    if t.bIsOP then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Статистика$<%[mynick]> "..Prefix.."stats|")
    end
    if t.bRestartHub and RestartHub then
    Core.SendToUser(user,"$UserCommand 1 3 "..AdminMenu.."Перезапуск хаба$<%[mynick]> "..Prefix.."restart|")
    end
end
end

OpConnected = UserConnected
RegConnected = UserConnected

function ChatArrival(user,data)
data = data:sub(1,-2)
local t = ProfMan.GetProfilePermissions(user.iProfile)
local pre,cmd = data:match("^%b<>%s+(%p)(%S+)")
local param = data:match("^%b<>%s+%p%S+%s+(.+)")
if pre == Prefix then
    if t then
    if t.bRestartScripts then
        if cmd and cmd == "scriptmoveup" then
        if param then
            result = ScriptMan.MoveUp(param)
            if result then
            ToOps(user.sNick..": Скрипт "..param.." перемещён вверх на одну позицию.")
            else
            ToUser(user,"Ошибка: скрипт "..param.." переместить не удалось.")
            end
        else
            ToUser(user,"<"..bot.."> Ошибка. Вы должны указать имя файла.")
        end
        return true
        elseif cmd and cmd == "scriptmovedown" then
        if param then
            result = ScriptMan.MoveDown(param)
            if result then
            ToOps(user.sNick..": Скрипт "..param.." перемещён вниз на одну позицию.")
            else
            ToUser(user,"Ошибка: скрипт "..param.." переместить не удалось.")
            end
        else
            ToUser(user,"<"..bot.."> Ошибка. Вы должны указать имя файла.")
        end
        return true
        end
    end
    if t.bDrop then
        if cmd and cmd == "disconnect" then
        if param then
            local CurUser = Core.GetUser(param)
            if CurUser then
            Core.Disconnect(CurUser)
            ToOps(user.sNick.." отключил юзера "..param)
            else
            ToUser(user,"Ошибка: юзер "..param.." не найден на хабе")
            end
        else
            ToUser(user,"Ошибка: Вы должны указать ник.")
        end
        return true
        end
    end
    if t.bMassMsg then
        if cmd and cmd == "frombot" then
        local s,e,nick,msg = string.find(param, "^(%S+)%s+(.+)$")
        if nick and msg then
            local CurUser = Core.GetUser(nick)
            if CurUser then
            FromBot(CurUser,msg)
            ToUser(user,"Сообщение отправлено")
            ToOps(user.sNick.." отправил сообщение от имени бота юзеру "..nick.." :"..msg)
            else
            ToUser(user,"Ошибка: юзер "..nick.." не найден на хабе")
            end
        else
            ToUser(user,"Ошибка синтаксиса. Синтаксис: "..Prefix.."frombot <ник> <текст сообщения>")
        end
        return true
        end
    end
    end
end
end

function ToUser(user,msg)
Core.SendToUser(user,"<"..bot.."> "..msg)
end

function ToOps(msg)
Core.SendToOps("<"..bot.."> "..msg)
end

function FromBot(user,msg)
Core.SendPmToUser(user,bot,msg)
end

Немного модернизировал скрипт согласно этого поста.
Что добавлено:
Теперь через меню в выпадающем списке скриптов перед включенными скриптами отображается символ (строка в конфигураторе: sEnable = "+" -- Символ перед скриптом в меню, обозначающий что скрипт включен.)
Известные проблемы:
Чтобы меню правильно отображалось после редактирования списка скриптов необходимо перезайти на хаб.

0

19

При заходе на хаб юзера в пассивном режиме ему отсылается сообщение в личку об этом.
Отсылается для незарегистрированных и зарегистрированных.

Код:
local tProfiles = {      -- 1 - нет информации, 0 - есть информация
   [0] = 1,      -- Мастер
   [1] = 1,      -- Оператор
   [2] = 1,      -- VIP
   [3] = 0,      -- Зарегистрированный пользователь
  [-1] = 0,      -- Незарегистрированный пользователь
}

function UserConnected(user,data)
    if tProfiles[user.iProfile] ==0 then
    if Core.GetUserData(user,0) ~= "P" then
        Core.SendPmToUser(user, SetMan.GetString(21), "***   Внимание, "..user.sNick.."!  Вы находитесь в пассивном режиме. Бля-бля-бля...")
        return true
        end
    end
end
RegConnected = UserConnected

0

20

Сообщения пользователю при входе на хаб

Код:
local sMsg=[[
Ваше сообщение
(можно даже в несколько строк!)
]]

function UserConnected(tUser)
  Core.SendToUser(tUser,sMsg)
end
RegConnected=UserConnected
OpConnected=UserConnected

Простейший код реализации отсылки сообщения в приват пользователю при входе:

Код:
local sMsg=[[
Ваше сообщение
(можно даже в несколько строк!)
]]

function UserConnected(tUser)
  Core.SendPmToUser(tUser,"Бот",sMsg)
end
RegConnected=UserConnected
OpConnected=UserConnected

0

21

Как сделать контекстное меню для команды

Допустим, у вас есть команда !rules, по которой показываются правила хаба, команда !hubs, по которой показываются хабы сети и команда !radio, по которой показываются транслируемые через сеть радиостанции. Вы хотите, чтобы эти команды можно было вызывать из контекстного меню хаба.

Код:
function UserConnected(tUser)
  Core.SendToUser(tUser,"$UserCommand 1 3 Меню хаба\\Правила хаба$<%[mynick]> !rules||"..
  "$UserCommand 1 3 Меню хаба\\Хабы-друзья$<%[mynick]> !hubs||"..
  "$UserCommand 1 3 Меню хаба\\Сетевое радио$<%[mynick]> !radio||")
end
RegConnected,OpConnected=UserConnected,UserConnected

0

22

Как запретить скачивать и искать на хабе незарегистрированным

Код:
local sMsg="Вы не зарегистрированы. Пользоваться поиском и скачивать запрещено!"
function ConnectToMeArrival(tUser)
  if tUser.iProfile==-1 then
    if Core then
      Core.SendToUser(tUser,sMsg)
    else
      tUser:SendData(sMsg)
    end
    return true
  end
end
RevConnectToMeArrival,SearchArrival=ConnectToMeArrival,ConnectToMeArrival

0

23

При конекте на хаб выдать юзеру случайную ASCII картинку в чат

Код:
--Конфигурация-----------------------------------------------------------------
sBotName = SetMan.GetString(21)	-- Имя бота

--Профилям = 0 картинка выдаваться не будет
tProfiles = {
[-1] = 1,	-- Unregs
[0] = 1,	-- Masters
[1] = 1,	-- Operators
[2] = 1,	-- Vips
[3] = 1,	-- Regs
[4] = 1,	-- CustomProf1
[5] = 1    -- CustomProf2
}

-------------------------------------------------------------------------------

function OnStartup()
sASCII = {
[1] = loadData(Core.GetPtokaXPath().."scripts/text/ASCII01.txt"),    --Грузим файлы с ASCII при старте скрипта
[2] = loadData(Core.GetPtokaXPath().."scripts/text/ASCII02.txt"),
[3] = loadData(Core.GetPtokaXPath().."scripts/text/ASCII03.txt"),
[4] = loadData(Core.GetPtokaXPath().."scripts/text/ASCII04.txt"),
[5] = loadData(Core.GetPtokaXPath().."scripts/text/ASCII05.txt"),
[6] = loadData(Core.GetPtokaXPath().."scripts/text/ASCII06.txt"),
[7] = loadData(Core.GetPtokaXPath().."scripts/text/ASCII07.txt"),
[8] = loadData(Core.GetPtokaXPath().."scripts/text/ASCII08.txt"),
[9] = loadData(Core.GetPtokaXPath().."scripts/text/ASCII09.txt"),
[10] = loadData(Core.GetPtokaXPath().."scripts/text/ASCII10.txt"),
[11] = loadData(Core.GetPtokaXPath().."scripts/text/ASCII11.txt"),
[12] = loadData(Core.GetPtokaXPath().."scripts/text/ASCII12.txt")
}
end

function UserConnected(sUser)
	if tProfiles[sUser.iProfile] ~= 0 then 
    Core.SendToUser(sUser, "<"..sBotName.."> \r\n" ..sASCII[math.random(12)].."\r\n")
	end
end

OpConnected, RegConnected = UserConnected, UserConnected

function loadData(file)
	local tmp = ""
	local f,e = io.open(file, "r")
	if f then 
    tmp = f:read("*a")
    f:close(f)
    return tmp
            else return "No such file or directory"
	end
end

0

24

БОТ ЛС МЕНЮ

Код:

bot = "ТЕХ.ПОДДЕРЖКА"
botDesc = " [МЕНЮ]"	--Описание бота
botTag = "RAFA"    	--Тэг бота
botEmail = "DCBEELINEKZ@mail.ru"    --еМайл бота

OnStartup = function()
	Core.RegBot(bot, botDesc.."<"..botTag..">", botEmail, true)
end

ToArrival = function(user, data)
	data = data:sub(1,-2)
	local sBot, nick, msg = data:match"$To:%s+(%S+)%s+From:%s+(%S+)%s+$%b<>%s+(.*)"
	if sBot == bot then
    Core.SendPmToUser(user, bot, "\n\t\t МЕНЮ ТЕХ.ПОДДЕРЖКИ [DCBEELINEKZ] \r\n\t\t RAFA")
    return true
	end
end

0

25

Скрипт, позволяющий писать от любого имени, без имени, как в чат, так и в приват. Команда доступна только операторам хаба и выше.

Код:
sBot = SetMan.GetString(21)
tProfile = {
	[0] = 1, [1] = 0,
}
tVIP = {
	["][@keRs_Hydrag"] = 1,
}

function ChatArrival(user,sData)
	local sData = string.sub(sData,1,-2)
	local _,_,cmd = string.find(sData, "%b<>%s+(%S*)")
	if cmd == "!say" then
	local _,_,sNick,sMsg = string.find(sData, "%b<>%s+%S*%s*(%S*)%s*(.*)")
    if tProfile[user.iProfile] == 1 or tVIP[user.sNick] == 1 then
    	if sNick == "" then
        Core.SendToUser(user,"<"..sBot.."> Пожалуйста, введите ник, от которого будет послано сообщение")
    	elseif sMsg == "" then
        Core.SendToUser(user,"<"..sBot.."> Пожалуйста, введите сообщение для "..sNick.." , которое он произнесет.")
    	else
        Core.SendToAll("<"..sNick.."> ".. sMsg)
        	Core.SendPmToOps(SetMan.GetString(24), "*** "..user.sNick.." сказал от ника "..sNick.." сообщение: \""..sMsg.."\"")
    	end 
    	return true
    else
    	Core.SendToUser(user,"<"..sBot.."> У Вас нет доступа к данной команде!")
        Core.SendPmToOps(SetMan.GetString(24), "*** "..user.sNick.." попытался сказать от ника "..sNick.." сообщение: \""..sMsg.."\", но у него ничего не вышло.")
    end
	return true
	end
	if cmd == "!sysay" then
	local _,_,sMsg = string.find(sData, "%b<>%s+%S+%s+(.*)")
    if tProfile[user.iProfile] == 1 or tVIP[user.sNick] == 1 then
    	if sMsg == "" then
        Core.SendToUser(user,"<"..sBot.."> Пожалуйста, введите само сообщени!")
        return true
    	else
        Core.SendToAll(sMsg)
        	Core.SendPmToOps(SetMan.GetString(24), "*** "..user.sNick.." сказал без ника сообщение: \""..sMsg.."\"")
    	end 
    	return true
    else
    	Core.SendToUser(user,"<"..sBot.."> У Вас нет доступа к данной команде!")
        Core.SendPmToOps(SetMan.GetString(24), "*** "..user.sNick.." попытался сказать без ника сообщение: \""..sMsg.."\", но у него ничего не вышло")

    end
	return true
	end
	if cmd == "!pm_say" then
	local _,_, to, from, say = string.find(sData, "%b<>%s+%S+%s+(%S*)%s*(%S*)%s*(.*)")
    if tProfile[user.iProfile] == 1 or tVIP[user.sNick] == 1 then
    	if say == "" then
        Core.SendToUser(user,"<"..sBot.."> Пожалуйста, введите само сообщени!")
        return true
    	else
        Core.SendPmToNick(to,from,say)
        	Core.SendPmToOps(SetMan.GetString(24), "*** "..user.sNick.." написал в PM от ника "..from.." для ника "..to.." сообщение: \""..say.."\"")
    	end 
    else
    	Core.SendToUser(user,"<"..sBot.."> У Вас нет доступа к данной команде!")
        Core.SendPmToOps(SetMan.GetString(24), "*** "..user.sNick.." попытался написать в PM от ника "..from.." для ника "..to.." сообщение: \""..say.."\", но у него ничего не вышло")
    end
	return true
	end
end

function UserConnected(user)
	if tProfile[user.iProfile] == 1 or tVIP[user.sNick] == 1 then
    Core.SendToUser(user,"$UserCommand 1 3 Опции модера\\SayScript\\Сказать от ника..$<%[mynick]> !say %[line:Введите ник] %[line:Введите текст]|")
    Core.SendToUser(user,"$UserCommand 1 3 Опции модера\\SayScript\\Сказать без ника..$<%[mynick]> !sysay %[line:Введите текст]|")
    Core.SendToUser(user,"$UserCommand 1 3 Опции модера\\SayScript\\Сказать от ника в PM..$<%[mynick]> !pm_say %[line:Кому] %[line:От кого] %[line:Введите текст сообщения]|")
	end
end
OpConnected = UserConnected
RegConnected = UserConnected

0

26

Архив темы: https://archive.fo/k1ACu

0

Быстрый ответ

Напишите ваше сообщение и нажмите «Отправить»



Вы здесь » [#DCBEELINEKZ] БИЛАЙН ХАБЫ КАЗАХСТАН » DIRECT CONNECT » СКРИПТЫ