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

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

MyDC.ru _ Разработчикам [PtokaX] _ Метод Быстрого Перевода Скриптов Под API_1

Автор: Setuper 16.10.2008, 16:40

Метод быстрого перевода скриптов под API_1 (PtokaX 0.3.6.0 и ниже).

Ограничения на язык: Lua 5.1



Скрипт, подключая который на API_1, будут работать скрипты, написанные под API_2 !!!

Для этого следует всего-то проделать следующие 3 шага:

1). Помещаем в папку scripts файл из архива:  old_api.rar ( 5.72 килобайт ) : 194


2). Открываем скрипт, написанный под API_2, и дописываем в начало скрипта код:

Код
if frmHub then dofile(frmHub:GetPtokaXLocation().."scripts/old_api.lu")
elseif not Core then error("Запуск скрипта возможен только при запущенном хабе!",1)
else dofile(Core.GetPtokaXPath().."scripts/old_api.lu") end
(код изменён для использования под обе версии API)

3). В именах основных функций PtokaX (OnStartup, OnExit, UserConnected, RegConnected, OpConnected и тд.) дописываем Core. спереди.

Примеры реализации пункта 3:

Было:
Код
function OnStartup() ... end
дописав Core., получается:
Код
function Core.OnStartup() ... end



Или так: было:
Код
OnStartup=function() ... end
дописав Core., получается:
Код
Core.OnStartup=function() ... end



Или даже так: было:
Код
ToArrival=ChatArrival
дописав Core., получается:
Код
Core.ToArrival=Core.ChatArrival



Или даже так: было:
Код
OpConnected,RegConnected=UserConnected,UserConnected
дописав Core., получается:
Код
Core.OpConnected,Core.RegConnected=Core.UserConnected,Core.UserConnected




Полный список всех функций в алфавитном порядке, впереди которых надо дописывать Core. :



В общем, находим в скрипте все вышеприведённые слова (если они есть в скрипте) и перед всеми найденными словами дописываем Core.


Всё! Почти любой скрипт, написанный под API_2 будет у вас работать на API_1 (исключения составляют вещи, которые есть только в API_2 - после перевода по данной методике эти вещи будут просто игнорироваться скриптом (или возвращать nil) - это связанно с расширенной функциональностью API_2, по сравнению с API_1)!!!

Обращаю внимание, что переведя по данной методике, скрипт будет работать вне зависимости от версии API, ОДНАКО таким макаром можно переводить только скрипты, написанные под API2 !!!

Таким образом можно за пару минут самому перевести скрипт на API_1, даже больших размеров (что в некоторых случаях заняло бы для перевода несколько дней). А когда вы всё же будете готовы перейти на новые версии PtokaX, обратные изменения также не займут много времени!

Автор: Wariner 16.10.2008, 18:14

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

PS: тема очень порадовала!!!

Автор: Setuper 28.10.2008, 13:02

Список функций, которые работают только на API2. При переводе по данной методике эти функции на API1 не будут ничего делать (будут возвращать nil)

Код
  Core.Shutdown() --Отключить хаб.
  Core.ResumeAccepts() --Продолжать прослушивать поток(и), если их прослышивание не было преостановлено.
  Core.GetBots() --Возбращает таблицу со всеми ботами, зарегистрированными скриптами, как таблицу с полями sNick, sMyINFO, bIsOP and sScriptName.
  Core.GetUserAllData(tUser) --Добавляет или обновляет все данные в таблице пользователя. Возвращает nil в случае неудачи (пользователь оффлайн) или true в случае успеха.
  Core.GetUserData(tUser, nValueId) --Добавляет или обновляет данные с указанным идентификатором в таблице пользователя. Возвращает nil в случае неудачи (пользователь оффлайн) или true в случае успеха.
  Core.DefloodWarn(tUser) --Предупреждение пользователю по причине флуда. Возвращает nil в случае неудачи, true - в случае успеха.
  SetMan.Save() --Принудительно сохраняет настройки.
  RegMan.Save() --Принудительно сохраняет зарегистрированных пользователей.
  BanMan.Save() --Принудительно cохраняет баны.
  BanMan.GetRangeBan(sIPFrom, sIPTo) --Возвращает таблицу забаненных рангов для данного ранга или nil в случае отсутствия таковой.
  BanMan.GetRangePermBan(sIPFrom, sIPTo) --Возвращает таблицу постоянно забаненных рангов для данного ранга или nil в случае отсутствия таковой.
  BanMan.GetRangeTempBan(sIPFrom, sIPTo) --Возвращает таблицу временно забаненных рангов для данного ранга или nil в случае отсутствия таковой.
  ProfMan.MoveDown(nProfileNumber) --Сдвиг профиля вниз. Возвращает nil в случае неудачи, true - в случае успеха.
  ProfMan.MoveUp(nProfileNumber) --Сдвиг профиля вверх. Возвращает nil в случае неудачи, true - в случае успеха.
  ProfMan.SetProfileName(nProfileNumber, sProfileName) --Изменяет имя профиля, возвращает true в случае удачи или nil, если указанного профиля не существует.
  ProfMan.SetProfilePermission(nProfileNumber, nPermissionId, bBoolean) --Изменяет профильную настройку с указанным идентификатором.
  UDPDbg.Reg(sIp, nPort, bAllData) --Регистрирует получателя данных от PtokaX через UDP, если параметр bAllData равен false, то получать данные только от этого скрипта. Возвращает nil в случае неудачи или true в случае успеха.
  UDPDbg.Unreg() --Удалить получателя данных.
  UDPDbg.Send(sData) --Отправить данные через UDP. Если скрипт зарегистрирован, то только от зарегистрированного скрипта, иначе от всех скриптов. Возвращает nil в случае неудачи или true в случае успеха.
  ScriptMan.GetScript() --Возвращает таблицу этого скрипта с полями sName, bEnabled, iMemUsage.
  ScriptMan.GetScripts() --Возвращает таблицу всех скриптов с полями sName, bEnabled, iMemUsage.
  ScriptMan.MoveUp(sScriptName) --Сдвинуть указанный скрипт выше. Возвращает nil в случае неудачи или true в случае успеха.
  ScriptMan.MoveDown(sScriptName) --Сдвинуть указанный скрипт ниже. Возвращает nil в случае неудачи или true в случае успеха.
  ScriptMan.StartScript(sScriptName) --Запустить скрипт с указанным именем. Возвращает nil в случае неудачи или true в случае успеха.
  ScriptMan.RestartScript(sScriptName) --Перезапустить указанный скрипт. Возвращает nil в случае неудачи или true в случае успеха.
  ScriptMan.StopScript(sScriptName) --Остановить указанный скрипт. Возвращает nil в случае неудачи или true в случае успеха.
  ScriptMan.Refresh() --Обновить скрипт-лист.
  IP2Country.GetCountryCode(sIP) --Возвращает код страны для указанного ip или nil, если ip не действителен.
  IP2Country.GetCountryName(sIP) --Возвращает имя страны для указанного ip или nil, если ip не действителен.
  IP2Country.GetCountryName(tUser) --Возвращает имя страны для указанного пользователя.


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

Автор: sphinx 29.10.2008, 18:44

Цитата(Setuper @ 16.10.2008, 16:40) *
Очень актуальная тема exciting.gif

Метод быстрого перевода скриптов под API_1.

А нету ли метода быстрого перевода наоборот, скриптов API_1 для работы на API_2 ? exciting.gif

Автор: Setuper 29.10.2008, 20:34

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

Автор: Mol 2.11.2008, 12:42

Цитата(Setuper @ 29.10.2008, 20:34) *
Нету и не вижу смысла такой писать, потому как сейчас все скрипты будут писаться под API2 и данное руководство для тех кто всё ещё использует старый API. Скрипты под API2 надо полностью переписывать, а не использовать быстрые переводы.


О4ень жаль. А не знаете где можно по4итать об этом ? (конвертирование/переводе скриптов API I под API II)

Автор: Setuper 2.11.2008, 19:47

Во-первых, есть конвертер. Во-вторых, чтобы самому переводить скрипты нужно знать различия в api (смотри файлы Scripting-Interface.txt в новой и старой версиях PtokaX)

Автор: Mol 2.11.2008, 21:04

Спасибо, понятно. Вообще стоит ли переходить на PtokaX 0.4.1.1 ?

Автор: Setuper 2.11.2008, 21:09

Да, без условно стоит. Во-первых, быстрее работает, больше оптимизации, во-вторых, расширены возможности, в-третьих, сейчас все скриптописатели будут писать скрипты под API2.

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

Перезалил файл old_api.rar

Исправлена невозможность использовать функцию Core.GetPtokaXPath() при инициализации скрипта.

Автор: Setuper 29.11.2008, 1:33

v 1.3.0.0 (файл перезалит в первой теме)

Fixed:

* ScriptMan.Restart()
* Core.Restart()
* TmrMan.AddTimer(nTimerInterval, sFunctionName)

Пофиксил функции рестартов (были перепутаны местами в старой версии)
В функции AddTimer параметр nTimerInterval задаём как обычно в милисекундах, однако, в целях оптимизации округление идет в меньшую сторону секунд, поэтому следует брать значения кратные секундам, иначе они в любом случае будут округляться до них.

Пример использования AddTimer:

Код
dofile(frmHub:GetPtokaXLocation().."scripts/old_api.lu")

function Core.OnStartup()
  TmrMan.AddTimer(1999,"Func1") -- округляется в меньшую сторону до 1000 (=1 сек)
  TmrMan.AddTimer(2000,"Func2") -- нечего округлять.  2000 (=2 сек)
end

function Func1()
  Core.SendToAll"Func1 -> 1999 мсек = 1 сек"
end

function Func2()
  Core.SendToAll"Func2 -> 2000 мсек = 2 сек"
end

Автор: Setuper 18.12.2008, 21:44

v 1.4.0.0 (файл перезалит в первой теме)

Fixed:

* Исправлена ошибка функции Core.GetUser (Огромное спасибо prapor-у за указание на найденную ошибку.)

Added:

* Добавлена реализация функции Core.GetUserValue

Автор: morn 30.12.2008, 6:05

Цитата
Метод быстрого перевода скриптов под API_1 (PtokaX 0.3.6.0 и ниже).


Респкт,Спасиба Бааальшое Сетаперу. Форум радует

Автор: Setuper 12.2.2009, 18:35

v 1.5.0.0 (файл перезалит в первом топике)

Fixed:

* TmrMan.AddTimer(nTimerInterval)

Пофиксил функцию AddTimer с одним параметром. Раньше не работала функция Core.OnTimer().

Пример использования AddTimer:

Код
dofile(frmHub:GetPtokaXLocation().."scripts/old_api.lu")

function Core.OnStartup()
  TmrMan.AddTimer(2000)
end

function Core.OnTimer()
  Core.SendToAll"Hi All"
end

Автор: Setuper 24.2.2009, 16:35

v 1.6.0.0 (файл перезалит в первом топике)

Added:

* Добавлена возможность использовать переведённый скрипт и на API2, то есть возможность, написав свой скрипт под API2 перевести его по данной методике и скрипт станет универсальным (под обе версии API).

Единственное для универсальности в начале переводимого скрипта нужно писать код:

Код
if frmHub then dofile(frmHub:GetPtokaXLocation().."scripts/old_api.lu")
elseif not Core then error("Запуск скрипта возможен только при запущенном хабе!",1)
else dofile(Core.GetPtokaXPath().."scripts/old_api.lu") end

Автор: BeSeR 6.3.2009, 0:02

Большое спасибо Setuper'у все работает victory.gif

Автор: Setuper 6.3.2009, 0:17

Самое главное, что не просто работает, а то что скрипт за считанные секунды приобретает свойства "кроссапишности", то есть идёт на любом апи))

Автор: BeSeR 6.3.2009, 0:22

Вот я перевел скрипт из API 2 под API 1,а он будет идти в API 2?Или нет? big_smile1.gif

Автор: Setuper 6.3.2009, 0:25

Да, будет. Если не будет, то отпиши сюда, будем разбираться почему не идёт))))

Автор: BeSeR 6.3.2009, 18:51

Вот почему то скачал скрипт,перевел с API 2 на API 1 включаю а он мне присылает сообщение в ЛС :

Цитата
[20:46:43] <[Chat]Operator's> <•Экзекутор•> *** 03/06/09 20:46:42 В скрипте произошла ошибка: ...C++\хаб и архив,нетрогать!\хаб\scripts\Ekzekutor.lua:250: module 'socket' not found:
no field package.preload['socket']
no file 'C_Documents and Settings\Ильдар\Рабочий стол\DC++\хаб и архив,не трогать!\хаб\socket.lua'
no file 'C_Documents and Settings\Ильдар\Рабочий стол\DC++\хаб и архив,не трогать!\хаб\libs\socket.lua'
no file 'C_Documents and Settings\Ильдар\Рабочий стол\DC++\хаб и архив,не трогать!\хаб\scripts\libs\socket.lua'
no file 'C_Documents and Settings\Ильдар\Рабочий стол\DC++\хаб и архив,не трогать!\хаб\socket.dll'
no file 'C_Documents and Settings\Ильдар\Рабочий стол\DC++\хаб и архив,не трогать!\хаб\libs\socket.dll'
no file 'C_Documents and Settings\Ильдар\Рабочий стол\DC++\хаб и архив,нетрогать!\хаб\scripts\libs\socket.dll'

Почему?Не подскажите? unhappy.gif

А вот и ссылка где скачал: http://mydc.ru/topic1403.html
И когда этот скрипт включен он мне присылает сообщение:
Цитата
[2009-03-06 21:02] [21:02:49] <[Chat]Operator's> <•Экзекутор•> *** 03/06/09 21:02:49 В скрипте произошла ошибка: ...л/DC++/хаб и архив,нетрогать!/хаб/scripts/old_api.lu:23: attempt to index local 'a' (a nil value)

Автор: Wariner 6.3.2009, 18:52

библиотеки надо качать другие!!!!!

PS: пиши в тему самого скрипта!!!!!!

Автор: BeSeR 6.3.2009, 19:00

Вот еще присылает когда он включен:

Цитата
[21:00:56] <[Chat]Operator's> <•Экзекутор•> *** 03/06/09 21:00:56 В скрипте произошла ошибка: ...л/DC++/хаб и архив,нетрогать!/хаб/scripts/old_api.lu:23: attempt to index local 'a' (a nil value)

Автор: Setuper 6.3.2009, 19:57

Мультиботов нельзя переводить этим скриптом - они слишком сложны и невозможно предусмотреть все мелочи.

Автор: Артём 18.5.2009, 7:30

Цитата(Setuper @ 16.10.2008, 16:40) *
Обращаю внимание, что переведя по данной методике, скрипт будет работать вне зависимости от версии API, ОДНАКО таким макаром можно переводить только скрипты, написанные под API2 !!!

victory.gif очень хорошо!!! exciting.gif

Автор: X-Sky 15.8.2009, 8:20

Супер. Спасибо exciting.gif

Автор: thehawk 6.9.2009, 21:59

Сделал всё как было написано в 1 посте и ...
Скрипт вроде как заработал, но вот этот как понять:

Цитата
[21:57] Синтакс D:/0.3.6.0/scripts/old_api.lu:23: attempt to index local 'a' (a nil value)

Автор: Setuper 6.9.2009, 22:12

Я добавил проверку и перезалил файл old_api.
Попробуй.

Автор: thehawk 9.9.2009, 10:44

Цитата(Setuper @ 6.9.2009, 22:12) *
Я добавил проверку и перезалил файл old_api.
Попробуй.

Всё работает, ошибок не выдаёт. Спасибо.

Автор: m3gap1x3L 22.11.2009, 5:51

Помогите ктонибуть ! По данной методке я решил перевести скрипт на АПИ1 написанный на АПИ2 !
Исправьте ошибки ! И покажите их сдесь , чтоб я увидел !(В скриптах разбираюсь плохо)

Раскрывающийся текст
Код
if frmHub then dofile(frmHub:GetPtokaXLocation().."scripts/old_api.lu")
elseif not Core then error("Запуск скрипта возможен только при запущенном хабе!",1)
else dofile(Core.GetPtokaXPath().."scripts/old_api.lu") end
(код изменён для использования под обе версии API)

-- Основные настройки
sBotName = "[Инфо]м&ж"            -- Имя бота
bBotReg = true                -- Регистрировать бота на хабе?
bBotOP = true                -- Бот с ключиком?
sBotDesc = "Бот, показывающий ваш пол"    -- Описание бота
sBotEmail = "steelseries-magadan@mail.ru"        -- Email бота

sMenuName = "Ваш пол"    --Имя меню
bSendIfNotSet = true    --Отправлять юзеру сообщение при входе, если пол не выбран

iSendTimer = 500    -- Время отправки MyINFO, ms

-- Как будет выглядить пол в описании?
tSex = {
    o = "[?]",                -- Пол не указан
    m = "[М]",                -- Мужской пол
    w = "[Ж]",                -- Женский пол
}

-- Доступ к командам
pUser = {
    [0] = 1,    -- =[Master]=
    [1] = 1,    -- =[OP]=
    [2] = 1,    -- =[ViP]=
    [3] = 1,    -- =[Reg]=
      [-1] = 1,   -- =[UnReg]=
}

-- Команды
cMySex = "mysex"
cSexList = "sexlist"
cSexListOnline = "sexlistonline"

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

tTimers = {}
tUsers = {}
function Core. OnStartup()
    if sBotName == "" then
        sBotName = SetMan.GetString(21)
    elseif bBotReg then
        Core.RegBot(sBotName,sBotDesc,sBotEmail,bBotOP)
    end
    fUsers = Core.GetPtokaXPath().."scripts/MySex.tbl"
    if loadfile(fUsers) then dofile(fUsers) end
end

function Core. UserConnected(user)
    if not tUsers[user.sNick] and bSendIfNotSet then
        Core.SendToUser(user,"<"..sBotName.."> Пожалуйста, укажите ваш пол!")
    end
    for i,v in pairs(Core.GetOnlineUsers(true)) do
        local s,e,other = string.find(v.sMyInfoString, "%$MyINFO%s$ALL%s%S+%s(.*)$")
        Core.SendToUser(user,"$MyINFO $ALL "..v.sNick.." "..(tSex[tUsers[v.sNick]] or tSex.o).." "..other)
    end
    if pUser[user.iProfile] == 1 then
        Core.SendToUser(user,"$UserCommand 1 3 "..sMenuName.."\\Указать свой пол\\Мужской$<%[mynick]> !"..cMySex.." m|")
        Core.SendToUser(user,"$UserCommand 1 3 "..sMenuName.."\\Указать свой пол\\Женский$<%[mynick]> !"..cMySex.." w|")
        Core.SendToUser(user,"$UserCommand 1 3 "..sMenuName.."\\Посмотреть пол юзеров$<%[mynick]> !"..cSexList.." %[line:m=мальчики/w=девочки или оставьте строку пустой]|")
        Core.SendToUser(user,"$UserCommand 1 3 "..sMenuName.."\\Посмотреть пол юзеров онлайн$<%[mynick]> !"..cSexListOnline.." %[line:m=мальчики/w=девочки или оставьте строку пустой]|")
    end
end

Core. OpConnected = UserConnected
Core. RegConnected = UserConnected

function SendInfo(tmr)
    local user = Core.GetUser(tTimers[tmr],true)
    if user then
        local s,e,other = string.find(user.sMyInfoString, "%$MyINFO%s$ALL%s%S+%s(.*)$")
        Core.SendToAll("$MyINFO $ALL "..user.sNick.." "..(tSex[tUsers[user.sNick]] or tSex.o).." "..other)
        tTimers[tmr] = nil
    end
    TmrMan.RemoveTimer(tmr)
end

function Core. MyINFOArrival(user,data)
    local tmr = TmrMan.AddTimer(iSendTimer, "SendInfo")
    tTimers[tmr] = user.sNick
end

function Core. ChatArrival(user,sData)
    if pUser[user.iProfile] == 1 then
        local sData = string.sub(sData, 1, -2)
        local s,e,cmd = string.find(sData, "%b<>%s+[%!%+%?%#](%S+)")
        if tCmds[cmd] then
            tCmds[cmd](user, sData);
            return true
        end
    end
end

tCmds = {
    [cMySex] = function(user, sData)
        local s,e,arg1 = string.find(sData, "%b<>%s+%S+%s+(%S+)")
        if arg1 then
            local s,e,other = string.find(Core.GetUserValue(user,1), "%$MyINFO%s$ALL%s%S+%s(.*)$")
            if arg1 == "m" then
                tUsers[user.sNick] = "m"
                Save()
                Core.SendToAll("$MyINFO $ALL "..user.sNick.." "..tSex.m.." "..other)
                Core.SendToUser(user,"<"..sBotName.."> Вы выбрали пол: мужской.")
            elseif arg1 == "w" then
                tUsers[user.sNick] = "w"
                Save()
                Core.SendToAll("$MyINFO $ALL "..user.sNick.." "..tSex.w.." "..other)
                Core.SendToUser(user,"<"..sBotName.."> Вы выбрали пол: женский.")
            else
                Core.SendToUser(user,"<"..sBotName.."> Вы не указали свой пол! Правильно: !mysex <m/w>")
            end
        end
    end,
    [cSexList] = function(user, sData)
        local s,e,arg1 = string.find(sData, "%b<>%s+%S+%s+(%S+)")
        local bm, bw = true, true
        if arg1    then
            if arg1 == "m" then
                bw = false
            elseif arg1 == "w" then
                bm = false
            end
        end
        local msg,msgm,msgw,cm,cw = "","Список мальчиков: ","Список девочек: ","",""
        for i,v in pairs(tUsers) do
            if bm and v == "m" then
                msgm = msgm..cm..i
                cm = ", "
            end
            if bw and v == "w" then
                msgw = msgw..cw..i
                cw = ", "
            end
        end
        if bm then
            msg = msg.."\n\n"..msgm
        end
        if bw then
            msg = msg.."\n\n"..msgw
        end
        Core.SendPmToUser(user,sBotName,msg)
        collectgarbage("collect")
    end,
    [cSexListOnline] = function(user, sData)
        local s,e,arg1 = string.find(sData, "%b<>%s+%S+%s+(%S+)")
        local bm, bw = true, true
        if arg1    then
            if arg1 == "m" then
                bw = false
            elseif arg1 == "w" then
                bm = false
            end
        end
        local msg,msgm,msgw,cm,cw = "","Мальчики онлайн: ","Девочки онлайн: ","",""
        for i,v in pairs(Core.GetOnlineUsers(true)) do
            if bm and tUsers[v.sNick] and tUsers[v.sNick] == "m" then
                msgm = msgm..cm..v.sNick
                cm = ", "
            end
            if bw and tUsers[v.sNick] and tUsers[v.sNick] == "w" then
                msgw = msgw..cw..v.sNick
                cw = ", "
            end
        end
        if bm then
            msg = msg.."\n\n"..msgm
        end
        if bw then
            msg = msg.."\n\n"..msgw
        end
        Core.SendPmToUser(user,sBotName,msg)
        collectgarbage("collect")
    end,
}

function Save()
    local hFile = io.open(fUsers, "w")
    if hFile then
        Serialize(tUsers, "tUsers", hFile);
        hFile:close();
    end
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

Автор: Setuper 22.11.2009, 16:22

Раскрывающийся текст
Код
if frmHub then dofile(frmHub:GetPtokaXLocation().."scripts/old_api.lu")
elseif not Core then error("Запуск скрипта возможен только при запущенном хабе!",1)
else dofile(Core.GetPtokaXPath().."scripts/old_api.lu") end

-- Основные настройки
sBotName = "[Инфо]м&ж"            -- Имя бота
bBotReg = true                -- Регистрировать бота на хабе?
bBotOP = true                -- Бот с ключиком?
sBotDesc = "Бот, показывающий ваш пол"    -- Описание бота
sBotEmail = "steelseries-magadan@mail.ru"        -- Email бота

sMenuName = "Ваш пол"    --Имя меню
bSendIfNotSet = true    --Отправлять юзеру сообщение при входе, если пол не выбран

iSendTimer = 500    -- Время отправки MyINFO, ms

-- Как будет выглядить пол в описании?
tSex = {
    o = "[?]",                -- Пол не указан
    m = "[М]",                -- Мужской пол
    w = "[Ж]",                -- Женский пол
}

-- Доступ к командам
pUser = {
    [0] = 1,    -- =[Master]=
    [1] = 1,    -- =[OP]=
    [2] = 1,    -- =[ViP]=
    [3] = 1,    -- =[Reg]=
      [-1] = 1,   -- =[UnReg]=
}

-- Команды
cMySex = "mysex"
cSexList = "sexlist"
cSexListOnline = "sexlistonline"

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

tTimers = {}
tUsers = {}
function Core.OnStartup()
    if sBotName == "" then
        sBotName = SetMan.GetString(21)
    elseif bBotReg then
        Core.RegBot(sBotName,sBotDesc,sBotEmail,bBotOP)
    end
    fUsers = Core.GetPtokaXPath().."scripts/MySex.tbl"
    if loadfile(fUsers) then dofile(fUsers) end
end

function Core.UserConnected(user)
    if not tUsers[user.sNick] and bSendIfNotSet then
        Core.SendToUser(user,"<"..sBotName.."> Пожалуйста, укажите ваш пол!")
    end
    for i,v in pairs(Core.GetOnlineUsers(true)) do
        local s,e,other = string.find(v.sMyInfoString, "%$MyINFO%s$ALL%s%S+%s(.*)$")
        Core.SendToUser(user,"$MyINFO $ALL "..v.sNick.." "..(tSex[tUsers[v.sNick]] or tSex.o).." "..other)
    end
    if pUser[user.iProfile] == 1 then
        Core.SendToUser(user,"$UserCommand 1 3 "..sMenuName.."\\Указать свой пол\\Мужской$<%[mynick]> !"..cMySex.." m|")
        Core.SendToUser(user,"$UserCommand 1 3 "..sMenuName.."\\Указать свой пол\\Женский$<%[mynick]> !"..cMySex.." w|")
        Core.SendToUser(user,"$UserCommand 1 3 "..sMenuName.."\\Посмотреть пол юзеров$<%[mynick]> !"..cSexList.." %[line:m=мальчики/w=девочки или оставьте строку пустой]|")
        Core.SendToUser(user,"$UserCommand 1 3 "..sMenuName.."\\Посмотреть пол юзеров онлайн$<%[mynick]> !"..cSexListOnline.." %[line:m=мальчики/w=девочки или оставьте строку пустой]|")
    end
end

Core.OpConnected = Core.UserConnected
Core.RegConnected = Core.UserConnected

function SendInfo(tmr)
    local user = Core.GetUser(tTimers[tmr],true)
    if user then
        local s,e,other = string.find(user.sMyInfoString, "%$MyINFO%s$ALL%s%S+%s(.*)$")
        Core.SendToAll("$MyINFO $ALL "..user.sNick.." "..(tSex[tUsers[user.sNick]] or tSex.o).." "..other)
        tTimers[tmr] = nil
    end
    TmrMan.RemoveTimer(tmr)
end

function Core.MyINFOArrival(user,data)
    local tmr = TmrMan.AddTimer(iSendTimer, "SendInfo")
    tTimers[tmr] = user.sNick
end

function Core.ChatArrival(user,sData)
    if pUser[user.iProfile] == 1 then
        local sData = string.sub(sData, 1, -2)
        local s,e,cmd = string.find(sData, "%b<>%s+[%!%+%?%#](%S+)")
        if tCmds[cmd] then
            tCmds[cmd](user, sData);
            return true
        end
    end
end

tCmds = {
    [cMySex] = function(user, sData)
        local s,e,arg1 = string.find(sData, "%b<>%s+%S+%s+(%S+)")
        if arg1 then
            local s,e,other = string.find(Core.GetUserValue(user,1), "%$MyINFO%s$ALL%s%S+%s(.*)$")
            if arg1 == "m" then
                tUsers[user.sNick] = "m"
                Save()
                Core.SendToAll("$MyINFO $ALL "..user.sNick.." "..tSex.m.." "..other)
                Core.SendToUser(user,"<"..sBotName.."> Вы выбрали пол: мужской.")
            elseif arg1 == "w" then
                tUsers[user.sNick] = "w"
                Save()
                Core.SendToAll("$MyINFO $ALL "..user.sNick.." "..tSex.w.." "..other)
                Core.SendToUser(user,"<"..sBotName.."> Вы выбрали пол: женский.")
            else
                Core.SendToUser(user,"<"..sBotName.."> Вы не указали свой пол! Правильно: !mysex <m/w>")
            end
        end
    end,
    [cSexList] = function(user, sData)
        local s,e,arg1 = string.find(sData, "%b<>%s+%S+%s+(%S+)")
        local bm, bw = true, true
        if arg1    then
            if arg1 == "m" then
                bw = false
            elseif arg1 == "w" then
                bm = false
            end
        end
        local msg,msgm,msgw,cm,cw = "","Список мальчиков: ","Список девочек: ","",""
        for i,v in pairs(tUsers) do
            if bm and v == "m" then
                msgm = msgm..cm..i
                cm = ", "
            end
            if bw and v == "w" then
                msgw = msgw..cw..i
                cw = ", "
            end
        end
        if bm then
            msg = msg.."\n\n"..msgm
        end
        if bw then
            msg = msg.."\n\n"..msgw
        end
        Core.SendPmToUser(user,sBotName,msg)
        collectgarbage("collect")
    end,
    [cSexListOnline] = function(user, sData)
        local s,e,arg1 = string.find(sData, "%b<>%s+%S+%s+(%S+)")
        local bm, bw = true, true
        if arg1    then
            if arg1 == "m" then
                bw = false
            elseif arg1 == "w" then
                bm = false
            end
        end
        local msg,msgm,msgw,cm,cw = "","Мальчики онлайн: ","Девочки онлайн: ","",""
        for i,v in pairs(Core.GetOnlineUsers(true)) do
            if bm and tUsers[v.sNick] and tUsers[v.sNick] == "m" then
                msgm = msgm..cm..v.sNick
                cm = ", "
            end
            if bw and tUsers[v.sNick] and tUsers[v.sNick] == "w" then
                msgw = msgw..cw..v.sNick
                cw = ", "
            end
        end
        if bm then
            msg = msg.."\n\n"..msgm
        end
        if bw then
            msg = msg.."\n\n"..msgw
        end
        Core.SendPmToUser(user,sBotName,msg)
        collectgarbage("collect")
    end,
}

function Save()
    local hFile = io.open(fUsers, "w")
    if hFile then
        Serialize(tUsers, "tUsers", hFile);
        hFile:close();
    end
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

Автор: Олешка 14.8.2011, 21:16

Очень хорошая тема! Большое спс!