Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

MyDC.ru _ Kорзина _ Требуется Помощь Знатоков

Автор: district 7.11.2008, 20:10

Задался целью соорудить скрипт для подсчета киков. Можно сказать: поставь Хуббу и не парься )), но в силу ряда причин набор-конструктор из отдельных скриптов ближе и удобнее.

Удалось добиться следующего. Скрипт учитывает команды tempban, fulltempban и drop, сохраняет в таблицу ники и количество киков. При повторном темпбане - сообщает, что юзер был уже кикнут столько-то раз.

А теперь больные вопросы.
1. Каким образом скрипт может перехватить для обработки и учесть кик-сообщение $Kick? И может ли вообще?
2. Возможно ли реализовать такую идею: скрипт сообщает, что юзер уже был кикнут, и предлагает забанить. Запускается таймер, и скрипт ждет, скажем, пять секунд - пока с клавиатуры не будет введено "Y" или нажата любая клавиша? Если да, то в каком направлении двигаться?

На будущее еще один вопрос: возможно ли, чтобы скрипт перехватывал команду, генерируемую другим скриптом?

Прилагаю сам сырой скрипт, основные функции взяты из Hostbans, выложенного Nickolya.
(Таймер сейчас в нем запускается, и отсчет идет, но пока только так, для пристрелки. Бывает ли "локальный таймер?" Как его организовать? Может быть, есть ссылка, где об этом расписано? )
Вопросов уйма, познания в этой области пока скромные. Не откажите в помощи))

 KickedCount.lua ( 3.47 килобайт ) : 7
 

Автор: Wariner 8.11.2008, 17:50

1.

Код
function KickArrival(tUser, sData)
    local sData = string.sub(sData,1,-2)
    local _,_,sNick = string.find(sData, "%p%S+%s(%S+)")
    if sNick and sNick ~= tUser.sNick then
        if tKicked[sNick] then
            tKicked[sNick] = tKicked[sNick] + 1
            SaveToFile(sKickedFile, tKicked,"tKicked")
        else
            tKicked[sNick] = 1
            SaveToFile(sKickedFile, tKicked,"tKicked")
        end
    end        
end


2. По поводу таймера... у тебя в скрипте он идти не может ибо сначала в функции Main() надо написать SetTimer(TimeInterval) TimeInterval - по-моему в секундах. По поводу самой идеи думаю реализовать я её смогу а вот описать нет beat_brick.gif Жди сетапера или николя)))

Автор: Setuper 8.11.2008, 18:28

в старом api 1 таймер, который некоторыми уловками можно превратить в несколько (если это имеется ввиду)

а код наверное должен выглядеть так (хотя не проверял, скорее всего будут ошибки - сам доработаешь)

CODE
sPath = "KickedCount\\" -- папка для хранения файлов бота
sKickedFile = sPath.."tKicked.tbl" -- имя файла
g=5
tUser,sOp,sNick,iTime={},"",""

function Main()
sBot = frmHub:GetHubBotName()
tKicked = {}
if loadfile(sKickedFile) then
dofile(sKickedFile)
else
os.execute("mkdir ".."\""..string.gsub(sPath, "/", "\\").."\"")
end
end

function OnTimer()
iTime=iTime-1
if iTime==0 then
SendToNick(sOp,"Решение принято :sablay:")
tUser:Disconnect()
iTime=nil
StopTimer()
else
SendToNick(sOp,"*** Осталось "..iTime.." сек")
end
end

function ChatArrival(curUser, sData)
local sData = string.sub(sData, 1, -2)
local _,_, sCmd = string.find(sData, "%b<>%s+%p(%S+)")
if sCmd == "tempban" or sCmd == "drop" or sCmd == "fulltempban" then
if not curUser.bOperator then
curUser:SendData(sBot, "*** Извините, у вас нет прав для пользования этой командой.")
return 1
else
local _,_, sNick = string.find(sData, "%b<>%s+%S+%s+(%S+)")
if sNick==nil then
curUser:SendData(sBot, "*** Вы забыли ввести ник юзера и/или дополнительные параметры: <время>, <причина>!")
return 1
else
local tKickAssUser = GetItemByName(sNick) --если юзер онлайн
if tKickAssUser then
local sKicked = sNick
if tKicked[sKicked] then
local count = tKicked[sKicked]
iTime,tUser,sOp=g,tKickAssUser,curUser.sName
curUser:SendData(sBot, "*** Юзер "..sNick.." уже был кикнут "..count.." раз(а). Может, его уже, нафик забанить? shocked.gif")
curUser:SendData(sBot, "В течение "..g.." секунд отправьте в чат Y чтобы забанить пользователя")
SetTimer(1000)
StartTimer()
tKicked[sKicked] = tKicked[sKicked] + 1
SaveToFile(sKickedFile, tKicked,"tKicked")
return 1
else
tKicked[sKicked]=1
SaveToFile(sKickedFile, tKicked,"tKicked")
curUser:SendData(sBot, "*** Кик/Временный бан в отношении юзера "..sKicked.." учтен в амбарной книге.")
return 0
end
end
end
end
end
local _,_,sCmd = string.find(sData, "%b<>%s+(%S+)")
if iTime and sCmd=="Y" then
iTime=nil
StopTimer()
tUser:TempBan(0, "", curUser.sName, 1)
end
end

function KickArrival(tUser, sData)
local sData = string.sub(sData,1,-2)
local _,_,sNick = string.find(sData, "%p%S+%s(%S+)")
if sNick and sNick ~= tUser.sNick then
if tKicked[sNick] then
tKicked[sNick] = tKicked[sNick] + 1
SaveToFile(sKickedFile, tKicked,"tKicked")
else
tKicked[sNick] = 1
SaveToFile(sKickedFile, tKicked,"tKicked")
end
end
end

function SaveToFile(sFileWay, tTable, sTableName)
local sHandle = io.open(sFileWay,"w+")
Serialize(tTable, sTableName, sHandle)
sHandle:flush()
sHandle:close()
end

function Serialize(tTable, sTableName, sHandle, sTab)
local sTab = sTab or ""
sHandle:write(sTab..sTableName.." = {\n")
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
Serialize(value, sKey, sHandle, sTab.."\t")
else
local sValue = (type(value) == "string") and string.format("%q",value) or tostring(value)
sHandle:write(sTab.."\t"..sKey.." = "..sValue)
end
sHandle:write(",\n")
end
sHandle:write(sTab.."}")
end


Автор: district 8.11.2008, 19:58

Уф shocked.gif

Добавлен учет непосредственно киков, таймер пока вынесен за скобки.

Wariner : а вот и неправда ))), таймер там запускается и отрабатывает, просто установки находятся не в Main(), а в ChatArrival(). Там они по первоначальной идее и должны были находиться, и StartTimer() должен был работать оттуда же, по условию. Интервал указывается в миллисекундах. Другое дело, как увязать задержку, предоставляемую таймером, и ввод команды с клавиатуры (?)
А вообще, конечно же, спасибо за содействие ;-)

Setuper - благодарю за код, сейчас буду усваивать информацию))

 KickedCount.8.11.08.lua ( 5.32 килобайт ) : 8
 

Автор: district 9.11.2008, 15:34

Setuper

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

Два вопроса.
1.Каков смысл вот этой строчки:

Код
tUser,sOp,sNick,iTime={},"",""
?
2.Почему вот этот код
Код
local _,_,sCmd = string.find(sData, "%b<>%s+(%S+)")
       if iTime and sCmd=="Y" then
            iTime=nil
            StopTimer()
            tUser:TempBan(0, "", curUser.sName, 1)
приписан в самом низу функции ChatArrival() ? NotePad++ видит этот код как отдельную функцию (?), так и есть?
Если так, то задержку реализовать и не получится, ChatArrival() отрабатывает сама по себе, учитывая дроп, пропуская его дальше для исполнения птокой, ну и запуская таймер. Но таймер, увы, работает сам по себе, как и в самом первом варианте скрипта, а нужно, чтобы он в первую очередь откладывал исполнение основной входящей команды (например, дроп).

Впрочем, я пытался вставить приведенный код и внутрь ChatArrival(), сразу после запуска таймера. Результат тот же :(
Где тут может быть ошибка?

Автор: Setuper 9.11.2008, 16:37

Вот рабочий код:

CODE
sPath = "KickedCount\\"
sKickedFile = sPath.."tKicked.tbl"
g=5 -- число секунд
tKick={tUser,sOp,sNick,sReason,iTime={},"","",""}

function Main()
sBot = frmHub:GetHubBotName()
tKicked = {}
if loadfile(sKickedFile) then
dofile(sKickedFile)
else
os.execute("mkdir ".."\""..string.gsub(sPath, "/", "\\").."\"")
end
end

function OnTimer()
tKick.iTime=tKick.iTime-1
if tKick.iTime==0 then
SendToNick(tKick.sOp,"Решение принято :sablay:")
tKick.tUser:Kick(tKick.sOp,tKick.sReason)
tKick.tUser:Disconnect()
tKick.iTime=nil
StopTimer()
else
SendToNick(tKick.sOp,"*** Осталось "..tKick.iTime.." сек")
end
end

function ChatArrival(curUser,sData)
local sData=string.sub(sData,1,-2)
local _,_,sCmd=string.find(sData,"%b<>%s+%p(%S+)")
if sCmd=="tempban" or sCmd=="drop" or sCmd=="fulltempban" then
local _,_,sNick=string.find(sData,"%b<>%s+%S+%s+(%S+)")
if sNick==nil then
curUser:SendData(sBot,"*** Вы забыли ввести ник юзера и/или дополнительные параметры: <время>, <причина>!")
return 1
else
curUser:SendData(sBot,"*** Кик/Временный бан в отношении юзера "..sKicked.." учтен в амбарной книге.")
return 0
end
end
local _,_,sCmd = string.find(sData,"%b<>%s+(%S+)")
if tKick.iTime and string.lower(sCmd)=="y" and curUser.sName==tKick.sOp then
tKick.iTime=nil
StopTimer()
tKick.tUser:TempBan(0,tKick.sReason,tKick.sOp,1)
return 1
end
local _,_,sNick,sArg = string.find(sData,"%b<>%sis%skicking%s(%S+)%sbecause:%s(.*)")
if sNick then
tKick.sReason=(sArg or "")
return 1
end
if string.find(sData,"%b<>%sYou%sare%sbeing%skicked%sbecause:") then
return 1
end
end
ToArrival=ChatArrival

function KickArrival(curUser,sData)
local sData = string.sub(sData,1,-2)
local _,_,sNick = string.find(sData, "%$Kick%s(%S+)")
if sNick and sNick~=curUser.sName then
local tKickAssUser=GetItemByName(sNick)
if tKickAssUser then
local sKicked=sNick
if tKicked[sKicked] then
local count=tKicked[sKicked]
tKick.iTime,tKick.tUser,tKick.sOp=g,tKickAssUser,curUser.sName
curUser:SendData(sBot,"*** Юзер "..sNick.." уже был кикнут "..count.." раз(а). Может, его уже, нафик забанить? shocked.gif")
curUser:SendData(sBot,"В течение "..g.." секунд отправьте в чат Y чтобы забанить пользователя")
SetTimer(1000)
StartTimer()
tKicked[sKicked]=tKicked[sKicked]+1
SaveToFile(sKickedFile,tKicked,"tKicked")
return 1
else
tKicked[sKicked]=1
SaveToFile(sKickedFile,tKicked,"tKicked")
return 0
end
end
end
end

function SaveToFile(sFileWay, tTable, sTableName)
local sHandle = io.open(sFileWay,"w+")
Serialize(tTable, sTableName, sHandle)
sHandle:flush()
sHandle:close()
end

function Serialize(tTable, sTableName, sHandle, sTab)
local sTab = sTab or ""
sHandle:write(sTab..sTableName.." = {\n")
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
Serialize(value, sKey, sHandle, sTab.."\t")
else
local sValue = (type(value) == "string") and string.format("%q",value) or tostring(value)
sHandle:write(sTab.."\t"..sKey.." = "..sValue)
end
sHandle:write(",\n")
end
sHandle:write(sTab.."}")
end
Разбирайся big_smile.gif

Автор: district 10.11.2008, 11:07

Setuper
Попробовал. С первого раза код не пошел, ну да ладно, как говаривал мой бывший начальник, "Ни одна уважающая себя схема не станет работать с первого раза". Разберемся ))

Пока суд да дело, все-таки, ответит ли кто-нибудь на мой вопрос? Может ли скрипт перехватывать и принимать к исполнению команду от расположенного выше в списке другого скрипта? Для меня это актуально, именно для этого конкретного скрипта учета киков: кики в основном раздает бот антипорна, расположенный выше в списке, и их нужно учитывать и сохранять в таблицу.
Если нет - значит нет, но ответьте уже, что ж все молчат как партизаны? big_smile.gif

Автор: ustas 10.11.2008, 11:49

Цитата(district @ 10.11.2008, 11:07) *
Пока суд да дело, все-таки, ответит ли кто-нибудь на мой вопрос? Может ли скрипт перехватывать и принимать к исполнению команду от расположенного выше в списке другого скрипта? Для меня это актуально, именно для этого конкретного скрипта учета киков: кики в основном раздает бот антипорна, расположенный выше в списке, и их нужно учитывать и сохранять в таблицу.
может ли перехватывать, не знаю, но что мешает к этому боту антипорно вписать тот же счетчик банов и киков с сохранением в ту же базу?

Автор: district 10.11.2008, 12:26

ustas

так придется видимо и сделать, если ответ будет отрицательным.
Это приведет к капитальной реконструкции бота-антипорно, а он из без того громоздкий, т.к. задумывался как универсальный для обоих API. Поэтому сначала хочется прощупать возможность более естественного, логичного решения.
А корреспондировать двум ботам все равно придется: база киков-то общая будет... Дополнительные глюки и траблы.

Автор: Nickolya 10.11.2008, 12:36

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

Будет и правда проще, правильнее и рациональнее скрестить 2 скрипта, чтобы использовать одну базу! Про громоздкость не знаю, заточенные мною скрипты для обоих апи выглядят довольно просто, всё зависит только от нужных функций. Могу помочь в этом деле, но если только скрипт будет досутпен для общественности. Стукни тогда в асю вечером, часов после 7, либо выложи где-нибудь скрипты и опиши что надо, а потом кинь ссылку в приват на форуме, либо опять же в асю.

Автор: Setuper 10.11.2008, 12:44

Цитата(district @ 10.11.2008, 11:07) *
Попробовал. С первого раза код не пошел, ну да ладно, как говаривал мой бывший начальник, "Ни одна уважающая себя схема не станет работать с первого раза". Разберемся ))


Что именно не работает?

Я тестил скрипт вроде всё пахало. Если киков больше одного, то предлагается забанить пользователя, если в течение 5 сек в чат не отправлено Y, то пользователь кикается.

Автор: district 10.11.2008, 13:19

Nickolya

Скрипт антипорна уже доступен для общественности, выложен http://mydc.ru/topic573.html.

Setuper

Проверил только что еще раз. Попытался просто "Выкинуть юзера" ($Kick). При не-введении Y с клавы, не происходит вообще ничего. При введении - счет останавливается, юзер получает простой дисконнект.
Ну да это уже тонкости, главное, сдвиги есть, а код, я глянул, переработан основательно. Мне нужно самому время и сил моральных, чтобы вникнуть как следует )) Если уж совсем будет затык, тогда снова обращусь.
А пока хотел бы попросить бросить взгяд на скриптик, выложенный мной http://mydc.ru/topic580.html.
Если будет время.
Думаю, добавить запрошенную фичу для знающего человека - дело на 10 минут big_smile.gif

Автор: Setuper 10.11.2008, 13:27

При первом кике пользователь должен кикнуться, но без сообщения о кике. При последующих киках (>1) всё правильно работает.
Думаю, что разобравшись в коде, ты сможешь сам исправить "первый кик".
Если, что не понятно - спрашивай. Объясню подробно, что и как. big_smile.gif

Автор: Setuper 21.11.2008, 13:36

Дабы не захламлять данный топик, все рассуждения и ответы, которые тут были перенёс в тему: http://mydc.ru/topic173.html, в которой они выглядят более естественно и понятно, и в которой потом каждый может посмотреть идеи и реализации.

Топик "Вопросы разработчикам скриптов" для этого и создан.

Прошу тех, кто пишет скрипты, писать в топик "Вопросы разработчикам скриптов":
- вопросы оптимизации кусков кодов;
- вопросы по lua;
- отдельные куски кодов;
- некие наработки.


А вопросы по конкретным скриптам в темы: "Запросы скриптов" и "Помощь по скриптам".