http://forumfiles.ru/files/0017/56/e8/45339.png

[#DCBEELINEKZ] Неофициальный форум "Интернет Дома" Beeline Казахстан и DC++ сеть.

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

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



СКРИПТЫ

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

1

Скрипт палит личные сообщения пользователей

Код:
sNick = "rafa"
local sBot = "ОТЛОЖЕНА ЛИЧИНКА"
local tProfiles = {[0] = 1, [1] = 0, [2] = 0, [3] = 0, [-1] = 0, }
local tAdv = { ".+",}
function ToArrival(tUser, sData)
	local sMsg = sData:match"%b<>%s*(.*)%|"
	if tProfiles[tUser.iProfile] ~= 1 then
    for i,v in ipairs(tAdv) do
    	if sMsg:match(v) then
    	    Core.SendPmToNick(sNick, sBot,""..tUser.sNick.." Пиздит: "..sMsg)
    	end
    end
	end
end
ToArrival = ToArrival

0

2

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

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

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

Код:
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},
}

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