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

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

MyDC.ru _ Помощь по скриптам для PtokaX _ жалобная книга + MySQL

Автор: fixx 6.7.2009, 12:35

Собственно сабж.
Помогите, пожалуйста, сам несмог..
Можно много незаморачиваться, а сделать по команде, скажем, !report <ник_на_кого_жалоба> <сообщение> - хотя менюшку желательно.
Если жалуются не на админа, то: КорСендТуЮзер "*** оператора с ником ..блабла.. несуществует".
При этом <сообщение> записывается в базу: _таблица_с_ником_админа (или некий ID админа)::: порядковый номер; дата; время; ник; сообщение.
Доступ к команде и менюшке только у профилей 3 и 2 - нефиг опам друг на друга стучать (опционально)
Антифлуд - неболее 1 жалобы 1 ника/ip в час (опционально). Интересно, а антимат возможен?
Что с базой делать - каждый сам решит, я вот на страницу выведу. Ну и жалобы через веб выведу - для забаненых. ;)
Хотя можно Мастеру дать возможность просматривать последние жалобы на хабе.
В идеале потом можно будет проводить конкурсы "Самый строгий админ" и "Самый добрый админ"
Пытался сам переделать из http://http://mydc.ru/topic1823.html, но, как обычно ничего невышло. big_smile.gif

Автор: Wariner 6.7.2009, 13:18

ты думаешь будет так много жалоб? почету то я сомневаюсь...

Автор: fixx 6.7.2009, 13:30

О, уверен, что жалоб будет много.
И даже знаю на кого больше всех - не менее 10-30 в сутки.
А жалобная книга - мальчик для битья, написал (дал затрещину) и успокоился. big_smile.gif
И ругани меньше будет, а то вечный флейм.

Автор: *FoxMalder* 6.7.2009, 15:11

что ж за админы такие страшные)

Автор: fixx 6.7.2009, 15:19

Да есть парочка - любители эпатажа, но не все это понимают (эпатаж), потому мыло мне уже заспамили. big_smile.gif
По большому счету у меня неполучается только перехватить сообщение из:

Код
sMsg = "$UserCommand 1 3 "..sMenu.."$<%[mynick]> !report %[line:Введите ник админа] %[line:Введите текст жалобы]&*#*124;|"..

и записать его в базу по принципу :
[line:Введите ник админа] - это уже существующие таблицы report_НИК_АДМИНА с полями ID;Date;Time;Nick;Msg
[line:Введите текст жалобы] - поле Msg в таблице
Ну и остальные поля
ID;Date;Time;Nick
непонимаю, как заполняются. Уже прочитал все что можно, но чего-то нехватает... Дайте толчек, прочитайте лекцию для новичков, с примерами, плиз. big_smile.gif

Автор: Wariner 6.7.2009, 18:30

итак
1) не надо делать кучу таблиц! сделай одну

Код
id........Admin.......Date........Time..........Nick............Msg

2) что конкретно не получается с нахождением, как пробуешь?(есть очень хорошая статья на форуме от Setuper`a об этом)
3)
id - при создании базы надо указывать что это автозаполняемое поле, при каждой новойзаписи оно будет принимать значение n+1, где n - id последней записи
Date и Time получаются из os.date("%d-%m-%Y") и os.date("%H:%M:%S") соответственно и просто вносятся в таблицу

если что не понятно спрашивай

Автор: fixx 6.7.2009, 20:06

Код
----чудо-юдо
-- надо ли local добавлять?
local sBot = "бот"            
local sNameDB = "report"
local sUserDB = "report"      
local sPasswordDB = "******"  
local sAdressDB = "localhost"
local sPortDB = "3306"
local sPrefixTable = "report_"
local sMenu = "Пожаловаться на админа"
local sBeDate = os.date("%d.%m.%Y")
local sBeTime = os.date("%H:%M:%S")
local sErrAdmNick = "Ошибка. Оператора с таким ником несуществует"
tProfiles = {
    [0] = 1, -- Мастер
    [1] = 1, -- ОПератор
    [2] = 1, -- VIP
    [3] = 1, -- Зарегистрированный пользователь
    [4] = 1, -- Net
    [-1] = 0, -- Незарегистрированный юзер
}
tAdmNick = {   -- Список админов
    ["Admin"] = 1,
    ["Admin2"] = 1,
    ["Admin3"] = 1,
    ["Admin4"] = 1,    
    ["Admin5"] = 1,
    ["Admin6"] = 1,
}
require "luasql.mysql"   -- подключение библиотеки
local env = assert (luasql.mysql()) --- почти понял, вернее понял, но описать немогу грамотно =))
local con = assert (env:connect(sNameDB, sUserDB, sPasswordDB, sAdressDB, sPortDB)) -- подключение к базе
function UserConnected(tUser)
    if tProfiles[tUser.iProfile] == 1 then
        sMsg = "$UserCommand 1 3 "..sMenu.."$<%[mynick]> !report %[line:Введите ник админа] %[line:Введите текст жалобы]&*#*124;|"..
    if (not sMsg = tAdmNick[tUser.sNick] ~= 1) then    --- нужны ли скобки? И вообще сомневаюсь в правильности.
    Core.SendToUser(tUser, sErrAdmNick) -- или надо "..sErrAdmNick.."- c точками и в кавычках?
-- следующая строка вообще напрягает, INSERT INTO `%sreport` - правильно ли обозначил?
local con:execute(("INSERT INTO `%sreport` (`Admin`, `Date`, `Time`,`Nick`,`Msg`) VALUES ('%s','%s','%s','%s','%s')"):dbformat(sPrefixTable, sAdmin, sBeDate, sBeTime, tUser.sNick, sMsg))

Вобщем вот. И половины не написал, а ошибок чую оч много.
В комментариях я написал как я понимаю действие или непонимаю его.
Там же и вопросы.
Непонимаю как мне выловить ник админа из этих лайнов....
Кусками могу почти все, что задумал написать (хоть и неправильно), а собрать из кусков немогу что-то...
Плиз, не бейте меня. И можно уже перенести в "Помощь по скриптам" big_smile.gif

Автор: Wariner 6.7.2009, 20:27

local лучше добавлять.
а вот тут ты не понятно что делаешь...

Код
function UserConnected(tUser)
    if tProfiles[tUser.iProfile] == 1 then
        sMsg = "$UserCommand 1 3 "..sMenu.."$<%[mynick]> !report %[line:Введите ник админа] %[line:Введите текст жалобы]&*#*124;|"..
    if (not sMsg = tAdmNick[tUser.sNick] ~= 1) then    --- нужны ли скобки? И вообще сомневаюсь в правильности.
    Core.SendToUser(tUser, sErrAdmNick) -- или надо "..sErrAdmNick.."- c точками и в кавычках?
-- следующая строка вообще напрягает, INSERT INTO `%sreport` - правильно ли обозначил?
local con:execute(("INSERT INTO `%sreport` (`Admin`, `Date`, `Time`,`Nick`,`Msg`) VALUES ('%s','%s','%s','%s','%s')"):dbformat(sPrefixTable, sAdmin, sBeDate, sBeTime, tUser.sNick, sMsg))


да сначала ты послал менюшку, причём не совсем правильно. так как менюшка всего одна надо так
Код
function UserConnected(tUser)
    if tProfiles[tUser.iProfile] == 1 then
        Core.SendToUser(tUser, "$UserCommand 1 3 "..sMenu.."$<%[mynick]> !report %[line:Введите ник админа] %[line:Введите текст жалобы]&#*124;")
        end
end

вот и вся твоя функция. все остальные действия будут выполнены в функции ChatArrival
посмотри как выполнен поиск фразы в других скриптах
из line`ов ничего выдерать не надо, ибо это просто меню, после ввода оно преобразуется в строку типа
Код
!report Admin Да он просто казёл))))

Автор: fixx 7.7.2009, 1:10

Код
require "luasql.mysql"   -- подключение библиотеки
local env = assert (luasql.mysql()) --- почти понял, вернее понял, но описать немогу грамотно =))
local con = assert (env:connect(sNameDB, sUserDB, sPasswordDB, sAdressDB, sPortDB)) -- подключение к базе
function UserConnected(tUser)
    if tProfiles[tUser.iProfile] == 1 then
        Core.SendToUser(tUser, "$UserCommand 1 3 "..sMenu.."$<%[mynick]> !report %[line:Введите ник админа] %[line:Введите текст жалобы]&#*124;")
    end
end
OpConnected = UserConnected
RegConnected = UserConnected
function ChatArrival(tUser, sData)
    local sAdmin, sMsg = sData:match"^!report (%S+)%s(.*)" -- уфф.. с этим разобрался, помог Setuper, его статья про регулярные выражения и захваты - 7 раз прочитал (там многое умалчивается, оказывается) , и еще спасибо Alexey за подсказки о том, о чем умалчивалось. =))
    
    if not tAdmNick[sAdmin] or tAdmNick[sAdmin] ~= 1 then -- спасибо, Setuper!!!
        Core.SendToUser(tUser, sErrAdmNick) -- эт я сам сообразил, благо примеров много.
    end
-- следующая строка вообще напрягает, INSERT INTO `%sreport` - правильно ли обозначил?
    local con:execute(("INSERT INTO `%sreport` (`Admin`, `Date`, `Time`,`Nick`,`Msg`) VALUES ('%s','%s','%s','%s','%s')"):dbformat(sPrefixTable, sAdmin, sBeDate, sBeTime, tUser.sNick, sMsg))

end

Шапка с переменными и таблицами выше - я не трогал.
А так пока вроде должно даже работать, .... вроде..., пока непробовал. (застрял при создании таблицы с полем id - разберусь) С мускулом мы хоть и не на "ты", но иногда здороваемся big_smile.gif
добавлено позже: Ну вот и поздоровались, кавычку пропустил в запросе )))
Как обычно все отметил в коментариях. big_smile.gif
Благодарности тоже.
Однако, даже если код рабочий, буду работать над антифлудом. Пока не определился как, что, почему и каким образом, но мысли есть (например добавить в таблицу поле IP, а в скрипт - таймер).
И еще, нет ли возможности вместо вручную забиваемой таблицы tAdmNick использовать *.xml файл птоки?

Так и знал, что именно здесь будет косяк :(
Код
    local con:execute(("INSERT INTO `%sreport` (`Admin`, `Date`, `Time`,`Nick`,`Msg`) VALUES ('%s','%s','%s','%s','%s')"):dbformat(sPrefixTable, sAdmin, sBeDate, sBeTime, tUser.sNick, sMsg))

Синтакс new.lua:46: unexpected symbol near ':'
я уж и так эти двоеточия и эдак.. хоть удаляю - все равно такую ерру пишет...

Автор: Wariner 7.7.2009, 11:14

да вроде всё правильно написано....

Автор: fixx 7.7.2009, 17:49

Все равно не работает.
Вроде бы и метод dbformat определен...
 new.lua ( 1.99 килобайт ) : 9

Автор: Wariner 7.7.2009, 18:07

тут вижу несколько проблем.
1) всё таки лучше если ты сначала будешь находить команду а уже по команде делать какие либо действия(возьми из того же чатлога)
2) лучше если таблица будет создаваться в скрипте

Автор: fixx 7.7.2009, 21:19

1) - непонял. Вроде все так как в чатлоге. Можно подробнее чуть-чуть. big_smile.gif
2) - это сделал, только она несоздается, потому что ошибка все таже вылезает.
--------------------------------------------------------------------------------------------
Закомментировал глючную строчку и скрипт запустился, создал таблицу и даже выводит сообщение ErrAdmNick

Автор: Wariner 7.7.2009, 21:43

насчёт команд:

Код
function ChatArrival(tUser, sData)
    local sData = sData:sub(1,-2)
    local sCmd = sData:match"%b<>%s+([!+-/*]%S+)"
    if sCmd == "!mainlogs" then

выложи то что ты уже сделал посмотрю

Автор: fixx 7.7.2009, 22:05

Вот.
 new.lua ( 2.34 килобайт ) : 7

Если закомментировать 57 строку, то запускается и создает базу. И все, кроме записи в базу, работает.

Цитата(Wariner @ 7.7.2009, 22:43) *
насчёт команд:
Код
function ChatArrival(tUser, sData)
    local sData = sData:sub(1,-2)
    local sCmd = sData:match"%b<>%s+([!+-/*]%S+)"
    if sCmd == "!mainlogs" then

выложи то что ты уже сделал посмотрю


Этот код чет никак не могу сунуть в ChatArrival
Чисто даже на логическом уровне неполучается. Если сунуть "как есть"... то получается, что если команда та, что надо, то выполняем
Код
    local sAdmin, sMsg = sData:match"^!report (%S+)%s(.*)"

а если нет? то ретурн что?

Автор: Wariner 7.7.2009, 22:32

ты путаешь менюшки и команды. ща гляну код

весь твой косяк был в том что ты написал local перед con))))
так же поправил некоторые косяки
1) нельзя дату и время выносить как сделал это ты. ибо они примут временное значение включения скрипта! исправил, а так же исправил формат даты! в постах выше писал про удобную для человека дату, а в MySQL свои типы почитать тут http://mydc.ru/r/?http://www.mysql.ru/docs/man/Date_and_time_types.html
2) забыл убрать звёздочку при создании менюшек
3) добавил нахождение команды
4) чутка преукрасил

 new.lua ( 2.83 килобайт ) : 19
 

Автор: fixx 7.7.2009, 23:15

Во, Спасибо!
Работает =)

Автор: fixx 8.7.2009, 15:19

Код
function ChatArrival(tUser, sData)
    local sData = sData:sub(1,-2)
    local sCmd = sData:match"%b<>%s+([!+-/*]%S+)"
    if sCmd == "!report" then
        local sAdmin, sMsg = sData:match"%b<>%s+[!+-/*]%S+%s+(%S+)%s+(.*)"
        if not tAdmNick[sAdmin] then
            Core.SendToUser(tUser, ("<%s> %s"):format(sBot, sErrAdmNick))
            
        elseif (not sMsg) or (not sMsg:match"%S") then
            Core.SendToUser(tUser, ("<%s> *** Вы не ввели текст жалобы!"):format(sBot))
        else    
            con:execute(("INSERT INTO `%sReport` (`Admin`, `Date`, `Time`,`Nick`,`Msg`) VALUES ('%s','%s','%s','%s','%s')"):dbformat(sPrefixTable, sAdmin, os.date("%Y-%m-%d"),os.date("%H:%M:%S"), tUser.sNick, sMsg))  --вносим жалобу в базу
            Core.SendToUser(tUser, ("<%s> *** Жалоба отправлена удачно!"):format(sBot))
        end
        return true
    end    
end

Подскажите, как в эту функцию еще условий добавить?
ну допустим
Код
if tAdmNick[sAdmin] == 0 then
Core.SendToUser(tUser, ("<%s> %s"):format(sBot, sMaster))

Вобщем весь код такой:
Если в таблице tAdmNick нет такой записи, то отправляем sErrAdmNick
а если в таблице есть запись, но она равна 0, то отправляем sMaster
Или ткните носом, где про это написано. Смотрел другие скрипты, там прям так и написано, но у меня так неработает.
И еще. Что делает этот последний кусок :
Код
string.dbformat = function(self, ...)
    local t = {...}
    for k, v in ipairs(t) do
        t[k] = tostring(v):gsub("'", "\\'")
    end
    return self:format(unpack(t))
end

Именно он ругается, если я что-то добавляю.

Автор: Setuper 8.7.2009, 15:23

метод dbformat экранирует одиночную кавычку для внесения данных в бд.

Автор: fixx 9.7.2009, 12:38

Со всем предыдущим разобрался, почитав всякие факи.
Сделал таблицу запретных слов в виде:

Код
tMat = {  
    ["бла"] = 1,
    ["стер"] = 1
{

Однако слово "бла" отлавливается нормально, а "Бла" или "бластер" нет.
И еще. tMat получается объемной, подумываю поместить в мускул, но пока об этом рано думать.
================================================
Скрипт получился гибкий, можно использовать как Гостевую книгу, или даже как ПМ Офлайн...