Версия для печати темы
MyDC.ru _ Библиотеки и модули для RusHub'а _ Модули для скриптов RusHub
Автор: Setuper 9.1.2010, 20:27
Модули кладутся в папку libs.
Давайте сделаем некое правила написания модулей: файлы модулей будем писать строчными буквами, а модули объявлять тем же словом, но начинающемся с заглавной буквы. Так будет проще отличать название файла с модулем, от названия самого модуля (для того чтобы вникнуть в их суть).
Пример использования функций модуля:
Код
require"files" -- подключение модуля
Files.SaveTable("myfile.txt", tTable, "tTable") -- Вызов функции модуля
Модуль для работы с файлами:
files.lua ( 1.34 килобайт )
: 646Модуль различных утилит:
utils.lua ( 1.77 килобайт )
: 280Давайте в этой теме обсуждать те функции, которые часто используются скриптами, и запихивать их в модули
Автор: STRELOK 9.1.2010, 20:31
Цитата(Setuper @ 9.1.2010, 22:27)
local function Serialize(tTable, sTableName, hFile, sTab)
sTab = sTab or ''
hFile:write(sTab..sTableName.." = {\n")
for k, v in base.pairs(tTable) do
if base.type(v) ~= "function" then
local sKey = base.type(k) == "string" and ("[%q]"):format(k) or ("[%d]"):format(k)
if base.type(v) == "table" then
Serialize(v, sKey, hFile, sTab..'\t')
else
local sValue = base.type(v) == "string" and ("%q"):format(v) or base.tostring(v)
hFile:write(sTab..'\t'..sKey.." = "..sValue)
end
hFile:write(",\n")
end
end
hFile:write(sTab.."}")
end
Автор: Setuper 9.1.2010, 20:34
Локальные функции не выходят за модуль, то есть они могут быть вызваны только внутри модуля, и не могут быть вызваны из скрипта
Для того чтобы было более понятно как использовать модули в скриптах, приведу простой пример на примере функции SaveTable:
Код
require"files" -- подключение модуля
Files.SaveTable(sFile, tTable, sTableName) -- Вызов функции модуля
Обратите внимание, что файл модуля у нас называется files.lua, а сам модуль имеет название Files (module"Files"). поэтому подключается модуль так: require"files", а вызываются функции модуля по таблице Files. (Files.SaveTable(sFile, tTable, sTableName)).
Автор: STRELOK 9.1.2010, 20:35
Цитата(Setuper @ 9.1.2010, 22:32)
Локальные функции не выходят за модуль, то есть они могут быть вызваны только внутри модуля, и не могут быть вызваны из скрипта
В прикреплённом модуле ошибка
Код
local function Serialize(tTable, sTableName, hFile, sTab)
а должно быть
Код
function Serialize(tTable, sTableName, hFile, sTab)
Автор: Setuper 9.1.2010, 20:44
Нет никакой ошибки. Я просто таким образом закрыл доступ к этой функции из вне модуля.
Это своего рода инкапсуляция.
Разве тебе пишет ошибку?
Смело используй функцию Files.SaveTable(sFile, tTable, sTableName)
Я конечно понимаю, что для тебя это немного по-новому, однако поверь, что тут всё грамотно написано.
Автор: STRELOK 9.1.2010, 20:46
Тогда извиняюсь...(
Автор: Setuper 9.1.2010, 20:49
Не нужно извиняться, лучше больше спрашивай что непонятно.
Автор: STRELOK 9.1.2010, 20:56
Тогда вот первый вопрос:
Цитата
.../Hub/scripts/texts.lua:20: attempt to call global 'LoadText' (a nil value)
Автор: Setuper 9.1.2010, 21:04
Files.LoadText
Теперь функции принадлежат определённым модулям и не являются глобальными, что ускоряет их вызов.
Автор: STRELOK 9.1.2010, 21:17
Цитата
.../Hub/scripts/texts.lua:21: bad argument #2 to 'SendToUser' (string expected, got nil)
Код
Core.SendToUser(UID, Files.LoadText(sPath..sCmd..".txt"), sBot, sBot)
Что же теперь не так? :(
Автор: Setuper 9.1.2010, 21:22
Файл не найден, поэтому функция Files.LoadText не смогла его открыть и вернула nil.
Вот правильный код:
Код
local sBot = "Security"
local sPath = Core.sMainDir.."texts/"
require "files" -- для Files.LoadText
function OnChat(UID, sData)
local sCmd = sData:match"%b<>%s+[!+*](%S+)"
if sCmd then
local sText = Files.LoadText(sPath..sCmd..".txt")
if sText then
Core.SendToUser(UID, sText, sBot, sBot)
return true
end
end
end
Автор: STRELOK 9.1.2010, 21:24
Сейчас попробую
UPD: Работает! Спасибо.
Автор: Setuper 13.1.2010, 15:54
В функции LoadText модуля files.lua добавлена замена
Код
sMsg = sMsg:gsub("|", "|")
для того, чтобы в сообщениях отображался символ вертикальной черты, и для того чтобы этот символ не служил разделителем команд.
Автор: STRELOK_IS74 3.3.2010, 20:10
Прикрепляю модуль киков. При использовании команды $kick юзера не отключало от хаба.
kick.lua ( 119 байт )
: 42
Установка:
1. Модуль кладём в папку libs
2. В любом скрипте(я добавил в BanManager.lua) добавляем в самом начале require "kick"
Автор: Setuper 3.3.2010, 20:20
Нет защиты от дурака.
То есть данную команду сможет применить любой пользователь против любого (даже самого админа), используя соответствующую RAW команду в своём клиенте.
Рекомендую все же в функции сделать проверку профиля.
Автор: STRELOK_IS74 3.3.2010, 20:38
Добавил.
Автор: Setuper 3.3.2010, 21:11
Не доступна только менюшка. Сама команда $Kick доступна.
Для защиты от дурака нужно проверить условие:
Код
if Core.GetUser(UID, 64) then -- проверка что киком воспользовался пользователь с ключиком
Core.Disconnect(sNick)
end
Кстати, по протоколу ( http://mydc.ru/index.html?showtopic=915&view=findpost&p=6718 ) команда $Kick не содержит причины кика, а содержит только ник, поэтому бестолку извлекать из этой команды причину. В итоге получаем:
Код
function OnKick(UID, sData)
if Core.GetUser(UID, 64) then
Core.Disconnect(sData:match"$Kick (%S+)")
end
end
Автор: STRELOK_IS74 11.3.2010, 17:05
Цитата(Setuper @ 9.1.2010, 22:27)
Модуль различных утилит
Предлагаю добавить функцию преобразования шары.
Код
function DoShareUnits(iSize)
local tShareUnits = {"Б", "КБ", "МБ", "ГБ", "ТБ", "ПБ"}
local iTableSize = table.maxn(tShareUnits)
local iSize = tonumber(iSize)
local sUnits = ""
for iTablePos = 1, iTableSize do
if iSize < 1024 or iTablePos == iTableSize then
sUnits = tShareUnits[iTablePos]
break
else
iSize = iSize / 1024
end
end
local sSize = string.format("%0.2f %s", iSize, sUnits)
local sSize = string.gsub(sSize, "%.", ",")
local _,_, s1stChar, s2ndChar = string.find(sSize, "%d+,(%d)(%d)")
local s1stChar, s2ndChar = tonumber(s1stChar), tonumber(s2ndChar)
if s2ndChar == 0 then
sSize = string.gsub(sSize, ","..s1stChar..s2ndChar, ","..s1stChar)
if s1stChar == 0 then
sSize = string.gsub(sSize, ","..s1stChar, "")
end
end
return sSize
end
Автор: Setuper 11.3.2010, 19:58
Добавил, немного оптимизировав
Автор: Nickolya 12.3.2010, 11:19
Пользуясь случаем задам вопрос, как будет лучше, определить вот эту таблицу в функции:
Код
local tUnits = {"Б", "КБ", "МБ", "ГБ", "ТБ", "ПБ"}
или же в глобальном окружении самого модуля дабы потом только ссылаться на нее? И тогда бы уже на будущее сразу бы добавили остальные единицы измерения:
Код
local tUnits = {"Б", "КБ", "МБ", "ГБ", "ТБ", "ПБ", "ЭБ", "ЗБ", "ЙБ"}
Автор: Setuper 12.3.2010, 12:13
Тут дело такое... Если определить таблицу вне функции, то это безусловно будет быстрее, так как при вызове функции каждый раз не будет создаваться таблица, с другой стороны, эта таблица будет постоянно занимать некоторое место в памяти, в отличие от таблицы внутри функции, которая будет удаляться из памяти сразу же после отработки функции.
Можно и так и так, однако, не думаю, что данная функция так уж часто используется, чтобы задумываться о быстродействии, тем более если данный модуль будет использоваться в нескольких скриптах, то занимаемая этой таблицей память будет прямо пропорциональна числу скриптов, использующих этот модуль, даже если скрипт и не использует функцию DoShareUnits !!!
Насчёт расширения этой таблицы, то 1024 ПБ - это очень много. И я думаю, что в ближайшие лет 20 мы ещё не доберёмся до таких размеров
Автор: Sekretchik 27.12.2010, 22:25
Илья, при вызове из модуля utils.lua функции - DoShareUnits получил такое сообщение об ошибке: utils.lua:44: attempt to call global 'tonumber' (a nil value)
Ошибка перестала появляться когда переместил саму функцию DoShareUnits в скрипт из которого запрашивал - Utils.DoShareUnits(tUser.iShare) Соответственно, что после переноса функции, запрос стал - DoShareUnits(tUser.iShare). В таком варианте работает.
Код
function DoShareUnits(iSize)
local tUnits = {"Б", "КБ", "МБ", "ГБ", "ТБ", "ПБ"}
iSize = tonumber(iSize)
for i = 1, 6 do
if iSize < 1024 or i == 6 then
iSize = ("%0.2f"):format(iSize):gsub("%.", ",")
local a, b = iSize:match"(%d)(%d)$"
if b == '0' then
if a == '0' then
iSize = iSize:sub(1, -4)
else
iSize = iSize:sub(1, -2)
end
end
return iSize..' '..tUnits[i]
else
iSize = iSize / 1024
end
end
end
Я не сильно силен в
lua, пока только постигаю сами азы. Хотелось бы узнать почему возможна такая ошибка. Возможно чего-то нет в самом модуле -
utils.lua?
P.S.После обновления -
utils.lua - увидел в чем была разница. Спасибо Илья.
Автор: Setuper 27.12.2010, 22:49
Спасибо. Исправил и перезалил
Автор: Saymon21 5.5.2011, 13:43
IP2Country - Модуль работы с IP2Country.csv
Автор: Nickolya
Подключение модуля: require"IP2Country"
Функции:
IP2Country.GetCountryCode(sIP) - Возвращает код страны для указанного ip
IP2Country.GetCountryName(sIP) - Возвращает имя страны для указанного ip
База IP2Country.csv должна быть в корневой дериктории хаба.
Автор: KCAHDEP 24.6.2012, 21:54
--* Подключение модуля: require"IP2Country"
--* Функции:
--* IP2Country.GetCountryCode(sIP) -- Возвращает код страны для указанного ip
--* IP2Country.GetCountryName(sIP) -- Возвращает имя страны для указанного ip
Это куда вписывать? или просто в libs скопировать достаточно?
Автор: Alexey 7.6.2014, 22:32
Модули из первого поста, оформленные по стандартам Lua 5.2. Пригодны для использования с Lua 5.1 при указанном способе подключения.
Модуль для работы с файлами:
files.lua ( 1.39 килобайт )
: 10
Подключение модуля в скрипте:
Код
local Files = require("files")
Модуль различных утилит:
utils.lua ( 1.95 килобайт )
: 6Подключение модуля в скрипте:
Код
local Utils = require("utils")
Что-бы сохранить в скрипте возможность использования старых модулей, надо добавить соответствующую строку сразу после подключения модуля:
Код
if Files and type(Files) ~= 'table' then Files = _G.Files end
Код
if Utils and type(Utils) ~= 'table' then Utils = _G.Utils end
Автор: Alexey 21.3.2017, 17:31
Улучшено оформление модулей, должны корректнее подключаться без правки скриптов.
Модуль для работы с файлами:
files.lua ( 1.35 килобайт )
: 3
Модуль различных утилит:
utils.lua ( 2.76 килобайт )
: 3
Добавлены функции:
Utils.Ip2Num(sIP) -- Преобразует IP в число
Utils.Num2Ip(i) -- Преобразует число в IP
Utils.tobin(n) -- Приводит десятичное число в бинарную строку