myDC.ru

Здравствуйте, гость ( Вход | Регистрация )

 
История благодарностей участнику Setuper. Спасибо сказали: 1708
Дата поста: В теме: За сообщение: Спасибо сказали:
12.1.2010, 20:17 Hideme
скрипт скрытия в юзер-листе
Название скрипта: Hideme
Версия скрипта: 1.3
Автор: Setuper
Описание: Скрипт позволяет скрываться в юзер-листе. Очень продвинутый функционал. В отличие от птохи, скрытые пользователи никак не могут быть обнаружены (даже при помощи CDM отладчика). Однако, скрытый пользователь может писать в чате и использовать все возможности. Он вообще может считать сябя не скрытым))). Сам скрытый видит свой ник в юзер-листе.
Скрытый режим сохраняется даже после переподключения к хабу и даже после перезапуска хаба. Предупреждение о том, что пользователь находится в скрытом режиме поступает непосредственно при входе на хаб. Таблица tProfiles содержит профили, которым разрешено переходить в скрытый режим.

Внимание! Для работы скрипта необходим модуль files.lua, который нужно положить в папку libs. Модуль можно скачать ТУТ

Для корректной работы скрипта лучше установить хаб не ниже v 2.0.7, так как был устранён небольшой баг в функции скрытия.

[attachment=5323:hideme.lua]
Invisible, fixx, Sekretchik, Saymon21, AltSide, мамин_парень
12.1.2010, 17:43 lfs
RusHub | Библиотека LuaFileSystem
Название: LuaFileSystem (lfs)
Версия: 1.4.2
Хаб: RusHub
Описание: Библиотека для работы с файловой системой.
Использование: Помещаем файл lfs.dll в папку libs. Для подключения библиотеки используем функцию require"lfs"

Библиотека win32: [attachment=3884:lfs_1.4.2.rar]
Библиотека win64: [attachment=5818:lfs_1.4.2_win64.rar]

Проект для сборки на vs2008 (win32): [attachment=6415:lfs_1.4.2_src_vs9.zip]
Исходники для сборки (*nix): [attachment=5198:lua_file....4.2.tar.gz]
Nickolya, Invisible, Saymon21, TiGRpp, DEN 007
12.1.2010, 17:10 mysql
RusHub | Библиотека базы данных mysql
Название: mysql
Версия библиотеки: 2.1.1
Хаб: RusHub
Версия БД: 5.0
Описание: Библиотека для подключения базы данных mysql
Использование: Содержимое архива mysql_2.1.1.rar распаковываем в папку libs. Подключается библиотека так: require"luasql.mysql".
Примечание: Если не работает, то попробуйте библиотеку libmysql.dll закинуть в корень (папку с rushub.exe) или же в system32 (syswow64 для x64).

Библиотека win32: [attachment=3882:mysql_2.1.1.rar]
Библиотека win64: [attachment=5814:mysql_2.1.1_win64.rar]

Проект для сборки на vs2008: [attachment=6418:mysql_2...._src_vs9.zip]

Скрипт примера работы с MySQL в LUA: [attachment=5868:mysql_test.lua]

Основные функции для работы
Основные функции для работы с mysql в lua


Код
luasql._COPYRIGHT = "Copyright (C) 2003-2007 Kepler Project"
luasql._DESCRIPTION = "LuaSQL is a simple interface from Lua to a DBMS"
luasql._VERSION = "LuaSQL 2.1.1"
luasql._MYSQLVERSION = "5.0.18"


  • Подключение драйвера (библиотеки):
    Код
    require"luasql.mysql"

  • Инициализация драйвера (библиотеки):
    Код
    env = luasql.mysql()

  • Деинициализация драйвера (библиотеки):
    Код
    env:close()
    Возвращает true в случае успешного закрытия, false в случае, если закрытие уже было сделано до этого, и порождает ошибку скрипта: "LuaSQL: environment expected", если в метод был подсунут неверный объект.




Объект - соединение (conn)

  • Метод вызова соединения с базой данных:
    Код
    conn = env:connect([имя_базы], [имя_пользователя], [пароль], [хост], [порт])
    Обязательным является только первый параметр, остальные параметры в случае отсутствия берутся по умолчанию: [имя_пользователя] = "root", [пароль] = "", [хост] = "localhost", [порт] = 3306.
    В случае нехватки памяти возвращается nil и сообщение об ошибке: "LuaSQL: Error connecting: Out of memory."
    В случае неудачного коннекта к базе данных возвращается nil и сообщение об ошибке: "LuaSQL: Error connecting to database. MySQL: [reason]"

  • Метод закрытия соединения с базой данных:
    Код
    conn:close()
    Закрытие может быть успешным только в случае если все курсоры закрыты. Возвращает true в случае успешного закрытия, false в случае, если закрытие уже было сделано до этого, и порождает ошибку скрипта: "LuaSQL: connection expected", если в метод был подсунут неверный объект.

  • Метод выполнения SQL запроса к базе данных:
    Код
    conn:execute("запрос")
    В случае правильности запроса, для запросов типа SELECT возвращает курсор, для остальных запросов возвращает число столбцов или строк, успешно обработанных запросом. В случае неверного синтаксиса, или несуществующих таблиц, или несуществующих полей, или прочих ошибок возвращается два значения: первое - nil, второе - сообщение с содержанием ошибки.

  • Метод выполнения (завершения, совершения) текущей транзакции:
    Код
    conn:commit()
    Возвращает true в случае успеха, false - в случае, когда транзакция не может быть завершина или база данных не поддерживает транзакции (поддержка транзакции в mysql осуществляется с версии 4.0).

  • Метод отката на предыдущую транзакцию:
    Код
    conn:rollback()
    Возвращает true в случае успеха, false - в случае, когда операция не может быть выполнена или база данных не поддерживает транзакции (поддержка транзакции в mysql осуществляется с версии 4.0).

  • Метод включения/отключения автоматических транзакций:
    Код
    conn:setautocommit(boolean)
    Эта функция не может работать на базах, на которых не осуществляются транзакции. На базах данных, на которых нет понятия режима автоматических транзакций, этот механизм осуществляется драйвером. Метод возвращает true в случае успеха, и false - в случае невыполнимости или неосуществимости (поддержка транзакции в mysql осуществляется с версии 4.0).



Объект - курсор (cur)

  • Метод закрытия курсора:
    Код
    cur:close()
    Возвращает true в случае успешного закрытия, false в случае, если закрытие уже было сделано до этого, и порождает ошибку скрипта: "LuaSQL: cursor expected", если в метод был подсунут неверный объект.

  • Метод извлечения результатов:
    Код
    cur:fetch([table[,modestring]])
    Извлекает следующий столбец с результатами. Если метод вызывается без параметров, то результаты возвращаются непосредственно вызывающему оператору. Если в первом параметре метода указана таблица, то результаты помещаются в эту таблицу, и методом возвращается эта таблица, при этом может быть использован второй параметр. Второй параметр - это строка, которая указывает на то, как создавать результирующую таблицу:
    "n" - результирующая таблица будет содержать целочисленные индексы (это значение по умолчанию);
    "a" - результирующая таблица будет содержать словесные индексы.
    Целочисленные индексы являются номерами полей в SELECT запросе. Словесные индексы являются названиями полей в SELECT запросе. Дополнительный табличный параметр является таблицей, которую нужно использовать для сохранения следующей строки запроса. В частности, это допускает использование одной уникальной таблицы для всех выборок, и такой механизм может улучшить общее выполнение выборки в целом. Нет гарантии того, что извлечённые результаты будут преобразовываться в нужные в lua типы (в зависимости от содержания), то есть это говорит о том, что возвращаемые результаты всегда представляются в виде строковых значений будь это строка или число. Метод возвращает результирующую таблицу или nil, в случае если достигнута конечная строка. Здесь нужно отметить, что этот метод может возвращать nil, но тем не менее запрос будет выполнен правильно.
    В случае, если у данного метода не указаны параметры, то выбранные из базы значения сливаются в стек, а так как стек не резиновый, то в случае переполнения стека может возникнуть ошибка скрипта: "LuaSQL: too many columns", поэтому в случае большого количества данных рекомендуется сливать данные в таблицу, указывая её в первом аргументе данного метода.

  • Метод, возвращающий таблицу с именами столбцов для данного курсора:
    Код
    cur:getcolnames()
    Метод порождает ошибку скрипта: "LuaSQL: cursor expected", если в метод был подсунут неверный объект.
    Метод порождает ошибку скрипта: "LuaSQL: cursor is closed", если курсор был закрыт.

  • Метод, возвращающий таблицу с типами столбцов для данного курсора:
    Код
    cur:getcoltypes()
    Метод порождает ошибку скрипта: "LuaSQL: cursor expected", если в метод был подсунут неверный объект.
    Метод порождает ошибку скрипта: "LuaSQL: cursor is closed", если курсор был закрыт.

  • Метод, возвращающий число строк, полученных в результате запроса:
    Код
    cur:numrows()
    Метод порождает ошибку скрипта: "LuaSQL: cursor expected", если в метод был подсунут неверный объект.
    Метод порождает ошибку скрипта: "LuaSQL: cursor is closed", если курсор был закрыт.
Invisible, Accelerator, PomanoB, Alexey, Saymon21
12.1.2010, 15:07 luasocket
RusHub | Библиотека сокетов
Название: luasocket
Версия: 2.0.2
Хаб: RusHub
Описание: Библиотека сокетов
Использование: Кладём содержимое архива luasocket_2.0.2.rar в папку libs. Подключается библиотека сокетов так: require"socket"

Библиотека win32: [attachment=5433:luasocket_2.0.2.rar]
Библиотека win64: [attachment=5819:luasocke....2_win64.rar]

Проект для сборки на vs2008: [attachment=6416:luasocke..._src_vs9.zip]
Nickolya, Invisible, Maximum, Sekretchik, Saymon21, Asbar, AfLc
11.1.2010, 22:15 RusHub
Кроссплатформенный консольный DC хаб
rushub v 2.0.6
lua plugin v 1.7


Изменения:

Added: Добавлена настройка установки локали. Корректное восприятие русских букв или букв других языков (в зависимости от локали). Теперь lua функции string.lower и string.upper корректно работают с русскими буквами. Если на хабе есть пользователь Вася, то с ником ВАСЯ уже нельзя войти на хаб.

Added: Добавлена функции сокрытия ника из списка пользователей (12-ый бит функции Core.GetUser и функция Core.SetUser(UID, 5, bool)).

Added: Добавлено событие OnKick(UID, sData)

Added: Добавлено событие OnOpForceMove(UID, sData)

Added: Добавлено событие OnGetINFO(UID, sData)
Nickolya, BIMMER71, Invisible, Serx, ExC0tiC, Sekretchik, X-Sky
9.1.2010, 21:22 Модули для скриптов RusHub
Файл не найден, поэтому функция 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
Invisible, Accelerator
9.1.2010, 20:27 Модули для скриптов RusHub
Модули кладутся в папку libs.
Давайте сделаем некое правила написания модулей: файлы модулей будем писать строчными буквами, а модули объявлять тем же словом, но начинающемся с заглавной буквы. Так будет проще отличать название файла с модулем, от названия самого модуля (для того чтобы вникнуть в их суть).

Пример использования функций модуля:
Код
require"files" -- подключение модуля
Files.SaveTable("myfile.txt", tTable, "tTable") -- Вызов функции модуля


Модуль для работы с файлами: [attachment=3901:files.lua]
Модуль различных утилит: [attachment=5424:utils.lua]



Давайте в этой теме обсуждать те функции, которые часто используются скриптами, и запихивать их в модули
Invisible, Ksan, Alexey, Sekretchik, Saymon21, AfLc, мамин_парень
9.1.2010, 19:44 Объявления (Announcements)
версия 1.1
Код
local tUser = Core.GetUser(UID, 2047)
local sUser = Core.GetUser(UID, 8)


Первая строка уже содержит почти все биты, поэтому вторую строку незачем писать.

Цитата
2^0 - ник (sNick)
2^1 - ip (sIP)
2^2 - UID (UID)
2^3 - профиль (iProfile)
2^4 - MyINFO строка (sMyINFO)
2^5 - пользовательские данные (sData)
2^6 - пользователь в оп-лите (bInOpList)
2^7 - пользователь полностью вошёл и добавлен в список пользователей (bInUserList)
2^8 - реальный порт (iPort)
2^9 - порт коннекта (iPortConn)
2^10 - мак адрес (sMacAddress)
2^11 - версия протокола (sVersion)


В двоичной системе:
000000000001 - ник (sNick)
000000000010 - ip (sIP)
000000000100 - UID (UID)
000000001000 - профиль (iProfile)
000000010000 - MyINFO строка (sMyINFO)
000000100000 - пользовательские данные (sData)
000001000000 - пользователь в оп-лите (bInOpList)
000010000000 - пользователь полностью вошёл и добавлен в список пользователей (bInUserList)
000100000000 - реальный порт (iPort)
001000000000 - порт коннекта (iPortConn)
010000000000 - мак адрес (sMacAddress)
100000000000 - версия протокола (sVersion)

Теперь, как перейти из двоичной системы в десятичную?
Всё очень просто: отсчитываем справа позицию, на которой стоит единица и возводим двойку в эту степень (отсчёт позиции происходит с 0, а не с 1). То есть для поля ника нулевая позиция, 2^0 = 1.
Код
local tUser = Core.GetUser(UID, 1)



Для профиля: третья позиция, следовательно для профиля 2^3 = 8
Код
local tUser = Core.GetUser(UID, 8)


А что если 1 не в одном поле, а в нескольких полях?
Пример: 101010101010.
Каждая позиция отвечает за добавление какого-то поля. Вот и смотрим по позициям какие поля добавятся. Для этих полей будет число (считаем справа на лева): 0*2^0 + 1*2^1 + 0*2^2 + 1*2^3 + 0*2^4 + 1*2^5 + 0*2^6 + 1*2^7 + 0*2^8 + 1*2^9 + 0*2^10 + 1*2^11 = 2730
То есть для того, чтобы в таблицу tUser поместить поля sIP, iProfile, sData, bInUserList, iPortConn и sVersion (именно на позициях этих полей стоит 1 в нашем бинарном числе), нужно в функции написать число 2730:
Код
local tUser = Core.GetUser(UID, 2730)


Давай те теперь разберёмся чему же отвечает число 2047, которое используется в скрипте?
Оно отвечает следующей бинарной строке: 011111111111. То есть это число добавит в таблицу tUser все поля, кроме поля sVersion.


Каждому десятичному числу отвечает двоичное число. Например, мы рассматривали двоичное число 101010101010 и выяснили, что ему отвечает десятичное число 2730. А каком двоичному числу отвечает следующее десятичное число 2731? Естественно ему соответствует двоичное число 101010101011, то есть для числа 2731 в таблицу tUser добавятся теже самые поля, что и для числа 2730, но плюс ещё поле sNick.

1 = 000000000001
2 = 000000000010
3 = 000000000011
4 = 000000000100
5 = 000000000101

...

2730 = 101010101010
2731 = 101010101011
2732 = 101010101100
2733 = 101010101101
2734 = 101010101110
2735 = 101010101111

и тд.


Надеюсь, что я понятно объяснил работу с бинарными числами.
Функция Core.GetUser достаточно хорошо оптимизирует код, если правильно ею распоряжаться и вносить в таблицу tUser только те поля, которые мы собираемся использовать в данной области видимости.

У тебя в функции OnChat используется только 2 поля: поле sNick и поле iProfile, поэтому самый оптимальный код будет выглядеть так:
Код
local tUser = Core.GetUser(UID, 9)
таблица tUser будет содержать только эти 2 поля (sNick и iProfile). В функции OnUserEnter всё оптимально, и там ничего менять не нужно.



И ещё раз повторю, что не нужно к каждому скрипту делать свой модуль. Модуль должен быть один для всех скриптов, и называться он должен в соответствии с теми функциями, которые он содержит.
Invisible, Accelerator, Saymon21
7.1.2010, 18:29 Скрипт банов для RusHub
тестим и комменьтруем
хехе ты читаешь всю базу зарегистрированных пользователей, для того чтобы сделать доступ только определённым.
А нужно чтобы скрипты работали отдельно, то есть не привязывать скрипт банов к скрипту регистрации.
Скрипт регистрации устанавливает пользователям профиль, и этот профиль можно использовать в любом скрипте. Это делается с помощью занесения в таблицу пользователя поля профиля:
Код
local tUser = Core.GetUser(UID, 8)
if tUser.iProfile == 0 or tUser.iProfile == 1 then -- если админ или оператор
  ...
end

Это так сказать пояснения...))))
Accelerator
6.1.2010, 23:45 RusHub
Кроссплатформенный консольный DC хаб
rushub v 2.0.5
lua plugin v 1.6

Изменения:

Fixed: Теперь в настройку sHubIP можно записывать не только ip адрес, но и хост.

Fixed: В целях оптимизации были убраны lua функции Core.GetMainDir(), Core.GetScriptsDir() и Core.GetHubInfo(). Вместо них теперь поля: Core.sMainDir, Core.sScriptsDir, Core.sHubVersion и Core.sLuaPluginVersion соответственно.
В связи с этим, некоторые скрипты откажутся работать!

Added: Добавлены lua функции: Core.GetConfig(sName), Core.SetConfig(sName, sValue), Core.GetLang(sName), Core.SetLang(sName, sValue).
Функции позволяют управлять конфигурацией и языковыми настройками хаба. Однако, для функции Core.SetConfig исключения составляют настройки: sHubIP, iMainPort, sSubPorts.
При изменении настройки sHubName или sTopic отправляется соответствующая команда. После изменения, настройки сохраняются.
Nickolya, Invisible, ExC0tiC
6.1.2010, 13:57 Предложения для развития
в русхабе намного продвинутый аналог этой функции содержится в функции Core.SendToUser(UID/sToNick, sData, sNick, sFrom)

UID/sToNick - UID или ник пользователя, которому хотим отослать сообщение
sData - само сообщение

Если указан параметр sNick, то сообщение будет отсылаться в чат от этого ника

Если кроме параметра sNick указан параметр sFrom, то сообщение будет отсылаться в приват от пользователя sFrom, с ником в сообщении sNick.
Для того, чтобы отсылающий и ник в сообщении совпадали, нужно чтобы совпадали параметры sNick и sFrom.

Пример:

Код
Core.SendToUser("Вася", "Тест", "Петя", "Бот")

эта строка отошлёт приватное сообщение "Тест" пользователю с ником "Вася", причём на закладке приватного окна будет указано, что сообщение пришло от "Бот", а в самом сообщении будет так: <Петя> Тест

Надеюсь понятно разъяснил))))
В общем пробуем))

Цитата(Wariner @ 6.1.2010, 10:33) *
Хм, вопрос не по хабу а по форуму. может стоит разделить скрипты и модули? т.е. отдельно ветка скриптов отдельно ветка модулей?

Модули, я думаю, можно обсуждать в разделе "Разработчикам".
Accelerator
6.1.2010, 13:53 AntiAdv
антиреклам
Кстати, по поводу всяких антиреклам и антиматов, обратите внимание на мощь функции Core.SetCmd(sData) big_smile.gif
Sekretchik, Saymon21
6.1.2010, 2:12 RusHub
Кроссплатформенный консольный DC хаб
rushub v 2.0.4
lua plugin v 1.5


Обновление хаба было связано с расширением возможностей установки ключика операторов в любое время, а не только при входе на хаб.


Список изменений:

Added: Добавлена функция Core.GetUpTime()

Added: Добавлена функция Core.GetHubInfo() информация о хабе и о плагине.

Added: Добавлена новая функция Core.SendToNicks(tNicks, sData, sNick, sFrom). Функция отправляет сообщение всем никам, которые находятся в таблице tNicks.

Added: Добавлена функция Core.DisconnectIP(sIP). Разъединяет всех пользователей с указанным IP.

Fixed: Исправлена функция Core.SetUser. Теперь пользователь может быть когда угодно занесён и извлечён из списка операторов, а не только при входе на хаб. Ставим/убираем ключик одним движением руки. Код написан оптимально и исключает повторных действий при вызове.

Fixed: Исправлен баг в функции Core.GetUsers

Fixed: Модифицирована функция Core.GetUsers(sIP, iByte).
Core.GetUsers() - таблица с UID'ми всех пользователей хаба
Core.GetUsers(iByte) - таблица с таблицами пользователей, которые содержат данные битов параметра iByte
Core.GetUsers(sIP) - таблица с UID'ми пользователей с указанным IP
Core.GetUsers(sIP, iByte) - таблица с таблицами пользователей с указанным IP, которые содержат данные битов параметра iByte
Nickolya, Invisible, ExC0tiC, Sekretchik
5.1.2010, 13:42 Скрипт для пингеров
Я убрал из хаба практически всё. Оставил только самое нужное. Остальное оставил на скрипты.

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

Я могу нагромоздить это всё в хабе, однако, разве это нужно?
Nickolya, dj_crazy_joker
4.1.2010, 23:56 Вопросы по RusHub
Технические вопросы
Пользовательские данные - это поле для хранения любой информации для данного пользователя, то есть туда можно записать всё, что угодно - своего рода блокнот пользователя. Можно сделать, чтобы админы туда что-то писали и просматривали эти данные, можно чтобы сами юзеры могли что-то туда заносить, а можно использовать это поле для передачи какой-то информации между скриптами.

Core.SetUser(UID, 4, true) до входа (после получения пароля) вносит пользователя в лист операторов (устанавливает ключик).


Пример из скрипта регистрации:
Код
function OnMyPass(UID, sData)
  local sPass = sData:match"^.- (%S+)$" -- "$MyPass <pass>"
  local tRegInfo = tRegUsers[Core.GetUser(UID, 1).sNick] -- Получаем регистрационные данные
  if not sPass or sPass ~= tRegInfo.sPass then -- Проверяем правильность пароля
    Core.SendToUser(UID, ("<%s> "):format(sBot)..sBadPassMsg.."|$BadPass") -- Отсылаем сообщение о неверном пароле
    Core.Disconnect(UID) -- Разъединяем пользователя
  else
    Core.SetUser(UID, 1, tRegInfo.iProfile) -- Устанавливаем профиль пользователю
    Core.SetUser(UID, 4, true) -- Добавляем пользователя в оплист
  end
end

Хотя действительно нужно сделать эту возможность не только при входе (не только до добавления пользователя в списки). В следующем релизе сделаю.
Nickolya
4.1.2010, 20:31 Скрипт банов для RusHub
тестим и комменьтруем
Название скрипта: модуль банов + менеджер банов
Скрипт для: RusHub
Автор: Wariner (немного доработал: Setuper)
Описание: Модуль банов позволяет использовать функции бана в скриптах. Менеджер банов позволяет забанить, используя команды.
Модуль банов не может работать отдельно от менеджера банов, так как менеждер банов содержит основную таблицу с банами.

Внимание. Этот скрипт будет работает только с lua плагином, который равен или выше, чем версия v1.4, так как в плагине был устранён баг в функции Core.SetGVal.

Теперь расскажу чего я добился. Теперь, подключая модуль Ban в любом скрипте можно будет забанить того или иного пользователя и при этом не нужно будет читать из файла базу забаненных или использовать таблицу с забаненными, - всё это скрыто в модуле Ban. Очень удобно банить с помощью модуля.


[attachment=5403:Ban.lua][attachment=5407:BanManager.rar]
FallenAngel, Invisible, Артём, Infinity_Love, Kingston, Sekretchik, CrazyKiller, Saymon21, Dimon21, X-Sky, Sorrow, AltSide, AfLc
4.1.2010, 20:23 RusHub
Кроссплатформенный консольный DC хаб
lua plugin v 1.4

Fixed: Исправлена несколько некорректная работа функции Core.SetGVal с таблицами.
Nickolya, Invisible, ExC0tiC
4.1.2010, 4:00 RusHub
Кроссплатформенный консольный DC хаб
lua plugin v 1.3

Added: Функции Core.GetGVal и Core.SetGVal теперь позволяют оперировать с таблицами и с lightuserdata данными.
Nickolya, Invisible
3.1.2010, 1:34 Репорты об ошибках старых версий
архив темы ошибок текущей версии хаба
вместо функций Core.SendToUID и Core.SendToNick теперь функция Core.SendToUser

Просто заменяем эти функции на Core.SendToUser и всё будет работать.
Core.SendToUser теперь общая функция отсылки данных пользователю как по нику так и по идентификатору UID.
Invisible, Saymon21
3.1.2010, 1:19 RusHub
Кроссплатформенный консольный DC хаб
rushub v 2.0.3
lua plugin v 1.2


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

Added: вместо функций Core.SendToUID и Core.SendToNick теперь функция Core.SendToUser(UID/sToNick, sData, sNick, sFrom)
Fixed: исправлен баг вылета в функции Core.GetScript при обращении к отключенному скрипту.
Fixed: исправлен баг, который не позволял создать лог ошибок скриптов, в случае, если в названии директории присутствовала кириллица.
Fixed: исправлен баг функции Core.Disconnect для случая разъединения пользователя по нику.
Nickolya, Invisible, ExC0tiC, Sekretchik, Saymon21
2.1.2010, 20:27 Скрипт для пингеров
Название скрипта: pinger
Скрипт для: RusHub
Версия скрипта: 1.0
Описание: Скрипт для пингеров. Отправляет пингерам, которые заходят на хаб, команду, содержащую информацию о хабе.
Автор: Setuper

[attachment=5669:pinger.lua]
Invisible, KT315, Sekretchik, Saymon21, stone, AfLc
2.1.2010, 18:41 Репорты об ошибках старых версий
архив темы ошибок текущей версии хаба
alex82, спасибо за скрипт. Я почти не сомневался, что хаб сможет цеплять практически все стандартные библиотеки lua. Что касается названия lua51.dll, то для удобства могу изменить его на lua.dll. Просто для подключения стандартной библиотеки для работы с mysql (http://luaforge.net/frs/?group_id=12&release_id=847) нужно имя lua51.dll, однако, её можно пересобрать под работу с lua.dll.


Nickolya, спасибо за обнаружение багов. По поводу функции Core.SendToUID, то про этот баг я знал, в ближайшее время исправлю.
По поводу бага с функцией перезагрузки, можно по-подробнее? Пример скрипта?
По поводу бага с функцией Core.GetScript, - исправлю в ближайшее время.

Объяснения по параметру iByte функции Core.GetUser:
С помощью данного параметра мы указываем какие поля мы хотим видеть в таблице, которую вернёт эта функция.
Параметр является числом, в котором зашифрованы биты полей.
Например:
мы хотим в таблице пользователя видеть следующие поля: sNick, sIP, iProfile, sMyINFO.
Для этого мы смотрим какие биты отвечают за эти поля:

Цитата
2^0 - ник (sNick)
2^1 - ip (sIP)
2^3 - профиль (iProfile)
2^4 - MyINFO строка (sMyINFO)

За эти поля отвечают биты: 0, 1, 3 и 4.
Складываем: 2^0 + 2^1 + 2^3 + 2^4 = 27
Пишем код:
Код
local tUser = Core.GetUser(UID, 27)

Таблица tUser будет содержать нужные нам поля (sNick, sIP, iProfile, sMyINFO).
Теперь для чего это нужно? Это является оптимальным вариантом подачи данных в lua. То есть, заносим в таблицу только то, что мы собираемся использовать, ни больше и не меньше.

Сравнение с птохой: в птохе всегда определены 4 поля в таблице пользователя (sNick, sIP, uptr и iProfile), а остальные поля можно занести в таблицу используя либо функцию Core.GetUserAllData, которая занесёт в таблицу все поля, либо функцию Core.GetUserData(tUser, nValueId), которая за один вызов будет заносит один параметр. Поэтому в птохе не оптимальная реализация, так как либо все параметры заноси в таблицу, либо делай несколько вызовов функции Core.GetUserData для занесения необходимых параметров, при этом 4 первоначальных поля в таблице также могут бестолку каждый раз заноситься в таблицу на каждом вызове того или иного события. В русхабе всё это реализовано функций Core.GetUser, которая является самым оптимальным вариантом, при сохранении всей возложенной не неё функциональности.


Изменение настроек хаба через lua, также попытаюсь реализовать в ближайшее время.

Совместить функции Core.SendToNick и Core.SendToUID - замечательная идея, так и сделаю. Наверное тогда стоит назвать функцию Core.SendToUser ?

Готов реализовать парсинг MyINFO, действительно наверное это было бы удобнее. Тут вопрос: парсить ли тэг, или парсить всё кроме тэга?

апи постепенно расширяется. Жду дельных идей.
Nickolya, Invisible
30.12.2009, 4:35 RusHub
Кроссплатформенный консольный DC хаб
rushub v 2.0.2

Fixed: Устранены причины падения при ошибках в скриптах и в некоторых api функция.

Параметр iMaxLevel - уровень лога событий. Для тестирования: 6 (логировать всё)
Nickolya, Invisible, ExC0tiC
29.12.2009, 22:44 Идея скрипта по отлову двойников
Во-первых, не кикает а разъединяет. Во-вторых, естественно при совпадении только обоих параметров. В-третьих, куда хочешь, туда и встраивай этот код.
TranceFM
28.12.2009, 22:58 RusHub
Кроссплатформенный консольный DC хаб
rushub v 2.0.0

Added: Реализован lua плагин (минимальный для работы lua функционал реализован). По средствам lua можно реализовать: регистрацию, баны и тд.
Для подключения lua плагина кладём файл lua.dll в папку plugins.

Lua библиотеки сторонних разработчиков (luasql и тд.) должны подключаться без каких либо перекомпиляций (ограничение только на формат COFF, то есть от птохи библиотеки не подходят, нужно качать отсюда: http://luaforge.net/projects/luasql/ ).

Работа продолжается...

Простенький скрипт приветствия: [attachment=3757:hello.lua]
Простенькая регистрация: [attachment=6513:registration.lua]
Nickolya, Invisible, ExC0tiC, Sekretchik, Saymon21, Mustik
27.12.2009, 14:22 Готовый Хаб
knuckles
23.12.2009, 17:29 Chathistory By Mutor
API2 | Переведен мною =)
За такую кривизну даже браться не хочется.


Не стал исправлять кривизну скрипта, однако подправил пару вещей:
Раскрывающийся текст
botname = "Последние 10 сообщений в чате" -- Имя бота
BadChars = {".","?","!","+","-",} --На какие префиксы скрипт не будет реагировать
maxhistory = 20 -- Максимум линий для чата в кеше
chatfile = "chathistory.dat"-- куда будут записываться логи чата

GetChat = "+история" -- Команда для показа последних сообщений; Например, +история 10 покажет последние 10 сообщений

-- Выбираем, для каких профилей будет доступна команда:
-- индекс профиля, история чата [0=нет 1=да], "Название профиля"
HistoryProfiles = {
[-1] = {0,"Незарегистрированные пользователи"},
[0] = {1,"Мастер"},
[1] = {1,"Оп"},
[2] = {1,"Вип"},
[3] = {1,"Зарегистрированные пользователи"},
}

--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------

function OnStartup()
if loadfile(chatfile) == nil then
chathistory = {}
local when = os.date(" %B %d %Y в: %X")
local chat = "Файл лога главного чата создан: "
table.insert(chathistory,when..chat)
local f,e = io.open( chatfile, "w+" )
f:write( "return {\n"..string.format("%q",chat..when)..",\n}" )
f:close()
end
chathistory = dofile(chatfile)
--frmHub:RegBot(botname)
end

function OnExit()
savehistory()
end

function UserConnected(user)
Core.GetUserAllData(user)
if HistoryProfiles[user.iProfile] and HistoryProfiles[user.iProfile][1] == 1 then
local n = #chathistory
local str = ""
for i = 1, n do str = str.."\r\n"..chathistory[i] end
Core.SendToNick(user.sNick,"<"..botname.."> "..str.."\r\n")
end
end

OpConnected = UserConnected

function ChatArrival(user,data)
Core.GetUserAllData(user)
local s,e,pre = string.find(data, "^%b<> (.)")
local s,e,cmd,lines = string.find(data, "^%b<>%s+(%S+)%s+(%d+)|$")
local when = os.date("[%H:%M] ")
local chat = string.sub(data, 1, -2)
if cmd and cmd == GetChat then
if lines ~= e then
GetChatLines(user, lines)
return true
else
Core.SendToNick(user.sNick,"<".."Пожалуйста.."> ".. укажите, сколько сообщений из лога главного чата вы хотите увидеть. Максимальное значение: "..maxhistory..".")
return true
end
else
for k,v in ipairs(BadChars) do
if pre == v then
return
end
end
table.insert(chathistory,when..chat)
if #chathistory > maxhistory then table.remove(chathistory, 1) end
savehistory()
end
end

function GetChatLines(user, linecount)
local n1 = #chathistory
local n2 = linecount
local n3 = n1 - (n2-1)
local str = ""
for i =n3,n1 do str = str.."\r\n"..chathistory[i] end
Core.SendPmToNick(user.sNick,botname,str.."\r\n")
end

function savehistory()
local f,e = io.open( chatfile, "w+" )
if f then
f:write("return {\n")
for i = 1, #chathistory do
f:write( "\t"..string.format("%q", chathistory[i])..",\r\n" )
end
f:write("}" )
f:close()
return 1
else
return nil
end
end
RegConnected = UserConnected
21.12.2009, 23:27 История чата
помогите
Под желания конкретного человека переделывать никто скрипты не станет. Так всем не угодишь.
Не нравится то, что есть, - либо не используй, либо учись корректировать скрипт под себя.
X-Sky
19.12.2009, 18:31 TimeToNewYear
API2 | Время до нового года
Кстати, что касается милисекунд, то меньше 100 мс бестолку ставить. Минимум это 100 мс именно такой минимальный интервал обработки таймеров в птохе
Nickolya, Invisible
16.12.2009, 15:29 С Новым Годом!
см название темы
Написано же с наступающим!
Uncle_Dif
15.12.2009, 23:23 RegmeEmail
API2 | Регистрация через e-mail
Сделал.

Пофиксил регулярное выражение для определения формата e-mail адреса (раньше не пропускало e-mail со знаком подчёркивания).
Для фикса качаем обновлённый файл email.lua
Saymon21
15.12.2009, 18:46 RegmeEmail
API2 | Регистрация через e-mail
luxemat:

local sFrom = "kirser@bk.ru" -- Адрес отправителя
local sServer = "smtp.bk.ru" -- Адрес сервера
local sUser = "kirser" -- Имя пользователя
local sPass = "*****" -- Пароль
local sHubAddress = "94.243.55.201:450" -- Адрес вашего хаба

Хабыч:
Для того, чтобы добавить команду, нужно в функцию OnStartup() добавить ещё одну функцию cmd.Add, вот так:

Код
function OnStartup()
  sBot = SetMan.GetString(21)
  sSubject = sSubject:gsub("%[HUBNAME%]", SetMan.GetString(0))
  email.SetValues(sFrom, sServer, sUser, sPass)
  cmd.Add("[Rr][Ee][Gg][Mm][Ee]", Regme, Protect)
  cmd.Add("[Рр][Ее][Гг][Ии][Сс][Тт][Рр][Аа][Цц][Ии][Яя]", Regme, Protect)
  if loadfile(sFile) then
    dofile(sFile)
  end
end


После этого регистрироваться можно будет как по команде !regme, так и по команде !регистрация
Собственно для этого и создавался модуль cmd.

Если не нужен верхний регистр, то можно просто добавить cmd.Add("регистрация", Regme, Protect), тогда регистрация будет срабатывать по команде !регистрация, но не будет срабатывать, например, по команде !РЕГИСРАЦИЯ или !рЕгИсТрАцИя
Короче говоря можно добавлять команды как регулярные выражения.
Wan, Saymon21, pol_91
15.12.2009, 16:21 RegmeEmail
API2 | Регистрация через e-mail
Код
function RegConnected(tUser)
  if tNoActivate[tUser.sNick] then
    tNoActivate[tUser.sNick] = nil
  end
  Core.SendToUser(tUser, "$UserCommand 1 3 Регистрация\\Сменить пароль$<%[mynick]> !passwd %[line:Введите новый пароль]&#124;")
end
OpConnected = RegConnected

function UserConnected(tUser)
  Core.SendToUser(tUser, "$UserCommand 1 3 Регистрация\\Зарегистрироваться$<%[mynick]> !regme %[line:Введите Ваш e-mail]&#124;")
end
Wan, Saymon21
15.12.2009, 14:36 RegmeEmail
API2 | Регистрация через e-mail
Название скрипта: RegmeEmail
Версия API: 2
Версия скрипта: 1.0
Автор: Setuper
Описание: Простенькая регистрация через e-mail. Команда для регистрации: !regme email@email.com
После отправки команды, у пользователя есть 10 минут для того, чтобы зайти в почту, посмотреть там пароль и зайти на хаб. В противном случае авторизация не произойдёт, и спустя 10 минут аккаунт удалится с хаба.

ВНИМАНИЕ! Для работы скрипта необходимы модули: cmd и email, а также необходима библиотека сокетов: http://mydc.ru/topic43.html
Модули и библиотеку сокетов следует поместить в папку libs.

Обо всех ошибках и просьбах писать сюда.

Необходимые модули:
[attachment=3615:cmd.lua][attachment=3626:email.lua]


Непосредственно сам скрипт:
[attachment=3625:regme_email.lua]
Nickolya, Goblin, Tsd, Invisible, valdis73, Saymon21, Stok, GULAM33
10.12.2009, 13:36 С Днюхой Тебя!
поздравления
Поздравляю!))
Invisible
9.12.2009, 17:00 Помогите
скрипты
ссылку кинул в лс.
Тему закрываю big_smile.gif
Nickolya
9.12.2009, 0:43 Нужен Скрип Регистрации
С запросом
Код
function ChatArrival(tUser)
  if tUser.iProfile == -1 then
    Core.SendToUser(tUser, "*Вы не можете писать в чат пока не зарегистрируетесь* Регистрация осуществляется администратором хаба ежедневно с 20:00 до 00:00")
    return true
  end
end
Master-Grow
8.12.2009, 1:55 Помогите со скриптом Pinger =)
У меня всё работает и пинг, и трассировка.

Кодировка OEM. Если бы использовалась английская версия винды, то всё нормально бы отображалось)))

Пользователи могут долго трассироваться, тем более, что трассировка может содержать до 30 шагов

Скрипт с перекодировкой OEM в ANSI: [attachment=3575:ping.lua]
Invisible, TiGRpp
7.12.2009, 21:11 Помогите со скриптом Pinger =)
см. файл ниже
Invisible
7.12.2009, 17:53 Предложения для развития
Ага. Реализация функционала операторов не будет привязываться к ключикам))) То есть все настройки зависят только от профиля, но никак не от какого-то атрибута профиля.
FallenAngel
6.12.2009, 1:00 Нужен скрипт скрывающий ботов
Бот скрывающий ботов
Это просто немыслимо использовать такой-то скрипт, который скрывает ботов скриптов)))))

Просто в скриптах нужно найти и удалить функцию Core.RegBot
PRIZrak, Pro009
3.12.2009, 19:27 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Найди отличия между твоим кодом и вот этим:
Код
function UserConnected(tUser)
  Core.SendToUser(tUser,"$UserCommand 1 3 »»» Информация\\Правила хаба$<%[mynick]> !rules&#124;|"..
  "$UserCommand 1 3 »»» Информация\\Друзья хаба$<%[mynick]> !friends&#124;|"..
  "$UserCommand 1 3 »»» Информация\\Адреса хаба$<%[mynick]> !adress&#124;|"..
  "$UserCommand 1 3 »»» Информация\\инфа тут например$<%[mynick]> !команда&#124;|")
end
RegConnected,OpConnected=UserConnected,UserConnected

Смотри очень внимательно.

И слово адрес по английски пишется с удвоенной буквой d: address
random name
30.11.2009, 22:49 Сброс соединения если много Core.Send*
PtokaX 0.4.1.1 \ Debian 5
В плане кода, я посмотрел, там вот как:
если размер буфера отправки начинает превышать некое пороговое значение, и при этом отключена настройка "Keep slow users online", тогда хаб отключает пользователя с переполненным буфером отправки. Если же при данном переполнении включена указанная настройка, то хаб отделяет от буфера несколько первых команд и отсылает пользователю только их, а остальные команды оставляет в буфере и отправляет в следующей партии.
Nickolya
27.11.2009, 3:04 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Выходов из данной ситуации 2:
1)
Код
local sss = "%%%%%%%%'\""
sss = (sss:gsub("%%", "%%%%").."%s%s"):dbformat("1%%", "2%%%%")
Core.SendToAll("sss:dbformat = "..sss.."    len = "..sss:len())


2)
Код
local sss = "%%%%%%%%%%%%%%%%'\"%s%s"
sss = sss:dbformat("1%%", "2%%%%")
Core.SendToAll("sss:dbformat = "..sss.."    len = "..sss:len())


То есть либо до вставки строки в метод формат удваивать проценты, либо самому формировать строку с удвоенными процентами.

Лучше наверное второй способ. Ведь как правило запросы мы сами определяем в программе, и они как правило постоянные.
Если же запросы определяются только в процессе (динамически), то первый способ спасёт))

Как правило в запросах у нас вообще нету процентов:
Код
("INSERT INTO `table` VALUES ('%s', '%s', '%s')"):dbformat(a, b, c)


Вообще-то, написанный пример не очень подходит для использования метода dbformat. Думаю для примера нужно так написать:
Код
local sss = "qwerty%s%s"
local a, b = "\\%%%", "\"\\'"
sss = sss:dbformat(a, b)
Core.SendToAll("sss:dbformat = "..sss.."    len = "..sss:len())
Ведь мы экранируем символы в параметрах (a, b), а не в самом запросе. В запросе нам всё известно, поэтому мы там пишем всегда всё корректно, а вот в параметрах может быть всё, что угодно.

Возможно я до конца не понял суть проблемы, но на данный момент (после написания поста) у меня сложилось впечатление, что проблемы как таковой и нету. Или всё же есть? Давайте расставим все точки над и big_smile.gif
Nickolya
26.11.2009, 23:50 Mysql
win32 - API 2 | Самая распространённая база данных
В очередной раз затрагиваю тему экранирования в mysql.

Символы, которые обязательно должны экранироваться: ' " \
Символы, которые могут экранироваться в LIKE запросе: % _ \ (при этом символ \ должен экранироваться так: \\\\)
Прочие экранированные символы в sql формате:
\0 - символ 0 (NUL) в ASCII коде;
\b - возврат на один символ;
\n - символ новой строки (перевода строки);
\r - символ перевода каретки;
\t - символ табуляции;
\z - символ (Control-Z) таблицы ASCII(26). Данный символ можно закодировать, чтобы обойти проблему, заключающуюся в том, что под Windows ASCII(26) означает конец файла (проблемы возникают при использовании ASCII(26) в выражении mysql database < filename).


Дабы скрипты никогда не падали из-за случайно некорректных запросов, модифицируем ранее описанный мною метод dbformat:
Код
string.dbformat = function(self, ...)
  local t = {...}
  for k, v in ipairs(t) do
    t[k] = tostring(v):gsub("(['\\\"])", "\\%1")
  end
  return self:format(unpack(t))
end



Кроме этого, для запросов типа LIKE, кроме метода dbformat, нужно будет применить ещё один метод:
Код
string.dblikeformat = function(self, ...)
  local t = {...}
  for k, v in ipairs(t) do
    t[k] = tostring(v):gsub("([%%\\_])", "\\%1")
  end
  return self:format(unpack(t))
end
Nickolya, Serx, Accelerator, Saymon21
22.11.2009, 21:38 Hub's Big Ass Bot
API2 | HUBBABOT v.2.28
Контекстное меню хаба)))
NeRvIk
22.11.2009, 1:34 Проблема с запрещенными символами.
Это никак нельзя исправить. Некоторые из запрещённых символов в нике запрещены протоколом, другие запрещены по другим соображениям, например из-за хранения ников в xml файле, или для возможности создать файл или папку с именем того или иного пользователя. Конечно, можно использовать всякие там эскейп последовательности для экранирования того или иного символа, или использовать коды символов для их отображения, однако, как сделано, так сделано, и это наиболее простой и оптимальный выход из ситуации, который нельзя никак изменить, разве что залезть в исходные коды.

Запрещённые символы в нике для PtokaX: $|<>:?*"/\ и пробел.
TYF
19.11.2009, 14:41 Сжатие Zlib
Сжатие с помощью zlib после команды $ZOn
Enyby
16.11.2009, 14:09 Ptokax Win Gui
Руководство по установке и настройке
Настройки - Дополнительно - Моя информация
Строка описания, строка тэга, строка соединения строка e-mail. Всем юзерам.
thehawk
15.11.2009, 18:49 Luasocket
win32 | Работа с сокетами
Интересно что и куда ты переписываешь?

Выложенные тут библиотеки работают только под виндой.
Под юниксы нужно самому собирать сошки из исходников:[attachment=3505:luasocket_2.0.2.tar.gz]
dj_crazy_joker
13.11.2009, 13:05 ShowTopic
API2 | Показ топика в чате
Условие
Код
if cmd and (cmd == cmdTop) then
было написано правильно. Оно предостерегает от попытки сравнить cmdTop с nil, так как пользователь может отправить, например, пустую строку в чат, и тогда регулярное выражение ничего не захватит.

Что касается установки топика, то нужно писать SetMan.GetString(10, "новый топик").

Код:
Код
Core.SendToAll(Data)
Core.SendToAll("<"..Bot.."> Топик хаба: "..SetMan.GetString(10).."")

лучше писать в одну функцию:
Код
Core.SendToAll(Data.."|<"..Bot.."> Топик хаба: "..SetMan.GetString(10))


И конечно же нужно избавляться от очень дурной привычки добавлять конкатенацию с пустой строкой! Не знаю от кого она пошла, но она очень вредная.
X-Sky
6.11.2009, 20:19 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Код
function OnStartup()
  Core.SendToAll(ScriptMan.GetScript().sName)
end


Нельзя вызывать функцию, которая возвращает информацию о самом скрипте, до выполнения функции, инициализирующей этот самый скрипт !!!
Jaska
1.11.2009, 12:44 Перевод Hexhub 5.03a
Нужны тестеры
По протоколу NMDC результаты поиска при пассивном поиске проходят через хаб, при активном поиске не через хаб, а напрямую.
valdis73
30.10.2009, 14:55 Как зашитится от спам бота
помогите спамят
как вариант: http://mydc.ru/topic1898.html
KamoK
29.10.2009, 23:55 PingerWatch
API2
вместо условия
Код
if x then

напиши условие
Код
if x and Pingers[x] then
Артём, мамин_парень
27.10.2009, 16:23 Защита от DDoS атак
Защита в первую очередь
DDOS атаки бывают разными. Никогда нет 100% защиты от них.

На уровне скриптов вообще практически ничего сделать нельзя. Единственная защита на уровне скриптов - это антифлуд.

Методы борьбы с DDOS:
  1. Отключение ответов на ICMP запросы (пинги). Реализуется, например, при помощи файрвола.
  2. Увеличение очереди "полуоткрытых" TCP-соединений.
  3. Уменьшение времени удержания "полуоткрытых" соединений.
  4. Включение механизма TCP syncookies.
  5. Ограничение максимального числа "полуоткрытых" соединений с одного IP к конкретному порту.
  6. Установка лимита на количество соединений в единицу времени к DNS-серверу на стороне шлюза.


Nickolya, shur49
23.10.2009, 17:10 Скачивание файл-листа, nmdc
Последовательность команд
Последовательность такая:

Активное соединение:
Код
Клиент1 -> Хаб: $ConnectToMe Ник2 ip1:port1|
Хаб -> Клиент2: $ConnectToMe Ник2 ip1:port1|
Клиент2 -> Клиент1: $MyNick Ник2|
Клиент1 -> Клиент2: $MyNick Ник1|$Lock ...|
Клиент2 -> Клиент1: $Lock ...|
Клиент1 -> Клиент2: $Supports ...|$Direction Download Number1|$Key ...|
Клиент2 -> Клиент1: $Supports ...|$Direction Upload Number2|$Key ...|
Клиент1 -> Клиент2: $ADCGET ...|
Клиент2 -> Клиент1: $ADCSND ...|


Пассивное соединение:
Код
Клиент1 -> Хаб: $RevConnectToMe Ник1 Ник2|
Хаб -> Клиент2: $RevConnectToMe Ник1 Ник2|
Клиент2 -> Хаб: $ConnectToMe Ник1 ip2:port2|
Хаб -> Клиент1: $ConnectToMe Ник1 ip2:port2|
Клиент1 -> Клиент2: $MyNick Ник1|
Клиент2 -> Клиент1: $MyNick Ник2|$Lock ...|
Клиент1 -> Клиент2: $Lock ...|
Клиент2 -> Клиент1: $Supports ...|$Direction Download Number2|$Key ...|
Клиент1 -> Клиент2: $Supports ...|$Direction Upload Number1|$Key ...|$ADCGET ...|
Клиент2 -> Клиент1: $ADCSND ...|


Номерами помечены параметры, которые относятся к соответствующим клиентам.
Вместо команд $ADCGET и $ADCSND могут использоваться команды $Get и $Send. Всё зависит от поддерживаемых клиентами характеристик, которыми они обмениваются при помощи команды $Supports.

Подробнее о каждой команде читай тут: http://mydc.ru/index.html?showtopic=915
Saymon21
19.10.2009, 18:22 Скрипт смены группы пользователей
1. Закрываешь хаб.
2. Открываешь файл cfg/RegistredUsers.xml
3. Жмёшь Ctrl-H.
4. Заменяешь <Profile>2</Profile> на <Profile>3</Profile>
5. Запускаешь хаб.
19.10.2009, 12:13 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Нет. Не так. В простых случаях нужно использовать конкатенацию:
Код
local s = "блабла"..MoreBla()

В сложных случаях - метод format.

Рассмотрим случай:
Код
local s = "блабла"..MoreBla()

Итак, как работает конкатенация? Память выделяется под строку "блабла" и под результат функции MoreBla(). Эти значения будут занимать 2 ячейки в lua стеке. После конкатенации по адресу "блабла" запишется результат конкатенации, по во второй же ячейке стека останется мусор.
Если же к этому случаю мы применим метод формат: local s = ("блабла%s"):format(MoreBla()), то произойдёт следующее: сначала в стек отправится сам метод format, потом отправится первый его аргумент, то есть строка "блабла%s", потом отправится второй аргумент, то есть MoreBla(). После выполнения метода, результат выполнения запишется на верх стека. То есть стек будет выглядеть так: 1: "блаблаBLABLABLA", 2: "блабла%s", 3: "BLABLABLA". Получили, что глубина стека равна 3. В случае конкатенации глубина стека у нас была равна 2. (1: "блаблаBLABLABLA", 2: "BLABLABLA"). Поэтому при простой конкатенации метод формат проигрывает, так как выделяет больше памяти.

Рассмотрим случай:
Код
local a = 123
local b = 456
local s1 = "блабла"..a..b
local s2 = ("блабла%s%s"):format(a, b)


1) Содержимое стека при конкатенации: 1: "блабла", 2: "123", 3: "456"
2) Содержимое стека при формате: 1: FUNC, 2: "блабла%s%s", 3: "123", 4: "456"

Опять имеем проигрыш.

Случай:
Код
local a = 123
local b = 456
local s1 = "блабла"..a.."hihi"..b
local s2 = ("блабла%shihi%s"):format(a, b)


Тут я выписывать содержимое стека не буду, но скажу, что тут конкатенация и метод формат идентичны. Однако, дабы не делать лишний вызов, использовать лучше конкатенацию.

Ещё один пример:
Код
local a = 123
local b = 456
local s1 = "блабла"..a.."hihi"..b.."qwerty"
local s2 = ("блабла%shihi%sqwerty"):format(a, b)


Тут уже выигрывает метод формат.

Делаем вывод: метод формат выгодно использовать при конкатенации трёх и более временных строк (Временные строки: "блабла", "hihi", "qwerty")!


Вообще говоря, метод format - это урезанный аналог сишной функции sprintf (http://ru.wikipedia.org/wiki/Printf). Почему урезанный? Да потому, что форматы данных в lua не столь разнообразны как в СИ.
district
18.10.2009, 19:48 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Можно.
Это называется оптимизацией глобальных переменных. Почему переменных? Потому что в lua функция - это тип переменной. То есть переменной мы можем присвоить как строку или таблицу так и функцию. Например:
Код
local p = "str" -- инициализация переменной с присвоением ей строки
p = {} -- присвоение таблицы
p = 5 -- присвоение числа
p = function() return "fff" end -- присвоение функции


Например, у нас есть глобальная функция MyFunc, которая объявлена в файле 1.lua. Мы её вызываем из файла 2.lua.
В самом начале файла 2.lua мы прописываем строку
Код
local _G = _G
после этого вызываем нашу функцию, которая уже будет локальной:
Код
_G.MyFunc
Тут код local _G = _G означает создание локальный ссылки на глобальную таблицу глобального окружения. Переменная является локальной ссылкой на уже существующие данные.

Вообще говоря таким способом следует оптимизировать и такие функции:

Код
local tbl_maxn = table.maxn
local tbl_insert = table.insert
local math_sin = math.sin
local os_date = os.date
local os_execute = os.execute


и так далее... И вызываем уже, например, функцию tbl_insert(tTable, 5), а не table.insert(tTable, 5), как мы это обычно делаем.

Однако, например string.find таким образом оптимизировать не стоит, так как можно просто воспользоваться уже локальным методом: ("строка"):find(...). Метод уже локален. Единственную функцию из таблицы string, которую нужно оптимизировать это функцию string.char, так как к ней нельзя применить локальный метод.

Кстати говоря, функцию MyFunc можно оптимизировать и так:
Код
local MyFunc = _G.MyFunc
и именно эта оптимизация является максимальной, а не та, что рассмотрена в начале поста. Однако, оптимизировать таким образом каждую глобальную функцию слишком нудно, да и код сильно возрастает при большом количестве функций, поэтому обычно делают так как я описал в начале поста.
district
18.10.2009, 17:56 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Локальные функции и переменные используются для экономии памяти. Память освобождается после использования.
Говорить о том эффективно ли использовать локальную функцию, вообще говоря не корректно. Под разные задачи разное использование. Однако именно в языке lua обращение к локальным переменным и функциям происходит быстрее, чем к глобальным. Поэтому там, где это возможно, следует использовать локальные переменные.

Использовать оператор вместо функции всегда преимущественно. Поэтому ответ на второй вопрос: x%y.
district
16.10.2009, 18:12 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Код
Действия \\

лишний пробел!
Код
Действия\\
Gate001
14.10.2009, 11:29 У вас нет прав на просмотр этой темы
У вас нет прав на просмотр этого сообщения
district
8.10.2009, 20:28 Greeting_in_OpChat
API2 | Пришёл/ушёл для администрации в ОпЧате
Функцию Core.GetUserAllData(tUser) так и не убрал.

Могу сказать одно, разработчики хаба пытались снизить затраты на выполнения скриптов, однако, на мой взгляд, до конца не снизили их, и оставили в таблице часто используемые поля: sNick, sIP, iProfile, хотя для наилучшей оптимизации программист в скрипте сам должен выбирать какие необходимые поля должна содержать таблица.

Думаю должно быть так:
Код
local sOpChat = "[Chat]OpChat"
local tInMessages = {
  [0] = "Пришёл админ",
  [1] = "Пришёл оператор",
}

function UserConnected(tUser)
  if tInMessages[tUser.iProfile] then
    Core.SendPmToOps(sOpChat, ("%s %s;)"):format(tInMessages[tUser.iProfile], tUser.sNick))
  end
end

local tOutMessages = {
  [0] = "Ушёл админ",
  [1] = "Ушёл оператор",
}

function UserDisconnected(tUser)
  if tOutMessages[tUser.iProfile] then
    Core.SendPmToOps(sOpChat, ("%s %s;)"):format(tOutMessages[tUser.iProfile], tUser.sNick))
  end
end

OpConnected, RegConnected = UserConnected, UserConnected
OpDisconnected, RegDisconnected = UserDisconnected, UserDisconnected
X-Sky
8.10.2009, 18:53 Greeting_in_OpChat
API2 | Пришёл/ушёл для администрации в ОпЧате
Если придерживаешься Венгерской нотации, то переменные нужно писать соответствующим образом: sOpChat, tInMessages, tOutMessages

Интересно из какого скрипта пошла такая петрушка с обрамлением переменной пустыми строками: ""..OpChat.."" ?
Ведь тут не только 2 лишние конкатенации, но и пустые строки "" будут каждый раз выделять под себя память.
X-Sky
8.10.2009, 18:52 Greeting_in_OpChat
API2 | Пришёл/ушёл для администрации в ОпЧате
Когда пишешь скрипт, нужно понимать за что отвечает каждая функция. Нужно писать скрипты как можно более оптимизированными.
Функция Core.GetUserAllData(tUser) бестолку вызывается, при этом нагружая хаб не столько из-за вызова, сколько из-за занесения данных в таблицу tUser.

Переменные sInMes и sOutMes следует сделать локальными, а не глобальными.

Переменные OpChat, sInMessages и sOutMessages также следует снабдить словом local, так как локальные переменные вызываются быстрее, чем глобальные.
X-Sky, Unique
2.10.2009, 16:44 Репорты об ошибках старых версий
архив темы ошибок текущей версии хаба
Нет. Просто хаб скидывал часть народу big_smile.gif
Это исправлено и теперь я надеюсь будет всё ок и без вылетов.

Если вылетов не будет, то вплотную займусь доделыванием lua плагина big_smile.gif
zip2002
1.10.2009, 18:37 RusHub
Кроссплатформенный консольный DC хаб
rushub v 1.0.5c [beta]

Fixed: Исправлены падения, однако они ещё не исключены.
Nickolya, Invisible, ExC0tiC
26.9.2009, 20:08 RusHub
Кроссплатформенный консольный DC хаб
rushub v 1.0.5

Fixed: Увеличено максимальное число сокетов.
Nickolya, Invisible
25.9.2009, 23:18 Женюсь
Мои поздравления big_smile.gif
Дерево ещё не сажал?))
Otshelnik-Fm
16.9.2009, 20:06 RusHub
Кроссплатформенный консольный DC хаб
rushub v 1.0.4

Added: Включены логи действий хаба.
Added: Добавлена характеристика UserIP2.
Nickolya, Invisible, ExC0tiC
14.9.2009, 16:18 TEST
Тут скорее тестирование тэгов. Страницы не при чём big_smile.gif
LaLa
12.9.2009, 23:16 Не пускает другие версии DC++
Конечно есть. Но для этого нужно в файле ClientTags.xml перечислить клиенты, которые разрешены и в настройках установить запрет входа без тэга (если хаб не находит такой тэг в файле ClientTags.xml, то тэг не отделяется от описания и получается что клиент без тэга)
Delion
11.9.2009, 15:57 RusHub
Кроссплатформенный консольный DC хаб
rushub v 1.0.3 [beta]

Fixed: Исправлен баг с удалением пользователя с хаба, и добавлены следующие настройки:

sUnregNickPrefix - обязательный префикс для незарегистрированных
sNickChars - символы, которые разрешается использовать в нике
bHubTopicAfterMotd - посылать хаб-топик после MOTD
bCheckSRNick - проверять ник в $SR команде
iMinLimitSlotsRatio - минимально доступное отношение лимит/слоты
iMaxHubsSlotsRatio - максимально доступное отношение хабы/слоты
iMinDLLimit - минимально доступное ограничение скорости
iMaxSlots - максимальное число слотов
iMinSlots - минимальное число слотов
iMaxHubs - максимальное число хабов
iMinNickLen - минимальная длина ника
iMaxNickLen - максимальная длина ника

Для появления новых настроек нужно удалить старые файлы hub_config и lang_config
Nickolya, Invisible, ExC0tiC
8.9.2009, 17:01 SetMan.GetString
В мануалах есть абсолютно всё что нужно, и то, что ты написал в том числе.


Выдержка из scripting-interface.txt:
Цитата
Setting string IDs for SetMan.(G/S)etString (| is not allowed in all strings, if max length is not specified then is max 4096)
-------------------
0 - Hub name. Min length 1, max 256.
1 - Admin nick. Min length 1, max 64, $ is not allowed.
2 - Hub address. Min length 1, max 256.
3 - TCP ports. Min length 1, max 64.
4 - UDP port. Min length 1, max 5.
5 - Hub description. Max length 256.
6 - Main redirect address. Max length 256.
7 - Hublist register servers. Max length 1024.
8 - Registered users only message. Min length 1, max 256.
9 - Registered users only redirect address. Max length 256.
10 - Hub topic. Max length 256.
11 - Share limit message. Min length 1, max 256. Use %[min] for min share size and %[max] for max share size.
12 - Share limit redirect address. Max length 256.
13 - Slot limit message. Min length 1, max 256. Use %[min] for min slots and %[max] for max slots.
14 - Slot limit redirect address. Max length 256.
15 - Hub/slot ratio limit message. Min length 1, max 256. Use %[hubs] for hubs and %[slots] for slots.
16 - Hub/slot ratio limit redirect address. Max length 256.
17 - Max hubs limit message. Min length 1, max 256. Use %[hubs] for max hubs.
18 - Max hubs limit redirect address. Max length 256.
19 - No tag rule message. Min length 1, max 256.
20 - No tag rule redirect address. Max length 256.
21 - Hub bot nick. Min length 1, max 64, $ and space is not allowed.
22 - Hub bot description. Max length 64, $ is not allowed.
23 - Hub bot email. Max length 64, $ is not allowed.
24 - OpChat bot nick. Min length 1, max 64, $ and space is not allowed.
25 - OpChat bot description. Max length 64, $ is not allowed.
26 - OpChat bot email. Max length 64, $ is not allowed.
27 - Temp ban redirect address. Max length 256.
28 - Perm ban redirect address. Max length 256.
29 - Chat commands prefixes. Min length 1, max 5.
30 - Hub owner email. Max length 64.
31 - Nick limit message. Min length 1, max 256. Use %[min] for min length and %[max] for max length.
32 - Nick limit redirect address. Max length 256.
33 - Additional message to ban message. Max lenght 256.
34 - Language. When language is default then return nil.
Invisible
8.9.2009, 12:31 SetMan.GetString
Invisible
8.9.2009, 10:39 Предложения для развития
Цитата(Alexey @ 8.9.2009, 4:43) *
Хотелось-бы отправлять хабтопик после мотд, а не до.

А есть большая разница? Конечно можно сделать настройку.


Баны сейчас первостепенная задача, и в то же время большая, так как для того, чтобы сделать баны, нужно сделать права пользователям, то есть профили пользователей, и, соответственно, отсюда и регистрацию нужно реализовать. Я буду на этим работать big_smile.gif
Drakula, Sekretchik
7.9.2009, 20:57 RusHub
Кроссплатформенный консольный DC хаб
rushub v 1.0.2

Added: Сделаны основные настройки хаба. Они хранятся в файле.
Файлы настроек появляются после первого запуска хаба
Nickolya, Jaska, Invisible, mariner, ExC0tiC
6.9.2009, 22:12 Метод Быстрого Перевода Скриптов Под API_1
Самостоятельный быстрый перевод из API_2 ---> в API_1
Я добавил проверку и перезалил файл old_api.
Попробуй.
Invisible, thehawk
6.9.2009, 1:41 RusHub
Кроссплатформенный консольный DC хаб
rushub v 1.0.1

Added: Сделан поиск и некоторые проверки.
Nickolya, Invisible, ExC0tiC
3.9.2009, 16:40 Leviathan
API2
Если вы ничего не меняли в скрипте, то делаем следующее:
Открываем файл: LV_4.1FINAL/LV_DataBase/lua/Commands.lua

И ищем строку:
Код
disp = disp.."\tМинимальная шара: "..FriendlyTable[v][1]..""..FriendlyTable[v][2].."\tАдресс: "..FriendlyTable[v][3].."\tИмя Хаба: "..v.."\r\n"


У меня эта строка № 3023.

И меняем эту строку на:
Код
disp = disp.."\tМинимальная шара: "..FriendlyTable[v][1]..""..FriendlyTable[v][2].."\tАдресс: "..FriendlyTable[v][3].." \tИмя Хаба: "..v.."\r\n"
то есть добавляем пробел после адреса.
EdeN, nikolos
31.8.2009, 19:28 Скрипты
Ну это всё зависит от того, какие скрипты, и что они делают или не делают при входе.
А вообще, любой скрипт грузит хаб, и чем их больше, тем больше загружен хаб, и это может также аукнуться при входе.
ozonek
31.8.2009, 12:17 Leviathan
API2
Пробел впаять после порта
DriverZX-10
30.8.2009, 23:57 LFS
win32 - API 2 | Библиотека файловой системы
Данную библиотеку нужно скопировать либо в папку с ptokax.exe, либо в папку libs
А вставлять нужно в начале скрипта, который нуждается в этой библиотеке.

По поводу PXControl следует задавать вопросы в соответствующей теме!
Invisible, DriverZX-10
28.8.2009, 21:12 Соедиенение Пользователей Инет + Локальная Сеть
Как соединить с лок. адреса с включ. VPN с юзерами из инета?
Ищи на форуме скрипт разделения сетей
Noal
28.8.2009, 13:37 RusHub
Кроссплатформенный консольный DC хаб
Название: RusHub
Текущая версия: 2.3.10
Платформы: Windows (XP/Vista/7), GNU Linux, FreeBSD, Mac OS X, Solaris
Разрядность: 32, 64
Лицензия: GPL v3
Основан на: verlihub
SourceForge: RusHub Source Forge Page
GoogleCode: RusHub Google Code Page
Официальный сайт: RusHub.org

Полная поддержка и использование протокола NMDC.
Хаб поддерживает работу с ipv6.
Хаб поддерживает ADC протокол (тестирование).
Хаб постоянно совершенствуется и развивается.


Описание настроек хаба
sAddresses - адреса хаба (указываются через пробел)
bAdcOn - включить режим работы хаба по протоколу ADC
sHubName - имя хаба
sTopic - топик хаба (приписка к имени хаба)
sHubBot - ник основного бота хаба.
sLocale - языковая локаль. По умолчанию устанавливается локаль системы (для России устанавливаем Russian_Russia.1251)
bSendUserIp - отсылать ip адреса пользователей, то есть использовать ли характеристики UserIP и UserIP2 (1 - да, 0 - нет).
bDelayedMyINFO - отсылать команды $MyINFO и $Quit с задержкой. Из-за отсутствия пока задержки входа рекомендуется установить этот параметр в 0.
bCheckSRNick - проверять ник в $SR команде.
bCheckRctmNick - проверять ли ник в RCTM команде (1 - проверять, 0 - не проверять).
bCheckCTMIp - проверять ip в CTM команде
bCheckSearchIp - проверять ip при активном поиске
bDelayedLogin - записывать пользователя только после полной отсылки ему списка всех пользователей (на больших хабах список всех пользователей может не отправиться за один раз, поэтому для таких хабов рекомендуется включить эту опцию).
bNicklistOnLogin - при входе на хаб отправлять список всех пользователей во время записи пользователя, а не по команде $GetNickList.
iTimeoutAny - время на получение от пользователя какой-либо команды (таймаут соединения)
iTimeoutLogon - максимальное время входа на хаб (в сек.).
iMaxPassiveRes - количество возвращаемых хабом результатов при пассивном поиске.
iTimerConnPeriod - период таймера соединения в мсек. (системная настройка, не рекомендуется изменять).
iTimerServPeriod - период таймера сервера в мсек. (системная настройка, не рекомендуется изменять).
iStepDelay - задержка в мсек на каждом цикле (системная настройка, не рекомендуется изменять).
iStrSizeMax - максимальная длина команды, отправленной на хаб пользователем.
iStartPing - время начала пинга пользователя в сек (отсчитывается от момента входа на хаб).
iPingInterval - период, через который пингуется пользователь.
iMaxLevel - уровень логирования событий хаба (от 0 до 6). По умолчанию 0 - не логировать события.
iMaxErrLevel - уровень логирования ошибок хаба (от 0 до 2). По умолчанию 2 - логировать все ошибки.
iSysLoading - коэффициент загруженности системы (системная настройка, не рекомендуется изменять).
iMaxNickLen - максимальная длина ника (проверяется только у пользователей с профилем -1).
iMinNickLen - минимальная длина ника (проверяется только у пользователей с профилем -1).
bDisableNoDCCmd - запретить использование команд, которые не относятся к NMDC командам (не начинаются со знака $, за исключением команды пинга и команды чата).
iFloodTime... и iFloodCount... - параметры флуда (количество iFloodCount за время iFloodTime (в сек.))
bRegMainBot - регистрировать основного бота.
bMainBotKey - ключ у основного бота.
sMainBotMyINFO - MyINFO основного бота.
sMainBotIP - ip основного бота.
bWebServer - включить веб-сервер (по умолчанию отключен).
sWebAddresses - адреса веб сервера (указываются через пробел). Через ; можно указывать порт.
iWebTimeout - тайм-аут соединения с веб сервером (в сек.). Время бездействия, по истечению которого веб-сервер закрывает соединение с клиентом.
iWebStrSizeMax - максимальный размер сообщения отсылаемого клиентом.
bMAC - включить определение MAC адреса (по умолчанию отключено).
iUsersLimit - глобальное ограничение числа пользователей (по умолчанию -1 - проверка отключена)
bUDPServer - включить udp сервер (1 - включить, 0 - отключить)
sUDPAddresses - udp адреса хаба
sMainPath - основная директория хаба
sPluginPath - директория плагинов
sLogPath - директория логов
sLangPath - директория языковых настроек
sLang - текущая языковая настройка (имя файла без расширения)
iMaxSendSize - настройка, отвечающая за максимальный размер буфера отсылки (по умолчанию 2818047). При превышении этого размера пользователь отключается от хаба.

Lua plugin:
LUA API события

UID - идентификатор пользователя, который отослал команду.
UID представляет из себя указатель на реальную структуру соединения пользователя (type(UID) = "userdata"). Введён с целью оптимизации выбора пользователя без нагрузки lua стека.

OnStartup()
Описание: Функция выполняется при старте скрипта.
Возвращаемое значение: любое



OnExit()
Описание: Функция выполняется при остановке скрипта
Возвращаемое значение: любое



OnError(sErrMsg)
Описание: Функция выполняется при ошибке в скрипте
Возвращаемое значение: true или 1 - не останавливать скрипт при ошибке во время выполнения
Исключения составляют таймерные функции, которые останавливают скрипт при ошибке, дабы не загружать систему и не прийти к переполнению лога



OnScriptError(sScriptName, sErrMsg, bStoped)
Описание: Функция выполняется при возникновении ошибки в скрипте sScriptName. sErrMsg - сообщение с ошибкой. Флаг bStoped равен true если скрипт, в котором возникла ошибка, был остановлен, в противном случае флаг bStoped равен false.
Функция не вызывается для текущего скрипта. Для отслеживания ошибок в текущем скрипте нужно использовать функцию OnError(sErrMsg).
Напомню, что по умолчанию скрипт отключается при ошибке, отключение скрипта можно предотвратить возвратом true в функции OnError этого скрипта.
Возвращаемое значение: true или 1 - не вызывать это событие в ниже стоящих скриптах (т.е. прекращение действия события).



OnScriptStart(sScriptName)
Описание: Функция выполняется при старте скрипта sScriptName.
Возвращаемое значение: true или 1 - не вызывать это событие в ниже стоящих скриптах (т.е. прекращение действия события).



OnScriptStop(sScriptName)
Описание: Функция выполняется при остановке скрипта sScriptName.
Возвращаемое значение: true или 1 - не вызывать это событие в ниже стоящих скриптах (т.е. прекращение действия события).



OnUserConnected(UID)
Описание: Функция выполняется при входе пользователя.
Функция выполняется после отправки пользователю первичной команды $Lock и до любого другого действия на хабе.
На данном этапе определён только IP адрес, порт и мак пользователя.
Возвращаемое значение: true или 1 - не отправлять при входе надпись: "Этот хаб работает под управлением..."



OnUserDisconnected(UID)
Описание: Функция выполняется после закрытия соедиения с пользователем.
Функция является последней функцией перед окончательным удалением соединения.
На данном этапе определён только IP адрес, порт и мак пользователя, все остальные данные уже удалены.
Возвращаемое значение: любое



OnUserEnter(UID)
Описание: Функция выполняется при окончательном входе пользователя, после добавления пользователя в списки.
Функция является последним этапом входа на хаб.
Возвращаемое значение: любое


OnUserExit(UID)
Описание: Функция выполняется при выходе пользователя, перед удаление пользователя из списков.
Функция является первым этапом выхода.
Возвращаемое значение: любое



OnSupports(UID, sData)
Описание: Функция выполняется при обмене характеристиками между клиентом и сервером.
Функция не будет выполняться, если клиент не поддерживает никаких дополнений и характеристик.
Возвращаемое значение: true или 1 - не отправлять характеристики хаба клиенту.



OnKey(UID, sData)
Описание: Функция выполняется при получении ключа от клиента.
Возвращаемое значение: true или 1 - проверять ключ.



OnValidateNick(UID, sData)
Описание: Функция выполняется после проверки ника и до проверки необходимости пароля. Ник пользователя уже определён.
Возвращаемое значение: true или 1 - отправить запрос на получение пароля.
Позволяет проводить регистрацию по средствам скриптов.



OnMyPass(UID, sData)
Описание: Функция выполняется после поступления на хаб пароля от пользователя.
Возвращаемое значение: true или 1 - вход оператора (отправка команды $LogedIn).



OnVersion(UID, sData)
Описание: Функция выполняется после поступления на хаб версии протокола.
Возвращаемое значение: true или 1 - проверять равенство версии 1,0091.



OnGetNickList(UID, sData)
Описание: Функция выполняется до отсылки списка пользователей.
Возвращаемое значение: true или 1 - не отсылать список.



OnMyINFO(UID, sData)
Описание: Функция выполняется при отправке на хаб MyINFO строки.
Функция выполняется после всех проверок параметров и до рассылки всем пользователям.
Возвращаемое значение (игнорируется при первой отправке, а работает только при последующих):
1) return false, return nil, return 0 - безусловное выполнение события
2) return true, return 1 - блокировка события
3) return 2 - выполнеие события и блокировка после обхода всех скриптов
4) return 3 - выполнение публичного события для всех соединений, кроме соединения, породившего это событие
5) return 4 - выполнение публичного события для всех соединений, кроме соединений, имеющих такой же ip адрес, что и соединение, породившее это событие
Примечание: Возвращаемое значение игнорируется при первой отправке на хаб MyINFO строки, так как в случае блокировки события пользователь будет скрыт (возможно эту политику следует пересмотреть (опустить) в дальнейшем).


OnChat(UID, sData)
Описание: Функция выполняется при отправке в чат сообщения пользователем.
Функция выполняется после всех проверок и до отправки.
Возвращаемое значение:
1) return false, return nil, return 0 - безусловное выполнение события
2) return true, return 1 - блокировка события
3) return 2 - выполнеие события и блокировка после обхода всех скриптов
4) return 3 - выполнение публичного события для всех соединений, кроме соединения, породившего это событие
5) return 4 - выполнение публичного события для всех соединений, кроме соединений, имеющих такой же ip адрес, что и соединение, породившее это событие



OnTo(UID, sData)
Описание: Функция выполняется при отправке в сообщения приват.
Функция выполняется после всех проверок и до отправки.
Возвращаемое значение: true или 1 - не отсылать сообщение.



OnConnectToMe(UID, sData)
Описание: Функция выполняется при попытке активного соединения.
Функция выполняется после всех проверок и до отправки.
Возвращаемое значение: true или 1 - не соединять пользователей.



OnRevConnectToMe(UID, sData)
Описание: Функция выполняется при попытке пассивного соединения.
Функция выполняется после всех проверок и до отправки.
Возвращаемое значение: true или 1 - не соединять пользователей.



OnSearch(UID, sData)
Описание: Функция выполняется при поиске.
Функция выполняется после всех проверок и до отправки.
Возвращаемое значение:
1) return false, return nil, return 0 - безусловное выполнение события
2) return true, return 1 - блокировка события
3) return 2 - выполнеие события и блокировка после обхода всех скриптов
4) return 3 - выполнение публичного события для всех соединений, кроме соединения, породившего это событие
5) return 4 - выполнение публичного события для всех соединений, кроме соединений, имеющих такой же ip адрес, что и соединение, породившее это событие



OnSR(UID, sData)
Описание: Функция выполняется при поступлении на хаб результатов пассивного поиска.
Функция выполняется после всех проверок и до отправки.
Возвращаемое значение: true или 1 - блокировать результаты поиска.



OnAny(UID, sData, iType)
Описание: Функция выполняется при поступлении на хаб любой команды.
Возвращаемое значение: true или 1 - блокировать команду.



OnUnknown(UID, sData)
Описание: Функция выполняется при поступлении на хаб любой не известной команды.
Возвращаемое значение: true или 1 - не блокировать команду.



OnKick(UID, sData)
Описание: Функция выполняется при поступлении на хаб команды кика.
Возвращаемое значение: любое.



OnOpForceMove(UID, sData)
Описание: Функция выполняется при поступлении на хаб команды перенаправления.
Возвращаемое значение: любое.



OnGetINFO(UID, sData)
Описание: Функция выполняется при поступлении на хаб команды $GetINFO.
Возвращаемое значение: true или 1 - не отсылать пользователю MyINFO запрошенного пользователя.



OnFlood(UID, iType, iNum)
Описание: Функция выполняется при обнаружении флуда со стороны пользователя. Может служить для устаноки бана за флуд или для разрешения флуда ОПераторам хаба. Параметр iType указывает тип команды, которой флудили. Параметр iNum указывает номер срабатываемого флуда 1 или 2 (см. настройки флуда).
Возвращаемое значение: true или 1 - не отключать пользователя.



OnWebData(WebID, sData)
Описание: Функция выполняется при поступлении данных на веб-сервер.
Возвращаемое значение: true или 1 - не разъединять пользователя по окончанию работы данного события.



OnConfigChange(sName, sValue)
Описание: Функция выполняется при изменении настройки. Параметр sName - название измененной настройки, sValue - новое значение настройки
Возвращаемое значение: любое.
Событие срабатывает только после изменения настройки при помощи объекта Config.



OnMCTo(UID, sData)
Описание: Функция выполняется при отправке приватного сообщения в чат.
Функция выполняется после всех проверок и до отправки.
Возвращаемое значение: true или 1 - не отсылать сообщение.
LUA API функции

Core.SendToAll(sData, sNick, sFrom)
Описание: Функция отправляет данные sData всем пользователям, которые находятся на хабе.
Если указан параметр sNick, то сообщение sData отправляется в чат от ника sNick.
Если указаны параметры sNick и sFrom, то сообщение sData отправляется в приват от отправителя sFrom с ником sNick.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.SendToUser(UID/sToNick/tNicks, sData, sNick, sFrom)
Описание: Функция отправляет данные sData пользователю с идентификатором UID (User ID) или с ником sToNick или таблице ников tNicks.
Если указан параметр sNick, то сообщение sData отправляется в чат от ника sNick.
Если указаны параметры sNick и sFrom, то сообщение sData отправляется в приват от отправителя sFrom с ником sNick.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.SendToAllExceptNicks(tExcept, sData, sNick, sFrom)
Описание: Функция отправляет данные sData всем пользователям, которые находятся на хабе, кроме пользователей, ники которых указаны в таблице tExcept, если таковые находится на хабе.
Если указан параметр sNick, то сообщение sData отправляется в чат от ника sNick.
Если указаны параметры sNick и sFrom, то сообщение sData отправляется в приват от отправителя sFrom с ником sNick.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.SendToProfile(iProfile/tProfiles, sData, sNick, sFrom)
Описание: Функция отправляет данные sData профилю/профилям. Если в первом аргументе функции указано число, то данные отправляются указанному профилю, если в первом аргументе указана таблица, то данные отправляются профилям, которые указаны в этой таблице.
Если указан параметр sNick, то сообщение sData отправляется в чат от ника sNick.
Если указаны параметры sNick и sFrom, то сообщение sData отправляется в приват от отправителя sFrom с ником sNick.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.SendToNicks(tNicks, sData, sNick, sFrom)
Описание: Функция отправляет данные sData всем пользователям, ники которых указаны в таблице tNicks, если таковые находится на хабе.
Если указан параметр sNick, то сообщение sData отправляется в чат от ника sNick.
Если указаны параметры sNick и sFrom, то сообщение sData отправляется в приват от отправителя sFrom с ником sNick.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.
Функция устарела. Используйте вместо неё функцию Core.SendToUser(tNicks, sData, sNick, sFrom)


Core.GetUser(UID/sNick, iByte)
Описание: Функция возвращает UID пользователя по нику sNick.


Core.SetUser(UID/sNick, iType, Value)
Описание: Функция устанавливает значение Value для данных типа iType для пользователя с ником sNick.
Описание типов данных iType:
1 - профиль (iProfile)
2 - MyINFO строка (sMyINFO)
3 - пользовательские данные (sData)
4 - пользователь в оп-листе, то есть имеет ключик (bInOpList)
5 - пользователь скрыт в ник-листе (bHide)
6 - пользователь в ip-листе, то есть ему отсылаются ip адреса всх пользователей (bInIpList)

Функция устарела. Используйте вместо неё прямую установку параметров: UID[sName] = Value или Core.GetUser(sNick)[sName] = Value, где sName - это одна из строк: "iProfile", "sMyINFO", "sData" и тд.


Core.GetUsersCount()
Описание: Функция возвращает текущее количество онлайн пользователей.


Core.GetTotalShare()
Описание: Функция возвращает текущую суммарную шару всех пользователей хаба.


Core.Disconnect(UID/sNick)
Описание: Функция отключает пользователя по идентификатору UID, или по нику sNick.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.DisconnectIP(sIP, iProfile/tProfiles)
Описание: Функция отключает всех пользователей с указанным IP.
Если указан профиль/таблица с профилями iProfile/tProfiles, то отключаются только пользователи с указанным профилем/профилями.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.RestartScripts(iType)
Описание: Функция перезапускает все скрипты. Если параметр iType отсутствует, равен nil или равен 0, то перезагружаются все скрипты без исключения. Если параметр iType равен 1, то перезагружаются все скрипты, кроме работающих на данный момент. Если параметр iType равен 2, то перезагружаются все скрипты, кроме текущего скрипта (из которого была вызвана данная функция).
Возвращает true.


Core.RestartScript(sScriptName)
Описание: Функция перезапускает скрипт с именем sScriptName. Если параметр sScriptName отсутствует или равен nil, то функция перезапускает текущий скрипт.
Возвращает true в случае успеха, nil в случае неудачи, nil и сообщение об ошибке в случае синтаксической ошибки.


Core.StopScript(sScriptName)
Описание: Функция останавливает скрипт с именем sScriptName. Если параметр sScriptName отсутствует или равен nil, то функция останавливает текущий скрипт.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.StartScript(sScriptName)
Описание: Функция запускает скрипт с именем sScriptName.
Возвращает true в случае успеха, nil в случае неудачи, nil и сообщение об ошибке в случае синтаксической ошибки.


Core.MoveUpScript(sScriptName)
Описание: Функция поднимает скрипт с именем sScriptName в дереве выполнения.
Если параметр не указан, то поднимается текущий скрипт.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.MoveDownScript(sScriptName)
Описание: Функция опускает скрипт с именем sScriptName в дереве выполнения.
Если параметр не указан, то опускается текущий скрипт.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.GetScripts()
Описание: Функция возвращает таблицу со скриптами как таблицы с полями sName, bEnabled, iMemUsage.


Core.GetScript(sScriptName)
Описание: Функция возвращает таблицу со скриптом таблицу с полями sName, bEnabled, iMemUsage.
Если имя не указано, то возвращается таблица текущего скрипта.


Core.GetGVal(sScriptName, sParam)
Описание: Функция возвращает значение глобальной переменной с именем sParam скрипта sScriptName.
Функция работает только с переменными типов: string, number, boolean, lightuserdata и table, для остальных типов будет возвращать nil.
Возвращает значение в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.SetGVal(sScriptName, sParam, Value)
Описание: Функция устанавливает значение глобальной переменной с именем sParam скрипта sScriptName.
Функция работает только с переменными типов: string, number, boolean, lightuserdata и table.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.SetCmd(sData)
Описание: Функция устанавливает новую команду для функций последующих скриптов.
Устанавливаемая команда должна быть синтаксически правильной, то есть соответствовать по синтаксису команде текущего события (API функции события). В противном случае функция не изменит команду и вернёт nil и соответствующее сообщение.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.GetUsers(sIP, bAll)
Описание: При отсутствии аргументов функция возвращает таблицу со всеми уже полностью вошедшими на хаб пользователями (с UID-ми всех вошедших пользователей хаба).
Core.GetUsers(true) - таблица со всеми пользователями хаба, даже которые только входят и ещё не вошли.
Core.GetUsers(sIP) - таблица с UID'ми вошедших пользователей с указанным IP
Core.GetUsers(sIP, true) - таблица со всеми пользователями с указанным IP.


Core.AddTimer(iId, iInterval, sFunc)
Описание: Функция добавляет таймер с идентификатором iId и интервалом срабатывания iInterval (в мсек). Если указано имя глобальной функции sFunc, то эта функция и будет выполняться, если имя функции не указано, то скрипт ищет глобальную функцию OnTimer (в параметр функции передаётся идентификатор). Идентификатор может повторяться.
Возвращает количество зарегистрированных таймеров с таким iId в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.DelTimer(iId)
Описание: Функция удаляет таймер по идентификатору iId.
Идентификатор может повторяться, однако, удаляется таймер по идентификатору, поэтому удалятся все таймеры с указанным идентификатором. Удаляются таймеры только текущего скрипта! Таймеры с таким же идентификатором других скриптов не удаляются!
Возвращает количество удалённых таймеров в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.GetUpTime()
Описание: Функция возвращает время работы хаба (в сек.)


Core.GetConfig(sName)
Описание: Функция возвращает настройку хаба sName. Какого бы типа не была настройка, всегда возвращается строковый тип.
В случае неудачи возвращает nil и сообщение об ошибке.
Функция устарела. Используйте вместо неё объект: Config[sName]


Core.SetConfig(sName, sValue)
Описание: Функция устанавливает настройку хаба sName в значение sValue.
Однако, исключения составляют настройки sHubIP, iMainPort, sSubPorts, которые нельзя изменить.
При изменении настройки sHubName или sTopic отправляется соответствующая команда. После изменения, настройки сохраняются.
При изменении sHubBot и/или bRegMainBot - автоматически перерегистрируется бот.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.
Функция устарела. Используйте вместо неё прямую установку параметров: Config[sName] = sValue


Core.GetLang(sName)
Описание: Функция возвращает "языковую" настройку sName.
В случае неудачи возвращает nil и сообщение об ошибке.


Core.SetLang(sName, sValue)
Описание: Функция устанавливает "языковую" настройку хаба sName в значение sValue.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.Call(sScriptName, sFunc, ...)
Описание: Функция вызывает функцию sFunc другого скрипта sScriptName с параметрами, которые указываются в аргументе 3, 4 и тд.
Параметры функции и возвращаемые значения функции могут быть только следующих типов: string, number, boolean, table и userlightdata.
Функция Core.Call возвращает все те значения, которые возвращает функция sFunc скрипта sScriptName.
В случае ошибки функция возвращает nil и сообщение об ошибке.


Core.SendToAllExceptIPs(tExcept, sData, sNick, sFrom)
Описание: Функция отправляет сообщение всем пользователям, за исключением пользователей с ip адресами, которые указаны в таблице tExcept.
Если указан параметр sNick, то сообщение sData отправляется в чат от ника sNick.
Если указаны параметры sNick и sFrom, то сообщение sData отправляется в приват от отправителя sFrom с ником sNick.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.SendToIP(sIP, sData, sNick, sFrom, iProfile/tProfiles)
Описание: Функция отправляет сообщение sData всем пользователям с указанным IP адресом sIP.
Если указан параметр sNick, то сообщение sData отправляется в чат от ника sNick.
Если указаны параметры sNick и sFrom, то сообщение sData отправляется в приват от отправителя sFrom с ником sNick.
Если указан профиль/таблица с профилями iProfile/tProfiles, то сообщение отправляется только указанным профилям с данным IP адресом.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.RegBot(sNick, bKey, sMyINFO, sIP)
Описание: Функция регистрирует бота с ником sNick. Если bKey равен true, то бот регистрируется с ключиком. sMyINFO - это часть MyINFO строки (часть после ника, начиная с описания и до конца MyINFO). sIP - возможный ip адрес для бота. Обязательным параметром является только первый параметр - sNick.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.UnregBot(sNick)
Описание: Функция удаляет регистрацию бота с ником sNick из списка.
Возвращает true в случае успеха, nil и сообщение об ошибке в случае неудачи.


Core.SetHubState(iNum)
Описание: Функция устанавливает состояние хаба.
iNum = nil или iNum = 0 - остановка хаба. iNum = 1 - рестарт хаба. Остальные значения заразервированы на будущее


Core.Redirect(UID/sNick, sAddress[, sReason])
Описание: Перенаправляет пользователя на адрес sAddress с причиной sReason. Причину указывать не обязательно.
Возвращает true в случае успеха, nil и сообщение с ошибкой - в случае неудачи


Config - объект конфигурационных настроек хаба
Config.table() - таблица с названиями всех возможных настроек хаба
Core.sMainDir - основной путь, по которому располагается хаб
Core.sScriptsDir - абсолютный путь, по которому располагается директория скриптов
Core.sHubVersion - название и версия хаба
Core.sLuaPluginVersion - название и версия плагина
Core.sSystem - название и версия ОС
_TRACEBACK = debug.traceback - способ включить stack trace для скрипта
Параметры пользователя
UID.sNick - ник
UID.sIP - ip
UID.iProfile - профиль
UID.bInOpList - пользователь в оп-листе, то есть имеет ключик
UID.bInIpList - пользователь в ip-листе, то есть ему отсылаются ip адреса всех пользователей
UID.bInUserList - пользователь полностью вошёл и добавлен в список пользователей
UID.bHide - пользователь скрыт в ник-листе
UID.iPort - порт хаба
UID.iPortConn - порт соединения
UID.sMacAddress - мак адрес
UID.sVersion - версия протокола
UID.sData - вспомогательное текстовое поле для различных нужд
UID.UID - UID юзера (lightuserdate)
UID.sSupports - параметр $Suppurts команды
UID.sMyINFO - MyINFO строка
UID.sDesc - описание
UID.sTag - тэг
UID.sClientName - название клиента
UID.sClientVersion - версия клиента
UID.sMode - режим
UID.iUsHubs - обычные хабы
UID.iRegHubs - рег хабы
UID.iOpHubs - оп хабы
UID.iSlots - слоты
UID.iLimit - ограничитель скорости скачивания с пользователя (L:x)
UID.iOpen - открытые экстра слоты (O:x)
UID.iBandwidth - ограничитель скорости скачивания с пользователя (B:x)
UID.iDownload - ограничитель скорости скачивания пользователем (D:x)
UID.sFraction - ограничитель скорости скачивания пользователем/с пользователя (F:x/y)
UID.sConn - соединение
UID.iByte - магический байт
UID.sEmail - email
UID.iShare - шара в байтах
UID.iEnterTime - время входа на хаб (время отсылки на хаб команды $Key)
UID.sIPConn - ip адрес (хост) хаба, на который был принят пользователь
UID.bKick - способность ОПератора к кику
UID.bRedirect - способность ОПератора к перенаправлению




Текущая версия:
[attachment=6486:rushub_2...10_win32.rar][attachment=6485:rushub_2...10_win64.rar]

Lua плагин:
[attachment=6490:lua_plug....9_win32.rar][attachment=6489:lua_plug....9_win64.rar]

Pdb файлы:
[attachment=6488:rushub_2...db_win32.rar][attachment=6487:rushub_2...db_win64.rar]
[attachment=6492:lua_plug...db_win32.rar][attachment=6491:lua_plug...db_win64.rar]

Исходники можно скачать с: SourceForge
SVN: https://rushub.svn.sourceforge.net/svnroot/rushub/trunk/
Nickolya, BIMMER71, Jaska, intlive, Wariner, DEL, FallenAngel, Invisible, mariner, fixx, Ksan, Serx, Артём, serrrios, ShadoWx, Maximum, Otshelnik-Fm, Vizunchik, Accelerator, Karumo, PomanoB, -=Alexandr=-, Infinity_Love, alex82, ExC0tiC, rival, KT315, Drakula, Alexey, Phazeus, Andrew Frost, BeN, Kingston, Sekretchik, CrazyKiller, Saymon21, hondas, Dimon21, X-Sky, TiGRpp, KamoK, ART8150, lewonchik, LOPD, andromed, Alexey5176, -=FugeN=- 2, SKIFI, stone, Egerj1, ke(x)one, AltSide, Jarkrait, arktik, Mangust, kma21
27.8.2009, 1:07 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Во-первых, переменные, которые возвращаются функцией string.find, либо все равны nil, либо все не равны nil. Поэтому нет смысла делать лишние проверки.

Во-вторых, на конце каждого сообщения присутствует символ |, который в NMDC протоколе разделяет команды друг от друга. Поэтому в переменную nNik запишется ник + символ |, соответственно такой изменённый ник запишется в таблицу nicker и при отсылке в чат будет работать как разделитель команд, то есть разобьёт нашу команду чата на две команды чата))

После всего сказанного получаем:
Код
message = message:sub(1, -2)
s,e,cmd,oNik,nNik= string.find(message,"%b<>%s(.+)%s(.+)%s(.+)")
if cmd == "!nickchange" then
  nicker[oNik]=nNik
end

s,e,mes = string.find(message, "%b<>%s(.*)")
if nicker[curUser.sNick] ~= nil then
  Core.SendToAll("<"..nicker[curUser.sNick].."> "..mes)
  return true
end
Akafellas
26.8.2009, 20:07 Реализация NMDC команды $MCTo
дабы не затерялось
Да, действительно. Про галочку в клиенте я совсем забыл упомянуть.

Скрипты равносильны и никто не проигрывает и не выигрывает.
Выигрыш будет, если данная команда реализована в протоколе, а не при помощи скрипта.

В отличии от указанного скрипта (сказать шёпотом), данная команда устроена так, что жертва не знает о том, что именно ему пришло сообщение, а считает, что это общее сообщение чата. Поэтому всем окружающим будет казаться, что он разговаривает сам с собой. Очень весело получается)))
Serx
26.8.2009, 17:19 Реализация NMDC команды $MCTo
дабы не затерялось
Расширяем протокол. А именно, добавляем дополнительные возможности: http://mydc.ru/index.html?showtopic=915&am...post&p=6917
Данная команда NMDC протокола работает как встроенная характеристика на YnHub-е.
На поддержку хабом этой команды указывает характеристика MCTo в команде $Supports.

Скриптовая реализация этой NMDC команды в PtokaX:

Код
function UnknownArrival(tUser, sData)
  local to, n, m = sData:match"%$MCTo: (%S+) %$(%S+) (.+)|$"
  if to and n == tUser.sNick then
    Core.SendToNick(to, "<"..n.."> "..m)
    Core.SendToUser(tUser, "<"..n.."> "..m)
    return true
  end
end


Для использования команды в настройках клиента нужно создать менюшку.
Заходим Файл > Настройки > Команды юзера > Добавить
Тип команды: RAW
Контекст: Меню юзера
Название: Сообщение этому юзеру в чат
Команда: $MCTo: %[userNI] $%[myNI] %[line:Сообщение]|

Или же менюшку можно создать средствами хаба:
Код
function UserConnected(tUser)
  Core.SendToUser(tUser, "$UserCommand 1 2 Сообщение этому юзеру в чат$$MCTo: %[nick] $%[mynick] %[line:Сообщение]&#124;")
end
RegConnected, OpConnected = UserConnected, UserConnected
Delion
26.8.2009, 12:49 Informer
API1, API2 | Скрипт рассылки сообщений
Просто человек впервые работает с ptokax и мало ещё что знает.

Скрипты - это файлы с расширениями .lua
Для запуска, файлы с таким расширением должны быть помещены в папку scripts.

scripts/InformEr_1.02/InformEr.lua ---> это неправильно!
scripts/InformEr.lua ---> это правильно!
DriverZX-10
17.8.2009, 11:16 состояние хабов
удалённое отображение информации
Ты что же предлагаешь изменить протокол? Ведь пингером нельзя вытащить такую инфу, которую ты хочешь. И вообще зачем переделывать какой-то клиент, когда нужно просто взять (или написать) пингер.

Пингер максимум может вытащить следующую инфу:
  • Имя хаба
  • Адрес хаба
  • Описание хаба
  • Макс. юзеров
  • Мин. шара при входе
  • Мин. слотов при входе
  • Макс. хабов при входе
  • Тип хаба
  • Владелец хаба


А то, что ты предлагаешь нуждается в дополнительных протокольных командах, кроме этого хаб должен будет сам отслеживать предлагаемую статистику.

В общем разговор на пустом месте. Как говориться мечтать не вредно)))
степашка
16.8.2009, 23:11 Sau_script
хелп-исправить ошибку...
Только без оффтопа плз!
Uncle_Dif
14.8.2009, 17:01 NoDescAdv
API2 | Удаление рекламы из описания юзеров
Ошибка не так переводится. А возникает ошибка из-за того, что нельзя бездумно вписывать антирекламные фразы. Некоторые символы нуждаются в экранировании:
Код
d%]c%]h%]u%]b


Подробнее о символах, нуждающихся в экранировании: http://mydc.ru/topic266.html
Sunshine-hub
14.8.2009, 16:45 Описание Протокола NMDC
NeoModus Direct Connect Protocol
ZLine

Описание:

Характеристика хаба/клиента.
Характеристика указывает на поддержку команды сжатия $Z.
14.8.2009, 16:37 Описание Протокола NMDC
NeoModus Direct Connect Protocol
UserIP2

Описание:

Характеристика хаба/клиента.
Указывает на то, что хабом (клиентом) поддерживается вторая версия команды $UserIP.
Вторая версия отличается от первой тем, что входящему на хаб пользователю всегда отсылается команда $UserIP с его ником и ip адресом. Ip адреса остальных же пользователей отсылаются в зависимости от статуса пользователя на хабе.

Характеристика поддерживается DC++ клиентами, начиная с версии 0.305.
14.8.2009, 16:21 Описание Протокола NMDC
NeoModus Direct Connect Protocol
UserCommand

Описание:

Характеристика хаба/клиента.
Данная характеристика указывает на поддержку со стороны хаба или клиента команды $UserCommand, которая позволяет клиенту создавать контекстные менюшки. Наличие этой характеристики в команде $Supports является не обязательным из-за большой распространённости команды.

Характеристика поддерживается клиентами DC++, начиная с версии 0.300.
14.8.2009, 16:09 Описание Протокола NMDC
NeoModus Direct Connect Protocol
TTHSearch

Описание:

Характеристика клиента.
Эта характеристика указывает на то, что клиент поддерживает поиск файлов по уникальному идентификатору TTH. Поиск по TTH является наиболее эффективным. Для получения большей информации по поиску смотрите описание команды $Search.

Характеристика поддерживается клиентами DC++, начиная с версии 0.307.
14.8.2009, 16:06 Описание Протокола NMDC
NeoModus Direct Connect Protocol
QuickList

Описание:

Характеристика хаба/клиента.
Позволяет быстро входить на хаб, экономя трафик и снижая нагрузку на сервер при входе.


Сравнение последовательностей входов с и без характеристики QuickList:

Обозначения:
H - хаб
C - клиент

С характеристикой QuickList
Код
H: $Lock EXTENDEDPROTOCOL[Код] Pk=[PrimaryKey]|
C: $Supports NoHello QuickList|
C: $Key [Рассчитанный_ключ]|
H: $Supports NoHello QuickList|
C: $MyINFO [Строка]|
C: $GetNickList|
H: Отсылает список пользователей.


Без характеристики QuickList
Код
H: $Lock EXTENDEDPROTOCOL[Код] Pk=[PrimaryKey]|
C: $Supports NoHello|
C: $Key [Рассчитанный_ключ]|
H: $Supports NoHello|
C: $ValidateNick [Ник]|
H: $Hello [Ник]|
C: $Version [Версия]|
C: $GetNickList|
C: $MyINFO [Строка]|
H: Отсылает список пользователей.


Поддержка характеристики:

Полноценно данную характеристику поддерживает хаб PtokaX.
Со стороны клиентов, данную характеристику поддерживают следующие клиенты: CZDC, BCDC

Внимание! Так как в данной характеристике отсутствуют шаги валидации ника и проверки версии, то при поддержке со стороны клиента данной характеристики на хабе PtokaX скриптовые функции ValidateNickArrival и VersionArrival для этого клиента выполняться не будут!
Saymon21, RAND(i)M
14.8.2009, 15:47 Описание Протокола NMDC
NeoModus Direct Connect Protocol
OpPlus

Описание:

Характеристика хаба. Указывает на то, что на хабе используются дополнительные команды для операторов. Например: $Ban, $TempBan, $UnBan, $GetBanList, $WhoIP, $Banned, $GetTopic, $SetTopic и тд.

На данный момент команду поддерживает хаб VerliHub.
14.8.2009, 15:35 Описание Протокола NMDC
NeoModus Direct Connect Protocol
NoHello

Описание:

Характеристика хаба/клиента.
Характеристика говорит о том, что при входе нового юзера на хаб, клиенту, уже находящемуся на хабе, не нужно отсылать оповещение о входе юзера в виде команды $Hello. Кроме этого, данная характеристика указывает на то, что хаб не должен отсылать клиенту при коннекте команду $NickList, которая отвечает за получение клиентом ников всех пользователей хаба, а клиент не должен отсылать на хаб команду $GetINFO для получения списка пользователей хаба. Для заполнения списка пользователей хаб должен отослать команду $MyINFO. Клиент отсылает команду $GetNickList для указания того, что он заинтересован в получении списка пользователей, однако, хаб не обязан ждать эту команду и должен отослать список пользователей в любом случае.

Важное замечание!
При наличии у клиента этой характеристики хаб при входе этого клиента будет отсылать клиенту список пользователей командами $MyINFO. Так как команда $MyINFO содержит ники пользователей, то получение ников командой $NickList является лишним действием. Поэтому данная характеристика является самым информативным и оптимальным вариантом.

Характеристика поддерживается клиентами DC++, начиная с версии 0.305.
14.8.2009, 15:13 Описание Протокола NMDC
NeoModus Direct Connect Protocol
NoGetINFO

Описание:

Характеристика хаба/клиента.
Характеристика указывает на то, что хабу не нужно получать от клиента команды $GetINFO для того, чтобы отсылать ему команды $MyINFO и $NickList. Это некое подобие характеристики QuickList, которая позволяет осуществлять быстрые получения списков пользователей.

Важное замечание!
При отсутствии у клиента характеристики NoHello и при наличии характеристики NoGetINFO хаб должен отсылать клиенту список пользователей при помощи команд $MyINFO и $NickList одновременно. При отсутствии обеих характеристик список пользователей отсылается по средствам команды $NickList, а список пользователей с участием команд $MyINFO можно будет получить только после отсылки на хаб команды $GetINFO.

Характеристика поддерживается клиентами DC++, начиная с версии 0.302.
14.8.2009, 15:06 Описание Протокола NMDC
NeoModus Direct Connect Protocol
MCTo

Описание:

Характеристика хаба.
Данная характеристика указывает на поддержку команды $MCTo.
На данный момент характеристику поддерживает хаб YnHub.
14.8.2009, 14:57 Описание Протокола NMDC
NeoModus Direct Connect Protocol
HubTopic

Описание:

Характеристика хаба. Указывает на поддержку команды $HubTopic. Данная характеристика является не обязательной, то есть хаб может поддерживать данную команду и без указания данной характеристики.
14.8.2009, 14:37 Описание Протокола NMDC
NeoModus Direct Connect Protocol
Feed

Описание:

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

На данный момент характеристику Feed поддерживает YnHub.
14.8.2009, 14:27 Описание Протокола NMDC
NeoModus Direct Connect Protocol
ClientID

Описание:

Характеристика клиента. Данная характеристика указывает на поддержку команды $ClientID.
Характеристику поддерживают следующие клиенты: BlackDC, iDC++, dDC++, Zion++
14.8.2009, 14:13 Описание Протокола NMDC
NeoModus Direct Connect Protocol
BotList

Описание:

Характеристика хаба/клиента. Данная характеристика указывает на поддержку команды $BotList.

Для полного понимания, данная характеристика должна присутствовать в команде $Supports как хаба, так и клиента.
12.8.2009, 21:43 Как включать скрипты в PtokaX 0.4.1.1
В сотый раз говорю, что не надо цитировать предыдущий пост! Итак ясно о чём речь!
pleomax
12.8.2009, 18:13 Как включать скрипты в PtokaX 0.4.1.1
В проге с GUI есть кнопка Скрипты. Там надо поставить галочки напротив нужных скриптов
pleomax
11.8.2009, 0:08 Описание Протокола NMDC
NeoModus Direct Connect Protocol
Lock2Key

Описание:

Реализация в различных языках функции lock2key для нахождения ключа по параметру команды $Lock.


Язык С/C++:

CODE
char *lock2key(char *lock)
{
int len = strlen(lock);
char *key = (char *)calloc(1, len + 1);

int i;
for(i = 1; i < len; ++i)
key[i] = lock[i] ^ lock[i-1];
key[0] = lock[0] ^ lock[len-1] ^ lock[len-2] ^ 5;

for(i = 0; i < len; ++i)
key[i] = ((key[i]<<4) & 0xF0) | ((key[i]>>4) & 0x0F);

char *newkey = (char *)calloc(1, len + 100);
char *newkey_p = newkey;
for(i = 0; i < len; ++i)
{
switch(key[i])
{
case 0:
case 5:
case 36:
case 96:
case 124:
case 126:
sprintf(newkey_p, "/%%DCN%03d%%/", key[i]);
newkey_p += 10;
break;
default:
*newkey_p = key[i];
++newkey_p;
}
}
*newkey_p = '\0';
return newkey;
}



Язык C++:

CODE
/// DCN экранирование
void DCN_Escape(const char *sBuf, int iLen, string &sDest)
{
sDest.clear();
unsigned char c;
char buf[11];
while(iLen-- > 0) {
c = *(sBuf++);
switch© {
case 0:
case 5:
case 36:
case 96:
case 124:
case 126:
sprintf(buf, "/%%DCN%03d%%/", c);
sDest += buf;
break;
default:
sDest += c;
break;
}
}
}

/// DCN разэкранирование
void DCN_UnEscape(const string &sSrc, char *sDest, int &iLen)
{
string sStart = "/%DCN", sEnd = "%/";
unsigned char c;
size_t iPos = sSrc.find(sStart), iPos2 = 0;
iLen = 0;
while((iPos != sSrc.npos) && (iLen < sSrc.size())) {
if(iPos > iPos2) {
memcpy(sDest + iLen, sSrc.c_str() + iPos2, iPos - iPos2);
iLen += iPos - iPos2;
}
iPos2 = sSrc.find(sEnd, iPos);
if((iPos2 != sSrc.npos) &&
(iPos2 - iPos <= sStart.size() + 3)) {
c = atoi(sSrc.substr(iPos + sStart.size(), 3).c_str());
sDest[iLen++] = c;
iPos2 += sEnd.size();
}
iPos = sSrc.find(sStart, iPos + 1);
}
if (iPos2 < sSrc.size()) {
memcpy(sDest + iLen, sSrc.c_str() + iPos2, sSrc.size() - iPos2 + 1);
iLen += sSrc.size() - iPos2;
}
}

/// Функция кодирования
void lock2key(const string &sLock, string &sKey)
{
int iCount = 0, iLen = sLock.size();
char *key = 0, *lock = new char[iLen + 1];
DCN_UnEscape(sLock, lock, iLen);

key = new char[iLen + 1];

key[0] = lock[0] ^ lock[iLen - 1] ^ lock[iLen - 2] ^ 5;
while(++iCount < iLen) key[iCount] = lock[iCount] ^ lock[iCount - 1];
key[iLen] = 0;

iCount = -1;
while(++iCount < iLen) key[iCount] = ((key[iCount] << 4)) | ((key[iCount] >> 4));

DCN_Escape(key, iLen, sKey);
delete [] key;
delete [] lock;
}



Язык C#:

CODE
private static string lock2key(string Lock)
{
int i, len = Lock.Length;
byte[] key = new byte[len];
for(i = 1; i < len; ++i)
key[i] = (byte)(Lock[i] ^ Lock[i - 1]);
key[0] = (byte)(Lock[0] ^ Lock[len - 1] ^ Lock[len - 2] ^ 5);

for(i = 0; i < len; ++i)
key[i] = (byte)(((key[i] << 4) & 0xF0) | ((key[i] >> 4) & 0x0F));

string Buf = "", Key = Encoding.Default.GetString(key);
for(i = 0; i < len; ++i)
switch((int)Key[i]) {
case 0:
case 5:
case 36:
case 96:
case 124:
case 126:
Buf += String.Format("/%DCN{0:000}%/", (int)Key[i]);
break;
default:
Buf += Key[i];
break;
}
return Buf;
}



Язык Lua (5.1):

CODE
function lock2key(lock)
local function bitwise(x, y, bw)
local c, p = 0, 1
local function bODD(x)
return x ~= math.floor(x / 2) * 2
end
while x > 0 or y > 0 do
if bw == "xor" then
if (bODD(x) and not bODD(y)) or
(bODD(y) and not bODD(x)) then
c = c + p
end
elseif bw == "and" then
if bODD(x) and bODD(y) then
c = c + p
end
elseif bw == "or" then
if bODD(x) or bODD(y) then
c = c + p
end
end
x = math.floor(x / 2)
y = math.floor(y / 2)
p = p * 2
end
return c
end

local key = {}
table.insert(key,
bitwise(bitwise(bitwise(string.byte(lock, 1),
string.byte(lock, -1),
"xor"),
string.byte(lock, -2),
"xor"),
5,
"xor"))
for i=2, string.len(lock),1 do
table.insert(key, bitwise(string.byte(lock, i), string.byte(lock, i - 1), "xor"))
end

local function nibbleswap(bits)
return bitwise(bitwise(bits * (2 ^ 4), 240, "and"),
bitwise(math.floor(bits / (2 ^ 4)), 15, "and"), "or")
end

local g = {["5"] = 1, ["0"] = 1, ["36"] = 1, ["96"] = 1, ["124"] = 1, ["126"] = 1}
for i=1, #key do
local b = nibbleswap(rawget(key, i))
rawset(key, i, (g[tostring(b)] and
string.format("/%%DCN%03d%%/", b) or string.char(b)))
end

return table.concat(key)
end



Язык PHP:

CODE
function lock2key($_LOCK, $port) {
$lockLength = strlen($_LOCK);
$LockToKey = '';

for ($j = 0; $j < strlen($_LOCK); $j++) {
if($j == 0) {
$h = ord($_LOCK{0}) ^ ord( $_LOCK{ $lockLength - 1} ) ^ ord( $_LOCK{ $lockLength - 2} ) ^ 5;
} else {
$h = ord($_LOCK{$j}) ^ ord($_LOCK{$j-1});
}

$h = $h % 256;
$a = (($h<<4) & 240) | (($h>>4) & 15);

if($a == '126' or $a == '124' or $a == '96' or $a == '36' or $a == '5' or $a == '0') {
$LockToKey .= "/%DCN";

if ($a < 100) $LockToKey .= "0";
if ($a < 10) $LockToKey .= "0";

$LockToKey .= $a;
$LockToKey .= "%/";
} else {
$LockToKey .= chr($a);
}
}
return $LockToKey;
}



Язык Perl:

CODE
sub lock2key($)
{
my @lock = split(//, shift);
my $i;
my @key = ();
# convert to ordinal
map {$_=ord} @lock;
# calc key[0] with some xor-ing magic
push(@key,$lock[0]^5);
# calc rest of key with some other xor-ing magic
for ($i=1;$i<@lock;$i++)
{
push(@key, ($lock[$i]^$lock[$i-1]));
}
# nibble swapping
for ($i=0;$i<@key;$i++)
{
$key[$i] = ((($key[$i] << 4) & 240) | (($key[$i] >> 4) & 15)) & 0xff;
}
$key[0] = $key[0] ^ $key[ @key - 1 ];
# escape some
foreach (@key)
{
$_ = ( $_ == 0 || $_ == 5 || $_ == 36 ||
$_ == 96 || $_ == 124 || $_ ==
126 ) ? sprintf('/%%DCN%03i%%/', $_) : chr;
}
# done
return join('', @key);
}



Язык Delphi / Pascal:

CODE
function lock2key(StrLock : string) : string;

// The follow function converts "1" (byte) to "001" (string), "10" to "010" and so on
function ByteToThreeCharStr (Value : byte) : string;
begin
if value < 10 then
result := '00'+inttostr(value)
else
if value < 100 then
result := '0'+inttostr(value)
else
result := inttostr(value);
end;

var i : byte;
Temp : string;
TempChar : byte;

begin
result := '';
if length (StrLock) < 3 then
begin
result := 'BROKENCLIENT';
setlength (result,length(strlock));
exit;
end;

// First char
temp := chr (ord (StrLock[1]) xor ord (StrLock[length(StrLock)])
xor ord (StrLock[length(strLock)-1]) xor 5);

for i := 2 to length (StrLock) do
temp := temp + chr (ord(StrLock[i]) xor ord (StrLock[i-1]));

for i := 1 to length (temp) do
begin
TempChar := ord (temp[i]);

// I now used assembler. In the visual basic code the same was done with ugly math
asm // <- Nibble swap! We swap the last four
// bits with the first four: 00101111 -> 11110010
ror TempChar, 4
end;

// Some chars need to be replaced with a string like "/%DCN005%/"
If (TempChar = 0) or (TempChar = 5) or (TempChar = 36) or (TempChar = 96)
or (TempChar = 124) or (TempChar = 126)
then
result := result + '/%DCN' + ByteToThreeCharStr(TempChar) + '%/'
else
result := result + chr (TempChar);
end;
end;



Язык Java:

CODE
private static final String CHARENCODING = "windows-1252";

public static String generateKey(String lockstr) throws UnsupportedEncodingException {
byte[] lock = lockstr.split(" ", 3)[1].getBytes(CHARENCODING);
byte[] key = new byte[lock.length];
for (int i = 1; i < lock.length; i++) {
key[i] = (byte) ((lock[i] ^ lock[i - 1]) & 0xFF);
}
key[0] = (byte) ((((lock[0] ^ lock[lock.length - 1]) ^ lock[lock.length - 2]) ^ 5) & 0xFF);
for (int i = 0; i < key.length; i++) {
key[i] = (byte) ((((key[i] << 4) & 0xF0) | ((key[i] >> 4) & 0x0F)) & 0xFF);
}
String modifiedLock = new String(key,CHARENCODING);
return dcnEncode(modifiedLock);
}

private static String dcnEncode(String lockstring) {
for (int i: new int[]{0,5,36,96,124,126}) {
String paddedDecimal = String.format("%03d", i);
String paddedHex = String.format("%02x", i);
lockstring = lockstring.replaceAll("\\x"+paddedHex, "/%DCN"+paddedDecimal+"%/");
}
return "$Key "+lockstring+"|";
}



Язык Visual Basic:

CODE
Public Function Lock2Key(StrLock As String) As String
Dim TLock2Key As String, TChar As Integer
If Len(StrLock) < 3 Then
Lock2Key = Left$("BROKENCLIENT", Len(StrLock))
Exit Function
End If
TLock2Key = Chr$(Asc(Left$(StrLock, 1)) Xor
Asc(Right$(StrLock, 1)) Xor
Asc(Mid$(StrLock, Len(StrLock) - 1, 1)) Xor 5)
For i = 2 To Len(StrLock)
TLock2Key = TLock2Key &
Chr$(Asc(Mid$(StrLock, i, 1)) Xor
Asc(Mid$(StrLock, i - 1, 1)))
Next i
For i = 1 To Len(TLock2Key)
TChar = Asc(Mid$(TLock2Key, i, 1))
TChar = TChar * 16 + TChar \ 16 'Swap bits 11110000 -> 00001111
TChar = TChar Mod 256
If TChar = 0 Or TChar = 5 Or TChar = 36 Or
TChar = 96 Or TChar = 124 Or TChar = 126 Then
Lock2Key = Lock2Key & "/%DCN" & Right$("000" & TChar, 3) & "%/"
Else
Lock2Key = Lock2Key & Chr$(TChar)
End If
Next i
End Function

Case "$LOCK"
'You've recived $LOCK, convert it to $KEY
Dim sLock2 As String
sLock2 = Split(Mid(sData2, 7), " Pk=")(0)
sLock2 = Lock2Key(sLock2)



Язык Python:

CODE
lock = self.sock.recv(1024)
lock = re.findall('\$Lock[\s](.*?)[\s]', lock)[0]

key = {}

for i in xrange(1, len(lock)):
key[i] = ord(lock[i]) ^ ord(lock[i-1])

key[0] = ord(lock[0]) ^ ord(lock[len(lock)-1]) ^ ord(lock[len(lock)-2]) ^ 5
for i in xrange(0, len(lock)):
key[i] = ((key[i]<<4) & 240) | ((key[i]>>4) & 15)

out = ""
for i in xrange(0, len(lock)):
out += unichr(key[i])

out = out.replace(u'\0', u'/%DCN000%/').replace(u'\5',
u'/%DCN005%/').replace(u'\44', u'/%DCN036%/')
out = out.replace(u'\140', u'/%DCN096%/').replace(u'\174',
u'/%DCN124%/').replace(u'\176', u'/%DCN126%/')



Язык Python 2.5.2 (Ubuntu 8.10):

CODE
# "lock" must be the exact lock character sequence, not the whole command.
# i.e. if the command is $Lock blah pk=bleh|, lock should be "blah"
def lock_to_key(lock):
"Decrypts lock to key."
key = {}
for i in xrange(1, len(lock)):
key[i] = ord(lock[i]) ^ ord(lock[i-1])
key[0] = ord(lock[0]) ^ ord(lock[len(lock)-1]) ^ ord(lock[len(lock)-2]) ^ 5
for i in xrange(0, len(lock)):
key[i] = ((key[i]<<4) & 240) | ((key[i]>>4) & 15)
out = ""
for i in xrange(0, len(key)):
if key[i] in (0, 5, 36, 96, 124, 126):
out += "/%%DCN%03d%%/" % (key[i],)
else:
out += chr(key[i])
return out
Nickolya, PomanoB, Кто-то_из_вне..., Saymon21, Enyby, Markiz
10.8.2009, 23:52 Описание Протокола NMDC
NeoModus Direct Connect Protocol
TTH (Tiger Tree Hashing)

Описание:

Тип хэш-кода. Служит для однозначной идентификации файлов в p2p сетях. Впервые появился в клиенте DC++ 0.400.

Пример TTH для 0б:

Код
LWPNACQDBZRYXW3VHJVCJ64QBZNGHOHHHZWCLNQ



Вычисления TTH:

Сначала данные делим на блоки не более 1024 байта на блок. Далее к каждому получившемуся блоку спереди добавляется байт 00 - эта какт называемый Leaf Tiger Hash. Затем для каждой пары хешей вычисляется так называемый Internal Tiger Hash - это хеш от пары хешей Internal Tiger Hash или Leaf Tiger Hash с добавлением в начале байта 01. После хеширования всех пар получается один хеш, который называется Tiger Tree Root, и который является хешем всего дерева. Именно его используют для однозначной идентификации файла и указывают в различных P2P ссылках.

Схема хеширования:

  • деление на блоки по 1024 байта;
  • получение Leaf Tiger Hash (LTH) - это Tiger Hash от блока данных с добавленным в начале байтом 00 (Байт 00 + Блок данных);
  • получение Internal Tiger Hash (ITH) - это Tiger Hash от двух других Tiger Hash (Internal Tiger Hash или Leaf Tiger Hash) с добавленным в начале байтом 01 (Байт 01 + Hash1 + Hash2);
  • получение Tiger Tree Root (TTR) - это хеш всего дерева или единственный оставшийся хеш, полученный из пары уровнем ниже.



Вычисление количества хешей на уровне:

Количество хешей на уровне можно посчитать циклически от нижнего до верхнего уровня следующим образом:

  1. Округлённое до большего целого количество хешей самого нижнего уровня (Количество байт данных \ 1024);
  2. Округлённое до большего целого количество хешей выше (Количество хешей ниже \ 2);
  3. Повторяем пункт 2 для нового уровня, пока не будет найдено количество хешей нужного уровня.



Поиск ($Search):

На данный момент в DC клиентах за поиск по TTH отвечает девятый тип поиска. Строка поиска девятого типа обязательно должна содержать TTH:[base32_encoded_tth_hash]


Результаты поиска ($SR):

Когда клиенту известен корневой хеш файла, клиент в команде $SR не должен отсылать имя хаба. Вместо имени хаба должен стоять TTH:[base32_encoded_tth_hash]. См. описание команды $SR.
10.8.2009, 23:04 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$ZOn

Синтаксис:

Код
$ZOn|[Блок_данных]


Направление команды:

Хаб -> Клиент

Описание:

Команда сжатия данных с использованием библиотеки zlib. Используется в хабе PtokaX.
Данная команда указывает на то, что после неё идёт блок данных, который сжат при помощи библиотеки zlib. Сжатый блок распаковывается на стороне клиента, после получения. Библиотека сжатия zlib использует алгоритм сжатия LZ77.

Для использования данной команды необходимо, чтобы в команде $Supports присутствовала характеристика ZPipe0.
Нолик на конце характеристики указывает на тестирование данной характеристики. В конечной реализации (не тестовой) данная характеристика имеет вид: ZPipe. Окончание блока сжатых данных трактуется символом EOF (End-Of-File).

См. также команду $Z
10.8.2009, 22:54 Registration_1_.v2
API1, API2 | Скрипт регистрации
все \r\n заменить на \n
Herurg, Dialog
10.8.2009, 1:18 Нужен скрипт
Код
function ChatArrival(tUser, sData)
  if sData:find"бот топик" then
    Core.SendToAll(sData.."<Bot> Топик хаба: "..SetMan.GetString(10))
    return true
  end
end
CrazyBoyTula
10.8.2009, 0:21 Нужен скрипт
Код
function ChatArrival(tUser, sData)
  if sData:find"бот топик" then
    for k,v in pairs(Core.GetOnlineUsers()) do
      Core.SendToUser(v, sData)
    end
    Core.SendToUser(tUser, "<Bot> Топик хаба: "..SetMan.GetString(10))
    return true
  end
end


или так:

Код
function ChatArrival(tUser, sData)
  if sData:find"бот топик" then
    Core.SendToUser(tUser, sData)
    Core.SendToUser(tUser, "<Bot> Топик хаба: "..SetMan.GetString(10))
    return true
  end
end


всё зависит от того, что именно нужно)
CrazyBoyTula
9.8.2009, 14:15 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Z / ZLine

Синтаксис:

Код
$Z [Блок]|


Направление команды:

Хаб -> Клиент

Описание:

Команда $Z используется расширением ZLine протокола NMDC.

Данная команда была предложена Jove и обсуждается в основном на DCDev хабе.
Команда предназначена для сжатия блоков команд.

Команда $Z [Блок]| будет развёрнута в строку: $Search ... |$MyINFO...|...

Используется простое zlib сжатие и дополнительное экранирование. Символ "\" экранируется так: "\\", а символ "|" так: "\P". Этого достаточно чтобы использовать взамен bzip.

Данную команду следует использовать только в одном направлении хаб -> клиент. В любом другом направлении она только создаст лишнюю нагрузку.

Клиент должен поддерживать эту команду. Он сообщает об этом хабу путём отсылки в команде $Supports флага ZLine

Оценка:
Проводились тесты для оценки эффективности данного дополнения.

Программа тестирования работала следующим образом: сначала пользователи соединялись, потом пользователи генерировали события:

  • $MyINFO
  • Сообщение чата
  • $Search
  • разъединение/соединение


Задержки между соединениями и событиями могут варьироваться. Настройки по умолчанию были выбраны следующими:
100 мсек между входами (10 соединений/сек) и 50 мсек между событиями (20 событий/сек).



Короткий тест (приблизительно 700 сек) со 100 пользователями.

Без ZLine
Общий трафик: Входящий 1986998, Исходящий 58506319
Среднее за 718 секунд: Входящий 16.140272 кб/с, Исходящий 475.764798 кб/с


С ZLine
Общий трафик: Входящий 1549938, Исходящий 15913487
Среднее за 719 секунд: Входящий 16.159448 кб/с, Исходящий 165.737719 кб/с




Тест с 1000 пользователями на хабе. Продолжительность теста примерно 22000 секунд (чуть больше 6 часов) в обоих случаях.

Без ZLine
Общий трафик: Входящий 58562006, Исходящий 18932614671
Среднее за 28078 секунд: Входящий 16.682808 кб/с, Исходящий 5393.331647 кб/с


С ZLine
Общий трафик: Входящий 48040395, Исходящий 3987767021
Среднее за 22318 секунд: Входящий 16.989433 кб/с, Исходящий 1410.093335 кб/с



Тест с 4000 пользователями на хабе. Продолжительность теста примерно 5000 секунд в обоих случаях.

Без ZLine
Общий трафик: Входящий 11675512, Исходящий 14732322239
Среднее за 5472 секунд: Входящий 16.910506 кб/с, Исходящий 21337.779879 кб/с


С ZLine
Общий трафик: Входящий 11102441, Исходящий 2805387234
Среднее за 5042 секунд: Входящий 17.197069 кб/с, Исходящий 4343.892306 кб/с



Ниже приведены немного другие тесты. Тесты с другими сообщениями. Основные сообщения те же самые, но кроме этого есть сообщения с произвольным числом символов. На результат влияют большие сообщения, которые труднее сжать.

1000 пользователей:


Без ZLine
Общий трафик: Входящий 26426307, Исходящий 8802244496
Среднее за 9358 секунд: Входящий 22.585492 кб/с, Исходящий 7522.500261 кб/с


С ZLine
Общий трафик: Входящий 27070505, Исходящий 4003114560
Среднее за 9359 секунд: Входящий 22.837603 кб/с, Исходящий 3376.263386 кб/с




Выводы:
Эффективность сжатия варьируется от 50% до 80% и зависит от количества пользователей и типа трафика. Данную команду нельзя применять для того, чтобы сжимать всё подряд. Хаб должен находить баланс между шириной полосы пропускания и ресурсностью процессора и памяти. В сущности, сжимаются только блоки команд, посылаемые клиентам. Поэтому нагрузка на процессор и память почти незаметна.


Хабы, поддерживающие данное дополнение:

Aquila
BDCH (планируется)
DDCH
tkhub
YnHub (планируется)
NitroHub (> 0.7)

Клиенты, поддерживающие данное дополнение:

DCDM++
iDC++
McDC++
Z++
9.8.2009, 13:30 ! Часто Задаваемые Вопросы !
Обязательно прочитать всем!!!
Как сделать оповещение в ОпЧат о слишком большой шаре пользователя?

Код
local iShareLimit = 15 * 0x100000 * 0x100000 -- 15 ТБ
local sReport = "Подозрительно большая шара у пользователя: "

function MyINFOArrival(tUser, sData)
  Core.GetUserData(tUser, 16)
  if tUser.iShareSize >= iShareLimit then
    Core.SendToOpChat(sReport..tUser.sNick.." ["..tUser.sIP.."]. Шара: "..tUser.iShareSize)
  end
end
Invisible
8.8.2009, 16:41 Словить 3ий аргумент в lua...
Помогите дописать...
Учись работать с описаниями функций.

Выдержка из файла scripting-interface.txt:
Цитата
Ban(tUser, sReason, sBy, bFull) - Perm ban user. Return nil when failed, true if success.
BanIP(sIP, sReason, sBy, bFull) - Perm ban given ip. Return nil when failed, true if success.


Поэтому должно быть так:
Код
BanMan.BanIP(sIP, sReason, tUser.sNick, 0)


В случае же использования функции Ban нужно ставить не ip, а таблицу пользователя!


P.S.
bad argument #1 to 'Ban' (table expected, got string) - переводится так: в первом аргументе функции 'Ban' ожидается таблица, а туда подставляется строка.
Win32
8.8.2009, 15:28 Фильмы/Сериалы
Кому что нравится..
Какие ещё скрипты? Смотри на название раздела))))
Uncle_Dif
8.8.2009, 10:15 Словить 3ий аргумент в lua...
Помогите дописать...
Ты всё правильно написал.
Код
local sCmd, sIP, sNick, sReason = sData:match"%b<>%s+(%S+)%s+(%S+)%s+(%S+)%s+(.+)


Данное регулярное выражение в методе будет действовать следующим образом:

%b<> - поиск в строке символов <> (не обязательно подряд идущих) - обрезание ника
%s+ - 1 или более пробельных символов
(%S+) - захват одного или более не пробельных символа и запись в переменную sCmd
%s+ - опять 1 или более пробельных символов
(%S+) - захват одного или более не пробельных символа и запись в переменную sIP
%s+ - опять 1 или более пробельных символов
(%S+) - захват одного или более не пробельных символа и запись в переменную sNick
%s+ - опять 1 или более пробельных символов
(.+) - захват всего оставшегося, то есть захват любого символа или символов (минимум 1 символ)


Однако, чтобы пользователь наверняка вводил ip адрес, лучше написать так:
Код
local sCmd, sIP, sNick, sReason = sData:match"%b<>%s+(%S+)%s+(%d+%.%d+%.%d+%.%d+)%s+(%S+)%s+(.+)
Win32
6.8.2009, 11:19 Несколько Слов О Захватах И Регулярных Выражениях
исключительно для разработчиков
Это конечно же не относится к регулярным выражениям, однако очень часто используется до захвата данных.

Речь идёт о методе sub (или функции string.sub). Данный метод (функция) служит для обрезания строк или для выделения подстрок.
Код
sData = sData:sub(s, e)

В переменную sData будет возвращена подстрока строки sData начиная с позиции s и заканчивая позицией e. s и e могут быть также отрицательными. В случае когда они положительные, всё понятно, например sData:sub(3, 6). Тут этот метод возьмёт из sData с третьего до шестого символа включительно. Если же sData:sub(-5, -2), то метод возьмёт из sData со второго до пятого символа включительно, но уже отсчёт позиций будет идти с конца строки. В этой функции последний параметр является необязательным, т.е. можно написать sData:sub(2), в этом случае последний параметр берётся по умолчанию -1. Если последний параметр равен -1 - это означает, что строка берётся до конца, в данном примере со второго символа и до конца.

Пример строки:
Код
<НИК> Пример.|

Составим таблицу для большей наглядности:
Код
'символ', 'позиция от начала', 'позиция от конца'
'<',    '1',    '-14'
'Н',    '2',    '-13'
'И',    '3',    '-12'
'К',    '4',    '-11'
'>',    '5',    '-10'
'пробел',    '6',    '-9'
'П',    '7',    '-8'
'р',    '8',    '-7'
'и',    '9',    '-6'
'м',    '10',    '-5'
'е',    '11',    '-4'
'р',    '12',    '-3'
'.',    '13',    '-2'
'|',    '14',    '-1'


Последний символ | мы не видим, но он есть, этот символ не выводится в чат, но позволяет скрипту определять конец строки, поэтому в случае использования кода sData:sub(1, -2) как раз таки мы избавляемся от этого символа, т.е. берём строку начиная с первого символа и, заканчивая вторым с конца, так как первый с конца это символ |.

А вообще, применяют чаще всего этот метод чтобы отсечь ник и символ | и оставить только данные, посылаемые в чат, вот так:
Код
sData = sData:sub(tUser.sNick:len() + 4, -2)
Nickolya, Tsd, Invisible, BeN
6.8.2009, 10:45 Словить 3ий аргумент в lua...
Помогите дописать...
2Win32: Почитай тему: http://mydc.ru/topic266.html
Win32
5.8.2009, 20:18 Словить 3ий аргумент в lua...
Помогите дописать...
Код
BanMan.Ban(sNick, sReason, tUser.sNick, true)
Win32
5.8.2009, 17:53 Словить 3ий аргумент в lua...
Помогите дописать...
Код
function ChatArrival(tUser, sData)
  sData = sData:sub(1, -2)
  local sCmd, sNick, sReason = sData:match"%b<>%s+(%S+)%s+(%S+)%s+(.+)"
  if sCmd and sCmd == "!ban" then
    Core.SendToAll("<"..BotName.."> Пользователь "..sNick.." навсегда лишен права доступа на хаб по причине: "..sReason..". Наказал: "..tUser.sNick)
  end
end
Win32
5.8.2009, 15:23 Точное Время
Помогите, скачал скрип а он не пашет.
Не стал глубоко разбираться в кривом скрипте, однако немного подправил

[attachment=3015:tochnoe_vremya.lua]

Дальше сам подправляй.
Очень кривой скрипт! Легче заново было написать, чем править эту кривизну.
Men
5.8.2009, 14:43 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Код
local tRanks = {
  {"10.0.0.0", "10.255.255.255"},
  {"192.168.0.0", "192.168.255.255"}
}

function Ip2Num(sIP)
  local a, b, c, d = sIP:match"^(%d+)%.(%d+)%.(%d+)%.(%d+)$"
  return a * 16777216 + b * 65536 + c * 256 + d
end

function OnStartup()
  for k, v in ipairs(tRanks) do
    tRanks[k][1], tRanks[k][2] = Ip2Num(v[1]), Ip2Num(v[2])
  end
end

function UserConnected(tUser)
  local iIP = Ip2Num(tUser.sIP)
  for _, v in ipairs(tRanks) do
    if iIP > v[1] and iIP < v[2] then
      return
    end
  end
  Core.Disconnect(tUser)
end

RegConnected, OpConnected = UserConnected, UserConnected
Syndicate
4.8.2009, 16:11 Антипрокси под API2
Прежде чем постить, нужно юзать поиск!
мамин_парень
15.7.2009, 18:57 Anekbot
API2 | Анекдоты из Интернета
не не не
Наоборот:

Код
TimerID = TmrMan.AddTimer(tCfg.Time*60*1000,"OnTimer")


и

Код
function OnTimer()
...
end
engineer
11.7.2009, 22:54 Вопрос по скрипту регистрации
API2
Ага. Я немного неверно написал. Пардон. Действительно оба должны быть истинными при конъюнкции.

Да да, ты верно расписал правила двоичной логики big_smile.gif
fixx
11.7.2009, 12:48 Вопрос по скрипту регистрации
API2
2district: Всё очень хорошо изложил, но вот по пункту 2 как раз таки наоборот.
Цитата(district @ 11.7.2009, 3:14) *
2.Не хватает общих скобок для всего выражения
Это самое явное. Т.е. должно быть так:
Код
local _,_,ip1,ip2 = e:find("(%d+%p%d+%p%d+%p%d+)%-(%d+%p%d+%p%d+%p%d+)")


Если у функции (или метода) всего лишь один аргумент, и этот аргумент является строкой без конкатенаций, то скобки можно и даже нужно опускать:
Код
local _,_,ip1,ip2 = e:find"(%d+%p%d+%p%d+%p%d+)%-(%d+%p%d+%p%d+%p%d+)"


Так как нагромождение скобками ухудшает читабельность кода, и скобки увеличивают размер кода big_smile.gif

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

Приведу пару примеров функций без скобок:
Код
MyFunc1"Всем пивет"
MyFunc2{[1] = 1, [2] = 1}
district
8.7.2009, 15:23 жалобная книга + MySQL
Юзеры могут пожаловаться на админов =)
метод dbformat экранирует одиночную кавычку для внесения данных в бд.
fixx
6.7.2009, 19:37 Cleanreg
API2 | Скрипт чистки регистраций
строка 141:
Код
Вас небыло на хабе "..td.." дней


Код
Вас небыло на хабе "..string.format("%.0f", td).." дней


Если конечно это та самая строка. Ту фразу, которая была написана я в скрипте не нашёл)))) В скрипте фраза:
Код
"<"..Bot.."> Hey "..user.sNick..
", we've missed you for the last "..td.." days.|"
fixx
3.7.2009, 15:50 Ищу разработчиков ADC Хабов
обменяться мнениями.
Хаб кроссплатформенный?

Я начал описывать протокол в разделе для разработчиков.
Steep
3.7.2009, 14:42 Ждущий режим
Будет ли нормально функционировать хаб?
В ждущем режиме оперативная память остаётся не тронутой, однако, любое функционирование будет отсутствовать, так как процессор в ждущем режиме отключается.

Поэтому, скорее всего, после выхода из длительного ждущего режима хаб сразу же сбросит всех пользователей.
Со стороны клиентов думаю, что будет следующее: клиент отправляет сообщение или команду на хаб, но не получает с хаба ответа и в скором времени клиент закроет соединение с таким хабом.
NikseR
29.6.2009, 14:21 идея, которая позволит избавиться от пассивных юзеров в DC :)
ИМХО дурная идея.
Перекраивать протокол никто не собирается!

Если данная идея и будет реализована, то я как актив сделаю следующее: по средствам файрвола заблокирую все входящие соединения, а разрешу только исходящие. Таким образом я буду качать, но никогда я не буду в роли медиатора)))
степашка
27.6.2009, 23:45 Checker
API2 | Детектор чата и привата
Данный скрипт нельзя переделать. Если ты знаешь как это сделать, то ты сможешь обойтись и без этого скрипта.

И не надо больше оффтопить))
мамин_парень
26.6.2009, 14:34 StatisticsMySQL
API2 | Скрипт сбора статистики
При написании скриптов с базой данных, нужно аккуратно подходить к их написанию.
Утечка памяти в скрипте может сильно сказаться в будущем и привести к падению скрипта через некоторое время стабильной работы.
В данном скрипте существует утечка. Думаю, что во всех скриптах этой ветки есть эта утечка. Автор просто игнорирует курсоры как объекты, и считает их за обычные lua переменные.
mariner
24.6.2009, 2:25 zK++ for Op's
Клиент для ОПераторов.
А что так сложно перевести?
Вот я накатал русик под zK++:

[attachment=2717:russian.xml]
мамин_парень
21.6.2009, 15:12 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
self - это и есть tTable, но в неявном виде.
Только вместо функции надо вызывать метод. Вот так будет работать:
Код
tTable = {
  bWork = true,
  Func = function(self)
    if self.bWork then
      SendToNick("[INT]district", "РАБОТАЕТ")
    end
  end
}

function Main()
  tTable:Func()
end


Когда мы пишем tTable:Func(), то это равносильно записи tTable.Func(tTable). Теперь должно быть понятно, что в качестве параметра self в методе выступает таблица.

Можно пойти намного дальше и реализовать так называемый "принцип полиморфизма":
Код
tTable = {
  bWork = true,
  Func = function(self)
    if self.bWork then
      SendToNick("[INT]district", "РАБОТАЕТ")
    else
      SendToNick("[INT]district", "НЕ РАБОТАЕТ")
    end
  end
}

tTable2 = {
  bWork = false,
}

function Main()
  tTable.Func(tTable2)
end

Вот последний пример это уже некое подобие полиморфизма в ООП.
district
20.6.2009, 12:20 Anekbot
API2 | Анекдоты из Интернета
Ошибка, на самом деле, переводится так: в строке 270 у функции 'random' плохой второй аргумент (пустой интервал). Другими словами второй аргумент TotalAneks равен значению nil. Смотрим далее, где у нас определяется переменная TotalAneks. Она определяется в строке 68: TotalAneks = GetTotalAneks(). Ищем функцию GetTotalAneks(), строка 251. Видим, что эта функция читает данные из файла localbase. Ищем переменную localbase. Находим её в строке 14. Теперь нам должно быть понятно, что дело в путях.

Это означает что в данном скрипте не правильно прописаны пути.
замени
Код
path = "scripts/"
на
Код
path = Core.GetPtokaXPath().."scripts/"
Sekretchik
19.6.2009, 20:35 От: Комнаты (чатрумы) Rooms
От темы с ID: 1443
Не путай темы.
Tarantul13
19.6.2009, 20:23 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Изменения именно в файле - вот что имелось ввиду. То есть за всё время работы скрипта функция require загрузить в память код только 1 раз, при последующих обращениях во время работы скрипта к данной функции она будет брать уже загруженный код.
district
17.6.2009, 14:02 Создание Контекстных Менюшек Средствами Клиента
Со стороны клиента - нельзя, клиент работает исключительно по протоколу. Отослав на хаб неизвестную команду, хаб в праве закрыть соединение с таким клиентом.
Uncle_Dif
15.6.2009, 19:24 Релизы с phpbb3 форума/трекера..
1. Прежде чем работать с курсором нужно проверить открыт ли он?
2. Курсоры лучше делать не глобальными, а локальными переменными.
3. Курсоры нужно всегда закрывать после работы с ними!
Nickolya, Jaska
13.6.2009, 15:41 Описание Протокола ADC
Advanced Direct Connect Protocol
5.3. Команды
Основные команды протокола ADC

SdimS, Invisible
13.6.2009, 15:33 Описание Протокола ADC
Advanced Direct Connect Protocol
5.2. Клиент – Клиент взаимодействие

Клиент - клиент соединение использует ту же самую последовательность входа, что и клиент - хаб соединение, исключая стадию VERIFY и команды GPA/PAS.
Поддержка VERIFY/GPA/PAS должны объявляться дополнениями.
Клиент, который первый отослал команду CTM/RCM, будет контролировать соединение, после достижения между клиентами стадии NORMAL.
SdimS, Invisible
13.6.2009, 15:31 Описание Протокола ADC
Advanced Direct Connect Protocol
5.1. Клиент – Хаб взаимодействие

Вход на хаб имеет определённую последовательность.
Непосредственно сам вход осуществляется на стадии под названием NORMAL.

Последовательность входа на хаб (стадии):
  1. PROTOCOL - отсылка поддерживаемых характеристик
  2. IDENTIFY - идентификация пользователя, статические проверки
  3. VERIFY - проверка пароля
  4. NORMAL - нормальная операция
  5. DATA - для двоичных передач



Последовательность входа на хаб:

Код
Клиент -> Хаб: HSUP ADBASE ADTIGR ...
Хаб -> Клиент: ISUP ADBASE ADTIGR ...
Хаб -> Клиент: ISID <Client-SID> ...
Хаб -> Клиент: IINF HU1 HI1 ...
Клиент -> Хаб: BINF <My-SID> ID... PD...
Хаб -> Клиент: IGPA ...
Клиент -> Хаб: HPAS ...
Хаб -> Клиент: BINF <To All Clients>
Хаб -> Клиент: BINF <Client-SID>


В отличие от NMDC протокола, в ADC протоколе первая команда следует со стороны клиента, а не со стороны хаба.
Invisible
13.6.2009, 15:11 Описание Протокола ADC
Advanced Direct Connect Protocol
5. Команды характеристики BASE

ADC клиенты/хабы, которые поддерживают основные команды должны отсылать характеристику "BASE" на стадии PROTOCOL.

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

Направления передачи определяет то, каким образом команда может быть получена/послана. Хабы и клиенты могут поддерживать в дополнениях и другие направления передачи, однако, для характеристики BASE определены следующие направления:

  • F (From)
    От хаба (хаб-клиент TCP)
  • T (To)
    К хабу (хаб-клиент TCP)
  • C (Client)
    Между клиентами (клиент-клиент TCP)
  • U (UDP Client)
    Между клиентами (клиент-клиент UDP)


Далее, в описаниях команд, первый символ, который отвечает за направление, будет опускаться.
Invisible
11.6.2009, 17:37 Алгоритм работы поиска в DC
Как работает поиск
1) Сортировка источников одного файла идет по мере поступления результатов поиска. Это наиболее оптимальный вариант, так как клиент просто дописывает в конец вновь поступившие источники.
2) Сортировку по разным файлам выбирает сам пользователь. Обычно, по умолчанию, установлена сортировка по количеству источников.
3) Каждый клиент отсылает максимум 5 результатов поиска для пассивных пользователей и 10 для активных.
4) Результаты активного поиска передаются непосредственно между клиентами (без участия хаба). Результаты пассивного поиска проходят через посредника, в роли которого выступает хаб. Хаб, в свою очередь, дабы снять нагрузку по пересылке пользователям этих данных, может ограничить количество результатов поиска. Ограничение результатов пассивного поиска - это значительная оптимизация работы хаба. Например, у меня в настройках хаба установлено - возвращать пользователю при пассивном поиске всего 3 результата, то есть я придерживаюсь простой логике: хочешь хороший поиск - юзай активный режим. Те, кто вынуждены находиться в пассиве, ограничены в возможностях поиска, однако таких меньшинство, и для них действую правила: пиши запрос конкретнее, дабы он попал в 3 результата big_smile.gif
bestnokia
10.6.2009, 15:55 Объектно-Ориентированное Программирование в Lua
Создание и использование классов
Глобальные функции и переменные модуля class.lua

Глобальные переменные:

class - "конструктор" класса. Переменная, отвечающая за создание класса.

Два эквивалентных метода создания простого класса:
1)
Код
class.MyClass{}

2)
Код
MyClass = class("MyClass", {})


Глобальные функции:

virtual(class) - функция, превращающая обычного класса в виртуальный класс.

typeof(value) - расширенная функция определения типа переменной. Возвращает "class", если переменная является классом, "virtual_class" - если переменная представляет из себя виртуальный класс, "object" - если переменная является объектом какого-то класса, а во всех остальных случаях возвращает lua тип переменной, то есть работает как обычная lua функция type().

classof(value) - функция возвращает переменную, если она является классам, в противном случае возвращает nil.

classname(value) - функция возвращает имя класса, если переменная является именованым классом, иначе возвращает nil.

implements(value, class) - функция проверяет, что объект или класс (value) поддерживает интерфейс целевого класса (class). Это означает, что объект или класс может быть подставлен в качестве аргумента в функцию, которая ожидает целевой класс. Мы рассматриваем только элементы класса, которые могут вызываться из класса, то есть вызываемые элементы (функции и таблицы).

is_a(value, class) - функция проверяет содержится ли указанный объект или класс (value), в целевом классе (class). Проверка начинается с самого объекта (или класса), и идёт по цепочке наследования вглубь до целевого класса. Если целевой класс найден, то происходит проверка поддержки интерфейсов (данная функция может вернуть false в механизме множественного наследования, из-за неоднозначностей).
Saymon21, serg_58
7.6.2009, 18:40 Объектно-Ориентированное Программирование в Lua
Создание и использование классов
Примеры использования классов:
(Быстро накатал - не судите строго)

Код
class.cutility {
  SomeFunction = function(self)
  end;
}

class.cbase {
}

class.cplagin (cutility, cbase, {
  name;
  desc;
  __init = function(self, sName, sDesc)
    self.name = sName
    self.desc = sDesc
  end;
})

--создание объектов класса

mPlagin = cplagin("myFirstPlagin", "ForTest") -- вызов конструктора __init


Существую классы, в которых мы можем описывать то, что нам нужно и существуют объекты, которые строятся на основании классов.

Свой класс можно создать двумя способами:

1)

Код
class.NameOfClass ([<наследуемый_класс>, <наследуемый_класс>, ..., ]{таблица с элементами класса})

в [скобках] - необязательные параметры

2)

Код
NameOfClass = class(["NameOfClass", ][<наследуемый_класс>, <наследуемый_класс>, ... , ]{таблица с элементами класса})


в данном примере класс cplagin наследует классы cutility и cbase. Поэтому в классе cplagin мы можем вызывать функции классов cutility и cbase.

Да, совсем забыл сказать, что для использования классов нужно подключить файл class.lua, который выложен в топике: http://mydc.ru/index.html?showtopic=1429&a...ost&p=15699
Файл кладётся в папку libs (либо в папку с ptokax.exe). Подключается так:
Код
require"class"


Такое подключение файла в lua аналогично подключению заголовочный файлов в с++
Saymon21
4.6.2009, 23:41 Отсылка в ЛС скачивающим у меня
Ну это само собой.
У хаба нет возможности отследить скачивание каждого файла. Есть только возможность отследить установку соединения между пользователями, и пока это соединение будет установлено будут качаться файлы. А для скачки ли устанавливалось соединение, или просто так посмотреть, хаба вовсе не заботит, его дело направить пользователей для их соединения между собой. Скачка не производится через хаб, а происходит между пользователями напрямую!!!


Код
local sMsg = "*** Connecting: [NICK]"
local sBot = "Bot"

function ConnectToMeArrival(tUser, sData)
  local sNick = sData:match"(%S+) %S+$"
  if sNick then
    Core.SendPmToNick(sNick, sBot, tostring(sMsg:gsub("%[NICK%]", tUser.sNick)))
  end
end
Uncle_Dif, мамин_парень
2.6.2009, 23:01 Описание Протокола ADC
Advanced Direct Connect Protocol
4.2. Файл-лист

files.xml - список файлов, предназначенных для просмотра. Этот список должен удовлетворять следующей XML схеме:

HTML
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="base32Binary">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Za-z2-7]+"></xs:pattern>
</xs:restriction>
</xs:simpleType>

<xs:simpleType name="zeroOne">
<xs:restriction base="xs:int">
<xs:enumeration value="0"></xs:enumeration>
<xs:enumeration value="1"></xs:enumeration>
</xs:restriction>
</xs:simpleType>

<xs:complexType name="ContainerType">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:choice>
<xs:element ref="Directory"></xs:element>
<xs:element ref="File"></xs:element>
<xs:any processContents="lax"></xs:any>
</xs:choice>
</xs:sequence>
</xs:complexType>

<xs:attribute name="Base" type="xs:string"></xs:attribute>
<xs:attribute name="CID" type="base32Binary"></xs:attribute>
<xs:attribute name="Generator" type="xs:string"></xs:attribute>
<xs:attribute name="Incomplete" type="zeroOne" default="0"></xs:attribute>
<xs:attribute name="Name" type="xs:string"></xs:attribute>
<xs:attribute name="Size" type="xs:int"></xs:attribute>
<xs:attribute name="Version" type="xs:int"></xs:attribute>

<xs:element name="FileListing">
<xs:complexType>
<xs:complexContent>
<xs:extension base="ContainerType">
<xs:attribute ref="CID" use="required"></xs:attribute>
<xs:attribute ref="Version" use="required"></xs:attribute>
<xs:attribute ref="Generator" use="optional"></xs:attribute>
<xs:attribute ref="Base" use="required"></xs:attribute>
<xs:anyAttribute processContents="lax"></xs:anyAttribute>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>

<xs:element name="Directory">
<xs:complexType>
<xs:complexContent>
<xs:extension base="ContainerType">
<xs:attribute ref="Name" use="required"></xs:attribute>
<xs:anyAttribute processContents="lax"></xs:anyAttribute>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>

<xs:element name="File">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded"></xs:any>
</xs:sequence>
<xs:attribute ref="Name" use="required"></xs:attribute>
<xs:attribute ref="Size" use="required"></xs:attribute>
<xs:anyAttribute processContents="lax"></xs:anyAttribute>
</xs:complexType>
</xs:element>

</xs:schema>


Пример файл-листа:

HTML
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<FileListing Version="1" CID="mycid" Generator="DC++ 0.701" Base="/">
<Directory Name="share">
<Directory Name="DC++ Prerelease">
<File Name="DCPlusPlus.pdb" Size="17648640" TTH="xxx" />
<File Name="DCPlusPlus.exe" Size="946176" TTH="yyy" />
</Directory>
<File Name="ADC.txt" Size="154112" TTH="zzz" />
</Directory>
<!-- Только при использовании частичного файл-листа -->
<Directory Name="share2" Incomplete="1"/>
</FileListing>


"encoding" должен быть всегда установлен в UTF-8. Клиенты должны иметь возможность оперировать с XML фалами как с BOM (byte order mark) так и без такового.

"Version" не изменяется, если не изменяется структура файла.

"CID" - это CID клиента, который генерирует файл-лист.

"Generator" - это опция для информативной цели.

"Base" - используется в частичных файл-листах, но также должно присутствовать и в простых файл-листах.

"Incomplete" - сигнализирует о том, что в частичном файл-листе содержатся не включённые в список пункты. "1" - означает, что директория содержит не включённые в список пункты, "0" - не содержит таковых. Incomplete="0" - по умолчанию и таким образом может быть опущено.

Дополнительная информация может быть добавлена в файл расширениями/дополнениями, но не гарантировано, что эта информация будет прочитана другими клиентами.
Invisible, Saymon21
2.6.2009, 22:44 Описание Протокола ADC
Advanced Direct Connect Protocol
4. Файлы

4.1. Имена файлов и структура

Имена файлов отсчитываются от относительного (вымышленного) корня в шаре пользователя. "/" - разделитель директорий; каждый файл или имя директории должно быть уникальным в регистро-независимом контексте. Все печатные символы, включая пробел, допустимы в имени файла, символы "/" и "\" экранируются символом "\". Клиенты должны использовать фильтры для имён под свои файловые системы, имена файлов, полученные от других клиентов, должны также подчиняться этим правилам. Специальные имена "." и ".." не могут содержаться в директории или имени файла; любой полученный файл-лист, содержащий эти имена должен быть проигнорирован. Все имена директорий должны оканчиваться на "/".

Расшаренные файлы идентифицируются относительно безымянного корня "/" ("/dir/subdir/filename.ext"), тогда как дополнения могут добавить имя корня. Например, "TTH/…" для TIGR дополнения используют имя корня "TTH" для идентификации файлов по их "Tiger Tree Hash". Это недопустимо для имён из безымянного корня, которые попали в шару с идентификатором по контрольной сумме.

Без корневое имя файла "files.xml" определяет полный файл-лист, в формате XML в кодировке UTF-8. Клиентам рекомендуется использовать дополнения чтобы сжимать данный файл-лист.

Дополнения могут добавлять к имени файла свои расширения, обычно это делается для того, чтобы избежать повторения имён.

Специальный тип "list" используется для просмотра списков файлов. Частичный файловый список имеет ту же структуру, что и нормальный список, но директории могут быть теговыми с атрибутом Incomplete="1", который показывает на частичность. Только директории без корневых файлов могут начинаться с символа "/". Содержимое такой директории в последствии будет послано просящему клиенту на глубину, выбранную им (это нужно для отправки только того уровня, который требуется пользователю). Атрибут "Base" для поля "FileListing" определяет к какой конкретной директории принадлежит данный файл.
Invisible, Saymon21
2.6.2009, 22:39 Описание Протокола ADC
Advanced Direct Connect Protocol
3.5.3. CID

Идентификатор клиента глобально и публично идентифицирует уникальные клиенты и лежит в основе связи между клиентами. Он генерируется по PID по определённому алгоритму. Хаб должен регистрировать клиентов по CID-у. CID должен оставаться неизменным в течении сессии. Клиенты должны уметь оперировать с CID-ми переменной длины.
Saymon21
2.6.2009, 22:35 Описание Протокола ADC
Advanced Direct Connect Protocol
3.5.2. PID

Приватный идентификатор глобально идентифицирует уникальных клиентов. Он используется при коннекте для генерации CID и не виден другим клиентам. PID генерируется для того, чтобы избежать конфузов. При генерации PID (при первом запуске клиента) используется текущее время и MAC адрес сетевой карты. Хабы и клиенты не должны раскрывать приватные идентификаторы другим клиентам, так как это нарушает безопасность ADC сетей. Клиенты должны иметь один и тот же PID в течение всей сессии на хабе.

Клиент отсылает на хаб данный идентификатор в команде INF. Хаб удаляет из команды INF этот идентификатор перед тем как отослать команду INF всем пользователям хаба.
Invisible, Saymon21
2.6.2009, 22:33 Описание Протокола ADC
Advanced Direct Connect Protocol
3.5.1. SID

Идентификатор сессии даётся клиенту на сессию, в течение которой он находится на хабе. Это идентификатор уникального пользователя на хабе, который назначается при входе на хаб. SID - 20-битный код, закодированный 4-байтной base32 строкой.
Invisible, Saymon21
2.6.2009, 22:29 Описание Протокола ADC
Advanced Direct Connect Protocol
3.5. Идентификация клиента

Каждый клиент идентифицируется по трём различным идентификаторам: идентификатор сессии - Session ID (SID), личный идентификатор - Private ID (PID) и идентификатор клиента - Client ID (CID).
Invisible, Saymon21
2.6.2009, 22:27 Описание Протокола ADC
Advanced Direct Connect Protocol
3.4. Хеш-функции

Некоторые команды используются для определяния хеш-функций. При установке каждого нового соединения по команде SUP происходит обмен хеш-функциями. При коннекте клиент передаёт серверу несколько хеш-функций посредствам параметров команды SUP. Сервер вбирает одну из них и передаёт её клиенту, поставив её до любой другой хеш-функции в команде SUP, которая отправится с сервера. Клиент и хаб должны иметь по крайней мере одну одинаковую хеш-функцию, которая будет использоваться в протоколе и в файловой идентификации.
Invisible
2.6.2009, 22:23 Описание Протокола ADC
Advanced Direct Connect Protocol
3.3. Типы команд

Тип команды (определяющий символ, находящийся в начале команды) определяет то, каким образом отсылать эту команду. Клиенты, как получатели, используют ограниченный набор типов для рассылки. Клиенты должны использовать типы только для того, чтобы помочь себе распарсить команду, иначе команда должна игнорироваться. Итак, определены следующие типы (префиксы) команд:

B (Broadcast)
Хаб должен отослать команду всем подключенным клиентам, включая и самого отправителя.

C (Client message)
Клиенты должны использовать эту команду только для прямого соединения по протоколу TCP.

D (Direct message)
Хаб должен отправить эту команду для пользователя с указанным sid.

E (Echo message)
Хаб должен отправить команду для пользователей с sid и my_sid.

F (Feature broadcast)
Хаб должен отослать эту команду всем клиентам, которые поддерживают(+)/не поддерживают(-) данную характеристику. Поддержка клиентом той или иной характеристики определяется из поля SU, которое содержится в команде INF, отсылаемой клиентом.

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

I (Info message)
Хабы должны использовать данный тип для отсылки команды, которая не была отослана другим клиентом.

U (UDP message)
Клиенты должны использовать эту команду только для прямого соединения по протоколу UDP.
Invisible
2.6.2009, 22:17 Описание Протокола ADC
Advanced Direct Connect Protocol
3.2. Синтаксис команд

Код
message               ::= message_body? eol
message_body          ::= (b_message_header | cih_message_header | de_message_header | f_message_header | u_message_header | message_header)
                          (separator positional_parameter)* (separator named_parameter)*
b_message_header      ::= 'B' command_name separator my_sid
cih_message_header    ::= ('C' | 'I' | 'H') command_name
de_message_header     ::= ('D' | 'E') command_name separator my_sid separator target_sid
f_message_header      ::= 'F' command_name separator my_sid separator (('+'|'-') feature_name)+
u_message_header      ::= 'U' command_name separator my_cid
command_name          ::= simple_alpha simple_alphanum simple_alphanum
positional_parameter  ::= parameter_value
named_parameter       ::= parameter_name parameter_value?
parameter_name        ::= simple_alpha simple_alphanum
parameter_value       ::= escaped_letter+
target_sid            ::= encoded_sid
my_sid                ::= encoded_sid
encoded_sid           ::= base32_character{4}
my_cid                ::= encoded_cid
encoded_cid           ::= base32_character+
base32_character      ::= simple_alpha | [2-7]
feature_name          ::= simple_alpha simple_alphanum{3}
escaped_letter        ::= [^ \#x0a] | escape 's' | escape 'n' | escape escape
escape                ::= '\'
simple_alpha          ::= [A-Z]
simple_alphanum       ::= [A-Z0-9]
eol                   ::= #x0a
separator             ::= ' '
Invisible
2.6.2009, 22:11 Описание Протокола ADC
Advanced Direct Connect Protocol
3. Структура протокола

3.1. Основное

  • Все команды протокола начинаются с четырёх букв. Первая буква определяет то, как команда должна быть послана, следующие три показывают что должно быть выполнено.

  • Параметры разделяются пробелами, а каждая команда заканчивается символом переноса строки (код 0x0a). Экранируются элементы: "\s" - пробел, "\n" - новая строка и "\\" - обратный слеш. Данная версия протокола резервирует все остальные экранированные символы для возможного дальнейшего использования; любые команды, содержащие неизвестные экранированные символы, должны игнорироваться.

  • Все отсылаемые команды должны отправляться в кодировке UTF-8 - закодированный Юникод в С нормализации.

  • Клиенты должны игнорировать неизвестные/неправильные команды. Хабы должны игнорировать неправильные команды, и должны отсылать неизвестные команды, согласно их типу (префиксу).

  • Адреса клиентов должны быть определены в виде десятичных чисел, разделённых точками ("x.x.x.x") для IPv4 или в формате RFC (1884) для IPv6. Адреса хабов должны быть определены ссылкой с добавкой "adc" спереди, которая показывает специфику данного протокола ("adc://server:port/").

  • Числа отсылаются как строки в соответствии со стандартом плавающей точки, в качестве разделителя между целой дробной частью используется точка "." . Целыми являются числа без дробной части и без экспоненциальной добавки. Приложения должны иметь возможность оперировать с 64-битными положительными числами и с 64-битными числами с плавающей точкой. Префиксом отрицания является знак "-".

  • SID, PID, CID и короткие бинарные данные отсылаются как закодированные base32 строки. Длинные бинарные данные должны передаваться, используя файловый механизм передачи.

  • Имена расширений, протокольные имена и другой текст, не входящий в сообщения пользователя, могут включать только видимые символы, которые кодируются одним байтом в кодировке UTF-8 (Юникодные символы с номера 33 до 127). ADC - регистрозависим, и требует, чтобы имена команд были только в верхнем регистре.

  • Некоторые команды и функциональные зависимости требуют использования хешей. Хеш генерируется в процессе установки сессии и остаётся постоянной на протяжении всей этой сессии (SID).
Invisible, Saymon21
2.6.2009, 22:07 Описание Протокола ADC
Advanced Direct Connect Protocol
2. История версий

Последующие версии этого документа, а также промежуточные и более старые версии могут быть получены по адресу: https://dcplusplus.svn.sourceforge.net/svnr...s/trunk/ADC.txt. Эта версия представляется к ревизии: 923.
Данная версия: 1.0, 2007-12-01 (Первый релиз)
Invisible
2.6.2009, 22:04 Описание Протокола ADC
Advanced Direct Connect Protocol
1. Введение

ADC - это протокол для клиент-серверных сетей, на подобии Neo-Modus' Direct Connect (NMDC). Целью является создание простого протокола, который не нагружает ни клиент, ни сервер, и который можно расширять. В нём исправлены некоторые неудачные решения протокола NMDC, но не все.

Рассматриваются те же самые взаимодействия: клиент-клиент и клиент-сервер. Данная документация разделена на две части; первая часть описывает структуру протокола, вторая - специфичность системы протокола для использования этой структуры. Advanced Direct Connect - это первая версия, которая будет постепенно улучшаться.

Большинство идей для протокола пришли из проекта DCTNG (Jan Vidar Krey's). Основные участники разработки: Dustin Brody, Walter Doekes, Timmo Stange, Fredrik Ullner, Fredrik Stenberg и другие. Jon Hess посодействовал как создатель протокола NMDC.

Преимущества протокола:
  • SID, а также названия команд протокола, состоят из четырёх латинских символов в верхнем регистре. Протокол достаточно хорошо подходит для реализации на языке СИ. По стандарту языка СИ sizeof(char) == 1, то есть 4 символа будут занимать 4 байта, или могут быть представлены в виде четырёхбайтового целого числа. Преобразование строки в число и обратно значительно упрощает и оптимизирует работу с командами и даёт возможность хранить команду в виде объединения.


Недостатки протокола:
  • Разделителями протокола являются очень распространённые символы (пробел и перенос), которые нужно заменять на \s и \n. Так как эти символы очень распространены в сообщениях, то число замен будет всегда большим, чего не было в протоколе NMDC.
  • По сравнению с протоколом NMDC, в протоколе ADC есть возможность в UserCommand удалить определённое меню. Однако, по-прежнему отсутствует возможность удаления определённого меню в определённом контексте.
Invisible, Saymon21
2.6.2009, 22:01 Описание Протокола ADC
Advanced Direct Connect Protocol
Структурированное описание протокола Advanced Direct Connect (ADC), под управлением которого уже работают некоторые хабы.
Ссылка на оригинальное описание: http://adc.sourceforge.net/ADC.html

По мере написания, в содержании будет появляться ссылка на соответствующий пост.
Делаю тему закрытой, дабы структурировано всё описать.


1. Введение
2. История версий
3. Структура протокола
3.1. Основное
3.2. Синтаксис команд
3.3. Типы команд
3.4. Хеш-функции
3.5. Идентификация клиента
3.5.1. SID
3.5.2. PID
3.5.3. CID

4. Файлы
4.1. Имена файлов и структура
4.2. Файл-лист

5. Команды характеристики BASE
5.1. Клиент – Хаб взаимодействие
5.2. Клиент – Клиент взаимодействие
5.3. Команды
STA
SUP
SID
INF
MSG
SCH
RES
CTM
RCM
GPA
PAS
QUI
GET
GFI
SND

6. Примеры
6.1. Связь Клиент – Хаб
6.2. Связь Клиент – Клиент

7. Стандартные дополнения/расширения
7.1. TIGR - поддержка TTH (Tiger Tree Hash)
7.2. BZIP – сжатие файл-листа пи помощи библиотеки bzip2
7.3. ZLIB - сжатие связи
7.3.1. ZLIB-FULL
7.3.2. ZLIB-GET
Nickolya, SdimS, Invisible, Saymon21
25.5.2009, 17:05 Скрипт бана читеров
использование greylink против читов
Вот накатал скрипт для бана читеров.
Используем грейлинк, для того, чтобы банить читеров big_smile.gif

Название скрипта: cheats-detector
Версия: 1.1
Автор: Setuper
Описание: Ловит несоответствия в размере шары. В действиях можно указать бан пользователя.
Команды:
/checkshare nick - проверка пользовтеля с указанным ником
/checkshare - проверка всех пользователей данного хаба
/luafile startup.lua - команда запуска скрипта
/lua dcpp = nil - команда остановки скрипта

Для работы скрипта в папке lua должны находиться библиотеки lua32.dll и dcutil32.dll (или соответствующие 64 разрядные)
Сам скрипт кидаем в папку scripts. Скрипт будет запускаться автоматически при старте клиента.

Открываем файл Settings/CustomMessages.ini и дописываем туда:
Код
/lua dcpp = nil
/luafile startup.lua
/checkshare
После этого можно будет не запоминать команды, а юзать меню "пользовательские сообщения".


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

Юзаем и отписываем сюда если что не так big_smile.gif


[attachment=2522:startup.lua]
мамин_парень
23.5.2009, 1:59 LFS
win32 - API 2 | Библиотека файловой системы
Библиотека работы с файловой системой.

Название: LuaFileSystem (LFS)
Версия API: 2
Версия библиотеки: 1.4.2
Версия LUA: 5.1
Авторы: Roberto Ierusalimschy, André Carregal, Tomás Guisasola

Подключение библиотеки:
Код
require"pxlfs"
Все функции библиотеки после подключения будут находиться в глобальной таблице lfs.

[attachment=2473:PXLFS.rar]
Invisible, Saymon21, DriverZX-10, MIKHAIL
20.5.2009, 17:41 Объектно-Ориентированное Программирование в Lua
Создание и использование классов
Доработки:

1) Добавлена возможность для описания функций и членов класса "внутри" самого класса.

Идентичные примеры:
Код
class.Account()

function Account:__init(initial)
    self.balance = initial or 0
end

function Account:deposit(amount)
    self.balance = self.balance + amount
end

function Account:withdraw(amount)
    self.balance = self.balance - amount
end

function Account:getbalance()
    return self.balance
end


Код
class.Account {

  __init = function(self, initial)
    self.balance = initial or 0
  end;

  deposit = function(self, amount)
    self.balance = self.balance + amount
  end;

  withdraw = function(self, amount)
    self.balance = self.balance - amount
  end;

  getbalance = function(self)
    return self.balance
  end;
}


Правила для объявления классов:
Код
class.MyClass([inherited,] [{members}])

Код
[local] MyClass = class(["MyClass",] [inherited,] [{members}])


2) Изменено название функции shared. Новое название: virtual. Думаю, что новое название более логично, а старое может только запутать. Данная функция служит для построения виртуальных классов, и она в точности реализует механизм виртуального наследования классов, как это происходит в языке С++.

3) Для того, чтобы таблица class приобрела свойства зарезервированного слова, запрещена запись в эту таблицу. Данная таблица используется исключительно для построения классов.

4) Исправлены все внутренние поля и локальные переменные с shared на is_virtual, дабы не вносить непонятности.

[attachment=2451:class.lua]
Saymon21
20.5.2009, 14:05 Объектно-Ориентированное Программирование в Lua
Создание и использование классов
Для того чтобы проследить работу с библиотекой классов и понять как всё это работает, предлагаю продебажить следующий простой пример. Дебажить можно с помощью средств LuaEdit.

Код
class.Account()

function Account:__init(initial)
    self.balance = initial or 0
end
function Account:deposit(amount)
    self.balance = self.balance + amount
end
function Account:withdraw(amount)
    self.balance = self.balance - amount
end
function Account:getbalance()
    return self.balance
end

-----------------------------------

class.NamedAccount(shared(Account))    -- shared Account base

function NamedAccount:__init(name, initial)
    self.Account:__init(initial) -- 10.00
    self.name = name or 'anonymous' -- 'John'
end

-----------------------------------

class.LimitedAccount(shared(Account))  -- shared Account base

function LimitedAccount:__init(limit, initial)
    self.Account:__init(initial) -- 10.00
    self.limit = limit or 0 -- 0.00
end

function LimitedAccount:withdraw(amount)
    if self:getbalance() - amount < self.limit then
       error 'Limit exceeded'
    else
       self.Account:withdraw(amount)
    end
end

-----------------------------------

class.NamedLimitedAccount(shared(NamedAccount), shared(LimitedAccount))

function NamedLimitedAccount:__init(name, limit, initial)
    self.NamedAccount:__init(name, initial) -- 'John', 10.00
    self.LimitedAccount:__init(limit, initial) -- 0.00, 10.00
end

-- widthdraw() disambiguated to the limit-checking version
function NamedLimitedAccount:withdraw(amount)
    return self.LimitedAccount:withdraw(amount)
end

-----------------------------------

myNLAccount = NamedLimitedAccount('John', 0.00, 10.00)
myNLAccount:deposit(2.00)
print('balance now', myNLAccount:getbalance())   --> 12.00
myNLAccount:withdraw(1.00)
print('balance now', myNLAccount:getbalance())   --> 11.00
--myNLAccount:withdraw(15.00)                    --> error, limit exceeded


[attachment=2675:screen.jpg]
Saymon21
17.5.2009, 23:02 Объектно-Ориентированное Программирование в Lua
Создание и использование классов
Библиотека построения именованых классов от разработчика lua.
Самая продвинутая реализация классов и практически всех принципов ООП, включая виртуальные классы!
[attachment=2423:classlib.lua]

Упрощённая библиотека построения безымянных классов от разработчика lua.
[attachment=2425:unclasslib.lua]

В дальнейшем мною будут выложены подкорректированные варианты, так как в данных вариантах мною были найдены мелкие недочёты.
Saymon21, xnt, dj--alex
11.5.2009, 11:38 У вас нет прав на просмотр этой темы
У вас нет прав на просмотр этого сообщения
степашка
6.5.2009, 15:02 Antibot
API2 | Скрипт против ботов
Название скрипта: Antibot
Версия API: 2
Автор: Setuper
Описание: Скрипт запрещает писать в чат или в приват незарегистрированному, пока пользователь не ответит на вопрос.


[attachment=2319:antibot.lua]
Invisible, Accelerator, Master-Grow, Pro009, shur49, Booth
3.5.2009, 18:20 От: Объектно-ориентированные Принципы В Lua
От темы с ID: 1429
Простой пример скрипта RegCmd на использование классов.

Содержит наглядные примеры использования в lua:
  • классов
  • объектов
  • модулей
  • передачи параметров по ссылке и по значению
  • инкапсуляции


Не содержит наглядных примеров на использование аппаратов наследования и полиморфизма (рассмотрено ранее).


[attachment=2304:example.rar]
MIKHAIL
27.4.2009, 14:32 ===> Прочитать перед использованием скриптов <===
ЧТО НЕОБХОДИМО ДЛЯ РАБОТЫ СКРИПТОВ
Все скрипты данной ветки форума работают с базой данных MySQL.

Поэтому, прежде чем качать скрипт, установите себе mysql сервер и соответствующие библиотеки.

Если у вас нету mysql сервера, то качаем его, например отсюда: http://www.mysql.ru/download/ (файл mysql-5.0.67-win32.zip)
Для удобного администрирования можно скачать утилиту mysql-gui-tools

Качаем архив http://mydc.ru/ipb.html?act=attach&type=post&id=1785
В архиве находится dll файл libmysql.dll и папка luasql с dll файлом mysql.dll. Обе эти дллелки нужны для работы бд.
Распаковываем архив в папку, где лежит файл ptokax.exe, и ничего никуда не перемещаем.
Для того, чтобы не засорять основную папку и для возможности более гибкого подключения модулей, в PtokaX предусмотрено создание папки libs, в которую и помещаются все DLL файлы. Поэтому можно создать папку libs (если она не была создана ранее) и распаковать архив с библиотеками в эту папку libs, а не в основную папку, где находится файл ptokax.exe.


И ещё. Все скрипты работают только на хабах с API 2, то есть на хабах PtokaX версии 0.4.0.0 и новее.



Более подробно в теме: http://mydc.ru/topic1508.html
Invisible, Kingston, Saymon21, shullz
23.4.2009, 11:18 У вас нет прав на просмотр этой темы
У вас нет прав на просмотр этого сообщения
степашка
22.4.2009, 22:40 У вас нет прав на просмотр этой темы
У вас нет прав на просмотр этого сообщения
степашка
22.4.2009, 10:38 У вас нет прав на просмотр этой темы
У вас нет прав на просмотр этого сообщения
степашка
21.4.2009, 19:23 Mysql
win32 - API 2 | Самая распространённая база данных
Экранирование в MySQL.

Для начала - немного о кавычках.
Если мы подставляем в запрос какие-либо данные, то, чтобы отличить эти данные от команд SQL, их надо брать в кавычки.
К примеру, если написать
Код
SELECT * FROM mytable WHERE name = Nick
то база решит, что Nick - это имя другого поля, не найдёт его, и выдаст ошибку. Поэтому подставляемые данные (в данном случае имя Nick) надо заключать в кавычки - тогда база сочтет его строкой, значение которой надо присвоить полю name:
Код
SELECT * FROM mytable WHERE name = 'Nick'
Однако, и в самих данных могут тоже встречаться кавычки. К примеру,
Код
SELECT * FROM mytable WHERE name = 'Д'Артаньян'
Здесь база данных решит, что 'Д' - это данные, а Артаньян - команда, которую она не знает, и тоже выдаст ошибку. Поэтому и надо прослешивать все данные, чтобы объяснить базе, что встречающиеся в них кавычки (и некоторые другие спецсимволы) относятся к данным.
В результате мы получим правильный запрос, который ошибок не вызовет:
Код
SELECT * FROM mytable WHERE name = 'Д\'Артаньян'


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


Следует специально отметить: добавленные слеши НЕ идут в базу. Они нужны только в запросе. При попадании в базу слеши отбрасываются. Соответственно, распространенной ошибкой является попытка удалить слеши при получении данных из базы.

На самом деле, всё вышесказанное относится к данным строкового типа и датам. Числа можно вставлять не прослешивая и не окружaя кавычками. Если вы так делаете, то ОБЯЗАТЕЛЬНО! насильно приводите данные к нужному типу перед вставкой в запрос, например:
Код
id = tonumber(id)
Однако для простоты (и надёжности) можно и с числами работать, как со строками (проскольку mysql всё равно преобразует их к нужному типу). Соответственно, мы будем любые данные, вставляемые в запрос, прослешивать и заключать в кавычки.

Так же, есть ещё одно правило - необязательное, но его следует придерживаться во избежание появления ошибок:
Имена полей и таблиц следует заключать в обратные одинарные кавычки - `поле` (клавиша с этим символом находится на стандартной клавиатуре слева от клавиши "1") Ведь имя поля может совпадать с ключевыми словами mysql, но если мы используем обратную кавычку, то MySQL поймёт всё правильно:
Код
SELECT * FROM `WHERE` WHERE `DATE` = '2009-04-21'


Следует различать эти кавычки и не путать одни с другими. Следует также помнить, что обратные кавычки слешами не экранируются!


Наиболее эффективное экранирование.

Для наиболее эффективного экранирования кавычек следует использовать функцию:
Код
_G.string.dbformat = function(self, ...)
  local t = {...}
  for k, v in _G.ipairs(t) do
    t[k] = _G.tostring(v):gsub("'", "\\'")
  end
  return self:format(_G.unpack(t))
end

Рассмотрим пример использования данной функции на примере вставки в таблицу данных:
Код
con:execute(("INSERT INTO `mytable` (`nick`, `ip`, `client`, `share`) VALUES
('%s', '%s', '%s', '%s')"):dbformat("Д'Артаньян", "192.168.0.1", "StrgDC++", 27635467))
Что мы сделали? Мы просто, так сказать, переопределили всем известный метод format, написав в качестве его аналога, метод dbformat, который выполняет тоже самое, что и метод format, но дополнительно к этому, он экранирует одинарные кавычки.
Invisible, Saymon21, Win32
13.4.2009, 14:43 Actions
Всем известный скрипт действий
Название скрипта: Actions
Версия: 1.1
Хаб: HeXHub
Автор: Setuper
Описание: Скрипт действий. Название говорит само за себя. Придумывайте и добавляйте свои действия.


[attachment=2547:actions.lua]
ANDRBEST, shur49
12.4.2009, 23:06 У вас нет прав на просмотр этой темы
У вас нет прав на просмотр этого сообщения
степашка
10.4.2009, 13:33 У вас нет прав на просмотр этой темы
У вас нет прав на просмотр этого сообщения
степашка
10.4.2009, 10:56 У вас нет прав на просмотр этой темы
У вас нет прав на просмотр этого сообщения
степашка
9.4.2009, 13:49 Модули Lua В Linux
приветы те многие
Не понял суть созданной темы!
мамин_парень
9.4.2009, 12:12 От: Объектно-ориентированные Принципы В Lua
От темы с ID: 1429
Описание класса с функциями "необязательного объявления".

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

Код
--[[
*
*     Copyright (C) 2009 by Setuper
*
*     This program is free software: you can redistribute it and/or modify
*     it under the terms of the GNU General Public License as published by
*     the Free Software Foundation, version 3 of the License.
*
*     This program is distributed in the hope that it will be useful,
*     but WITHOUT ANY WARRANTY; without even the implied warranty of
*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*     GNU General Public License for more details.
*
*     You should have received a copy of the GNU General Public License
*     along with this program.  If not, see <http://www.gnu.org/licenses/>.
]]

--[[  Module for building of classes with inheritance
*     Returns function for building of the class
*    
*     class(...)
*    
*     @author Setuper
]]

do
  local _G = _G
  local function concat(p1, p2)
    local t = {}
    for k, v in _G.pairs(p1) do
      t[k] = v
    end
    for k, v in _G.pairs(p2) do
      t[k] = v
    end
    if _G.next(p1.__parent or {}) or _G.next(p2.__parent or {}) then
      t.__parent = concat(p1.__parent or {}, p2.__parent or {})
    end
    return t
  end
  
  class = function(...)
    local t, m = {}, {}
    _G.setmetatable(t, m)
    for i = 1, _G.select('#', ...) do
      local p = _G.select(i, ...)
      if _G.type(p) == "table" then
        for k, v in _G.pairs(p) do
          t[k] = v
        end
      end
    end
    m.__call = function(self, ...)
      local t, mt_old, mt_new = {}, {}, {}
      for k, v in _G.pairs(_G.getmetatable(self) or {}) do
        mt_old[k] = v
      end
      for k, v in _G.pairs(self) do
        mt_old[k] = v
      end
      for i = 1, _G.select('#', ...) do
        local p = _G.select(i, ...)
        if _G.type(p) == "table" then
          for k, v in _G.pairs(_G.getmetatable(p) or {}) do
            mt_new[k] = v
          end
          for k, v in _G.pairs(p) do
            t[k] = v
          end
        end
      end
      mt_new = concat(mt_old, mt_new)
      mt_new.__index = function(self, key)
        if t.__parent[key] then
          return t.__parent[key]
        else
          return function(self)
            return nil
          end
        end
      end
      t.__parent = mt_new
      _G.setmetatable(t, mt_new)
      return t
    end
    return t
  end
end
MIKHAIL
5.4.2009, 11:30 Соедиенение Пользователей Инет + Локальная Сеть
Как соединить с лок. адреса с включ. VPN с юзерами из инета?
мамин_парень
1.4.2009, 11:36 Motd_for_ops
API1, API2 | Сообщение дня для ОПераторов хаба
опробуй ща.
мамин_парень
31.3.2009, 21:51 Hideme
Прячет ник
Название скрипта: HideMe
Версия: 1.1
Хаб: HeXHub
Автор: Setuper
Описание: Скрипт скрывает ник в списке пользователей.
Действует на одну (текущую) сессию.
После ухода с хаба удаляет ник пользователя из списка скрытых ников.
Доступен чат между всеми скрытыми.
Скрыть ник можно только через меню.
Скрываться могут пользователи с уровнем >= 20000. Уровень можно настроить по своему усмотрению (в самом скрипте настройка iLevel).
Для просмотра скрытый пользователей отошлите в чат слово: СКРЫТЫЕ. Слово можно отсылать в любом регистре.

[attachment=2018:hideme.lua]
shur49, мамин_парень
30.3.2009, 1:28 Motd_for_ops
API1, API2 | Сообщение дня для ОПераторов хаба
Перезалил
мамин_парень
22.3.2009, 18:59 Say_script 1.03 - 1.031
API1 | Скрипт, позволяющий писать от любого имени
От бота понятно, а от пользователя то зачем?
Ksan
21.3.2009, 12:34 Вопросы Разработчикам Скриптов с SQL
вопросы по скриптам (мелкие вопросы)
id - это индексированное поле. Служит для наискорейшего выполнения запросов.

Апострофами выделяются имена полей, таблиц, баз данных и тд. Выделять апострофами не обязательно, если имя уникально (не используется в синтаксисе sql), однако хорошие программисты, дабы не отвлекаться на эту мелочь, всегда выделяют все имена апострофами. Приведу пример:
Код
assert(con:execute"CREATE TABLE IF NOT EXISTS TABLE(`field` INT)")
в данном случае запрос не выполнится и будет выдана ошибка, всё из-за того, что имя таблицы - TABLE, является ключевым словом sql. Однако если написать так:
Код
assert(con:execute"CREATE TABLE IF NOT EXISTS `TABLE`(`field` INT)")
то запрос выполнится. Поэтому чтобы не отвлекаться и не проверять на совпадение с ключевыми словами, имена всех придуманных объектов заключаем в апострофы.

По поводу скрипта:
1) Не закрыт курсор!!!!!
2) Ограничение можно делать в самом sql, используя LIMIT.

[attachment=1917:MsgTopMySQL.lua]
Saymon21
19.3.2009, 14:35 ! Часто Задаваемые Вопросы !
Обязательно прочитать всем!!!
Как сделать приветствие с указанием времени суток?

Код
function UserConnected(tUser)
  local iHour, sMsg = tonumber(os.date"%H"), tUser.sNick..". Добро пожаловать на хаб!"
  if iHour >= 5 and iHour < 12 then
    Core.SendToUser(tUser, ("Доброе утро %s"):format(sMsg))
  elseif iHour >= 12 and iHour < 18 then
    Core.SendToUser(tUser, ("Добрый день %s"):format(sMsg))
  elseif iHour >= 18 and iHour <= 23 then
    Core.SendToUser(tUser, ("Добрый вечер %s"):format(sMsg))
  else
    Core.SendToUser(tUser, ("Доброй ночи %s"):format(sMsg))
  end
end
RegConnected, OpConnected = UserConnected, UserConnected
Tsd, Invisible, Accelerator, Uncle_Dif, Saymon21, X-Sky, Cyber_voodoo, мамин_парень
17.3.2009, 22:13 Нормализатор Меню
API2
Не совсем понятно действие:
Код
local _,_,script=string.find(debug.getinfo(1).source,"@(.*)")
while ScriptMan.MoveUp(script) do
  ScriptMan.MoveUp(script)
end
ведь не работает.

Если смысл был поставить скрипт самым первым, то я думаю надо было написать так:
Код
local _,_,script=string.find(debug.getinfo(1).source,"@.+\\(.*)")
while ScriptMan.MoveUp(script) do
  ScriptMan.MoveUp(script)
end



Строка Nick=user.sNick тоже не понятно зачем написана.

Использовать дебагер луа вооще говоря не рекомендуется)))
Invisible
14.3.2009, 23:34 Md5
win32 и Unix - API 2 | 128-битный алгоритм хеширования
Библиотека для получения md5 хеша.

Версия API: 2
ОС: win32 или unix
Автор библиотеки: Roberto Ierusalimschy

Для windows: распаковываем содержимое архива в ту папку, где лежит файл ptokax.exe (не извлекаем dll и lua файлы из папки md5!)
Для unix: файлы для сборки в соответствующем архиве.



Краткий мануал по функциям библиотеки

Все функции, зарегистрированные в таблице md5

  • Код
    md5.sum(message)
    Вычисляет MD5 хеши для указанного сообщения. Эта функция берёт входящее сообщение, которое может быть произвольной длины и произвольного содержания, и выводит 128-битный отпечаток (дайджест строки). Входящая строка преобразуется в 16-байтную строку. Предполагается, что это вычисление не может привести к одинаковым хешам от двух различных сообщений.


  • Код
    md5.sumhexa(message)
    Данная функция на подобии функции md5.sum, но возвращает величину из 32-х шестнадцатиричных значений.


  • Код
    md5.crypt(message, key [,seed])
    Кодирует строку, используя MD5, в CFB (Cipher-feedback mode). message - произвольная строка, которая должна быть закодирована. key - произвольная строка, которая используется в качестве ключа для кодирования. seed - необязательный параметр.
    Если необязательный параметр не задан, то вместо него для кодирования используется значение функции os.time(). Рекомендуется использовать различные значения параметра seed для каждого сообщения. Параметр seed не является приватным параметром, которые следует прятать, так как этот параметр передеётся в начале закодированного сообщения.
    Длина закодированного сообщения равна длине сообщения, плюс длина параметра seed, плюс один.


  • Код
    md5.decrypt(message, key)
    Функция декодирует сообщение, закодированное функцией md5.crypt. Для любого сообщения, ключа и параметра seed выполнимо следующее тождество: md5.decrypt(md5.crypt(msg, key, seed), key) == msg


  • Код
    md5.exor(s1, s2)
    Функция возвращает строку в виде побитовой разницы между строками s1 и s2. Строки s1 и s2 должны иметь одинаковую длину, и эта длина равна длине возвращаемой строки.


Архив с библиотекой win32: [attachment=1852:libmd5.rar]
Архив для сборки под unix системы: [attachment=1862:md5.tar]
Пакет для дебиан и убунты: [attachment=1871:libptoka....deb.tar.gz]
Скрипт для тестирования и обучения работе с функциями: [attachment=1853:md5tests.lua]
Nickolya, Invisible
14.3.2009, 14:23 Mysql
win32 - API 2 | Самая распространённая база данных
Свистопляска с кодировками MySQL

Начиная с версии 4.1 появилась возможность устанавливать кодировку на уровне сервера, базы данных, таблицы, столбца. Также появились переменные, которые определяют кодировку клиента (character_set_client), соединения (character_set_connection) и результата (character_set_results).

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

Переменная character_set_connection используется для определения кодировки для литералов, у которых она не определена и при преобразовании числа в строку.

Это значит, что если у вас данные в кодировке cp1251, то для корректной передачи данных необходимо чтобы character_set_client и character_set_connection были установлены в cp1251.

Во все три выше перечисленные параметры можно установить кодировку одним запросом к MySQL:
Код
SET NAMES cp1251
Это эквивалентно трём следующим командам:
Код
SET character_set_client=cp1251
SET character_set_connection=cp1251
SET character_set_results=cp1251


Однако, этой всей свистопляски можно и не делать если установить кодировки по умолчанию. Кодировки по умолчанию устанавливаются в файле my.ini, который находится в директории установленного вами мускула. В данном файле, в соответствующих "разделах", дописывается следующее:
Код
[client]

default-character-set=cp1251
character-sets-dir="C:/MySQL/share/charsets/"


Код
[mysql]

default-character-set=cp1251


Код
[mysqld]

default-character-set=cp1251
default-collation=cp1251_general_ci
character-sets-dir="C:/MySQL/share/charsets/"
init-connect='SET NAMES cp1251'


Внимание! Прописанная настройка init-connect, позволяет не прописывать каждый раз при коннекте к базе данных команду "SET NAMES cp1251", о которой говорилось выше, НО эта настройка не будет выполняться для пользователей, у которых есть привилегия SUPER.

Команда для просмотра кодировок:
Код
SHOW VARIABLES LIKE 'char%';

Использование:
Код
require"luasql.mysql"
local env = assert(luasql.mysql())
local con = assert(env:connect("название_бд", "пользователь", "пароль_пользователя", "localhost"))
local cur = assert(con:execute"SHOW VARIABLES LIKE 'char%'")
local row = cur:fetch({}, "n")
while row do
  Core.SendToAll(string.format("Variable_name: %s, Value: %s", row[1], row[2]))
  row = cur:fetch(row, "n")
end
cur:close()
con:close()
env:close()


И последнее...

При создании базы данных нужно также указывать кодировку создаваемой базы:
Код
CREATE DATABASE IF NOT EXISTS `my_dc_base` DEFAULT CHARACTER SET cp1251 COLLATE cp1251_general_ci;



Соблюдая все вышеизложенные факты, корректная работа базы данных обеспечена!
Invisible, Saymon21, DEN 007
13.3.2009, 19:25 Наборчик Новичку.
Подобного рода вопросы по различным подборкам скриптов прошу обсуждать в данном разделе (Общалка aka Флуд).
Другие разделы просьба не засорять подобного рода темами.
Разделы не просто так существуют. Каждый раздел предназначен для определённых целей, прошу соблюдать тематики разделов.
степашка
12.3.2009, 22:13 Наборчик Новичку.
Тема находилась в разделе запросы скриптов. В теме была просьба о выборе скриптов. В разделе "Запросы скриптов" пишутся идеи по написанию того или иного скрипта, а если вы не знаете какие скрипты себе поставить, то зачем вообще тогда их ставить? Все темы с просьбами подъискать вам подходящие скрипты обречены на закрытие.
степашка
12.3.2009, 1:55 Ridinghubname
API1, API2 |Бегущая строка
Название скрипта: RidingHubName
Версия API: 1, 2
Автор: Nickolya
Описание: Бегущая строка.
Перенесено из раздела "Запросы скриптов".

[attachment=1813:RidingHubName.lua][attachment=1814:RidingHubName_АПИ2.lua]
Invisible, Vizunchik, denis, EnerGetIck, ART8150, Pro009
11.3.2009, 19:37 Наборчик Новичку.
Подобного рода тема - пример неправильной темы.
Прошу в дальнейшем не создавать подобного рода темы!

Модераторы не удаляйте тему некоторое время, чтобы показать всем, что такие темы создавать не нужно.
степашка
11.3.2009, 19:33 Запрет На Пассивный Режим
Скрипт не будет публиковаться в готовых скриптах, дабы направлен на отключение порой жизненно необходимой функции.

Закрыто.
мамин_парень
9.3.2009, 19:37 Mysql
win32 - API 2 | Самая распространённая база данных
DLL библиотека для работы с базой данных MySQL 5.

Версия lua: 5.1
Версия API: 2
Разрядность ОС: 32
Протестировано на PtokaX 0.4.1.1

Копирайт: Copyright © 2003-2007 Kepler Project
LuaSQL is a simple interface from Lua to a DBMS
Версия: LuaSQL 2.1.1


В связи с непонятной работой sqlite предлагаю перейти на стабильную и отчасти более функциональную базу данных.
Хоть преимуществом sqlite и является работа на локальном компьютере и легкая переносимость, однако весь мир использует mysql и надо отдать должное - mysql великолепен!


Теперь о содержимом библиотеки.
Я прикладываю rar архив. В нём dll файл libmysql.dll и папка luasql с dll файлом mysql.dll. Обе эти дллелки нужны для работы бд.
Распаковываем архив в папку, где лежит файл ptokax.exe (или в папку libs), и ничего никуда не перемещаем.
После этого запускаем скрипт для тестирования.




Основные функции для работы с mysql в lua

  • Подключение драйвера (библиотеки):
    Код
    require"luasql.mysql"

  • Инициализация драйвера (библиотеки):
    Код
    env = luasql.mysql()

  • Деинициализация драйвера (библиотеки):
    Код
    env:close()
    Возвращает true в случае успешного закрытия, false в случае, если закрытие уже было сделано до этого.




Объект - соединение (conn)

  • Метод вызова соединения с базой данных:
    Код
    conn = env:connect([имя_базы], [имя_пользователя], [пароль], [хост], [порт])
    Обязательным является только первый параметр, остальные параметры в случае отсутствия берутся по умолчанию: [имя_пользователя] = "root", [пароль] = "", [хост] = "localhost", [порт] = 3306

  • Метод закрытия соединения с базой данных:
    Код
    conn:close()
    Закрытие может быть успешным только в случае если все курсоры закрыты. Возвращает true в случае успеха, false - в случае неудачи.

  • Метод выполнения (завершения, совершения) текущей транзакции:
    Код
    conn:commit()
    Возвращает true в случае успеха, false - в случае, когда транзакция не может быть завершина или база данных не поддерживает транзакции (поддержка транзакции в mysql осуществляется с версии 4.0).

  • Метод выполнения SQL запроса к базе данных:
    Код
    conn:execute("запрос")
    В случае правильности запроса, для запросов типа SELECT возвращает курсор, для остальных запросов возвращает число столбцов или строк, успешно обработанных запросом. В случае неверного синтаксиса, или несуществующих таблиц, или несуществующих полей возвращается два значения: первое - nil, второе - сообщение с содержанием ошибки.

  • Метод отката на предыдущую транзакцию:
    Код
    conn:rollback()
    Возвращает true в случае успеха, false - в случае, когда операция не может быть выполнена или база данных не поддерживает транзакции (поддержка транзакции в mysql осуществляется с версии 4.0).

  • Метод включения/отключения автоматических транзакций:
    Код
    conn:setautocommit(boolean)
    Эта функция не может работать на базах, на которых не осуществляются транзакции. На базах данных, на которых нет понятия режима автоматических транзакций, этот механизм осуществляется драйвером. Метод возвращает true в случае успеха, и false - в случае невыполнимости или неосуществимости (поддержка транзакции в mysql осуществляется с версии 4.0).



Объект - курсор (cur)

  • Метод закрытия курсора:
    Код
    cur:close()
    Возвращает true в случае успешного закрытия, false - в случае, если этот курсор уже закрыт.

  • Метод извлечения результатов:
    Код
    cur:fetch([table[,modestring]])
    Извлекает следующий столбец с результатами. Если метод вызывается без параметров, то результаты возвращаются непосредственно вызывающему оператору. Если в первом параметре метода указана таблица, то результаты помещаются в эту таблицу, и методом возвращается эта таблица, при этом может быть использован второй параметр. Второй параметр - это строка, которая указывает на то, как создавать результирующую таблицу:
    "n" - результирующая таблица будет содержать целочисленные индексы (это значение по умолчанию);
    "a" - результирующая таблица будет содержать словесные индексы.
    Целочисленные индексы являются номерами полей в SELECT запросе. Словесные индексы являются названиями полей в SELECT запросе. Дополнительный табличный параметр является таблицей, которую нужно использовать для сохранения следующей строки запроса. В частности, это допускает использование одной уникальной таблицы для всех выборок, и такой механизм может улучшить общее выполнение выборки в целом. Нет гарантии того, что извлечённые результаты будут преобразовываться в нужные в lua типы (в зависимости от содержания), то есть это говорит о том, что возвращаемые результаты всегда представляются в виде строковых значений будь это строка или число. Метод возвращает результирующую таблицу или nil, в случае если достигнута конечная строка. Здесь нужно отметить, что этот метод может возвращать nil, но тем не менее запрос будет выполнен правильно.

  • Метод, возвращающий таблицу с именами столбцов для данного курсора:
    Код
    cur:getcolnames()

  • Метод, возвращающий таблицу с типами столбцов для данного курсора:
    Код
    cur:getcoltypes()

  • Метод, возвращающий число строк, полученных в результате запроса:
    Код
    cur:numrows()




Как работать с таблицами для достижения большей производительности

  1. По возможности все поля декларировать как NOT NULL. Это сделает работу с таблицами более быстрой и сохранит 1 бит на каждое такое поле.
  2. Применять значения по умолчанию (DEFAULT). При вызове запроса INSERT в таблицу будут записываться только те поля, значения которых отличаются от DEFAULT.
  3. Используйте настолько малые типы INT, насколько это возможно. Например, применять MEDIUMINT намного лучше, чем обычный INT.
  4. Если у вас нет записей с переменной длиной ( ни одного поля с типом VARCHAR, BLOB или TEXT), то таблица сохраняется в формате " постоянной длиной записи ". Это несколько расходует память, но намного повышает скорость работы.
  5. При использовании нескольких последовательных INSERT запросов, лучше все данные указать в одном INSERT, чем делать несколько INSERT.
  6. При загрузке данных в таблицу лучше использовать LOAD DATA INFILE, чем INSERT, такой метод в 20 раз быстрее.
  7. Для увеличения скорости LOAD DATA INFILE и INSERT нужно увеличить значение переменной key_buffer.
  8. Если ожидается много запросов INSERT или UPDATE, работающих одновременно, то для большей скорости рекомендуется приметь LOCK TABLES.
  9. Время от времени нужно дефрагметировать таблицы. Это делается утилитой isamchk с опциями - evi.



--------------------

Если у вас нет mysql сервера, то качаем его, например отсюда: http://www.mysql.ru/download/ (файл mysql-5.0.67-win32.zip)
Для удобного администрирования там же можно скачать утилиту mysqlgui-win32-static
MySQL распространяется под GNU General Public License и под собственной коммерческой лицензией, на выбор.


Архив с библиотеками под PtokaX 0.4.*.*: [attachment=1785:mysql.rar]
Скрипт примера работы с MySQL в LUA: [attachment=1794:mysql_test.lua]
Nickolya, BIMMER71, Tsd, Invisible, Parad0x, vicious, Kingston, Saymon21, Win32, TiGRpp, MIKHAIL
9.3.2009, 13:22 Autotopic
API2 | Автоматически меняющийся топик
Код
function OnTimer()
  if type(tTopic) == "table" and next(tTopic) then
    SetMan.SetString(10,tTopic[math.random(1,#tTopic)]:sub(1,256))
  end
end
berkut2123
7.3.2009, 18:34 Комманды И Текст
Помогите пожалуйста ;-)
Код
hubscmd = "!hubs"
hubsfile = "texts/hubs.txt"


function ChatArrival(curUser,data)
  local data = string.sub(data,1,-2)
  local s,e,cmd =string.find(data, "%b<>%s+(%S+)")

  if cmd == hubscmd then
    local h = io.open(frmHub:GetPtokaXLocation()..hubsfile)
    if h then
      curUser:SendPM("Bot", h:read"*a")
          h:flush()
          h:close()
    end
  end
end

function NewUserConnected(curUser)
  curUser:SendData("$UserCommand 1 2 Ваше меню\\Внутрисетевые хабы$<%[mynick]> "..hubscmd.." %[nick]&#*124;")
end

OpConnected = NewUserConnected
мамин_парень
7.3.2009, 2:58 Свой Dc++ Клиент
Нужен второй разработчик
Самое главное, лично для меня, так это чтобы клиент был кросс-платформенным, быстрым (без всяких лишних наворотов), маленьким, консольным и с открытом С++ кодом.
Если бы данный клиент подходит по этим параметрам, то я бы посодействовал в его создании)))
Nissan_GT
7.3.2009, 2:43 ! Часто Задаваемые Вопросы !
Обязательно прочитать всем!!!
Как изменить выводимые в чат ники пользователей?

Код
tNames = {
  ["Вася"] = "Барабас",
  ["Петя"] = "Гондурас",
}
    
function ChatArrival(tUser, sData)
  if tNames[tUser.sNick] then
    Core.SendToAll("<"..tNames[tUser.sNick].."> "..sData:sub(tUser.sNick:len()+4, -2))
    return true
  end
end
Invisible, Saymon21, мамин_парень
7.3.2009, 2:41 ! Часто Задаваемые Вопросы !
Обязательно прочитать всем!!!
Как запретить символы в нике для определённых профилей?

Код
tSmbs={
   [0]="",  -- Master
   [1]="",  -- Operator
   [2]="[®™]",  -- Vip
   [3]="[®™]",  -- Reg
   [-1]="[®™]",  --UnReg
}
tBeginSmbs={    -- хотя цифры (одну) можно записать как %d
   [0]="",  -- Master
   [1]="",  -- Operator
   [2]="[1234567890]",  -- Vip
   [3]="[%[%]%!]",  -- Reg    -- запрет []! в самом начале ника (1 символ)
   [-1]="[%.@]",  --UnReg    -- запрет .@
}

function UserConnected(tUser)
    local sSmb=tBeginSmbs[tUser.iProfile]
    if sSmb and string.find(tUser.sNick,"^("..sSmb..")") then
        Core.SendToUser(tUser,"*** Украшения в никах запрещены!")
        Core.Disconnect(tUser)
    end
    sSmb=tSmbs[tUser.iProfile]
    if sSmb and string.find(tUser.sNick,"("..sSmb..")") then
        Core.SendToUser(tUser,"*** Украшения в никах запрещены!")
        Core.Disconnect(tUser)
    end
end
RegConnected=UserConnected
OpConnected=UserConnected
Invisible, DrakonSP, Mega-Killer
6.3.2009, 0:13 Запрет На Пассивный Режим
Никому не советую использовать подобного рода скрипты!!!
Пассивный режим не для того существует чтобы его запрещали!!!
мамин_парень
5.3.2009, 2:55 Sqlite
Unix | База данных
Создаём папку luasql в рабочем (конфигурационнком) каталоге PtokaX (если ставили из установщика или пакета mariner, то это /etc/ptoka/).
Получаем папку /etc/ptoka/luasql/. Теперь создадим в ней необходимую ссылку на системную библиотеку, правда сначала найдем эту библиотеку.
Пишем:
Код
updatedb
locate sqlite | grep lua

И получаем приблизительно такой вывод:
Цитата(ssh)
root /etc/ptokax # locate sqlite G lua
/usr/include/lua5.1/lua-sql-sqlite3.h
/usr/lib/liblua5.1-sql-sqlite3.a
/usr/lib/liblua5.1-sql-sqlite3.la
/usr/lib/liblua5.1-sql-sqlite3.so
/usr/lib/liblua5.1-sql-sqlite3.so.2
/usr/lib/liblua5.1-sql-sqlite3.so.2.0.0
/usr/lib/lua/5.1/luasql/sqlite3.so
/usr/lib/pkgconfig/lua5.1-sql-sqlite3.pc
/usr/share/doc/liblua5.1-sql-sqlite3-2
/usr/share/doc/liblua5.1-sql-sqlite3-dev
/usr/share/doc/liblua5.1-sql-sqlite3-2/README
/usr/share/doc/liblua5.1-sql-sqlite3-2/changelog.Debian.gz
/usr/share/doc/liblua5.1-sql-sqlite3-2/copyright
/usr/share/doc/liblua5.1-sql-sqlite3-dev/README
/usr/share/doc/liblua5.1-sql-sqlite3-dev/changelog.Debian.gz
/usr/share/doc/liblua5.1-sql-sqlite3-dev/copyright
/var/cache/apt/archives/liblua5.1-sql-sqlite3-2_2.2.0~rc1-1_i386.deb
/var/cache/apt/archives/liblua5.1-sql-sqlite3-dev_2.2.0~rc1-1_i386.deb
/var/lib/dpkg/info/liblua5.1-sql-sqlite3-2.list
/var/lib/dpkg/info/liblua5.1-sql-sqlite3-2.md5sums
/var/lib/dpkg/info/liblua5.1-sql-sqlite3-2.postinst
/var/lib/dpkg/info/liblua5.1-sql-sqlite3-2.postrm
/var/lib/dpkg/info/liblua5.1-sql-sqlite3-2.shlibs
/var/lib/dpkg/info/liblua5.1-sql-sqlite3-dev.list
/var/lib/dpkg/info/liblua5.1-sql-sqlite3-dev.md5sums

Жирным отмечена необходимая библиотека. Теперь создаем симлинк на нее(для данного случая это делаем так):
Код
ln -s /usr/lib/lua/5.1/luasql/sqlite3.so /etc/ptokax/luasql/sqlite3.so

Вот и все. Все лежит там, где надо.

Пишем тестовый скрипт:
Код
require "luasql.sqlite3"
local env = assert(luasql.sqlite3())
local conn = assert(env:connect("test.db3"))
local res = conn:execute"DROP TABLE people"
res = assert(conn:execute[[
  CREATE TABLE people(name  varchar(50), email varchar(50))
]])

local list = {
  {name = "Jose das Couves", email = "jose@couves.com"},
  {name = "Manoel Joaquim", email = "manoel.joaquim@cafundo.com"},
  {name = "Maria das Dores", email = "maria@dores.com"}
}
for i, p in pairs(list) do
  res = assert(conn:execute(string.format([[
    INSERT INTO people VALUES ('%s', '%s')
]], p.name, p.email)))
end

local cur = assert(conn:execute"SELECT name, email from people")

local row = cur:fetch({}, "a")
while row do
  Core.SendToAll(string.format("Name: %s, E-mail: %s", row.name, row.email))
  row = cur:fetch(row, "a")
end

cur:close()
conn:close()
env:close()


Для скачки библиотек:
Под убунту: http://mirror.yandex.ru/ubuntu/pool/universe/l/lua-sql/ (и тут выбираем архитектуру)
Под дебиан: http://mirror.yandex.ru/debian/pool/main/l/lua-sql/ (и тут выбираем архитектуру)
Asbar
4.3.2009, 19:56 Autotopic
API2 | Автоматически меняющийся топик
Название скрипта: AutoTopic
Версия API: 2
Автор: Wariner
Описание: Скрипт меняет топики через интервал времени. Есть возможности добавлять через меню и смотреть все топики.
Перенесено из раздела "Запросы скриптов".
stone, AfLc, мамин_парень
28.2.2009, 17:48 ! Часто Задаваемые Вопросы !
Обязательно прочитать всем!!!
Как запретить пользоваться чатом и личкой на хабе незарегистрированным?

API2:
Код
local sMsg=[[Сообщение о недоступности чата и лички незарегистрированному]]
function ChatArrival(tUser)
  if tUser.iProfile == -1 then
    Core.SendToUser(tUser,sMsg)
    return true
  end
end
ToArrival=ChatArrival


API1:
Код
local sMsg=[[Сообщение о недоступности чата и лички незарегистрированному]]
function ChatArrival(tUser)
  if tUser.iProfile == -1 then
    tUser:SendData(sMsg)
    return 1
  end
end
ToArrival=ChatArrival
Invisible, Nissan_GT, denis
28.2.2009, 16:13 Аааа, Подскажите.
Пусть хаб установлен на машине в локальной сети и имеет доступ в интернет
локальный ip адрес - 192.168.0.100
интернетовский ip адрес - 123.123.123.123 (выделенный)


Рассмотрим следующих пользователей хаба:

1).
Локальный пользователь.
Локальный ip адрес - 192.168.0.1
Инетовский ip адрес - 111.111.111.111 (выделенный)

2).
Локальный пользователь.
Локальный ip адрес - 192.168.0.2
Инетовский ip адрес - 111.111.100.1 (не выделенный)

3).
Локальный пользователь.
Локальный ip адрес - 192.168.0.3
Инетовский ip адрес - нет доступа в интернет

4).
Интернет пользователь.
Локальный ip адрес - 10.10.10.1
Инетовский ip адрес - 222.222.222.222 (выделенный)

5).
Интернет пользователь.
Локальный ip адрес - 10.10.10.2
Инетовский ip адрес - 222.222.100.1 (не выделенный)

Введём обозначанеия:
Код
цифра - номер пользователя;
"А" - актив;
"П" - пассив;
"->" - направление соединения;
"+" - соединение установится;
"-" - соединение не установится;
"*" - соединение установится только в случае подключения к хабу через интернет


Код
1А -> 2А +    1А -> 3А +    1А -> 4А *    1А -> 5А *
1П -> 2П -    1П -> 3П -    1П -> 4П -    1П -> 5П -
1П -> 2А +    1П -> 3А +    1П -> 4А +    1П -> 5А -
1А -> 2П +    1А -> 3П +    1А -> 4П *    1А -> 5П *

2А -> 1А +    2А -> 3А +    2А -> 4А -    2А -> 5А -
2П -> 1П -    2П -> 3П -    2П -> 4П -    2П -> 5П -
2П -> 1А +    2П -> 3А +    2П -> 4А +    2П -> 5А -
2А -> 1П +    2А -> 3П +    2А -> 4П -    2А -> 5П -

3А -> 1А +    3А -> 2А +    3А -> 4А -    3А -> 5А -
3П -> 1П -    3П -> 2П -    3П -> 4П -    3П -> 5П -
3П -> 1А +    3П -> 2А +    3П -> 4А -    3П -> 5А -
3А -> 1П +    3А -> 2П +    3А -> 4П -    3А -> 5П -

4А -> 1А +    4А -> 2А +    4А -> 3А -    4А -> 5А +
4П -> 1П -    4П -> 2П -    4П -> 3П -    4П -> 5П -
4П -> 1А +    4П -> 2А -    4П -> 3А -    4П -> 5А -
4А -> 1П +    4А -> 2П +    4А -> 3П -    4А -> 5П +

5А -> 1А -    5А -> 2А -    5А -> 3А -    5А -> 4А -
5П -> 1П -    5П -> 2П -    5П -> 3П -    5П -> 4П -
5П -> 1А +    5П -> 2А -    5П -> 3А -    5П -> 4А +
5А -> 1П -    5А -> 2П -    5А -> 3П -    5А -> 4П -
Tsd, Delia, мамин_парень
27.2.2009, 13:39 От: Экзекутор (ekzekutor)
От темы с ID: 1403
Ну этим ты никого не удивил. Данный приём работает в каждом втором скрипте.
27.2.2009, 0:32 Объектно-Ориентированное Программирование в Lua
Создание и использование классов
ООП широко распространено из-за его эффективности. Эта эффективность выражается в экономном использовании памяти и ресурсов компьютера. Достигается это всё при помощи таких мощных аппаратов как инкапсуляция, наследование и полиморфизм и абстракция.

Реализация класса, которая будет описываться в данном топике является первым вариантом, и служит для введения в курс дела. В своих проектах же не следует её использовать. В проектах используйте доработанную версию библиотеки.

Итак, во-первых, не вдаваясь в подробности, напишу основную функцию, которая содержит в себе все выше изложенные аппараты.
Те, кто достаточно хорошо знают язык LUA, могут попытаться понять как это всё работает, ну а всем остальным нужно только скопировать без понимания - понимать нужно будет дальше (после этого кода).
Код
local _G = _G
local function concat(p1, p2)
  local t = {}
  for k, v in _G.pairs(p1) do
    t[k] = v
  end
  for k, v in _G.pairs(p2) do
    t[k] = v
  end
  if _G.next(p1.__parent or {}) or _G.next(p2.__parent or {}) then
    t.__parent = concat(p1.__parent or {}, p2.__parent or {})
  end
  return t
end
  
cClass = function(...)
  local t, m = {}, {}
  _G.setmetatable(t, m)
  for i = 1, _G.select('#', ...) do
    local p = _G.select(i, ...)
    if _G.type(p) == 'table' then
      for k, v in _G.pairs(p) do
        t[k] = v
      end
    end
  end
  m.__call = function(self, ...)
    local t, mt_old, mt_new = {}, {}, {}
    for k, v in _G.pairs(_G.getmetatable(self) or {}) do
      mt_old[k] = v
    end
    for k, v in _G.pairs(self) do
      mt_old[k] = v
    end
    for i = 1, _G.select('#', ...) do
      local p = _G.select(i, ...)
      if _G.type(p) == 'table' then
        for k, v in _G.pairs(_G.getmetatable(p) or {}) do
          mt_new[k] = v
        end
        for k, v in _G.pairs(p) do
          t[k] = v
        end
      end
    end
    mt_new = concat(mt_old, mt_new)
    t.__parent = mt_new
    mt_new.__index = mt_new
    _G.setmetatable(t, mt_new)
    return t
  end
  return t
end
Приведённая функция (cClass) представляет из себя функцию для реализации класса.


Давайте же попробуем написать свой класс, используя эту самую функцию:
Код
cMyFirstClass = cClass{
  mMember1 = 5;
  mMember2 = "first_class_mMember2";
  func1 = function(self)
    Core.SendToAll(self.mMember2)
  end
  func2 = function(self)
    Core.SendToAll"Example"
  end
}



Функция содержит 2 члена (числовой и строковый) и два метода (func1, func2).
Выведем содержимое всех членов класса на экран:
Код
for k, v in pairs(cMyFirstClass) do
  Core.SendToAll("["..k.."] = "..tostring(v))
end



На экране видим следующее:
Цитата
[mMember1] = 5
[func1] = function: 01A57710
[func2] = function: 01A525B0
[mMember2] = first_class_mMember2





Наследование.
Теперь рассмотрим аппарат наследования.
Построим ещё один класс (будем его называть производным классом), который будет наследовать все члены и функции нашего (базового) класса cMyFirstClass.


Код
cMySecondClass = cMyFirstClass{
  mMember2 = "second_class_mMember2";
  func3 = function(self)
    self:func2()
  end
}



Если теперь мы выведем на экран все члены класса:
Код
for k, v in pairs(cMyFirstClass) do
  Core.SendToAll("["..k.."] = "..tostring(v))
end
то мы увидим следующее:
Цитата
[mMember2] = second_class_mMember2
[func3] = function: 01A12170
[__parent] = table: 01A640F0
то есть, мы видим элемент mMember2 и метод func3, но также мы можем наблюдать некую таблицу __parent. Это таблица базового класса (cMyFirstClass).




Полиморфизм.
К любым элементам базового класса можно обращаться через эту самую таблицу __parent. Например, я не могу из класса cMySecondClass обратиться непосредственно к элементу mMember2 класса cMyFirstClass, так как в классе cMySecondClass есть элемент с точно таким же именем и при обращении именно он будет возвращаться:
Код
Core.SendToAll(cMySecondClass.mMember2)
на экране видим
Цитата
second_class_mMember2
Однако, если написать так:
Код
Core.SendToAll(cMySecondClass.__parent.mMember2)
мы увидим на экране желаемый результат:
Цитата
first_class_mMember2





Инкапсуляция.
Теперь рассмотрим аппарат инкапсуляции.
Код
local cMyFirstClass = {}
do
  local mMember3 = "private_mMember3"

  cMyFirstClass = cClass{
    mMember1 = 5;
    mMember2 = "first_class_mMember2";
  
    func1 = function(self)
      Core.SendToAll(self.mMember2)
    end
    func2 = function(self)
      Core.SendToAll"Example"
    end
  }
end

Инкапсуляция предполагает закрытие доступа к переменной вне класса. Для реализации инкапсуляции используем блок do ... end. Несколько не обычный ход, не правда ли?


Проверим содержимое таблицы __parent класса cMySecondClass:
Код
for i,v in pairs(cMySecondClass.__parent) do
  SendToAll("["..i.."] = "..tostring(v))
end

На экране видим следующее:
Цитата
[mMember2] = first_class_mMember2
[mMember1] = 5
[func1] = function: 01A78A60
[func2] = function: 01A62500
[__index] = table: 01A454B8
[__call] = function: 01A78AD0

На переменные __index и __call можем не обращать внимания (они являются метаметодами).



Теперь, для чего всё это нужно?
А нужно это для значительной оптимизации работы и для структурированного написания скриптов.
Дело вот в чём. Создавая класс cMyFirstClass, под него выделяется определённое количество памяти. Память, выделенная под класс cMySecondClass, - это память выделенная под переменные mMember2 и func3, а подо все унаследованные переменные память не выделяется (она уже выделена под класс cMyFirstClass) (тут имеется ввиду выделяемая память под реализацию функций). Поэтому получаем большую функциональность при малом выделении памяти и при малом количестве строк реализации.


В конце вопрос на засыпку: Что выведет на экран метод cMySecondClass:func1() ?

Ответ: second_class_mMember2
Saymon21
25.2.2009, 21:22 От: Объектно-ориентированные Принципы В Lua
От темы с ID: 1429
Универсальная функция для создания класса в lua.
Включает в себя аппарат простого и множественного наследования.
Для множественного наследования используется несколько раз простое наследование.
Код
local function concat(p1, p2)
  local t = {}
  for k, v in pairs(p1) do
    t[k] = v
  end
  for k, v in pairs(p2) do
    t[k] = v
  end
  if next(p1.__parent or {}) or next(p2.__parent or {}) then
    t.__parent = concat(p1.__parent or {}, p2.__parent or {})
  end
  return t
end

class = function(...)
  local t, m = {}, {}
  _G.setmetatable(t, m)
  for i = 1, _G.select('#', ...) do
    local el = _G.select(i, ...)
    if _G.type(el) == 'table' then
      for k, v in _G.pairs(el) do
        t[k] = v
      end
    end
  end
  t.__parent = m
  m.__call = function(self, ...)
    local t, mt_old, mt_new = {}, {}, {}
    for k, v in pairs(getmetatable(self) or {}) do
      mt_old[k] = v
    end
    for k, v in pairs(self) do
      mt_old[k] = v
    end
    for i = 1, _G.select('#', ...) do
      local el = _G.select(i, ...)
      if _G.type(el) == 'table' then
        for k, v in pairs(getmetatable(el) or {}) do
          mt_new[k] = v
        end
        for k, v in _G.pairs(el) do
          t[k] = v
        end
      end
    end
    mt_new = concat(mt_old, mt_new)
    mt_new.__index = mt_new
    t.__parent = mt_new
    _G.setmetatable(t, mt_new)
    return t
  end
  return t
end


Объявляем классы
Код
A = class{
  f1 = function()
    Core.SendToAll"A.f1"
  end;
}

B = A{
  f1 = function()
    Core.SendToAll"B.f1"
  end;
  f2 = function()
    Core.SendToAll"B.f2"
  end;
}

C = class{
  f2 = function()
    Core.SendToAll"C.f2"
  end;
  f3 = function()
    Core.SendToAll"C.f3"
  end;
}

D = B{
  f1 = function()
    Core.SendToAll"D.f1"
  end;
  f2 = function()
    Core.SendToAll"D.f2"
  end;
  f3 = function()
    Core.SendToAll"D.f3"
  end;
}

D = C(D) -- реализация множественного наследования


Структура наследования такова:
* класс A - базовый класс
* класс B - наследует класс A
* класс С - базовый класс
* класс D - наследует классы B и С (множественное наследование)

Вызов функций классов:
Код
Core.SendToAll"\t\tВызываем в каждом классе свои функции:"
Core.SendToAll"\tКласс A"
A.f1()
Core.SendToAll"\tКласс B"
B.f1()
B.f2()
Core.SendToAll"\tКласс C"
C.f2()
C.f3()
Core.SendToAll"\tКласс D"
D.f3()
D.f3()
D.f3()
Core.SendToAll"\t\tВызываем в классе D унаследованные функции:"
D.__parent.__parent.f1()
D.__parent.f1()
D.__parent.f2()
D.__parent.f3()


Что выводится на экран:
Цитата
Вызываем в каждом классе свои функции:
Класс A
A.f1
Класс B
B.f1
B.f2
Класс C
C.f2
C.f3
Класс D
D.f3
D.f3
D.f3
Вызываем в классе D унаследованные функции:
A.f1
B.f1
B.f2
C.f3
MIKHAIL
24.2.2009, 18:35 От: Экзекутор (ekzekutor)
От темы с ID: 1403
Я так понимаю, что ты автор скрипта?

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

Первое что бросилось в глаза в данном скрипте - это проверка в функциях на использование той или иной платформы (имеются ввиду функции на подобии PMToUser, PMToAll и тд.). Лучше сделать так: написать 2 файла (например verli.lua и ptokax.lua). В одном файле пишутся API функции verli, во втором API функции ptokax. В основном исполняемом файле вместо этих функций написать код:
Код
if Core then
  if loadfile(ptokax.lua) then
    dofile(ptokax.lua)
  end
else
  if loadfile(verli.lua) then
    dofile(verli.lua)
  end
end
в данном случае нужные функции будут загружаться в зависимости от платформы хаба и нагрузка на проверку по части исполнения той или иной функции исчезнет. Для большей читаемости кода всё же советую раздробить на большее количество файлов (и самому буде легче разобраться что и где).
Тёмич
24.2.2009, 16:35 Метод Быстрого Перевода Скриптов Под API_1
Самостоятельный быстрый перевод из API_2 ---> в API_1
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
Invisible
21.2.2009, 21:20 Cleanreg
API2 | Скрипт чистки регистраций
Цитата(Serx @ 21.2.2009, 21:16) *
Ошибка пропала.
Но работы скрипта все так-же не видно (нет меню и сообщений)

P.S. запускал как раз при включенном хабе.

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

ПМ:
Меняем
Код
return Core.SendToUser(user,"<"..Bot.."> "..Cmds[cmd][1](user,data,cmd).."|"),true
на
Код
return Core.SendPmToUser(user,Bot, Cmds[cmd][1](user,data,cmd).."|"),true
Invisible
21.2.2009, 20:51 Cleanreg
API2 | Скрипт чистки регистраций
Я перезалил. Теперь можно включать скрипт и при отключенном хабе)))
Invisible
18.2.2009, 21:17 Функции Для Разработчиков
склад полезных функций
Очередная интересная по реализации функция форматирования шары:
Код
local t={"Б","КБ","МБ","ГБ","ТБ","ПБ"}
local function loop(i,n,c)
  if i<0x400 then coroutine.yield(n:format(i)..(t[c] or "??"))end
  return loop(i/0x400,n,c+1)
end
GetNormalShare=coroutine.wrap(function(s,n)return loop(s and tonumber(s) or 0,n and "%."..n.."f " or "%.3f ",1)end)


Использование:
Код
Core.SendToAll(GetNormalShare(142589996842624,4))
Saymon21
15.2.2009, 22:40 Функции Для Разработчиков
склад полезных функций
Аналог стандартной LUA функции для PtokaX:
Код
function _G.print(...)
  local m = ''
  for i = 1, _G.select('#', ...) do
    m = m..tostring(_G.select(i, ...))
  end
  Core.SendToAll(m)
end


Использование:
Код
print("55 qwerty ", 34, " ", 66, " str ", 12, " 78 ", 0x22b==555)





Функции работы с бинарными числами.

Функция, преобразующая десятичное число в бинарную строку:
Код
function tobin(n)
  local m, x = ''
  while n >= 2 do
    n, x = _G.math.modf(n / 2)
    m = 2 * x..m
  end
  return n ~= 0 and '1'..m or '0'
end


Функция, преобразующая бинарную строку в десятичное число:
Код
tonumber(str, 2)


Можно использовать для раздачи собственных прав профилям хаба. Например, на хабе профили: 0 - Master, 1 - Operator, 2 - VIP, 3 - Reg, -1 - UnReg. Профили можно записать в двоичную строку. Будем полагать, что строка "11111" разрешает всем пяти профилям то или иное действие, строка "10000" разрешает действие только профилю Master. Думаю, что ясен смысл.
Alexey, Govorun
12.2.2009, 18:35 Метод Быстрого Перевода Скриптов Под API_1
Самостоятельный быстрый перевод из API_2 ---> в API_1
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
Invisible
12.2.2009, 12:25 Stoptrep
API2 | Запрещает говорить больше N сообщений подряд в чате
Название скрипта: StopTrep
Версия API: 2
Автор: Nickolya
Описание: Скрипт запрещает говорить больше N сообщений подряд в чате.
Перенесено из раздела "Запросы скриптов".


[attachment=1629:stop_trep.lua]
Invisible, WINS, zeusby
12.2.2009, 12:16 Coolmenu
API1 | Забавная менюшка
Название скрипта: CoolMenu
Версия API: 1
Автор: Fislons
Описание: Менюшка, показывающая информацию о пользователе (то есть о вас).
Перенесено из раздела "Запросы скриптов"


[attachment=1628:CoolMenu.lua]
Saymon21, TiGRpp
8.2.2009, 18:41 ! Часто Задаваемые Вопросы !
Обязательно прочитать всем!!!
Как написать функцию оповещения об ошибках скрипта?

Код
function OnError(s)
  local h=io.open("errors.log","a+")
  if h then
    h:write(os.date()..": "..s.."\r\n")
    h:close()
  end
  if Core then
    Core.SendToOpChat(s)
  else
    SendToOpChat(s)
  end
end
Invisible, Nissan_GT, Saymon21, мамин_парень
7.2.2009, 21:04 ! Часто Задаваемые Вопросы !
Обязательно прочитать всем!!!
Как запретить скачивать и искать на хабе незарегистрированным?

Код
local sMsg="Вы не зарегистрированы. Пользоваться поиском и скачивать запрещено!"
function ConnectToMeArrival(tUser)
  if tUser.iProfile==-1 then
    if Core then
      Core.SendToUser(tUser,sMsg)
    else
      tUser:SendData(sMsg)
    end
    return true
  end
end
RevConnectToMeArrival,SearchArrival=ConnectToMeArrival,ConnectToMeArrival
Invisible, мамин_парень
7.2.2009, 20:33 Функции Для Разработчиков
склад полезных функций
Не знаю для чего нужно округлять до количества цифр, обычно округляют до какого-то знака после запятой, ну да ладно.

Самый быстрый по выполнению мой код, так как в ветке выполнения содержится минимальное количество операций, однако очень порадовал код sphinx-а))) :
Код
function GetNormalShare(s,n)
  local i,t=1,{"Б","КБ","МБ","ГБ","ТБ","ПБ"}
  s=s and tonumber(s) or 0
  n=n and "%."..n.."f " or "%.3f "
  while s>0x400 do s,i=s/0x400,i+1 end
  return n:format(s)..(t[i] or "??")
end

1) Цикл пробегается от меньшего значения - оптимизация прохода (большинство пользователей не имеют большой шары)
2) Цикл while, а не for, поэтому для выхода из цикла не нужен оператор break (в случае прохода по for i=1,6 нужен был оператор break)
3) Код не громоздкий
Invisible, Saymon21, ramzes
7.2.2009, 19:07 Функции Для Разработчиков
склад полезных функций
А что тогда означает выражение: "до скольки знаков округлить значение шары" ??

Код
function GetNormalSize(s, n)
    s=s and tonumber(s) or 0
    n=n and "%."..n.."f" or "%.3f"
    if s>=1125899906842624 then return string.format(n,s/1125899906842624).." ПБ"
    elseif s>=1099511627776 then return string.format(n,s/1099511627776).." TБ"
    elseif s>=1073741824 then return string.format(n,s/1073741824).." ГБ"
    elseif s>=1048576 then return string.format(n,s/1048576).." МБ"
    elseif s>=1024 then return string.format(n,s/1024).." КБ"
    else return s.." Б" end
end
Invisible, Saymon21
1.2.2009, 16:35 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$UGetZBlock

Синтаксис:

Код
$UGetZBlock [старт] [число_байт] [имя_файла]|


Направление команды:

Клиент ---> Клиент

Описание:

Это дополнение к протоколу DC++. На поддержку этого дополнения указывает параметр XmlBZList в команде $Supports.

Другой клиент отсылает команду "$Sending [байты]|[данные]", если всё в порядке, иначе он отправляет команду "$Failed [описание_ошибки]|". Где [байты] - это несжатое число байт (клиент не знает до какой степени сжат файл).
Более детальное описание параметров смотрите в команде $UGetBlock

Сжатие:

Сжатие выполняется библиотекой zlib, использующей динамический уровень сжатия. Уровень сжатия может изменяться для того чтобы снизить нагрузку на процессор или в случае если файл не сжимается. Уровень сжатия регулируется с помощью хеш-функции adler32.
1.2.2009, 16:11 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$UGetBlock

Синтаксис:

Код
$UGetBlock [старт] [число_байт] [имя_файла]|


Пример

Код
$UGetBlock 0 -1 files.xml.bz2|


Направление команды:

Клиент ---> Клиент

Описание:

Это дополнение к протоколу DC++, используется вместо команд $Get и $Send. На поддержку этого дополнения указывает параметр XmlBZList в команде $Supports.

• [старт] - начальный индекс файла
• [число_байт] - число байт для получения или -1, если число байт неизвестно (когда файл целый)
• [имя_файла] - имя получаемого файла (utf8)

Отметим, что начальный индекс 0 для команды $UGetBlock подобен начальному индексу 1 для команды $Get. Другой клиент затем отсылает команду "$Sending [байты]|[данные]", если всё в порядке, иначе он отправляет команду "$Failed [описание_ошибки]|".

Имя файла [имя_файла] в кодировке UTF-8 для того, чтобы допустить символы, которые отсутствуют в обычной кодировке DC (cp1252).

Существует другая версия этой команды $UGetZBlock, которая поддерживает сжатие данных.
1.2.2009, 14:37 Verlihub
Описание
LUA API функции Verli хаба.
Код
Main() - функция, выполняемая при старте скрипта
UnLoad() - функция, выполняемая при остановке скрипта
VH_OnTimer() - таймер (выполняется каждую секунду)
VH_OnNewConn(sIP) - функция соединения
VH_OnCloseConn(sIP) - функция разъединения
VH_OnParsedMsgChat(sNick, sMsg) - функция приёма сообщения в чат
VH_OnParsedMsgPM(sFrom, sMsg, sTo) - функция приёма пм
VH_OnParsedMsgSearch(sNick, sData) - функция поиска
VH_OnParsedMsgConnectToMe(sNick, sOtherNick, sIP, iPort) - функция, выполняемая при активном коннекте
VH_OnParsedMsgRevConnectToMe(sNick, sOtherNick) - функция, выполняемая при пассивном коннекте
VH_OnParsedMsgSR(sNick, sData) - функция возврата результата поиска (при пассивном поиске)
VH_OnParsedMsgMyINFO(sNick, sData) - функция получения MyINFO строки
VH_OnParsedMsgValidateNick(sData) - функция проверки ника
VH_OnParsedMsgAny(sNick, sCmd) - функция приёма другой команды (не чат и не пм)
VH_OnParsedMsgSupport(sNick, sParams) - функция поддерживаемых дополнений
VH_OnParsedMsgMyPass(sNick, sData) - функция, выполняемая при отсылке пароля
VH_OnUnknownMsg(sNick, sCmd) - функция неизвестных для хаба команд
VH_OnOperatorCommand(sNick, sCmd) - функция, выполняемая при отсылке в чат команды оператора (префикс !)
VH_OnOperatorKicks(sOPNick, sNick, sReason) - функция кика
VH_OnOperatorDrops(sOPNick, sNick) - функция дропа
VH_OnValidateTag(sNick, sTag) - функция получения тэга
VH_OnUserCommand(sNick, sCmd) - функция, выполняемая при отсылке в чат команды пользователя (префикс +)
VH_OnUserLogin(sNick) - функция, выполняемая при входе юзера
VH_OnUserLogout(sNick) - функция, выполняемая при выходе юзера
VH_OnNewReg(sOPNick, sNick, sClass) - функция регистрации
VH_OnNewBan(sOPNick, sIP, sNick, sReason) - функция бана


Методы Verli хаба:
Код
VH:SendDataToUser(sData, sNick) - отправляет данные пользователю
VH:SendDataToAll(sData, iMinClass,  iMaxClass) - отправляет данные всем
VH:SendPMToAll(sData, sFrom, iMinClass,  iMaxClass) - отправляет данные всем в пм
VH:CloseConnection(sNick) - закрывает соединение с пользователем
VH:GetMyINFO(sNick) - возвращает MyINFO строку пользователя
VH:GetUserClass(sNick) - возвращает класс пользователя
VH:GetUserHost(sNick) - возвращает хост пользователя
VH:GetUserIP(sNick) - возвращает ip пользователя
VH:GetNickList() - возвращает список пользователей хаба
VH:Ban(sNick, iTime, iBanType) - выставляет временный бан пользователю
VH:KickUser(sOPNick, sNick, sReason) - кикает пользователя
VH:ParseCommand(sCommandLine) - разбирает командную строку по командам
VH:SetConfig(sConfigName, sKey, sValue) - устанавливает значение настройки
VH:GetConfig(sConfigName, sKey) - возвращает значение настройки
VH:AddRobot(sBotName, iClass, sBotDescription, sConnection, sBotEMail, sShareSize) - регистрирует бота
VH:DelRobot(sBotName) - удаление бота
VH:SQLQuery(sQuery) - делает запрос в бд
VH:SQLFetch(sData) - преобразует данные в читаемый вид
VH:SQLFree() - очищает используемую базой данных временную память
VH:GetUsersCount() - возвращает общее число пользователей на хабе
VH:GetTotalShareSize() - возвращает общую шару хаба
VH:GetVerliPath() - возвращает путь к хабу
Vizunchik, Saymon21
30.1.2009, 13:21 Функции Для Разработчиков
склад полезных функций
Функция коррекции данных пользователя.
Если клиент неизвестен для хаба, то тэг клиента дописывается в описание. Данная функция извлекает тэг из описания и корректно прописывает данные пользователя (такие как слоты, хабы, режим и тд.).
Данная функция корректно воспринимает тэг Авалинка.
Код
function GetNormalValue(tUser)
  if not tUser.sTag and tUser.sDescription then
    local sDescription,sTag,sClient,sClientVersion,sMode,iNormalHubs,iRegHubs,iOpHubs,iSlots,iLlimit = tUser.sDescription:match"(.*)(<(.+)%sV?:?(.-),M:(.-),H:(%d+)/(%d+)/(%d+),S:(%d+)>)$"
    if not sDescription then
      sDescription,sTag,sClient,sClientVersion,sMode,iNormalHubs,iRegHubs,iOpHubs,iSlots,iLlimit = tUser.sDescription:match"(.*)(<(.+)%sV?:?(.-),M:(.-),H:(%d+)/(%d+)/(%d+),S:(%d+),L:(%d+)>)$"
    end
    if not sDescription then
      sDescription,sTag,sClient,sClientVersion,sMode,iNormalHubs,iRegHubs,iOpHubs,iSlots,iLlimit = tUser.sDescription:match"(.*)(<(.+)%sV?:?(.-),M:(.-),H:(%d+)/(%d+)/(%d+),S:(%d+),B:(%d+)>)$"
    end
    tUser.sDescription=sDescription
    tUser.sTag=sTag
    tUser.sClient=sClient
    tUser.sClientVersion=sClientVersion
    tUser.sMode=sMode
    tUser.iNormalHubs=tonumber(iNormalHubs)
    tUser.iRegHubs=tonumber(iRegHubs)
    tUser.iOpHubs=tonumber(iOpHubs)
    tUser.iHubs=tonumber(iNormalHubs and iRegHubs and iOpHubs and (iNormalHubs + iRegHubs + iOpHubs))
    tUser.iSlots=tonumber(iSlots)
    tUser.iLlimit=tonumber(iLlimit)
  end
  return tUser
end


Использование метода:
Код
function UserConnected(tUser)
  tUser=GetNormalValue(tUser)
  ...
end
Invisible, stoparik
27.1.2009, 14:23 Gagbyshare
API2 | Гаг по шаре
Название скрипта: GagByShare
Версия API: API 2
Автор: Wariner
Описание: Скрипт глушит по шаре.
Перенесено из раздела "Запросы скриптов"

[attachment=1525:GagByShare.rar]
KT315, Saymon21, andromed
27.1.2009, 14:06 Txt_manager
API2 | Скрипт управления текстовыми файлами
Название: Txt_Manager
Версия API: API 2
Версия скрипта: 1.0
Автор: Setuper
Описание: Скрипт управления текстовыми файлами.
Перенесён из раздела "Запросы скриптов"

1. Команда "+changetxt [имя_файла] [текст]" - изменяет содержимое файла, то есть полностью заменяет содержимое файла на [текст]
Примечание: Если файла с указанным именем нет, то он автоматически создается! Если параметр [текст] отсутствует, то файл становится пустым.

2. Команда "+addtxt [имя_файла] [текст]" - добавляет к содержимому файла, то есть после содержимого файла дописывает [текст]
Примечание: Если файла с указанным именем нет, то он автоматически создается! Если параметр [текст] отсутствует, то в файл ничего не добавляется.

3. Команда "+deletetxt [имя_файла]" - удаляет указанный файл.
Примечание: Данная команда выполняется всегда, даже если файла с указанным именем нет.

[attachment=1524:Txt_Manager.lua]
TiGRpp
27.1.2009, 13:40 Textfiles_manager_and_updater
API1, API2 | Обновление TXT файлов по интервалу
Название: Textfiles_Manager_And_Updater
Версия API: API 1, 2
Автор: Nickolya
Описание: Скрипт обновляет файлы по интервалу (только с расширением txt), можно поменять папку с которой работает скрипт (путь указан от главной папки хаба), указывается куда отсылаются данные: в приват или общий чат. Библиотеку кладем в папку с PtokaX.exe

[attachment=1522:textfile...ter_api1.lua][attachment=1523:PXLFS.rar]
Invisible, TiGRpp
27.1.2009, 13:17 Cleanreg
API2 | Скрипт чистки регистраций
Название: CleanReg
Версия API: API 2
Версия скрипта: 1.1
Автор: Mutor (перевод на русский KauH)
Описание: Чистка регистраций зарегистрированных юзеров.
Перенесено из раздела "Запросы скриптов".

[attachment=1666:CleanReg_API2.lua]
Invisible, Игорь Станиславович, striker, доктор ливси, shur49, AfLc, dj_crazy_joker, Nikolaevich, zeusby
27.1.2009, 12:45 Функции ===> Читаем, Дабы Не Задавать Вопросов <===
Скрипт-интерфейс PtokaX Lua. ВСЕ СКРИПТОВЫЕ ФУНКЦИИ PtokaX API
ВНИМАНИЕ!!!
Все доступные для программирования под хаб функции находятся:
для API1 в папке с PtokaX.exe в файле Scripting-Interface.txt
для API2 в папке scripting.docs в файле scripting-interface.txt



Описания функций для работы с файлами, строками, таблицами и другими элементами lua языка находятся в мануале по lua: [attachment=1520:manual.html]


Если вы не знаете синтаксис языка lua, то почитайте его на русском сайте lua: http://www.lua.ru/doc/
Invisible, Andrew Frost, Sekretchik, Saymon21, Enyby, DEN 007, ramzes
26.1.2009, 22:59 Реализация Таймеров
Прежде чем удалять тему напишу реализацию возникшего вопроса)))
Код
local iID1,iID2
local iTime1,iTime2=60000,180000
function OnStartup()
  Core.SendToAll"Start"
  iID1=TmrMan.AddTimer(iTime1,"Func1")
  iID2=TmrMan.AddTimer(iTime2,"Func2")
end

function Func1()
  Core.SendToAll"Timer1"
end

function Func2()
  Core.SendToAll"Timer2"
  TmrMan.RemoveTimer(iID2)
end
Invisible, Serx
25.1.2009, 19:11 Компиляция Клиента Strongdc & Flylinkdc
StrongDC++ 221
Если хочешь понять как и что работает и добавить в протокол свою команду, то зачем брать и копать сложные клиенты? Лучше взять простой DC++.
мамин_парень
20.1.2009, 20:20 Motd_for_ops
API1, API2 | Сообщение дня для ОПераторов хаба
Название скрипта: MOTD_for_OPs
Версия API: API1, API2 (универсальный)
Версия скрипта: 1.1
Автор: Setuper
Описание: Скрипт отсылает операторам MOTD при входе. Текст сообщения нужно писать в папке texts в файле opmotd.txt
Скрипт перенесён из раздела "Запросы скриптов".


[attachment=2019:MOTD_for_OPs.lua]
Pro009, AfLc, мамин_парень
20.1.2009, 19:41 Translate
API2 | Переводчик слов
Название скрипта: Translate
Версия API: API2
Версия скрипта: 1.0
Автор: Mutor
Описание: Перевод отдельных слов. Подключение к интернету обязательно. Под API1 спрашивать у автора скрипта (Mutor)!
Скрипт перенесён из раздела "Запросы скриптов".


[attachment=1492:Translate1.0.rar]
TiGRpp, Pro009
20.1.2009, 19:18 Minshare
API1, API2 | Различная Минимальная Шара Для Разных Профилей
Название скрипта: MinShare
Версия API: API1, API2 (универсальный)
Версия скрипта: 2.0
Автор: Setuper
Описание: Скрипт устанавливает нижний предел шары для каждого профиля в отдельности. Настраивается это в таблице tProfileShare.
Скрипт перенесён из раздела "Запросы скриптов".


[attachment=1491:MinShare.lua]
Saymon21
20.1.2009, 19:05 Fromvippm
API1, API2 | Запрет Привата
Название скрипта: FromVipPm
Версия API: API1, API2 (универсальный)
Автор: Nickolya
Описание: Скрипт запрещает пользоваться приватом, если профиль ниже випа. Можно настроить профили по своему усмотрению.
Перенесено из раздела "Запросы скриптов".


[attachment=1490:FromVipP...I_1_2___.lua]
Kar@bas, AfLc
18.1.2009, 14:41 ! Часто Задаваемые Вопросы !
Обязательно прочитать всем!!!
Как сделать контекстное меню для команды?

Допустим, у вас есть команда !rules, по которой показываются правила хаба, команда !hubs, по которой показываются хабы сети и команда !radio, по которой показываются транслируемые через сеть радиостанции. Вы хотите, чтобы эти команды можно было вызывать из контекстного меню хаба.

API 2:
Код
function UserConnected(tUser)
  Core.SendToUser(tUser,"$UserCommand 1 3 Меню хаба\\Правила хаба$<%[mynick]> !rules&#124;|"..
  "$UserCommand 1 3 Меню хаба\\Хабы-друзья$<%[mynick]> !hubs&#124;|"..
  "$UserCommand 1 3 Меню хаба\\Сетевое радио$<%[mynick]> !radio&#124;|")
end
RegConnected,OpConnected=UserConnected,UserConnected


API 1:
Код
function NewUserConnected(tUser)
  tUser:SendData("$UserCommand 1 3 Меню хаба\\Правила хаба$<%[mynick]> !rules&#124;|"..
  "$UserCommand 1 3 Меню хаба\\Хабы-друзья$<%[mynick]> !hubs&#124;|"..
  "$UserCommand 1 3 Меню хаба\\Сетевое радио$<%[mynick]> !radio&#124;|")
end
OpConnected=NewUserConnected
Invisible, Nissan_GT, DrakonSP, drynyry, Saymon21, Тёмич, ProGeTTo, мамин_парень
18.1.2009, 14:29 ! Часто Задаваемые Вопросы !
Обязательно прочитать всем!!!
Как по команде сделать показ сообщения (например правил хаба)?

1. Открываем папку, где располагается файл PtokaX.exe, и заходим в папку texts.
2. Создаём в этой папке текстовый файл.
3. Переименовываем этот файл (например в имя rules.txt)
4. Открываем его, и пишем сообщение (например правила хаба)
5. Ищем в настройках хаба настройку: "Включить текстовые файлы" (В старых версиях настройка находится во вкладке "Настройки" справа. В новых версиях в "основных настройках" - "Больше настроек"). Там же можно (если необходимо) установить отправку этого сообщения в приват.
6. Для старых версий там же в настройках нужно перезагрузить текстовые файлы (или просто воспользоваться командой в чат !reloadtxt).

Всё готово и по команде !rules можно будет увидеть правила хаба.

Таким образом можно создать любые текстовые сообщения по команде. Например, можно сделать правила, сайты, хабы сети, информацию для операторов и тд. и тп.
Invisible, Pro009, Mega-Killer, Тёмич, shur49, мамин_парень
18.1.2009, 14:14 ! Часто Задаваемые Вопросы !
Обязательно прочитать всем!!!
Что такое MOTD или как установить сообщение при входе?

MOTD - это сокращение от Message Of The Day. Переводится как "Сообщение дня". Показывается при входе на хаб. Для старых версий PtokaX устанавливается на первой вкладке. Для новых версий устанавливается в настройках. Для отсылки данного сообщения в приват нужно установить галочку: "Отправлять сообщение дня в приват".
Invisible
18.1.2009, 13:49 ! Часто Задаваемые Вопросы !
Обязательно прочитать всем!!!
Как сделать отсылку сообщения пользователю при входе на хаб?

Простейший код реализации отсылки сообщения в чат пользователю при входе:

API 2:
Код
local sMsg=[[
Ваше сообщение
(можно даже в несколько строк!)
]]

function UserConnected(tUser)
  Core.SendToUser(tUser,sMsg)
end
RegConnected=UserConnected
OpConnected=UserConnected


API 1:
Код
local sMsg=[[
Ваше сообщение
(можно даже в несколько строк!)
]]

function NewUserConnected(tUser)
  tUser:SendData(sMsg)
end
OpConnected=NewUserConnected


Простейший код реализации отсылки сообщения в приват пользователю при входе:

API 2:
Код
local sMsg=[[
Ваше сообщение
(можно даже в несколько строк!)
]]

function UserConnected(tUser)
  Core.SendPmToUser(tUser,"Бот",sMsg)
end
RegConnected=UserConnected
OpConnected=UserConnected


API 1:
Код
local sMsg=[[
Ваше сообщение
(можно даже в несколько строк!)
]]

function NewUserConnected(tUser)
  tUser:SendPM("Бот",sMsg)
end
OpConnected=NewUserConnected
Invisible, Nissan_GT, drynyry, Saymon21, AfLc
18.1.2009, 13:38 ! Часто Задаваемые Вопросы !
Обязательно прочитать всем!!!
Где скачать хаб PtokaX?

Читаем внимательно тут: http://mydc.ru/topic19.html
Invisible
18.1.2009, 13:36 ! Часто Задаваемые Вопросы !
Обязательно прочитать всем!!!
В данной теме будут описываться часто задаваемые вопросы. Прежде чем писать очередной пост, посмотрите нету ли решения вашей проблему в этой теме!!!

Итак, поехали...

Где скачать хаб PtokaX?
Как сделать отсылку сообщения пользователю при входе на хаб?
Как прописать абсолютные пути?
Что такое MOTD или как установить сообщение при входе?
Как по команде сделать показ сообщения (например правил хаба)?
Как сделать контекстное меню для команды?
Как запретить скачивать и искать на хабе незарегистрированным?
Как запретить пользоваться чатом и личкой на хабе незарегистрированным?
Как написать функцию оповещения об ошибках скрипта?
Как запретить символы в нике для определённых профилей?
Как изменить выводимые в чат ники пользователей?
Как сделать действие по команде?
Как сделать приветствие с указанием времени суток?
Есть ли скрипт статистики скачивания на хабе?
Как сделать оповещение в ОпЧат о слишком большой шаре пользователя?
Как сделать ограничения действий или добавить исключения по профилям?
Как сделать ограничения действий или добавить исключения по никам пользователей?
Как установить/удалить/запустить PtokaX как службу?
Как сделать сообщение, которое будет выдаваться при входе на хаб(Перед надписями "Этот хаб работает ...")?
Invisible, Nissan_GT, Milena, TiGRpp
15.1.2009, 21:08 Способы Повышения Производительности
методы оптимизации lua кода
Самый оптимальный:
Код
function ChatArrival(tUser, sData)
  if sData:find"%b<>%s!startAR|"  then
    ...
  end
end


Однако чаще всего используется не одна команда, поэтому так:
Код
function ChatArrival(tUser, sData)
  local CmdMain = sData:match"%b<>%s(%S+)|"
  if CmdMain then
    if CmdMain=="!startAR"  then
      ...
    elseif ...
    end
  end
end
Invisible
14.1.2009, 18:16 Ключик Без Прав
API1
Название: addkey
Версия API: API1
Версия скрипта: 1.4.7
Автор: Sephiroth_Lukaw
Описание: Скрипт раздаёт ключики без прав.
Перенесено из раздела "Запросы скриптов".

[attachment=1448:addkey_v.1.4.7.lua]
andromed, shur49
14.1.2009, 18:07 Регистрация С Подтверждением
API2
Название: Registration
Версия API: API2
Версия скрипта: 2.0
Автор: DestroyNet
Описание: Скрипт регистрации с подтверждением.
Перенесено из раздела "Запросы скриптов".

[attachment=1446:Registration.v2.0.lua]
Saymon21, Pro009, zeusby
14.1.2009, 17:59 Антиреклама+антимат
API2
Название: Janus_HS_light
Версия API: API2
Версия скрипта: 1.01
Автор: Berkut
Описание: Скрипт содержит антирекламу и антимат (реализовано путём замены фраз).
Перенесено из раздела "Запросы скриптов"

[attachment=1496:Janus_HS...ght_API2.lua]
denis, sergius, vanyashalun, PSIX, Pro009
14.1.2009, 17:44 Прохождение Тестов
API1
Название: TestScript
Версия скрипта: 1.0
Версия API: API1
Автор: GhosTjokeR
Описание: Скрипт для прохождения тестов.
Перенесён из раздела "Запросы скриптов"

[attachment=1444:TestScript.zip]
zeusby
13.1.2009, 18:57 Onesend
API1, API2 | Скрипт одноразовой рассылки
Название: OneSend
Версия: 1.0
Версия API: API1, API2 (универсальный)
Автор: Setuper
Описание: Отсылает PM сообщение 1 раз при входе пользователя. При последующих входах сообщение отсылаться не будет.
Скрипт перенесён из раздела "Запросы скриптов".

[attachment=2353:OneSend.lua]
Invisible, Pro009, AfLc, dj_crazy_joker
13.1.2009, 18:50 Pxsettings
API2 | Скрипт управления настройками хаба
Название: PxSettings
Версия скрипта: 1.0d
Версия API: API2
Автор: Mutor
Язык: англ.
Описание: Зарубежный скрипт управления настройками хаба.
Скрипт перенесён из раздела "Запросы скриптов".

[attachment=1442:PxSettings1.0_API2.lua]
TiGRpp
13.1.2009, 18:38 Очередной Скрипт Приветствий
API2
Название: HelloUser
Версия API: API2
Автор: ?
Предоставил: brigadir
Описание: Скрипт выводит информационное сообщение при входе (сообщение с различными параметрами: Время Хаб онлайн, Общая шара хаба, Количество посетителей, Ник, ip, шара, вклад шары, профиль, тэг, описание, email, тип соединения).
Скрипт перенесен из раздела "Запросы скриптов"

[attachment=1441:HelloUser.lua]
Invisible, striker
13.1.2009, 17:45 Очистка Чата
API1, API2 | Скрипт очищает чат
Название: Chat-cleaner
Автор: Svyat
Подправления: Nickolya
Сделано: 16.06.08
Версия: RC2
Лог версий:
- 16.06.08 - Дата релиза RC1
- 17.06.09 - Добавлено меню
Описание: Скрипт Очистки главного чата. Очищает главный чат хаба, посылая сообщение с большим количеством знаков переноса (\n)
Перенесено из раздела запросы скриптов.

[attachment=1439:chat_cle..._API_1__.lua][attachment=1440:chat_cle..._API_2__.lua]
Pro009, andromed, shur49, Kar@bas, zeusby
13.1.2009, 17:18 Kicker
API1, API2 | Скрипт ограничения одновременных киков
Название: Kicker
Автор: Setuper
Версия API: API1, API2 (универсальный)
Версия: 1.1
Описание: Скрипт ограничения одновременных киков. Скрипт, который запрещает выделять всех юзеров и кикать. Вместо этого кикается тот, кто пытался всех кикнуть.
Скрипт перенесён из запросов скриптов и старая тема удалена.

[attachment=1438:Kicker.lua]
Al-j®, stone, AfLc
11.1.2009, 19:43 Способы Повышения Производительности
методы оптимизации lua кода
Вместо кода:
Код
string.match(sData, "%b<>%s+(%S+)")
можно писать код:
Код
sData:match"%b<>%s+(%S+)"

Оптимизация состоит в использовании метода вместо функции, ну и конечно же меньше символов писать (в свою очередь интерпретатор загружает данный код чуть-чуть быстрее).

И ещё обратите внимание на отсутствие внешних скобок big_smile.gif Можно было написать так:
Код
sData:match("%b<>%s+(%S+)")
однако, в данном случае внешние скобки можно опустить)))

Скобки у аргумента функции (или метода) можно опускать только в том случае, когда аргумент один и этот аргумент представляет из себя постоянную строку без конкатенаций.
Invisible, MIKHAIL
9.1.2009, 21:55 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Sending

Синтаксис:

Код
$Sending [Конечный_байт - Начальный_байт]|


Если запрошенные байты равны -1, то:

Код
$Sending|


Направление команды:

Клиент ---> Клиент

Описание:

Данная команда является расширением протокола. Отсылается в ответ на команду $GetZBlock, $UGetBlock, или $UGetZBlock.
Оба параметра [Начальный_байт] и [Конечный_байт] имеют номера, начиная с 0; первый принятый байт будет байт с номером 0.
Сначала, во время тестирования этой команды (GetTestZBlock), не было никаких параметров.
9.1.2009, 20:09 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$GetZBlock

Синтаксис:

Код
$GetZBlock [Число] [Число_байт] [Имя_файла]|


Направление команды:

Клиент ---> Клиент

Описание:

Данная команда является дополнением к протоколу. На поддержку данной команды указывает характеристика GetZBlock в команде $Supports.

Вместо команд $Get и $Send используется вышеприведенная команда.
Параметр [Число] начинается с 0 (именно с 0, в отличии от команды $Get, в которой данный параметр начинается с 1) и обозначает начальную точку загрузки файла.
[Число_байт] - это число отправляемых байт (или -1 для неизвестного или целого файла).
[Имя_файла] - очевидно, что это имя файла.

После этого второй клиент отвечает командой "$Sending [Байты]|[Сжатие]", если отправка прошла успешно или командой "$Failed [Описание_ошибки]|" в противном случае.

Если всё в порядке, то данные будут отправляться до тех пор пока не отошлёться вся не сжатая длина файла.
[Байты] - указывает сколько будет извлечено отосланных байт без сжатия, потому как отсылающий клиент не знает на сколько хорошо был сжат файл. Одна отсылка туда и обратно оптимизирует механизм передачи файла.

Сжатие: Для сжатия используется библиотека ZLib (v 1.1.4 в DC++ начиная с версии 0.21), использующая динамическое сжатие. Уровень сжатия может изменяться для того чтобы снизить нагрузку на процессор или в случае если файл не сжимается. Уровень сжатия регулируется с помощью хеш-функции adler32.

Команда $GetZBlock устарела, но согласно DC++ 0.696 её поддержка ещё существует. Новая реализация этой команды используется в команде $ADCGET с параметром ZL1.
9.1.2009, 12:56 Как Сделать Такое Меню?
API2
Цитата(Fislons @ 9.1.2009, 11:27) *
А как зделать что б итог "[10:25:47] * Fislons Мой ip: 127.0.0.7" показывался только мне??

лучше над этим не заморачиваться, так как для этого надо будет много написать кода))))

Вместо ip чтобы шара была делается так:
Код
function UserConnected(tUser)
  Core.GetUserData(tUser,16)
  Core.SendToUser(tUser,"$UserCommand 1 2 Меню для "..tUser.sNick.."\\Ваша шара: "..tUser.iShareSize.." байт$<%[mynick]> /me Моя шара: "..tUser.iShareSize.."  байт&#*124;")
end
RegConnected=UserConnected
OpConnected=UserConnected


Цитата
User data IDs for Core.GetUserData call.
-------------------
0 - sMode
1 - sMyInfoString
2 - sDescription
3 - sTag
4 - sConnection
5 - sEmail
6 - sClient
7 - sClientVersion
8 - sVersion
9 - bConnected
10 - bActive
11 - bOperator
12 - bUserCommand
13 - bQuickList
14 - bSuspiciousTag
15 - iProfile
16 - iShareSize
17 - iHubs
18 - iNormalHubs
19 - iRegHubs
20 - iOpHubs
21 - iSlots
22 - iLlimit
23 - iDefloodWarns
24 - iMagicByte
25 - iLoginTime
26 - sCountryCode


Читаем файл scripting-interface.txt, и меньше вопросов будет
Saymon21
7.1.2009, 13:41 PtokaX LUA API Converter
Конвертор из API в API2
В функции GetUserAllData должен быть только 1 аргумент. Удали второй.
Invisible, Saymon21
3.1.2009, 15:02 Способы Повышения Производительности
методы оптимизации lua кода
Довольно давно на форуме летали мысли по созданию подобной темы. В данной теме предполагается раскрывать как общие методы оптимизации, которые применяются ко всем lua скриптам, так и методы оптимизации конкретных кусков кода.

Итак, немного слов о том как работает lua.
LUA - это скриптовый язык программирования, то есть для работы ему не обязательна предварительная компиляция. "Загрузка" lua кода осуществляется интерпретатором. Существуют и скомпилированные lua коды. Компиляция осуществляется с помощью инструмента luac.

Преимущества скомпилированного кода:

  • Компилятор Lua способен выполнять элементарную оптимизацию. Например, он оптимизирует простые выражения с участием переменных и констант. Не обязательно заменять, скажем, выражение
    Код
    a = 2 * 34567 + b
    на
    Код
    a = 69134 + b
    Однако в открытом lua коде эту оптимизацию всё же следует производить.
  • Скомпилированный код загружается интерпретатором в разы быстрее из-за того, что интерпретатору не надо тратить время на перевод скрипта в байт-код.



Основные методы оптимизации.

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

  1. Доступ к локальным переменным в Lua несколько быстрее, чем к глобальным. Если требуется интенсивный доступ к глобальной таблице или функции, лучше завести локальную, присвоить ей значение глобальной и только потом начинать использовать. Эта техника не несет накладных расходов на копирование, так как в Lua данные таких типов копируются как ссылки, а не как значения.
    Код
    t = {"1", "2", "3", "4", "5"}
    function test()
      local temp, i = t, 0
      while i < 6 do
        Core.SendToAll(temp[i])
        i = i + 1
      end
    end


  2. По возможности в коде, критичном по производительности, не создавай множество объектов Lua, управляемых сборщиком мусора. Такие объекты создаются при склеивании строк, вызове конструкторов таблиц (например при вызовах функций с переменным числом аргументов), при объявлении любых функций, при выполнении команд dofile/dostring. Не следует дробить строки и лишний раз использовать конкатенацию, то есть вместо кода
    Код
    "test1".."\r\n".."test2"
    следует использовать код
    Код
    "test1\r\ntest2"
    В первом случае в lua стеке до следующей уборки мусора останутся строки: "test2", "\r\n" и "test1\r\ntest2", во втором же случае в стеке останется всего лишь строка "test1\r\ntest2". Подумайте над этим! Это не пустые слова. Каждый может проверить данное утверждение, используя lua debagger.

  3. Вместо многочисленных конкатенаций можно использовать метод format. Использование метода не будет оставлять много мусора. Например, вместо того, чтобы писать
    Код
    local str = "String: "..sParam1..", "..sParam2..", "..sParam3..", "..sParam4
    можем написать
    Код
    local str = ("String: %s, %s, %s, %s"):format(sParam1, sParam2, sParam3, sParam4)
    Для незначительных конкатенаций (менее 4 строк ("String: ", ", ", ", ", ", ") ) выигрыша нет, но для множества конкатенаций данный метод сэкономит память. Рекомендуется для конкатенации менее 4 временных строк использовать оператор конкатенации (..), а для множественной конкатенации использовать метод (format).
    Давайте разберём, что в данных 2 случаях записывается в мусор:
    1)
    Код
    local str = "String: "..sParam1..", "..sParam2..", "..sParam3..", "..sParam4
    В мусоре будет следующее:
    Код
    tostring(sParam4)
    ", "
    tostring(sParam3)
    ", "
    tostring(sParam2)
    ", "
    tostring(sParam1)
    "String: sParam1, sParam2, sParam3, sParam4"

    2)
    Код
    local str = ("String: %s, %s, %s, %s"):format(sParam1, sParam2, sParam3, sParam4)
    В мусоре будет следующее:
    Код
    "String: sParam1, sParam2, sParam3, sParam4"
    tostring(sParam4)
    tostring(sParam3)
    tostring(sParam2)
    tostring(sParam1)
    "String: %s, %s, %s, %s"
    "String: sParam1, sParam2, sParam3, sParam4"


  4. Одним из способов оптимизации является вариант использования для строк локальных методов, вместо глобальных функций. Например, использовать метод:
    Код
    sData:find(sStr)
    вместо функции глобальной таблицы
    Код
    string.find(sData, sStr)


  5. Перевод скриптового кода в код на C/C++ - один из действенных методов оптимизации. Если вдруг показалось, что какой-то участок кода на Lua нужно подвергнуть интенсивной оптимизации, обнаружен первый сигнал к тому, что этот кусок кода нужно переписать на C++.

  6. Большинство команд протокола NMDC оканчивается на символ "|", который служит для разделения команд, когда они находятся в одном потоке или в одной строке. Поэтому эффективнее отсылать 1 раз единую строку с командами, нежели отсылать несколько раз отдельные команды.
    Код
    local t = {
      "$MyINFO $ALL nick1 $ $ $ $0$",
      "$MyINFO $ALL nick2 $ $ $ $0$",
      "$MyINFO $ALL nick3 $ $ $ $0$"
    }
    local sStr = ""
    for i, v in ipairs(t) do
      sStr = (sStr == "" and "" or sStr.."|")..v
    end
    Core.SendToAll(sStr)
    тоже самое касается и сообщений (если вместо команд отправляются сообщения).

  7. Если в таблице используются только целочисленные индексы, то в цикле следует использовать функцию ipairs, в противном случае использовать функцию pairs
    Код
    local t1 = {
      "1",
      "2",
      "3"
    }
    for i, v in ipairs(t1) do
      ...
    end
    local t2 = {
      a = "1",
      b = "2",
      c = "3"
    }
    for i, v in pairs(t2) do
      ...
    end

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

  9. По возможности подключайте файлы с помощью функции require, а не с помощью функции dofile.
    Функция require выполняет файл однажды и передаёт загруженные параметры по ссылке.
    Функция dofile выполняет файл каждый раз и передаёт загруженные параметры по значению.
    При этом стоит учитывать, что функция require ищет загружаемые lua модули по путям, которые хранятся в переменной package.path (для загрузки dll библиотек package.cpath), а функция dofile загружает файлы по полному пути, который вы указываете перед названием файла.



Управление памятью

Язык Lua автоматически управляет памятью при помощи сборщика мусора (garbage collector): интерпретатор периодически вызывает сборщик мусора, удаляющий объекты, для которых была выделена память (таблицы, userdata, функции, потоки и строки) и которые стали недоступными из Lua («мертвые» объекты).

Интерпретатор Lua задает предел объема памяти (threshold), занимаемого данными. Как только занятый объем достигнет этого предела, запускается алгоритм, освобождающий память, занятую накопившимися «мертвыми» объектами. Затем устанавливается новый предел, равный двукратному объему памяти, занимаемой после очистки.

Чтобы запустить сборку мусора немедленно, нужно программно установить предел занимаемой памяти в 0 (вызвав lua_setgcthreshold() из C или collectgarbage() из Lua). Чтобы остановить сборку мусора, устанавливаем этот предел в достаточно большое значение.

Замечено, что в некоторых случаях память, занимаемая данными Lua, проявляет тенденцию к разрастанию, что может негативно сказаться на производительности программы. Чтобы избежать этого, лучше периодически вызывать сборку мусора принудительно.

При написании программ на Lua обязательно учитывай то, каким образом интерпретатор Lua управляет распределением памяти. Сборка мусора в версии 5 — относительно затратная по производительности операция (используется алгоритм non-incremental mark and sweep). Она инициируется автоматически, когда объем выделенной памяти превышает двукратный объем памяти, оставшейся выделенной после предыдущей сборки мусора (объем выделенной памяти, при превышении которого произойдет следующая сборка мусора, также можно задавать программно). Значит, фактически, в достаточно большой динамической системе сборка мусора может быть запущена в произвольный момент времени, вызвав просадку по производительности. Чем больше памяти выделено под объекты Lua, тем дольше происходит сбор мусора.

Итак, если мы, например, читаем в Lua данные из файла построчно и склеиваешь их в одну строку линейно, скорее всего, процесс будет продвигаться страшно медленно: после каждой следующей операции склейки объем занятой памяти, как минимум, удваивается и, соответственно, запускается процесс сборки мусора.

Код создает новую строку (и присваивает ее переменной some_string), а строка, хранившаяся в some_string до склейки, остается в памяти до следующей сборки мусора:
Код
local some_string = some_string.."a"
Tsd, Invisible, Ksan, Maximum, Alexey, Kingston, Saymon21, MIKHAIL, мамин_парень
29.12.2008, 14:22 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$GetINFO

Синтаксис:

Код
$GetINFO [Ник_жертвы] [Ник]|


Направление команды:

Клиент ---> Хаб

Описание:

Запрос команды $MyINFO с хаба.

[Ник] - ник отправителя.
[Ник_жертвы] - ник пользователя, о котором нужно узнать информацию. Сервер должен отправить строку MyINFO указанного клиента.
29.12.2008, 13:43 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Capabilities

Синтаксис:

Код
$Capabilities [Характеристика1]$[Характеристика2]$ ... $[ХарактеристикаN]|


Характеристики:

Поддерживается: Valknut (Hub to Client)

Направление команды:

Клиент ---> Хаб
Хаб ---> Клиент

Описание:

Команда $Capabilities является расширением протокола (используется в клиенте DCGUI). Цель данной команды такая же как и у более популярной команды $Supports.

Известные Характеристики:

UniSearch
XSearch
MD4x
29.12.2008, 13:30 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$ADCGET / $ADCSND

Направление команды:

Клиент ---> Клиент

Описание:

Данная команда является дополнительной клиент-клиент командой протокола NMDC, указываемая по средствам характеристики ADCGet в команде $Supports. Эта характеристика указывает на поддержку команды GET нового протокола ADC, и используется для скачивания файлов между клиентами. Команды должны выполняться после того как клиенты уже связались друг с другом и готовы получать или отдавать файлы.

ZLIG, TTHL, и TTHF - это все доступные дополнения команды $ADCGET

запрос:

Код
$ADCGET file TTH/PPUROLR2WSYTGPLCM3KV4V6LJC36SCTFQJFDJKA 0 1154 ZL1|


ответ:

Код
$ADCSND file TTH/PPUROLR2WSYTGPLCM3KV4V6LJC36SCTFQJFDJKA 0 1154 ZL1|[Содержимое_файла]


Файл-лист: запрос

Код
$ADCGET file files.xml.bz2 0 -1 ZL1|


ответ:

Код
$ADCSND file files.xml.bz2 0 8775 ZL1|[Содержимое_файла]


а также запрос по контрольной сумме TTH:

Код
$ADCGET tthl TTH/PPUROLR2WSYTGPLCM3KV4V6LJC36SCTFQJFDJKA 0 -1|


ответ:

Код
$ADCSND tthl TTH/PPUROLR2WSYTGPLCM3KV4V6LJC36SCTFQJFDJKA 0 24|[Interleaves]
29.12.2008, 13:06 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Ping

НЕ ПОДДЕРЖИВЕТСЯ КЛИЕНТОМ DC++

Синтаксис:

Код
$Ping [IP]:[Порт]|


Направление команды:

Клиент ---> Клиент

Описание:

[IP]:[Порт] - это IP и UDP порт, который отправитель пытается прослушать.
Пинг измеряет время ожидания сигнала.
Если вы своим клиентом пытаетесь пинговать, то вы должны быть уверены в том, что данная команда соответствует протоколу NMDC v1.0 beta 9 и поддерживается другим клиентом.
29.12.2008, 12:48 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$BotINFO / $HubINFO

Синтаксис:

Запрос клиента на пинг:

Код
$BotINFO [Описание_бота]|


Ответ сервера

Код
$HubINFO [Имя_хаба]$[Адрес_хаба:Порт]$[Описание_хаба]$[Макс_юзеров]$[Мин_шара]$[Мин_слотов]$[Макс_хабов]$[Тип]$[Владелец]|


Направление команд:

Клиент ---> Хаб ($BotINFO)
Хаб ---> Клиент ($HubINFO)

Описание:

Данная команда нужна для получения более полной информации о хабе.

[Описание_бота] - может быть любой строкой, обычно это информация об адресе или хаб-листе.
[Имя_хаба], [Адрес_хаба] и [Описание_хаба] - это пункты, которые будут показаны в хаб-листе (некоторые хабы имеют несколько адресов это помогает определит главный адрес). Описание хабов меняется часто, поэтому требует частого обновления.
[Макс_юзеров], [Мин_шара], [Мин_слотов], [Макс_хабов] - соответственно максимально допустимое число пользователей, минимально допустимая шара на хабе, минимальное число слотов, максимальное число подключенных хабов.
[Тип] - этот параметр даёт информацию о программе, под управлением которой работает хаб.
[Владелец] - владелец хаба или email адрес владельца хаба

Если адрес хаба 127.0.0.1, то Hublist.org удалит информацию об этом хабе из своей базы данных.

Поддержка:

Данные команды поддерживаются следующими программами:

• PtokaX
• Verlihub
• Yhub
• SDCH
• PHPDC-Hub
• DB Hub >= 0.314
• GeneralBot >= 0.24 (NMDCH Script)
• HubRules >= 1.11 (DCH++ Plugin)
• HubList >= 0.1.0 (ODC(#)H Plugin)

На поддержку данных команд указывают характеристики BotInfo/HubInfo в команде $Supports
Различные хабы по разному обрабатывают данные команды, - некоторые отключают пингера после отсылки ему команды, а некоторые продолжают держать пингера на хабе, предполагая, что пингер сам разорвёт соединение с хабом.
28.12.2008, 19:00 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$MultiSearch

ЧАСТИЧНО ПОДДЕРЖИВАЕТСЯ КЛИЕНТОМ DC++

Синтаксис:

Активный пользователь:

Код
$MultiSearch [IP]:[Порт] [Строка_поиска]


Направление команды:

Клиент ---> Хаб

Описание:

Данная команда является командой со стороны клиента для того чтобы иметь преимущество перед линкованым NMDC хабом. Клиент отсылает команду $MultiSearch на хаб, хаб, в свою очередь, пересылает команду $Search по UDP на все связанные с ним хабы, на подобие того, как команда $Search отсылается хабом всем пользователям хаба.

Данная команда используется совместно с командой $MultiConnectToMe. Поддержка этой команды была ограничена в версиях oDC. Её поддержка вызвана некоторыми проблемами. Для детального разбора проблем смотрите описание команды $MultiConnectToMe.

Описание синтаксиса параметров смотрите в команде $Search.
28.12.2008, 18:52 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$MultiConnectToMe

ЧАСТИЧНО ПОДДЕРЖИВАЕТСЯ КЛИЕНТОМ DC++

Синтаксис:

Код
$MultiConnectToMe [Удалённый_ник] [IP_отправителя]:[Порт_отправителя]


Направление команды:

Клиент ---> Хаб

Описание:

Эта команда была придумана как команда со стороны клиента, для того чтобы иметь преимущество перед слинкованным хабом. Клиент отсылает команду $MultiConnectToMe на хаб, хаб, в свою очередь, пересылает команду $ConnectToMe по UDP на все связанные с ним хабы, на подобие того, как команда $Search отсылается хабом всем пользователям хаба.

Данная команда используется совместно с командой $MultiSearch. Поддержка этой команды была ограничена в версиях oDC. Было проблематично поддерживать эту команду, потому как NMDC хаб не мог контролировать все свои линкованые части и не мог транслировать соединение с удалёнными пользователями. Таким образом, oDC клиент должен был отсылать команду $MultiConnectToMe даже тогда, когда пользователь находился в оффлайне.

Пример:

Код
$MultiConnectToMe RemoteNick 10.10.10.10:13671
28.12.2008, 18:23 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$FeaturedNetworks

Синтаксис:

APN мульти-хаб-чат сообщение обычно выглядит следующим образом:

Код
<(YYY)XXX> MMM|


Где YYY - это префикс, XXX - это ник пользователя и MMM - это сообщение.

Код
$FeaturedNetworks YYY$$YYY$YYY$$|


YYY - идентификатор хаба в сети. На настоящее время APN MultiHubChat система может иметь до 5 таких идентификаторов, а в некоторых случаях и больше.

Направление команды:

Хаб ---> Хаб

Описание:

Команда $FeaturedNetworks - это команда дополнения к протоколу Access Point Name (APN) MultiHubChatsystem, для того, чтобы определить другие хабы и другие точки входа (IRC, Telnet) и тд. Первоначально команда была создана для того чтобы помочь разработчикам APN и для того чтобы добиться лучшей интеграции между мульти-хабами.

На мульти-хабах сообщения в чат поступают с уникальными префиксами (идентификаторами), обычно длинной в 3 символа (в нике). Хаб, который получает сообщение от какого-то "своего" пользователя должен разослать его по всем остальным хабам.


Реализация:

Если хаб отсылает данную команду, то на хабе должен быть определён какой-то префикс, который будет применяться к пользователям хаба.

Префикс хаба определяет админ хаба. Однако существуют следующие префиксы:

APx - Хаб x (DC, где x - это ¹, ² или ³).
APt - Telnet доступ (Telnet Чат Плагин)
IRC - IRC доступ (IRC Плагин)
APs - Shoutcast (Shoutcast Announcer Плагин)

Команда $FeaturedNetworks может использоваться практически любым хабом или MHC ботом.
27.12.2008, 15:44 От: Объектно-ориентированные Принципы В Lua
От темы с ID: 1429
Продолжаю знакомство с ООП в LUA.

Реализация класса в lua.
  • Конструкторы
  • Открытые переменные и функции (public)
  • Закрытые переменные и функции (private)

Код
--//Функция-конструктор класса cMyClass
cMyClass = function(tData)
    local t = {}
    tData = tData or {}
    
--//private:
    t.z = 0 --//Значение по умолчанию
    t.PrivateFunc = function()
        return "Это закрытая функция, которая доступна только внутри данного класса cMyClass!"
    end
    
--//public:
    tData.x = tData.x or 0
    tData.y = tData.y or 0
    
    
    --//Инициализация полей 'x' и 'y'
    t.__call = function(f, a, b)
        if a then tData.x = a end
        if b then tData.y = b end
    end
    
    
    --//Получения значения индекса
    t.__index = function(tab, key)
        if key == "z" then --//Защита от чтения 'private' переменной 'z'
            return
            
        elseif key == "GetZ" then --//Объявление 'public' функции, которая возвращает значание 'private' переменной 'z'
            return function()
                return t.z
            end
            
        elseif key == "SetZ" then --//Объявление 'public' функции, которая записывает значание в 'private' переменную 'z'
            return function(z)
                t.z = z
                return true
            end
            
        elseif key == "x" then --//Доступ к 'public' полю 'x'
            return tData.x or 0
            
        elseif key == "y" then --//Доступ к 'public' полю 'y'
            return tData.y or 0
            
        elseif rawget(tab, key) then --//Доступ к любому другому 'public' полю
            return rawget(tab, key)
        end
    end
    
    
    --//Присвоение новому индексу значения
    t.__newindex = function(tab, key, val)
        if key == "z" then --//Защита от записи в 'private' переменную 'z'
            return
            
        else --//Запись в любое другое поле
            return rawset(tab, key, val)
        end
    end
    
    
    setmetatable(tData, t)
    return tData
end



Использование класса cMyClass
Код
--//Создаём объект 'u' типа 'cMyClass' с 'public' полем 'z'
local u = cMyClass({z="u.z_value"})


--//Создаём объект 'v' типа 'cMyClass' с 'public' полями 'x' и 'y'
local v = cMyClass({x="v.x_value",y="v.y_value"})


--//Инициализируем 'public' поля 'x' и 'y' объекта 'u'
u("u.x_value", "u.y_value")


--//Устанавливаем значение 'private' поля 'z' объекта 'u'
u.SetZ("private_z_value")


--//Выводим результаты
Core.SendToAll("\n==============================================\n\t"..
"u.x = '"..tostring(u.x).."', \tv.x = '"..tostring(v.x).."';\n\t"..
"u.y = '"..tostring(u.y).."', \tv.y = '"..tostring(v.y).."';\n\t"..
"u.z = '"..tostring(u.z).."', \tv.z = '"..tostring(v.z).."';\n\t"..
"u.GetZ() = '"..tostring(u.GetZ()).."', \tv.GetZ() = '"..tostring(v.GetZ()).."'.\n"..
"==============================================")
MIKHAIL
22.12.2008, 22:35 Антиреклама
идея более сложного скрипта
хехе. Давайте я вам расскажу самый продвинутый способ борьбы против рекламы.

Смысл вот в чём: если хорошенько подумать, то можно понять, что избавиться от рекламы не так уж и просто, потому что если запрещаешь что-то, то юзер находит обходные пути. Тогда назревает вопрос: как сделать так, чтобы юзер не мог найти обходные пути. Ответ на этот вопрос прост: надо чтобы юзер не находил обходные пути, то есть использовал старые пути, которые уже известны. Этого можно добиться только в том случае, если у юзера не возникает потребности изобретать что-то новое.

Из всего сказанного следует простой метод борьбы с рекламой: надо уверить рекламщика в том, что его реклама успешно прошла.


Пример:

Рекламщик пытается рекламировать свой хаб: dchub://10.10.10.10

Антиреклама действует следующим образом: она рекламщику отсылает его же рекламу: dchub://10.10.10.10
А всем остальным пользователям отсылается модифицированное сообщение. Допустим установлен генератор случайных чисел и всем пользователям (кроме рекламщика) придёт сообщение: dchub://245.85.94.77

То есть мы уверили рекламщика в том, что его реклама прошла в чат, и он, успокоившись, уже не станет изобретать какие-то другие методы рекламы.

Метод реализован в проекте мульти-бота SBot.

За два с половиной года существования на моём хабе такого метода антирекламы никто не смог прорекламировать свои хабы.
LOKI
20.12.2008, 15:40 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$To

Синтаксис:

Код
$To: [Ник_получателя] From: [Ник_отправителя] $<[Ник]> [Сообщение]|


Направление команды:

Клиент ---> Хаб
Хаб ---> Клиент

Описание:

Эта команда используется для отправки личного сообщения.

[Ник] - этот параметр не обязан совпадать с ником отправителя (это может быть, например, бот), НО он не обязан совпадать только в случае поступления этой команды от хаба клиенту, а не от клиента хабу! При поступлении команды от клиента хабу, последний может (обязан) проверять совпадение ника с ником отправителя.
[Ник_получателя] - ник получателя приватного сообщения.

При поступлении данной команды от клиента, хаб просто транслирует эту команду в соответствующее соединение.
Saymon21
20.12.2008, 15:33 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Send

Синтаксис:

Код
$Send|


Направление команды:

Клиент ---> Клиент

Описание:

Данная команда посылается скачивающим клиентом в ответ на команду $FileLength отдающего клиента.
Команда просит отдающего клиента начать отдачу файла.
20.12.2008, 15:27 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$MyNick

Синтаксис:

Код
$MyNick [Ник]|


Направление команды:

Клиент ---> Клиент

Описание:

Первая команда, которую нужно послать клиенту при соединении с другим клиентом.
Команда $Lock должна быть послана вслед за данной командой.

Специфичность:

DC++ проверяет, чтобы указанный в этой команде ник был найден хотя бы на одном из хабов, в противном случае соединение закрывается немедленно.
20.12.2008, 15:20 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$MCTo

Синтаксис:

Код
$MCTo: [Ник_принимающего] $[Ник_отсылающего] [Сообщение]|


Направление команды:

Клиент ---> Хаб

Описание:

Данная команда отсылает сообщение пользователю, которое видно в чате только ему.
20.12.2008, 15:06 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$MaxedOut

Синтаксис:

Код
$MaxedOut|


Направление команды:

Клиент ---> Клиент

Описание:

Данная команда отсылается клиентом, когда у него нету свободных слотов.
20.12.2008, 15:01 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$GetListLen

Синтаксис:

Код
$GetListLen|


Направление команды:

Клиент ---> Клиент

Описание:

Старая команда.

Данная команда используется для того, чтобы получит размер файл-листа стиля DcLst удалённого пользователя. Удалённый пользователь в ответ отправит команду $ListLen.

Однако эта команда давно исключена из протокола. Начиная с версии 0.69, DC++ больше не генерирует списки стиля DcLst.
20.12.2008, 14:49 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Get

Синтаксис:

Код
$Get [Файл]$[Число]|


Направление команды:

Клиент ---> Клиент

Описание:

Данная команда используется для инициализации загрузки нужного файла. Клиент как бы просит у другого клиента файл.

[Файл] - это полное имя файла и путь к нему в соответствие с указанным в команде $SR или в файл-листе.
[Число] - начальная точка загрузки (начинается с 1, а не с 0)

Команда $Error с параметром "File Not Found" посылается когда файл не доступен. NMDC разъединяет пользователя если в запросе не указана директория. (то есть клиент отсылает команду $Error в ответ на команду "$Get не_существующая_директория\не_существующий_файл$1|" и разъединяет в ответ на команду "$Get не_существующий_файл$1|")

Когда файл доступен, источник файла отсылает команду $FileLength.

Для извлечения файл-листа служит команда:
Код
$Get MyList.DcLst$1|
20.12.2008, 14:35 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$FileLength

Синтаксис:

Код
$FileLength [Размер_файла]|


Направление команды:

Клиент ---> Клиент

Описание:

Данная команда отсылается отдающим клиентом скачивающему клиенту в ответ на команду $Get. Единственным параметром является размер скачиваемого файла в байтах.
20.12.2008, 14:30 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Failed

Синтаксис:

Код
$Failed [Сообщение]|


Направление команды:

Клиент ---> Клиент

Описание:

Эта команда является командой DC++ дополнительных характеристик. Отсылается в ответ на команду $GetZBlock, $UGetBlock, или $UGetZBlock. Одним из значений параметра [Сообщение] может быть значение "File Not Available" (Файл не найден).
20.12.2008, 14:23 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Error

Синтаксис:

Код
$Error [Сообщение]|


Направление команды:

Клиент ---> Клиент

Описание:

Эта команда отсылается когда возникает ошибка.

[Сообщение] - это строка, описывающая ошибку. Наиболее распространённая ошибка "File Not Available" (Файл не доступен), возвращается когда у запрошенного клиента не оказалось нужного файла (хотя он раньше у него был). Если вы пишете своего клиента, то учтите, что реализация этой строки может привести к несовместимости.
20.12.2008, 14:11 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Direction

Синтаксис:

Код
$Direction [Направление] [Номер]|


Направление команды:

Клиент ---> Клиент

Описание:

Эта команда отсылается в ответ на команду $Key. Команда решает какая сторона будет скачивать.

[Направление] - данный параметр может принимать значения "Upload" или "Download". Параметр принимает значение "Upload" только в случае если ваш клиент ничего не хочет скачать с соединяемого пользователя.
[Номер] - это случайное число. Когда оба клиента хотят скачивать друг у друга, первым начинает скачивать тот, у кого это число выше. Если эти числа равны, то соединение закрывается.

Специфичность:

Максимальное значение параметра [Номер] - 0x7FFF. NMDC должен разорвать соединение, если отсылаемое число вдруг оказалось больше максимального.

DC++ может не посылать эту команду после команды $Lock, если в команде $Lock встретилось значение EXTENDED. Смотрите описание команды $Supports.

У DC++ клиентов есть следующий баг:
У клиента A ноль свободных слотов, у клиента B есть свободные слоты. Клиент B хочет скачать у A файлы, клиент A также хочет скачать у B некоторые файлы.
Если клиент A хочет получить что-то от клиента B и он посылает случайное число, клиент B не может получить слот, потому что их нет у клиента A и тогда в статусной строке появляется надпись "Соединение...". Решение этой проблемы предложено на страницах обсуждения клиента. Выход из этой ситуации осуществляется отправкой всё большего и большего случайного числа, пока не освободится свободный слот и не установится соединение.
20.12.2008, 13:35 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Canceled

Синтаксис:

Код
$Canceled


Направление команды:

Клиент ---> Клиент

Описание:

Данная команда отсылается клиентом в ответ на команду $Cancel другого клиента. Смотрите описание команды $Cancel для более детального вникания. Следует отметить орфографию написания команды $Canceled, в отличии от хорошо известного слова "Cancelled."
20.12.2008, 13:22 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Cancel

Синтаксис:

Код
$Cancel


Направление команды:

Клиент ---> Клиент

Описание:

Скачивающий клиент может отменить скачку с некоторых клиентов (версии NMDC Windows по крайней мере). Это делается с помощью отсылки команды $Cancel (без символа | на конце!).

В свою очередь отдающий клиент при получении этой команды должен закрыть поток и отослать в ответ команду $Canceled (также без символа | на конце). Следующий пример показывает как это работает. D - скачивающий клиент, U - отдающий клиент.

Цитата
D>U: $Send|
U>D: файловый поток (D сохраняет куски файла на диск)
D>U: $Cancel (D прекращает сохранять на диск и ожидает команду $Canceled)
U>D: отдача может продолжаться, однако она уже будет игнорироваться клиентом D
U>D: $Canceled


Данная команда поддерживается только в версиях NMDC 1.x. Mac и Windows NMDC 2.x версии не могут отменить передачу как это делает NMDC 1.x. DC++ никогда не поддерживал команду $Cancel или $Canceled.

Смотрите также описание команды $Canceled
20.12.2008, 12:05 Описание Бота
помогите перевести под API1
исправил
мамин_парень
20.12.2008, 2:43 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$ValidateDenide

Синтаксис:

Код
$ValidateDenide [Ник]|


Направление команды:

Хаб ---> Клиент

Описание:

Эта команда является частью рукопожатия между клиентом и хабом. Хаб отправит эту команду клиенту в ответ на команду $ValidateNick, если такой ник уже используется на хабе, или ник совпадает с зарезервированным ником (таким как "Hub-Security").

[Ник] - это отвергнутый ник.
После того как эта команда придёт к клиенту клиент сгенерирует сообщение "Your nick was already taken (Ваш ник уже используется)" (содержание этого сообщения, вообще говоря, настраивается в клиенте).

Замечание:
Обратите внимание на название команды: $ValidateDenide, а не $ValidateDenied, как казалось бы должно быть!
Saymon21, мамин_парень
20.12.2008, 2:31 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$ValidateNick

Синтаксис:

Код
$ValidateNick [Ник]|


Направление команды:

Клиент ---> Хаб

Описание:

Эта команда является частью рукопожатия между клиентом и хабом. Она посылается клиентом на хаб после команды $Key. Она определяет ник [Ник], который вы хотите использовать на хабе.

Внимание!
По протоколу ник не должен содержать символы: $ | и пробел.
Клиент, до входа на хаб, может преобразовывать все пробелы на нижние подчёркивания, и, таким образом, продолжать использование данного модифицированного ника.

Смотрите также:

$HubIsFull, когда хаб полон
$ValidateDenide, когда ник уже используется
$GetPass, когда для ника запрашивается пароль
$Hello, когда ник принят
20.12.2008, 2:23 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Version

Направление команды:

Клиент ---> Хаб

Синтаксис:

Код
$Version [Версия]|


Описание:

Команда, содержащая версию NMDC протокола клиента.
Эта команда должна быть послана клиентом на хаб после того, как хаб пошлёт клиенту команду $Hello.

Последняя 1.x версия NMDC была 1.0091. Используется альтернативный десятичный разделитель (,). Поэтому, DC++ использует номер версии в качестве числа 1,0091 не зависимый от местоположения компьютера.
20.12.2008, 2:10 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$UserIP

Направление команды:

Хаб ---> Клиент
Клиент ---> Хаб

Синтаксис:

Запрос со стороны клиента:

Код
$UserIP [Ник1]$$[Ник2]$$[Ник3]$$ ... $$[НикN]$$|


Ответ со стороны сервера:

Код
$UserIP [Ник1] [IP1]$$[Ник2] [IP2]$$[Ник3] [IP3]$$ ... $$[НикN] [IPN]$$|


Описание:

Эта команда посылается клиентом на хаб, для того, чтобы получить ip адрес одного или более пользователей. Все пользователи разделены в команде знаками $$ (также как и в командах $NickList и $OpList). IP адрес, посылаемый хабом, должен быть реальным для хаба удалённым IP адресом, и этот IP адрес может отличаться от IP адреса, посылаемого в команде $ConnectToMe (потому что клиент может быть подключен к хабу напрямую, а между вторым клиентом и данным клиентом может находится маршрутизатор, который и сменит ip адрес в случае использования команды $ConnectToMe). DC++ не просит свой собственный IP адрес. Хабы, поддерживающие расширение протокола UserIP2 (UserIP v2), должны автоматически отсылать собственный IP клиента при входе на хаб.
20.12.2008, 1:50 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$UserCommand

Направление команды:

Хаб ---> Клиент

Синтаксис:

Код
$UserCommand [Тип] [Контекст] [Детали]||




[Тип] - положительное, целое число, описывающее тип команды:
0 - разделитель
1 - raw команда
2 - raw команда с ограничением на единственный ник %[nick]
255 - очистка команд
[Контекст] - целое число, регулирующее где показывать контекстные менюшки:
[1] - Контекстное меню хаба (доступно по клику на вкладке хаба). Примеры: просмотр правил, смена пароля. Эта команда может содержать параметр %[nick]. Вместо этого следует использовать переменную %[mynick] или %[line:blah].
[2] - Контекстное меню юзера (доступно по клику на любого юзера). Примеры: показ статистики юзера, проверка бана юзера. Эта команда может содержать переменные: %[nick], %[mynick] и %[line:blah].
[4] - Контекстное меню поиска. Пример: сообщить о битом файле. Эта команда может содержать специфические аргументы ника и файла.
[8] - Конкестное меню файл-листа. Пример: сообщение о найденном итом файле у юзера в списке файлов. Эта команда может содержать специфические аргументы ника и файла.
Замечание: этот контекст является новым в DC++ 0.669

[Детали] - этот параметр зависит от параметра [Тип]
[Тип] = 0 (разделитель) и [Тип] = 255 (очистка) не должны содержать параметра [Детали]
[Тип] = 1 (raw) использует в качестве деталей [Заголовок]$[Команда]
[Заголовок] - это название менюшки. Менюшка может быть составной, то есть содержать подменюшки. Для построения подменюшки используется обратный слеш (\). Например, [Подменю]\[Заголовок]. Степень вложенности подменюшек может быть любой.

Более высокие числа зарезервированы для дальнейшего использования.


Эскейп последовательности:
Если в меню используются знаки $, | и &, то их необходимо заменить на кодовые аналоги (аналоги html). Соответственно $ | и &

Как и все команды NMDC, данная команда разделяется от других знаком |.


Контекст:

Контекстное число - это бинарный флаг, который может быть составлен из других чисел, например, меню юзера и меню поиска вместе дадут (2 | 4 = 6). То есть для того, чтобы менюшка появилась в меню юзера и в меню поиска следует указывать контекст равный шести.


Детали:

Разделитель (вертикальная черта):

Код
$UserCommand 0 [Контекст] |


После [Контекста] и перед символом | может находиться некий текст, который в любом случае будет игнорироваться

Raw команды:

Код
$UserCommand 1 [Контекст] [Заголовок]$[raw]||


Команда добавляет raw пункт меню с заголовком [Заголовок] и raw командой [raw]. Эта команда должна оканчиваться на |, и если этого символа нет, то она отвергается.

Raw команда с ограничением на единственный ник:

Код
$UserCommand 2 [Контекст] [Заголовок]$[raw]||


Тоже самое, что и в предыдущем случае, но эта команда работает одна на один ник. Это должно помешать использованию массовой рассылки.

Очистка меню:

Код
$UserCommand 255 [Контекст] |


Команда стирает все менюшки из указанного контекста и ниже. То есть, например, 7 - сотрёт все менюшки с контекстами 1,2 и 4.

Примеры:

Код
$UserCommand 2 6 Кик$$To: %[nick] From: %[mynick] $<%[mynick]> You are being kicked====|$Kick %[nick]||


Эта команда отсылает в приват сообщение "You are being kicked====" для ника, и отправляет команду $Kick. Менюшки будут в поиске и меню юзера. Raw команда с ограничением на единственный ник не позволит сделать множественный кик.

Код
$UserCommand 255 1 |


Команда удалить все менюшки из контекстного меню хаба (вкладка хаба).

На поддержку данной команды может указывать наличие характеристики UserCommand в команде $Supports. Однако, из-за большой распространённости данной команды наличие этой характеристики в команде $Supports не обязательно.
Saymon21, TiGRpp
19.12.2008, 10:39 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Supports

Синтаксис:

Код
$Supports [Характеристика1] [Характеристика2] [Характеристика3] ... [ХарактеристикаN] |


Характеристики поддерживаются: DC++ 0.17+ (Клиент - Клиент), DC++ 0.300 (Хаб - Клиент)

Направление команды:

Хаб ---> Клиент
Клиент ---> Хаб
Клиент ---> Клиент
Хаблист ---> Хаб
Хаб ---> Хаблист
Пингер ---> Хаб
Хаб ---> Пингер

Описание:

Данная команда используется для определения характеристик. Чтобы указать на то, что сервер имеет хотя бы одну характеристику, он должен отослать в начале команды $Lock следующую фразу EXTENDEDPROTOCOL. Если вторая сторона также поддерживает некоторые характеристики, то она также отсылает $Supports. Эта команда обязательно предшествует команде $Key.

Замечания:

• EXTENDEDPROTOCOL не должна отсылаться, если сервер не поддерживает никакие характеристики
• Пустая команда $Supports не допустима
• Пробелы в именах характеристик также не допустимы
• Для характеристик клиента, имя дополнения должно быть таким же как и имя команды этого дополнения.
• Хабы обычно хотят получить команду $Supports до команд $Key и $ValidateNick. Итак, последовательность должна быть такова:
Код
$Supports ..|$Key ..|$ValidateNick ..|


Характеристики для связи Клиент - Хаб:

BotList
ClientID
Feed
HubTopic
IN
MCTo
NoGetINFO
NoHello
OpPlus
QuickList
TTHSearch
UserCommand
UserIP2
ZLine
ZPipe0


Характеристики для связи Клиент - Клиент:

ADCGet
BZList
CHUNK
ClientID
GetCID
GetTestZBlock
GetZBlock
MiniSlots
TTHL
TTHF
XmlBZList
ZLIG
19.12.2008, 10:20 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$SR

Синтаксис:

Код
$SR [Ник_ответчика] [Результат][0x05][Свободные_слоты]/[Всего_слотов][0x05][Имя_хаба] ([IP_хаба:Порт]){[0x05][Целевой_ник]}|


Направление команды:

Клиент ---> Хаб
Хаб ---> Клиент
Клиент ---> Клиент
Хаб ---> Хаб

Описание:

Данная команда используется для возврата файла или директории, которая соответствует запросу в команде $Search. Все условия, которые находятся в оригинальном запросе, должны находиться в [Результат], и все типы и ограничения, используемые в команде $Search, должны быть выполнены.

[Результат] представляет из себя либо [Имя_файла][0x05][Размер_файла] для поиска по файлам, либо [Директория] для поиска по директориям
[0x05] - это 5-ый ASCII символ (используется в качестве разделителя).

Данная команда посылается клиентом, если у данного клиента нашлось что-то из запроса команды $Search от другого клиента.
Если команда $Search была послана от пассивного пользователя, то команда $SR должна быть возвращена хабу (через TCP). В этом случае, в конец данной команды должно быть дописано [0x05][Целевой_ник]. Перед пересылкой этой команды пользователю, который инициализировал поиск, хаб удаляет данную приписку с разделителем и целевым ником. Если команда $Search была послана от активного пользователя, то команда $SR возвращается на указанный в команде $Search IP адрес и UDP порт.
Параметр [IP_хаба:Порт] нужен только в том случае, если порт хаба не является портом по умолчанию (411).
В UNIX системах в путях к файлу должен встречаться только прямой слеш (/).
DC++ клиент будет отсылать максимум 5 результатов поиска для пассивных пользователей и 10 для активных. Кроме этого, для того, чтобы снизить нагрузку, хаб может сократить количество возвращаемых поисковых запросов.
Для файлов, содержащих TTH, параметр [Имя_хаба] заменяется на TTH:[base32_encoded_tth_hash] (см. TTH)

Примеры:

Ответ на пассивный поиск:

Код
$SR Вася Файл.txt[0x05]437 3/4[0x05]МойХаб (10.10.10.10:411)[0x05]Петя|


Ответ на активный поиск:

Код
$SR Вася Файл.txt[0x05]437 3/4[0x05]МойХаб (10.10.10.10:411)|
Karumo, PPA
18.12.2008, 21:44 Метод Быстрого Перевода Скриптов Под API_1
Самостоятельный быстрый перевод из API_2 ---> в API_1
v 1.4.0.0 (файл перезалит в первой теме)

Fixed:

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

Added:

* Добавлена реализация функции Core.GetUserValue
Invisible
17.12.2008, 19:24 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Search

Синтаксис:

Пользователь в активе:

Код
$Search [IP]:[Порт] [Строка_поиска]


Пользователь в пассиве:

Код
$Search Hub:[Ник] [Строка_поиска]


Направление команды:

Клиент ---> Хаб
Хаб ---> Клиент
Хаб ---> Хаб

Описание:

Данная команда используется для начала поиска файлов на хабе. Формат [Строки_поиска] не зависит от режима подключения клиента (актив, писсив).


[IP] - IP адрес активного пользователя.
[Порт] - UDP порт, который клиент слушает для приёма ответов на запрос от других клиентов.
[Ник] - ник пассивного пользователя.
[Строка_поиска] - строка поиска, которая описывает файл, который ищет клиент. Части этой строки разделяются знаками вопроса ('?'):

[Размер_ограничения]?[Максимальный_размер]?[Размер]?[Тип_данных]?[Поисковый_параметр]

[Размер_ограничения] - принимает значение 'T', если поиск должен быть ограничен максимальным или минимальным размером, иначе 'F'.
[Максимальный_размер] - принимает значение 'F', если [Размер_ограничения] равен 'F' или если размер ограничения устанавливает более низкий предел размера файла, инача 'T'.
[Размер] - минимальный или максимальный размер файла в байтах (в случае если указан [Максимальный_размер]) и если [Размер_ограничения] принимает значение 'T', иначе 0.
[Тип_данных] - ограничение поиска по типу файлов. Данное ограничение принимает одно из следующих целых чисел:
  • 1 для любого типа файлов;
  • 2 для аудио файлов ("mp3", "mp2", "wav", "au", "rm", "mid", "sm");
  • 3 для архивов и сжатых файлов ("zip", "arj", "rar", "lzh", "gz", "z", "arc", "pak");
  • 4 для документов и текстовых файлов ("doc", "txt", "wri", "pdf", "ps", "tex");
  • 5 для выполняемых файлов ("pm", "exe", "bat", "com");
  • 6 для картинок ("gif", "jpg", "jpeg", "bmp", "pcx", "png", "wmf", "psd");
  • 7 для видео ("mpg", "mpeg", "avi", "asf", "mov");
  • 8 для папок;
  • 9 для TTH поиска;
  • 10 для CD/DVD образов.

[Поисковый_параметр] - поисковый параметр определяет совпадения в имени файлов
Если тип поиска установлен в 9, то поисковый параметр должен представлять из себя TTH искомого файла.

Как и во всех сообщениях NMDC, в поисковом параметре следует избегать употребления следующих символов: "$", "|" и "&".
Все пробелы в поисковом параметре заменяются на знак '$'.

После отправки на хаб этого сообщения, хаб должен без изменений переслать это сообщение всем пользователям хаба. Каждый пользователь с одним или более совпадениями должен послать UDP пакет на [IP]:[Порт] в случае активного запроса или на хаб в случае пассивного запроса.

Смотрите описание команды $SR для детального разбора.

Примеры:

Код
$Search 10.10.10.10:412 T?T?500000?1?Gentoo$2005
$Search Hub:Вася T?T?500000?1?Gentoo$2005

$Search 10.10.10.10:3746 F?T?0?9?TTH:TO32WPD6AQE7VA7654HEAM5GKFQGIL7F2BEKFNA
$Search Hub:Пётр F?T?0?9?TTH:TO32WPD6AQE7VA7654HEAM5GKFQGIL7F2BEKFNA
Karumo, PPA
17.12.2008, 18:10 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$RevConnectToMe

Синтаксис:

Код
$RevConnectToMe [Ник1] [Ник2]|


Направление команды:

Клиент ---> Хаб
Хаб ---> Клиент

Описание:

Клиент посылает данную команду на хаб для того, чтобы попросить пользователя [Ник2] инициализировать соединение с помощью команды $ConnectToMe. Команда $RevConnectToMe отсылается когда клиент не может сам соединиться (находится в пассивном режиме соединения с хабом).

[Ник1] - ник клиента, который просить соединиться с ним (пассивный).
[Ник2] - ник клиента, с которым нужно соединиться (активный).

Примечание:

Данная команда не применима к пассивному пользователю (к клиенту в пассивном режиме). Соединение пассив-пассив невозможно!
17.12.2008, 17:47 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Quit

Синтаксис:

Код
$Quit [Ник]|


Направление команды:

Хаб ---> Клиент
возможен случай: Клиент ---> Хаб

Описание:

Данная команда может отсылаться только хабом для того, чтобы клиент удалил разъединившегося пользователя из своего списка пользователей. Если вы решили написать свой клиент, не посылайте на хаб команду $Quit.
Данная команда показывает, что [Ник] отключился от хаба.

Пример:

Код
$Quit Вася|


Известны случаи, когда данная команда использовалась на хабе. Данная команда отсылалась клиентом на хаб и ник являлся ником клиента - хаб закрывал соединение с клиентом. Реализован этот принцип в Verli хабе.
Saymon21
17.12.2008, 17:36 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$OpList

Синтаксис:

Код
$OpList [ОПератор1]$$[ОПератор2]$$[ОПератор3]$$ ... $$|


Направление команды:

Хаб ---> Клиент

Описание:

Данная команда используется хабом для отсылки клиентам списка ОПераторов (ники с ключиками). Этот список ограничен и разделён символами "$$".

В старых версиях протокола NMDC команда $OpList является подмножеством команды $NickList.

По протоколу NMDC v1 хаб также включает в команду $OpList всех зарегистрированных на хабе ботов. Современные хабы должны быть наделены способностью как показывать ботов среди ОПераторов, так и не показывать.

Если клиент найдёт в параметрах данной команды свой ник, то он должен включить у себя функции перенаправления и кика пользователей (добавить соответствующие контекстные менюшки).
Saymon21
17.12.2008, 17:19 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$OpForceMove

Синтаксис:

Код
$OpForceMove $Who: [Ник_жертвы]$Where: [Новый_адрес]$Msg: [Причина]|


Направление команды:

Клиент ---> Хаб

Описание:

ОПератор может отослать команду $OpForceMove для того, чтобы предложить клиенту переместиться на другой хаб.

[Ник_жертвы] - ник, которому предлагается перенаправиться.
[Новый_адрес] - это IP адрес или хост-имя (и опционально через двоеточие порт) другого хаба, на который происходит перенаправление.
[Причина] - причина перенаправления.

После получения этой команды хаб должен отослать жертве команду $ForceMove.
Сервер разъединяет клиента, однако клиент и сам закрывает соединение с хабом.

Комментарии:

После отправки ОПератором на хаб команды $OpForceMove, хаб отсылает жертве команды
Код
$ForceMove [Новый_адрес]|
$To:[Ник_жертвы] From: [Ник_отправителя] $<[Ник_отправителя]> You are being re-directed to [Новый_адрес] because: [Причина]
и прекращает отсылать клиенту-жертве какие-либо команды.
Если команда $OpForceMove послана на хаб пользователем, не являющемся ОПератором, хаб должен разъединить такого пользователя.
Invisible
17.12.2008, 16:35 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$NickList

Синтаксис:

Код
$NickList [Ник1]$$[Ник2]$$[Ник3]$$ ... $$|


Направление команды:

Хаб ---> Клиент

Описание:

Данная команда используется хабом для того, чтобы отправить ники пользователей, которые находятся на хабе в данный момент. Этот список ников оканчивается и разделён символами "$$". Команда используется в старых версиях протокола NMDC.

Смотрите также $OpList, $GetNickList
Invisible
17.12.2008, 16:24 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$MyPass

Синтаксис:

Код
$MyPass [Пароль]|


Направление команды:

Клиент ---> Хаб

Описание:

Данная команда посылается клиентом на хаб в ответ на команду $GetPass.
[Пароль] - это обычно не шифрованный текст пароля клиента.
Символ | недопустим в пароле.

Также см. команду $GetPass
Invisible, Saymon21
17.12.2008, 3:11 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$MyINFO

Синтаксис:

Код
$MyINFO $ALL [Ник] [Описание][Тэг]$ $[Соедиенние][Флаг]$[E-Mail]$[Шара]$|


Направление команды:

Клиент ---> Хаб
Хаб ---> Клиент

Описание:
Данная команда отправляется клиентом на хаб, и хабом всем клиентам и, содержит всю основную информацию о клиенте.

Описание параметров команды:

[Ник] - ник пользователя (без пробелов).

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

[Тэг] - автоматически добавляемый клиентом тэг. Общий вид любого тэга: <[Имя_клиента] V:[Версия_клиента],M:[Режим],H:[Хабы],S:[Слоты],[Ограничители]>
Вообще говоря параметры не обязательно должны быть в тэге именно в такой последовательности. Такая последовательность просто является общепринятой, и некоторые клиенты любую другую последовательность параметров могут воспринимать не правильно.

Несколько примеров различных видов тэгов:

DC++:
<++ V:x,M:x,H:x/y/z,S:x,O:x>

BCDC++:
<++ V:x,M:x,H:x/y/z,S:x,O:x,B:x>

CZDC++:
<++ V:x,M:x,H:x/y/z,S:x,O:x,L:x>

DC:Pro:
<DC:PRO V:x,M:x,H:x/y/z,S:x,O:x,F:x/y>

DC++k CDM:
<++ V:x,M:x,H:x/y/z,S:x,O:x>

DCDM++:
<++ V:x,M:x,H:x/y/z,S:x,O:x,B:x>

DCGUI:
<DCGUI V:x,M:x,H:x,S:x,L:x>

iDC++:
<++ V:x,M:x,H:x/y/z,S:x,O:x>

MS++V:
<++ V:x,M:x,H:x/y/z,S:x,O:x,B:x>

NMDC v2:
<DC V:x,M:x,H:x/y/z,S:x,O:x>

oDC:
<oDC V:x,M:x,H:x/y/z,S:x,O:x>

PhantomDC:
<++ V:x,M:x,H:x/y/z,S:x,O:x,B:x>

PeerWebDC++:
<PWDC++ V:x,M:x,H:x/y/z,S:x>

PeerWebDC++:
<PWSDC++ V:x,M:x,H:x/y/z,S:x>

rmDC++:
<RMDC++ V:y,M:x,H:x/y/z,S:x,O:x,B:x,D:x>

StrongDC++:
<StrgDC++ V:y,M:x,H:x/y/z,S:x,O:x,L:x>

zDC++
<++ V:x,M:x,H:x/y/z,S:x,O:x>

Z++
<Z++ V:x,M:x,H:x/y/z,S:x,L:x>

LDC++
<LDC++ V:x,M:x,H:x/y/z,S:x,L:x>

ApexDC++
<ApexDC++ V:x,M:x,H:x/y/z,S:x,L:x>

AvaDC++
<AvaDC V:x,M:x,H:x/y/z,S:x,L:x>

FlylinkDC++
<FlylinkDC++ V:x,M:x,H:x/y/z,S:x,L:x>

Greylink++
<gl++ V:x,M:x,H:x/y/z,S:x,L:x>

Pelink++
<pl++ V:x,M:x,H:x/y/z,S:x,L:x>

RSX++
<RSX++ V:x,M:x,H:x/y/z,S:x,L:x>

zK++
<zK++ V:x,M:x,H:x/y/z,S:x,L:x>

UKCable++
<UKC++ V:x,M:x,H:x/y/z,S:x,L:x>





[Имя_клиента] - имя, которое определяет тот или иной клиент.

[Версия_клиента] - версия, под которой выпущен клиент.

[Режим] - режим клиента. Может принимать значения: A, P или иное (5). A - активное соединение с хабом, P - пассивное соединение с хабом, 5 - соединение через прокси-сервер SOCKS5.

[Хабы] - хабы на которых находится клиент. Параметр может иметь следующий формат: U/R/O, где U - число хабов, на которых данный пользователь является незарегистрированным, R - число хабов, на которых данный пользователь является зарегистрированным, O - число хабов, на которых пользователь яляется ОПератором.

[Слоты] - число свободных или полное число слотов в клиенте.

[Ограничители] - данный параметр является не обязательным. Он может содержать в себе несколько параметров. Всё зависит от того или иного клиента. Обычно данный параметр показывает ограничение скорости. Конкретные значения данного параметра не привожу, для тех, кто хочет узнать его значения, я привёл примеры тэгов различных клиентов (см. чуть выше).

[Соединение] - тип соединения с хабом (указывается либо тип соединения, либо скорость соединения). Устанавливается непосредственно пользователем клиента.
Типы соединений в клиенте NMDC1: 28.8Kbps, 33.6Kbps, 56Kbps, Satellite, ISDN, DSL, Cable, LAN(T1), LAN(T3).
Типы соединений в клиенте NMDC2: Modem, ISDN, Wireless, DSL, Cable, Satellite, LAN(T1), LAN(T3).
Новые типы (Мбит/c): 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 1000

[Флаг] - статус пользоателя (ascii символ). Этот символ ещё называют магическим байтом. При отсутствии принимает значение кода 0.
Типы статусов (коды ascii символов для данного статуса):
  • normal (1, 16, 17, 32);
  • normal away (2, 3, 18, 19);
  • server (4, 5, 12, 13, 20, 21, 28, 29);
  • server away (6, 7, 14, 15, 22, 23, 30, 31);
  • fireball (8, 9, 24, 25);
  • fireball away (10, 11, 26, 27).

Статус server используется, когда клиент пробыл на хабе больше 2 часов, расшарил больше 2 ГБ и имеет отдачу свыше 200 МБ.
Статус fireball используется, когда с клиента скачивают со скоростью, превышающей 100 КБ/с.

[E-Mail] - email адрес пользователя. Может отсутствовать (пустая строка).

[Шара] - количество байт, которые расшарил пользователь. Этот параметр в любом случае должен приводится к числу.



Расшифровка буквенных обозначений тэга (на английском):
V: Client Version.
M: Mode.
H: The number of Hubs the client is connected to.
S: Number of Slots open.
O: Open an extra slot if speed is below.
B: Upload Bandwidth limit in kb/s.
L: Upload bandwidth Limit.
D: Download bandwidth limit in kb/s.
F: Fraction download / upload.



Возможные комбинации ограничителей:
  • L:x
  • O:x
  • O:x,B:x
  • O:x,B:x,D:x
  • O:x,L:x
  • O:x,F:x/y
Ограничители, ограничивающие скорость скачки:
  • L:x
  • B:x
  • F:x/y




В параметрах данной команды символы $ и | не допустимы!

Эта команда является частью рукопожатия между клиентом и хабом. Посылается клиентом на хаб после получения команды $Hello. Клиент также отсылает эту команду время от времени, а также когда какой-либо из параметров этой команды изменится. Любая, как правило изменённая, отсылка этой команды транслируется хабом всем клиентам с характеристикой NoHello.
Invisible, mariner, Saymon21, TiGRpp, Enyby
17.12.2008, 2:32 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$LogedIn

Синтаксис:

Код
$LogedIn [Ник]|


Направление команды:

Хаб ---> Клиент

Описание:

Данная команда отсылается хабом клиенту в ответ на успешную последовательность пройденных команд $GetPass / $MyPass. Эта команда отправляется исключительно ОПераторам. Команда как бы контролирует вход операторов.

Замечание:
Обратите внимание на название команды: $LogedIn, а не $LoggedIn, как казалось бы должно быть.
Invisible
17.12.2008, 2:20 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Lock

Синтаксис:

Код
$Lock [Код] Pk=[ПК]|


Направление команды:

Хаб ---> Клиент
Клиент ---> Клиент
Хаблист ---> Хаб
Хаб ---> Пингер

Описание:

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

[Код] - это какая-либо последовательность символов (может даже случайная), исключая пробел, $ и |, максимальная и минимальная длина которой неизвестна.
[ПК] - это идентификатор устройства.

Эта команда является частью рукопожатия между клиентом и хабом, между клиентом и клиентом и в регистрации хаб-листа. Из-за того, что используемый алгоритм легко декодируется (см. Lock2Key), практически каждый может создать свой клиент.

Клиент никогда не должен посылать команду $Lock на хаб. Клиенты должны отсылать команду $Lock, когда два клиента соединяются друг с другом.

Пример для DC++:

Код
$Lock EXTENDEDPROTOCOLABCABCABCABCABCABC Pk=DCPLUSPLUS0.242ABCABC|


Секции "ABCABC" являются наполнителями.

Ключевое слово EXTENDEDPROTOCOL в коде команды даёт право клиенту, кроме прочих команд рукопожатия отправить команду $Supports. Те есть это слово говорит о том, что хаб (клиент) поддерживает систему дополнительных расширений или характеристик.
Хаб(клиент) в ответ на команду $Supports также отправляет эту команду другой стороне уже со своим списком поддерживаемых расширений. Если какой-либо из участников не поддерживает дополнительные расширения, отправки команды $Supports не происходит.

Характеристики команды $Lock в протоколе NMDC:
  • длина кода от 46 до 115 символов;
  • длина Pk до 16 символов;
  • символы команды $Lock: случайные, с кодами от 37 до 122.
  • символы команд $Lock и $Key с кодами 0, 5, 36, 96, 124 и 126 должны быть заменены, соответственно, на /%DCN000%/, /%DCN005%/, /%DCN036%/, /%DCN096%/, /%DCN124%/ и /%DCN126%/

Экранируемые коды(символы):
0 (\0), 5(\5), 36($), 96(`), 124(|), 126(~)
Invisible, Enyby
17.12.2008, 1:58 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Kick

Синтаксис:

Код
$Kick [Ник_жертвы]|


Направление команды:

Клиент ---> Хаб

Описание:

Данная команда отсылается на хаб клиентом и заставляет хаб закрыть соединение с жертвой. Жертве отсылается оповещение, в отличии от команды $Close. Только ОПераторы могут отсылать команду $Kick. В простонароде данную команду называют КИК.

Замечание:
На самом дела на хаб клиентом отправляется строка, состоящая из 3 команд:
Код
$To: [Ник_жертвы] From: [Ник_оператора] $<[Ник_оператора]> You are being kicked because: [Причина_кика]|<[Ник_оператора]> is kicking [Ник_жертвы] because: [Причина_кика]|$Kick [Ник_жертвы]|

Однако, первые 2 команды, которые представляют из себя, соответственно, сообщение в личку жертве, и сообщение всем в чат, автоматически приписывает клиентом. А непосредственно за кик отвечает только последняя команда: $Kick [Ник_жертвы]|
Invisible, Saymon21
17.12.2008, 1:49 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Key

Синтаксис:

Код
$Key [Рассчитанный_ключ]|


Направление команды:

Клиент ---> Хаб
Хаб ---> Хаблист
Клиент ---> Клиент
Пингер ---> Хаб

Описание:

Команда $Key отсылается на хаб в ответ на команду $Lock, которая отсылается хабом перед входом на хаб. Когда соединяются клиент с клиентом, или хаб с клиентом, ключ рассчитывается по определённому алгоритму, исходные коды которого доступны и свободно распространяются на разных языках программирования (см. Lock2Key). Команда $Key также используется, когда хаб регистрируется в хаб-листе, однако, в этом случае ключ вычисляется по иному. Такой обмен ключами является своего рода гарантом того, что соединяемые устройства работают на одном протоколе.

Сторона, которой отсылается ключ, может и не проверять правильность этого ключа, однако, отсылающая сторона всегда обязана отсылать рассчитанный ключ.
Invisible, Enyby
17.12.2008, 1:33 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$HubTopic

Синтаксис:

Код
$HubTopic [Топик]|


Направление команды:

Хаб ---> Клиент

Описание:

Команда $HubTopic отсылает клиенту топик хаба, на подобии IRC.

[Топик] - это строка, содержащая топик.

Доступность команды в клиентах:

Данная команда поддерживается почти всеми современными клиентами.

Данная команда поддерживается следующими хабами: Verlihub, RusHub. Хаб PtokaX не поддерживает данную команду, однако команда может отправляться скриптом. На поддержку данной команды может указывать наличие дополнения HubTopic в команде $Supports, однако, это наличие не обязательно.
Invisible, Enyby
17.12.2008, 1:21 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$HubName

Синтаксис:

Код
$HubName [Имя_хаба]|


Направление команды:

Хаб ---> Клиент

Описание:

Данная команда является частью рукопожатия между клиентом и хабом. Команда отправляет клиенту имя хаба.

[Имя_хаба] - это имя, которое использует данный хаб. Имя хаба обычно состоит из самого имени и из топика.

Дополнения:
Эта команда может быть отправлена в любое время, например, когда хаб изменил имя. Данная команда используется только для описания хаба.

Клиент1 и Клиент2 на одном и том же хабе этой командой могут получить разные имена, это может получится только на NMDC хабах, поэтому это имя не может быть использовано для однозначного определения хаба.

В Имени хаба в DC++ вместо символов (&, |, $) ожидаются их HTML эквиваленты.
Invisible
17.12.2008, 0:59 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$HubIsFull

Синтаксис:

Код
$HubIsFull|


Направление команды:

Хаб ---> Клиент

Описание:
Команда, посылаемая клиенту хабом для того, чтобы сообщить, что хаб полный, то есть на хабе достигнут предел пользователей.

Связанная с данной команда: $ValidateNick
Invisible
17.12.2008, 0:53 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Hello

Синтаксис:

Код
$Hello [Ник]|


Направление команды:

Хаб ---> Клиент

Описание:

Данная команда является частью рукопожатия между клиентом и хабом. Посылается клиенту для того, чтобы указать ему ник, с которым хаб сопоставляет данный клиент. Хаб как бы даёт согласие на вход пользователя под данным ником. В ответ на эту команду, входящий на хаб клиент, должен отослать команду $Version

Данная команда является командой приветствия пользователя и отправляется хабом не только вошедшему на хаб клиенту, но и всем клиентам, находящимся в данный момент на хабе. Однако, если клиент при входе на хаб в команде $Supports указал характеристику NoHello, то такому клиенту, при входе какого-либо пользователя, хаб не будет отправлять команду $Hello.
Invisible, Saymon21
17.12.2008, 0:41 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$GetPass

Синтаксис:

Код
$GetPass|


Направление команды:

Хаб ---> Клиент

Описание:

Хаб посылает данную команду клиенту для запроса пароля зарегистрированного пользователя.
Команда посылается соединяющемуся с хабом пользователю только если его ник находится в регистрационном листе хаба (ник зарегистрирован на хабе).

Также см. команду $MyPass
Invisible, Saymon21
17.12.2008, 0:29 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$GetNickList

Синтаксис:

Код
$GetNickList|


Направление команды:

Клиент ---> Хаб

Описание:

Эта команда заставляет хаб послать клиенту 2 списка зарегистрированных(вошедших) ников.

Код
$NickList [Ник1]$$[Ник2]$$[Ник3]$$ ... $$|
$OpList [ОПератор1]$$[ОПератор2]$$[ОПератор3]$$ ... $$|


Тут надо отметить, что список $OpList является подмножеством списка $NickList. Если на хабе нет операторов и ботов, то хаб должен послать просто "$OpList $$|".

Однако, только старые версии протокола отправляют данные команды. Новые же версии несколько упрощены и отправляют только команду $OpList, а вместо команды $NickList используется команда $MyINFO.

Замечание:
Клиент не обязан запрашивать у хаба список пользователей, поэтому данная команда по своей сути не является обязательной.
Invisible, Saymon21, Enyby
16.12.2008, 23:32 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$ForceMove

Синтаксис:

Код
$ForceMove [Новый_адрес]


Команда сопровождается отсылкой в личку оповещения о перенаправлении:

Код
$To: [Ник_жертвы] From: [Ник_отправителя] $<[Ник_отправителя]> You are being redirected to [Новый_адрес]: [Причина]|


Команда сопровождается отсылкой в чат оповещения о перенаправлении:

Код
<[Ник_бота]> [Причина]|


Направление команды:

Хаб ---> Клиент

Описание:

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

[Ник_отправителя] - ник, который отправляет команду $OpForceMove.
[Ник_бота] - ник основного бота на хабе.
[Ник_жертвы] - ник, который должен быть перенаправлен на новый адрес.
[Новый_адрес] - это IP адрес или хост-имя (и опционально, через двоеточие, порт) другого хаба, на который происходит перенаправление.
[Причина] - причина перенаправления.

Комментарии:

Жертва может следовать перенаправлению или не следовать ему, это зависит от настроек клиента. По этой причине разъединение после отсылки клиенту этой команды - это общее, но не обязательное требование для хаба.

Примечание:

Обратите внимание, что если команды чата и лички следуют после команды перенаправления, то в случае автоматического следования перенаправлению пользователь не увидит сообщения о перенаправлении в чате и личке, однако, последовательность отсылаемых команд полностью на совести хаба, который может отослать сообщения как после команды перенаправления, так и до.
Invisible, Saymon21
16.12.2008, 20:21 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$ConnectToMe

Синтаксис:

Для клиентов DC++ и NMDC.

Код
$ConnectToMe [Ник_получателя] [IP_отправителя]:[Порт_отправителя]|


Пример:

Код
$ConnectToMe Вася 10.10.10.10:16437|


Для клиентов NMDC v2.205 и DC:PRO v0.2.3.97A:

Код
$ConnectToMe [Ник_отправителя] [Ник_получателя] [IP_отправителя]:[Порт_отправителя]|


Пример:

Код
$ConnectToMe Петя Вася 10.10.10.10:16437|


Направление команды:

Клиент ---> Хаб
Хаб ---> Клиент
Хаб ---> Хаб

Описание:

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

[Ник_отправителя] - ник клиента в активном режиме, который хочет соединиться с целевым клиентом [Ник_получателя]. Клиент отправителя, после отправки на хаб запроса на соединение, начинает слушать указанный в запросе TCP порт.

Замечание:

Обратите внимание, что в скриптовую функцию старой версии PtokaX данная команда передаётся без символа вертикальной черты '|' на конце.
Invisible, Saymon21, Enyby
16.12.2008, 19:50 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$Close

Синтаксис:

Код
$Close [Ник]|


Направление команды:

Клиент ---> Хаб

Описание:

Эта команда заставляет хаб закрыть соединение с клиентом, чей ник написан в аргументе этой команды. Только операторы могут (имеют право) отправлять эту команду хабу. Эта команда в простонародье называется ДРОП.

[Ник] - ник пользователя, который подлежит разъединению с хабом.

В отличии от команды $Kick, команда $Close разъединяет пользователя без уведомления о разъединении. (По крайней мере на хабах NMDC первой версии эта команда работает именно так).
Invisible
16.12.2008, 19:35 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$BotList

Синтаксис:

Код
$BotList [Бот1]$$[Бот2]$$[Бот3]$$ ... $$|


Направление команды:

Хаб ---> Клиент

Описание:

Данная команда используется хабом для передачи клиенту списка ботов. Этот список ограничен и разделён символами "$$". Клиенты BDCH, BlackDC и ZionPlusPlus поддерживают эту команду для того чтобы различать операторов и ботов. Однако данная команда не является распространённой и не поддерживается большинством хабов.

На поддержку данной команды указывает наличие характеристики BotList в команде $Supports.
Invisible, Saymon21
16.12.2008, 19:19 Описание Протокола NMDC
NeoModus Direct Connect Protocol
$BadPass

Синтаксис:

Код
$BadPass|


Направление команды:

Хаб ---> Клиент

Описание:

Эту команду отсылает хаб клиенту, который коннектится. Команда посылается, если клиент отослал хабу неправильный(некорректный) пароль в ответ на посланную хабом команду $GetPass. После отсылки этой команды хаб закрывает соединение с этим клиентом, или даже банит его.
Invisible
16.12.2008, 18:57 Описание Протокола NMDC
NeoModus Direct Connect Protocol
Protocol NMDC

Структурированное описание протокола NeoModus Direct Connect (NMDC), под управлением которого на сегодняшний день работает подавляющее большинство хабов. Хотя уже внедряется новый протокол ADC, однако, как говориться, всему своё время.

По мере написания, на каждую команду будет появляться ссылка на пост, описывающий эту команду.
Делаю тему закрытой, дабы структурировано описать команды.


О структуре команд

Все команды протокола начинаются с символа $. Исключение составляет команда сообщения чата, которая должна иметь следующую структуру:
Код
<Ник> Сообщение|
При этом, данный синтаксис команды чата обязателен в направлении клиент -> хаб, в то время, как хаб может отсылать клиенту любые сообщения, не начинающиеся с символа $, и клиент должен принимать такие сообщения, однако обработка таких сообщение не регламентирована протоколом (клиент может отображать такие сообщения как в чате, так и в статусной строке, или же вовсе игнорировать такие сообщения).

Символы-разделители протокола: $, | и пробел. Протокол не имеет экранирующих символов, поэтому для отсылки символов $ и | в параметрах команд нужно использовать их коды: &#36; и &#124;
Строка сообщения разделяется на команды по средствам символа |. Пример трёх команд, отосланных одной строкой:
Код
$Cmd1 параметр|$Cmd2|$Cmd3 параметр1 параметр2$параметр3|



Взаимодействие хаб-клиент


$BadPass
$Close
$ConnectToMe
$ForceMove
$GetINFO
$GetNickList
$GetPass
$Hello
$HubIsFull
$HubName
$HubTopic
$Key
$Kick
$Lock
$LogedIn
$MyINFO
$MyPass
$MultiConnectToMe
$MultiSearch
$NickList
$OpForceMove
$OpList
$Quit
$RevConnectToMe
$Search
$SR
$Supports
$UserCommand
$UserIP
$Version
$ValidateNick
$ValidateDenide


Взаимодействие клиент-клиент

$Cancel
$Canceled
$Direction
$Error
$Failed
$FileLength
$Get
$GetListLen
$Key
$Lock
$MaxedOut
$MyNick
$Ping
$Send
$To


Взаимодействие хаб-хаб

$FeaturedNetworks
$ConnectToMe
$Search
$SR
$Up
$UpToo




Взаимодействие хаб-хаблист

$Key
$Lock
$Supports


Взаимодействие пингер-хаб

$BotINFO
$HubINFO
$Key
$Lock
$Supports


Команды характеристик

$ADCGET / $ADCSND
$BotList
$Capabilities
$FeaturedNetworks
$GetZBlock
$MCTo
$Sending
$UGetBlock
$UGetZBlock
$Z
$ZOn


Разное

TTH
Lock2Key


Известные характеристики

Хаб-Клиент:
BotList
ClientID
Feed
HubTopic
IN
MCTo
NoGetINFO
NoHello
OpPlus
QuickList
TTHSearch
UserCommand
UserIP2
ZLine
ZPipe0

Клиент-Клиент:
ADCGet
BZList
CHUNK
ClientID
GetCID
GetTestZBlock
GetZBlock
MiniSlots
TTHL
TTHF
XmlBZList
ZLIG



Общая (обязательная) последовательность входа на хаб.
"Рукопожатие" между клиентом и хабом.

Общая (обязательная) последовательность входа на хаб
Хаб:
Код
$Lock [Код] Pk=[PrimaryKey]|

Клиент:
Код
$Key [Рассчитанный_ключ]|$ValidateNick [Ник]|

Хаб:
Код
$HubName [Имя_хаба]|$Hello [Ник]|

Клиент:
Код
$Version [Версия]|$GetNickList|$MyINFO [Строка]|

Хаб:
Код
Отсылает список пользователей.


Примечания:
  1. Команда $HubName может "выпадать" из этой последовательности и отсылаться, например, после команды $Lock, или вовсе отсутствовать.
  2. Если в начале параметра команды $Lock присутствует слово EXTENDEDPROTOCOL, то клиент должен отослать на хаб команду с поддерживаемыми им характеристиками $Supports. В ответ хаб должен отослать такую же команду со своими характеристиками. Однако, данный механизм обмена характеристиками фактически является не обязательным.
  3. Также, вне зависимости от данной последовательности, в любом месте входа хаб может отослать клиенту команду чата: "<[Бот_хаба]> Этот хаб работает под управлением...".
  4. При входе, клиент отошлёт команды $Version, $GetNickList и $MyINFO только после того, как получит от хаба команду $Hello [Ник], причём со своим ником, который он отсылал на хаб в команде $ValidateNick. Причем команда $GetNickList может и вовсе не отсылаться клиентом.
  5. Команду $Version клиент может отослать и раньше указанного шага (например, непосредственно после $ValidateNick), однако она должна быть отослана до команды $MyINFO.
  6. При отсылке хабом списка пользователей, хаб руководствуется поддержкой со стороны клиента той или иной характеристики. Подробности см. в описании характеристик NoHello и NoGetINFO.


Вход на пальцах выглядит так: Клиент коннектится, сервер отвечает командой $Lock, что мол я такой-то сервер, на что клиент отвечает: ок раз ты такой-то сервер - вот тебе ключ ($Key) и проверь мой ник ($ValidateNick), сервер проверяет ник и отправляет клиенту приглашение на вход под этим ником ($Hello), на что клиент отправляет на сервер внутреннюю версию ($Version), запрашивает список пользователей ($GetNickList) и отправляет информацию о себе ($MyINFO), а сервер отсылает ему список пользователей хаба.



Последовательность входа на хаб, который поддерживает характеристику QuickList.
Входа на хаб при поддержке характеристики QuickList (быстрый вход)
Хаб:
Код
$Lock EXTENDEDPROTOCOL[Код] Pk=[PrimaryKey]|

Клиент:
Код
$Supports QuickList|$Key [Рассчитанный_ключ]|

Хаб:
Код
$Supports QuickList|

Клиент:
Код
$MyINFO [Строка]|$GetNickList|

Хаб:
Код
Отсылает список пользователей.


См. подробности в характеристике QuickList



Последовательность действий хаба при регистрации в хаб-листе
Последовательность действий хаба при регистрации в хаб-листе
Хаб коннектится к хаб-листу.

Хаб-лист:
Код
$Lock [Код] Pk=[PrimaryKey]|

Хаб:
Код
$Key [Рассчитанный_ключ]|[Имя_хаба]|[Хост_хаба(:порт)]|[Описание_хаба]|[Число_юзеров]|[Текущая_шара]|


Тут хаб выступает в роли клиента. Он коннектится к прописанным в настройках хаб-листам и передаёт им текущую информацию о себе.
Коннект к хаб листу должен производится не чаще чем раз в 15 минут, в противном случае, хаб может быть забанен хаб-листом)).



Последовательность входа на хаб PtokaX
(последовательные команды могут отсылаться одной строкой, разделённой символом | )
Последовательность входа на хаб PtokaX
Хаб -> Клиент: ---> $Lock EXTENDEDPROTOCOL[некий_ключ_хаба] Pk=PtokaX
Клиент -> Хаб: ---> $Supports UserCommand NoGetINFO NoHello UserIP2 TTHSearch ZPipe0 |$Key [ключ_сгенерированный_по_полученному_ключу_хаба]|$ValidateNick [Мой_ник]|
Выполнение скриптовой функции SupportsArrival
Выполнение скриптовой функции KeyArrival (выполнение не происходит, если проверка ключа отключена)
Выполнение скриптовой функции ValidateNickArrival
Хаб -> Клиент: ---> $Supports NoHello|$GetPass|
Клиент -> Хаб: ---> $MyPass [Мой_пароль]|
Выполнение скриптовой функции PasswordArrival
Хаб -> Клиент: ---> $Hello [Мой_ник]|
Клиент -> Хаб: ---> $Version 1,0091|$GetNickList|$MyINFO $ALL [Мой_ник] [Описание]<[Клиент] V:[Версия],M:[Режим],H:[Хабы],S:[Слоты]>$[EMail]$[Соедиение][Магический_байт]$ $[Шара]$|
Выполнение скриптовой функции VersionArrival
Выполнение скриптовой функции GetNickListArrival
Выполнение скриптовой функции MyINFOArrival
Хаб -> Клиент: ---> $LogedIn [Мой_ник]|$HubName [Имя_хаба] - [Топик]|<[Бот_хаба]> Этот хаб работает под управлением PtokaX DC Hub ...
Хаб -> Клиент: ---> $ZOn
Хаб -> Клиент: ---> $MyINFO $ALL [Бот_хаба] [Описание]$ $ $[EMail]$0$|$MyINFO $ALL [Ник1] [Описание]<[Клиент] V:[Версия],M:[Режим],H:[Хабы],S:[Слоты]>$[EMail]$[Соедиение][Магический_байт]$ $[Шара]$|$MyINFO $ALL [Ник2] [Описание]<[Клиент] V:[Версия],M:[Режим],H:[Хабы],S:[Слоты]>$[EMail]$[Соедиение][Магический_байт]$ $[Шара]$|
...
$MyINFO $ALL [Мой_ник] [Описание]<[Клиент] V:[Версия],M:[Режим],H:[Хабы],S:[Слоты]>$[EMail]$[Соедиение][Магический_байт]$ $[Шара]$|$OpList [Оператор1]$$[Оператор2]$$[Оператор3]$$ ... $$[ОператорN]$$|$UserIP [Ник1] [IP1]$$[Ник2] [IP2]$$ ... $$[НикN] [IPN]$$|
Выполнение скриптовых функций UserConnected, RegConnected и OpConnected


Примечание: Команда $LogedIn отсылается только в случае если у вас есть ключ (операторские права).

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



Последовательность команд при получении списка пользователей (GetNickList) на хабе PtokaX
Последовательность команд при получении списка пользователей (GetNickList) на хабе PtokaX
Клиент -> Хаб: ---> $GetNickList|
Выполнение скриптовой функции GetNickListArrival
Хаб -> Клиент: ---> $MyINFO $ALL [Бот_хаба] [Описание]$ $ $[EMail]$0$
Хаб -> Клиент: ---> $MyINFO $ALL [Ник1] [Описание]<[Клиент] V:[Версия],M:[Режим],H:[Хабы],S:[Слоты]>$[EMail]$[Соедиение][Магический_байт]$ $[Шара]$|
Хаб -> Клиент: ---> $MyINFO $ALL [Ник2] [Описание]<[Клиент] V:[Версия],M:[Режим],H:[Хабы],S:[Слоты]>$[EMail]$[Соедиение][Магический_байт]$ $[Шара]$|
...
Хаб -> Клиент: ---> $MyINFO $ALL [Мой_ник] [Описание]<[Клиент] V:[Версия],M:[Режим],H:[Хабы],S:[Слоты]>$[EMail]$[Соедиение][Магический_байт]$ $[Шара]$|
Хаб -> Клиент: ---> $OpList [Оператор1]$$[Оператор2]$$[Оператор3]$$ ... $$[ОператорN]$$



Последовательность входа на хаб HeX
(последовательные команды могут отсылаться одной строкой, разделённой символом | )
Последовательность входа на хаб HeX
Хаб -> Клиент: ---> $Lock EXTENDEDPROTOCOL[некий_ключ_хаба] Pk=versiunea5.03
Клиент -> Хаб: ---> $Supports UserCommand NoGetINFO NoHello UserIP2 TTHSearch ZPipe0 |$Key [ключ_сгенерированный_по_полученному_ключу_хаба]|$ValidateNick [Мой_ник]|
Хаб -> Клиент: ---> $HubName [Имя_хаба] - [Топик]|$HubTopic [Топик]|<[Бот_хаба]> HeXHub 5.03a Firewall 1.09 Hex Script 1.1.0.2 ...|
Обработка команды $Supports скриптовой функцией OnCommand
Хаб -> Клиент: ---> $Supports UserCommand NoGetINFO NoHello|
Обработка команды $Key скриптовой функцией OnCommand
Обработка команды $ValidateNick скриптовой функцией OnCommand

Хаб -> Клиент: ---> *** Your nickname is already taken by someone else|*** Current nickname: [Мой_ник]_1|*** This nick is also taken...|*** Current nickname: [Мой_ник]_2|<[Бот_хаба]> Your nickname is registered, please enter a password|$GetPass|
Клиент -> Хаб: ---> $MyPass [Мой_пароль]|
Обработка команды $MyPass скриптовой функцией OnCommand
Хаб -> Клиент: ---> $LogedIn [Мой_ник]|$Hello [Мой_ник]|
Клиент -> Хаб: ---> $Version 1,0091|$GetNickList|$MyINFO $ALL [Мой_ник] [Описание]<[Клиент] V:[Версия],M:[Режим],H:[Хабы],S:[Слоты]>$[EMail]$[Соедиение][Магический_байт]$ $[Шара]$|
Хаб -> Клиент: ---> $Hello [Мой_ник]|
Обработка команды $Version скриптовой функцией OnCommand
Обработка команды $GetNickList скриптовой функцией OnCommand
Обработка команды $MyINFO скриптовой функцией OnCommand
Хаб -> Клиент: ---> $MyINFO $ALL [Бот_хаба] [Описание]$ $ $[EMail]$0$|$MyINFO $ALL [Ник1] [Описание]<[Клиент] V:[Версия],M:[Режим],H:[Хабы],S:[Слоты]>$[EMail]$[Соедиение][Магический_байт]$ $[Шара]$|$MyINFO $ALL [Ник2] [Описание]<[Клиент] V:[Версия],M:[Режим],H:[Хабы],S:[Слоты]>$[EMail]$[Соедиение][Магический_байт]$ $[Шара]$|
...
$MyINFO $ALL [Мой_ник]_2 [Описание]<[Клиент] V:[Версия],M:[Режим],H:[Хабы],S:[Слоты]>$[EMail]$[Соедиение][Магический_байт]$ $[Шара]$|$OpList [Оператор1]$$[Оператор2]$$[Оператор3]$$ ... $$[ОператорN]$$|$UserIP [Ник1] [IP1]$$[Ник2] [IP2]$$ ... $$[НикN] [IPN]$$|
Выполнение скриптовой функции OnUserJoined

Примечание: Данный хаб различает вход и переподключение к хабу! Это достигается с помощью задержки в отправлении команды $Quit.


Материал из этой темы перенесён в вики: http://wiki.mydc.ru/Описание_протокола_NMDC
Nickolya, Invisible, Serx, Maximum, alex82, VNoName, Kingston, Sekretchik, Saymon21, Werwolf, dc4u, Enyby, Markiz, RAND(i)M, Meloun
13.12.2008, 15:01 Объектно-Ориентированное Программирование в Lua
Создание и использование классов
Объектно-Ориентированное Программирование (ООП) в LUA

В данной теме обсуждаются мощнейшие методы ООП big_smile.gif


Итак, потихоньку буду писать основные понятия.

Объект и класс

Прежде всего следует понять что такое объект, и что такое класс

Согласно языку С++, класс - это определяемый пользователем тип, а объект - это экземпляр класса.
Попробуем в lua определить понятие класса.

Каждому классу могут соответствовать несколько объектов. Каждый объект занимает своё место в памяти и манипулирует со своими переменными и функциями. Приведу пример класса и объектов:
Возьмём класс - автомобиль. У этого класса есть некие свои "переменные" и "функции", такие как цвет (функция определения цвета), тип (хэтчбек, универсал, седан) и тд.
Объектом данного класса, например, будет красный седан
Другим объектом будет синий универсал
Третьим объектом будет также синий универсал

Второй и третий объекты не отличаются ничем, однако, они разные объекты, физически разные машины, хоть и выглядят одинаково (они занимают разные адреса в памяти).

Итак, класс - это некая общность объектов.


Конструктор

Функция, которая предназначается для инициализации (создания) объектов называется конструктором. Ввиду того, что такая функция создаёт (конструирует) объект. В С++ имя конструктора совпадает с именем класса, и вызывается при выделении памяти под объект.
В lua бы будем использовать для конструктора имя: __init, а вызываться конструктор будет при создании объекта.

Пример:

Код
class.MyClass {
  __init = function(a, b, c) -- конструктор с параметрами a, б и c
    ... -- описание конструктора
  end
}

MyObject = MyClass(1, 2, 3) -- создание объекта (вызов конструктора)


То есть при создании объекта обязательно сначала вызывается конструктор. В приведённом примере при создании объекта по средствам конструктора в объект передаются некоторые значения: 1, 2, 3. Если конструктор не содержит передаваемых параметров, то такой конструктор называется конструктором по умолчанию.


Деструктор

Деструктор вызывается каждый раз при уничтожении объекта. Это полная противоположность конструктору.


Закрытые переменные (private переменные)

Закрытые переменные - это переменные, которые могут использоваться только членами-классами.
В lua закрытые переменные у нас будут содержать 2 подчёркивания спереди.


Защищённые переменные (protected переменные)

Защищённые переменные - это переменные, которые могут наследоваться
В lua защищённые переменные у нас будут содержать 1 подчёркивание спереди.



продолжение следует...
Saymon21
12.12.2008, 20:12 Luasocket
win32 | Работа с сокетами
вообще говоря вот код из исходников:
Код
#define LUA_PATH_DEFAULT  \
        "!\\?.lua;"  "!\\libs\\?.lua;"  "!\\scripts\\libs\\?.lua"
Отсюда можно видеть, что библиотеки можно класть в папку с PtokaX, либо в libs, либо в scripts/libs
FallenAngel, Invisible, Tarantul13, dj_crazy_joker
3.12.2008, 19:05 Жалоба Юзера
Жалоба Опираторам и админам
[attachment=1106:Report.lua]
Pro009, AfLc
3.12.2008, 17:38 Жалоба Юзера
Жалоба Опираторам и админам
исправил и перезалил))
AfLc
30.11.2008, 12:20 Жалоба Юзера
Жалоба Опираторам и админам
скрипт был написан под апи1 !!!

Под апи2 прикрепляю: [attachment=1107:Report.lua]
Pro009, AfLc
29.11.2008, 1:33 Метод Быстрого Перевода Скриптов Под API_1
Самостоятельный быстрый перевод из API_2 ---> в API_1
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
Invisible
27.11.2008, 19:15 Ваши Вопросы И Предложения По Поводу Форума
Давно уже все просят сделать "спасибы". И флуда меньше будет, а то очень часто наблюдаю посты со словами спасибо.
мамин_парень
24.11.2008, 22:53 Вопрос По Лицензии
самая важная фраза: пользователи всех производных программ получат вышеперечисленные права
Mustik
22.11.2008, 20:40 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Если имя клиента является неизвестным, то тег клиента приклеивается к описанию!!!

Функция коррекции данных пользователя:
Код
function GetNormalValue(tUser)
  if not tUser.sTag then
    local _,_,sDescription,sTag,sClient,sClientVersion,sMode,iNormalHubs,iRegHubs,iOpHubs,iSlots,iLlimit=tUser
.sDescription:find("(.*)(<(.+)%sV:(.-),M:(.-),H:(%d+)/(%d+)/(%d+),S:(%d+)>)$")
    if not sDescription then
    _,_,sDescription,sTag,sClient,sClientVersion,sMode,iNormalHubs,iRegHubs,iOpHubs,iSlots,iLlimit=
tUser.sDescription:find("(.*)(<(.+)%sV:(.-),M:(.-),H:(%d+)/(%d+)/(%d+),S:(%d+),L:(%d+)>)$")
    end
    if not sDescription then
    _,_,sDescription,sTag,sClient,sClientVersion,sMode,iNormalHubs,iRegHubs,iOpHubs,iSlots,iLlimit=
tUser.sDescription:find("(.*)(<(.+)%sV:(.-),M:(.-),H:(%d+)/(%d+)/(%d+),S:(%d+),B:(%d+)>)$")
    end
    tUser.sDescription=sDescription
    tUser.sTag=sTag
    tUser.sClient=sClient
    tUser.sClientVersion=sClientVersion
    tUser.sMode=sMode
    tUser.iNormalHubs=iNormalHubs
    tUser.iRegHubs=iRegHubs
    tUser.iOpHubs=iOpHubs
    tUser.iHubs=iNormalHubs+iRegHubs+iOpHubs
    tUser.iSlots=iSlots
    tUser.iLlimit=iLlimit
  end
  return tUser
end


Использование коррекции:
Код
function MyINFOArrival(tUser)
  tUser=GetNormalValue(tUser)
  tUser:SendData("sName = "..tostring(tUser.sName).."\n"..
  "sClient = "..tostring(tUser.sClient).."\n"..
  "sClientVersion = "..tostring(tUser.sClientVersion).."\n"..
  "sMode = "..tostring(tUser.sMode).."\n"..
  "sMyInfoString = "..tostring(tUser.sMyInfoString:sub(1,-2)).."\n"..
  "iShareSize = "..tostring(tUser.iShareSize).."\n"..
  "iHubs = "..tostring(tUser.iHubs).."\n"..
  "iSlots = "..tostring(tUser.iSlots).."\n"..
  "sTag = "..tostring(tUser.sTag).."\n"..
  "sDescription = "..tostring(tUser.sDescription).."\n"..
  "sConnection = "..tostring(tUser.sConnection).."\n"..
  "sEmail = "..tostring(tUser.sEmail).."\n"..
  "iNormalHubs = "..tostring(tUser.iNormalHubs).."\n"..
  "iRegHubs = "..tostring(tUser.iRegHubs).."\n"..
  "iOpHubs = "..tostring(tUser.iOpHubs))
end
Saymon21
20.11.2008, 20:50 Компиляция Клиентов Dc++
создание собственных модов
Компиляция Клиентов Dc++
Думаю, что многие видели различные версии клиентов DC++.
Однако, все эти клиенты возникли от одного праотца DC++.

Для компиляции своего клиента необходимо следующее:
1). Среда разработки Microsoft Visual Studio 2008.
2). Библиотека WTL [attachment=927:WTL80_sf.7z]3). Исходники клиента DC++ [attachment=926:DCPlusPl..._src_vs9.7z]

1). Microsoft Visual Studio 2008 качаем откуда-нибудь или покупаем feel_good.gif
2). Библиотеку WTL (Windows Template Library) распаковываем в любую папку, и после этого из этой папки копируем содержимое папки include в папку Microsoft Visual Studio/VC/include.
3). В исходниках уже создан проект, поэтому просто открываем файл DCPlusPlus.sln. После открытия компилируем проект, построенный проект после компиляции появится в папке app.

Вот и всё! Строим проект, модифицируем файлы и создаём свои моды клиента exciting.gif
Saymon21, X-Sky, ™Wizard™, мамин_парень
15.11.2008, 19:02 Onenick-oneip
API1, API2 | Запрет входа с одного ip под несколькими никами
Название скрипта: OneNick-OneIP
Версия API: API1, API2 (универсальный)
Версия скрипта: 1.1
Автор: Setuper
Описание: Скрипт, запрещающий заходить с одного IP под несколькими никами.
Invisible, Sekretchik
14.11.2008, 12:35 Скрипт Наград
А конвертер юзать не пробовали? Я думаю, что нормально должно сконвертироваться.
Marc
10.11.2008, 23:20 Скрипты И Совметимость Операционных Систем
Рабочие файлы скриптов в Unix системах
Проблема совместимости некоторых скриптов заключается в путях к файлам и директориям.

Windows вообще говоря использует в путях как прямые (/), так и обратные слеши (\).
Unix'ы в путях используют только прямые слеши (/).

Отсюда возникает проблема совместимости скриптов на Windows и Unix системах.


Предлагаю эту проблему совместимости решать следующим образом:

В путях писать только прямые слеши:
Например, для API 2:
Код
dofile(Core.GetPtokaXPath().."scripts/file.lua")
Для API 1:
Код
dofile(frmHub:GetPtokaXLocation().."scripts/file.lua")

(функции Core.GetPtokaXPath() и frmHub:GetPtokaXLocation() возвращают пути с прямыми слешами)

При использовании той, или иной консольной команды (mkdir, rmdir и тд.) путь в параметре этой команды нужно заключать в двойные кавычки, тогда путь может содержать только прямые слешы, что как раз будет соответствовать предложенному принципу совместимости.

Предлагаю разработчикам учесть этот факт и писать универсальные скрипты, совместимые с обеими системами windows и unix!!!


Самый универсальный, кроссплатформенный и кроссхабный метод определения абсолютных путей:
Код
sMainPath, sMainSlash = debug.getinfo(1).source:match"^@?(.+([/\\])).-$"
Saymon21, -=ДЕМОН=-, che_guevara
10.11.2008, 20:24 Чат Комнаты
API2 | Возможно создать несколько чат комнат
Не понимаю, что не понятного? Всё очень подробно разобрано. Объясняю всё конкретно для этого скрипта:

1). Копируем в папку scripts файл old_api.lu

2). Открываем скрипт chatrooms.lua и в самом начале скрипта (можно перед комментарием, можно после) дописываем строчку:
Код
dofile(frmHub:GetPtokaXLocation().."scripts/old_api.lu")

3). Вместо OnStartup() пишем Core.OnStartup()
Вместо UserConnected(tUser) пишем Core.UserConnected(tUser)
Вместо RegConnected=UserConnected пишем Core.RegConnected=Core.UserConnected
Вместо OpConnected=UserConnected пишем Core.OpConnected=Core.UserConnected
Вместо ChatArrival(tUser,sData) пишем Core.ChatArrival(tUser,sData)
Вместо ToArrival(tUser,sData) пишем Core.ToArrival(tUser,sData)

Всё! Скрипт переведён! Не понимаю чего тут трудного?
Всё по инструкции big_smile.gif
Invisible
8.11.2008, 21:52 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
я бы немного упростил и оптимизировал)))
Код
function GetNormalTime(s)
    s=tonumber(s) or 0
    local r=""
    if s>=31104000 then r=math.floor(s/31104000).." г. " s=math.fmod(s,31104000) end
    if s>=2592000 then r=r..math.floor(s/2592000).." мес. " s=math.fmod(s,2592000) end
    if s>=86400 then r=r..math.floor(s/86400).." д. " s=math.fmod(s,86400) end
    if s>=3600 then r=r..math.floor(s/3600).." ч. " s=math.fmod(s,3600) end
    if s>=60 then r=r..math.floor(s/60).." мин. " s=math.fmod(s,60) end
    return r..s.." сек."
end


или ещё более оптимизированный вариант (используя стандартные средства lua):
Код
function GetNormalTime(s)
    s=tonumber(s) or 0
    local r,t="",os.date("!*t",s)
    t.year,t.month,t.day=t.year-1970,t.month-1,t.day-1
    if t.year~=0 then r=t.year.." г. " end
    if t.month~=0 then r=r..t.month.." мес. " end
    if t.day~=0 then r=r..t.day.." д. " end
    if t.hour~=0 then r=r..t.hour.." ч. " end
    if t.min~=0 then r=r..t.min.." мин. " end
    if t.sec~=0 then r=r..t.sec.." сек. " end
    return r
end
Saymon21
8.11.2008, 17:40 Антибан Опов
API2
мамин_парень
8.11.2008, 16:07 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Переименовал тему в Вопросы разработчикам скриптов. Так название лучше отражает суть темы
8.11.2008, 13:36 Метод Быстрого Перевода Скриптов Под API_1
Самостоятельный быстрый перевод из API_2 ---> в API_1
Перезалил файл old_api.rar

Исправлена невозможность использовать функцию Core.GetPtokaXPath() при инициализации скрипта.
Invisible
28.10.2008, 13:44 Trans
API1, API2
Лучше бы сделал командой. Например, пользователь отправил в чат какую то фразу не в той раскладке, скрипт её сохранил и пользователю достаточно отправить какую-нибудь команду, например для крактоски, !r и скрипт отправит это сообщение повторно, но уже транслированное в нормальную раскладку.
MIKHAIL
28.10.2008, 13:02 Метод Быстрого Перевода Скриптов Под API_1
Самостоятельный быстрый перевод из API_2 ---> в API_1
Список функций, которые работают только на 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) --Возвращает имя страны для указанного пользователя.


По своей сути почти все эти функции связаны с управлением хабом, поэтому можно сказать, что почти нигде эти функции не используются!!!
Invisible, Saymon21
22.10.2008, 21:34 Open Dc Hub
Unix/Linux
Проект закрыт, а программа то существует. Может кого заинтересует, разные люди бывают))))
мамин_парень
17.10.2008, 12:38 Чат Комнаты
API2 | Возможно создать несколько чат комнат
Название: Чат комнаты
Версия: 1.0
Версия API: 2
Код: открытый
Автор: Setuper
Описание: возможно создать несколько чат комнат. Чат комнаты могут быть "закрытыми", то есть для получения сообщений нужно войти, а могут быть открытыми, то есть сообщения отсылаются всем доступным профилям (как в ОпЧате, вы не входите постоянно в ОпЧат, если вы Оператор, то он вам доступен). При запуске скрипта создаётся файл ChatRoom.dbs, в котором по умолчанию создаются 3 комнаты: комната для операторов, комната для випов и общая закрытая комната. В файле ChatRoom.dbs множество настроек. Опишу их на общей комнате:
Код
["-MembersRoom-"] = { -- название комнаты
    ["sMsgExit"] = "*** Вы покинули комнату.",  -- сообщение, отправляемое пользователю после выхода из комнаты
    ["tAllow"] = { -- профили, которым доступна комната
        [0] = 1,
        [2] = 1,
        [3] = 1,
        [1] = 1,
        [-1] = 0,
    },
    ["sDescription"] = "[БОТ] Чат комната для пользователей", -- описание бота
    ["sAway"] = false, -- режим бота: true - away, false - не away
    ["sEmail"] = "setuper@gmail.com", -- email бота
    ["sClientName"] = "DCBOT", -- название клиента бота
    ["bKey"] = true, -- имеет ли ключик бот: true - имеет, false - не имеет
    ["sTagOption"] = "M:A,H:0/0/1,S:0", -- тэг бота (не трогать, если не знаешь что это)
    ["sMsgEnter"] = "*** Добро пожаловать в чат комнату!", -- сообщение пользователю при входе в чат комнату
    ["bMembers"] = true, -- надо ли входить(выходить) в чат комнату: true - надо, false - не надо
    ["iShareSize"] = 0, -- шара бота чат комнаты
    ["tMembers"] = { -- таблица членов чат комнаты (не изменять)
    },
    ["tVisible"] = { -- профили, которым видна чат комната в списке пользователей
        [0] = 1,
        [2] = 1,
        [3] = 1,
        [1] = 1,
        [-1] = 1,
    },
    ["bReturn"] = true, -- возвращаемое значение чат комнатой
},
добавлю, что если скрипт чат комнаты в списке скриптов стоит до скрипта антирекламы и параметр bReturn=true, то сообщения чат комнаты не будут отслеживаться антирекламой, в противном случае будут.
После первого запуска скрипта в файле настроек по умолчанию создаётся 3 комнаты. Вы можете менять количество комнат по смоему усмотрению.

Конечно возможности программирования на lua не ограничены. Данный код я вырвал из SBot'a и немного преобразовал, но большая часть возможностей чат комнат осталась в SBot'е (чат комната непосредственно в чате, а не в личке, чёрные и белые списки для любого пользователя, установка паролей на чат комнаты, антифлуд, антимат, антикапс, антиреклама в чат комнатах и тд. и тп.). Нету времени.

Для самостоятельного перевода скрипта под версию API 1 следует воспользоваться инструкцией: ИНСТРУКЦИЯ

Юзаем! big_smile.gif
Nickolya, Invisible, strateg, TiGRpp, dimajak, zeusby
16.10.2008, 16:40 Метод Быстрого Перевода Скриптов Под API_1
Самостоятельный быстрый перевод из API_2 ---> в API_1
Метод быстрого перевода скриптов под API_1 (PtokaX 0.3.6.0 и ниже).

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



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

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

1). Помещаем в папку scripts файл из архива: [attachment=3987:old_api.rar]

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. :
  • BotINFOArrival
  • ChatArrival
  • CloseArrival
  • ConnectToMeArrival
  • GetINFOArrival
  • GetNickListArrival
  • KeyArrival
  • KickArrival
  • MultiConnectToMeArrival
  • MultiSearchArrival
  • MyINFOArrival
  • OnExit
  • OnError
  • OnStartup
  • OnTimer
  • OpConnected
  • OpDisconnected
  • OpForceMoveArrival
  • PasswordArrival
  • RegConnected
  • RegDisconnected
  • RevConnectToMeArrival
  • SearchArrival
  • SRArrival
  • SupportsArrival
  • ToArrival
  • UDPSRArrival
  • UnknownArrival
  • UserConnected
  • UserDisconnected
  • ValidateNickArrival
  • VersionArrival



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


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

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

Таким образом можно за пару минут самому перевести скрипт на API_1, даже больших размеров (что в некоторых случаях заняло бы для перевода несколько дней). А когда вы всё же будете готовы перейти на новые версии PtokaX, обратные изменения также не займут много времени!
Nickolya, FallenAngel, Invisible, Saymon21, X-Sky, TiGRpp, MasssteR, Litе, Олешка
13.10.2008, 20:04 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Называется венгерская нотация)))))
Код
s - string
i - integer
n - number
l - long
b - boolean
p - pointer
h - handle
C - class
T - type
t - table
mt - metatable


В lua можно использовать следующие:
Код
s - string
i - integer
b - boolean
h - handle
t - table
mt - metatable


(iShareSize, bConnected, hFile, tTable, mtTable)

http://mydc.ru/ipb.html?s=&showtopic=3...post&p=2068
26.9.2008, 18:42 Функции ===> Читаем, Дабы Не Задавать Вопросов <===
Скрипт-интерфейс PtokaX Lua. ВСЕ СКРИПТОВЫЕ ФУНКЦИИ PtokaX API
Продолжение разбора интерфейса PtokaX.

Функции API 2 и их аналоги в API 1:

Core.Version - Получить версию PtokaX.
Аналог API 1: второе значение функции getHubVresion()

Core.Restart() - Перезапустить хаб.
Аналог API 1: frmHub:Restart()

Core.Shutdown() - Отключить хаб.
Аналог API 1: нету

Core.ResumeAccepts() - Продолжать прослушивать сокет(ы), если их прослушивание не было приостановлено.
Аналог API 1: нету

Core.SuspendAccepts() - Приостановить прослушивание сокета(ов). Хаб выглядит так, как будто не работает.
Аналог API 1: SuspendAccepts(0)

Core.SuspendAccepts(nTime) - Приостановить прослушивание сокета(ов) на указанное время в секундах. Хаб выглядит так, как будто не работает.
Аналог API 1: SuspendAccepts(nTime)

Core.RegBot(sBotName, sDescription, sEmail, bHaveKey) - Регистрирует бота на хабе. Максимальная длина строковых параметров - 64 символа !!! В нике недопустимы символы: $|<>:?*"/\ и пробел. В параметрах Description и Email недопустимы символы $ и |. Функция возвращает nil в случае невозможности зарегистрировать бота, в случае удачной регистрации возвращает true.
Аналог API 1: frmHub:RegBot(sBotName, bHaveKey, sDescription, sEmail)

Core.UnregBot(sBotName) - Удаление бота. Функция возвращает nil в случае невозможности разрегистрировать бота, в случае удачной разрегистрации возвращает true.
Аналог API 1: frmHub:UnregBot(sBotName)

Core.GetBots() - Возвращает таблицу со всеми ботами, зарегистрированными скриптами, как таблицу с полями sNick, sMyINFO, bIsOP and sScriptName.
Аналог API 1: нету

Core.GetActualUsersPeak() - Возвращает фактический пик пользователей.
Аналог API 1: frmHub:GetActualUsersPeak()

Core.GetMaxUsersPeak() - Возвращает максимальный пик пользователей.
Аналог API 1: frmHub:GetMaxUsersPeak()

Core.GetCurrentSharedSize() - Возвращает суммарную шару хаба в байтах.
Аналог API 1: frmHub:GetCurrentShareAmount()

Core.GetHubIP() - Возвращает IP хаба, если он доступен, иначе возвращает nil.
Аналог API 1: frmHub:GetHubIp()

Core.GetHubSecAlias() - Возвращает фактический псевдоним Hub-Security бота.
Аналог API 1: frmHub:GetHubSecAliasName()

Core.GetPtokaXPath() - Возвращает путь до файла PtokaX.exe.
Аналог API 1: frmHub:GetPtokaXLocation()

Core.GetUsersCount() - Возвращает число пользователей на хабе.
Аналог API 1: frmHub:GetUsersCount()

Core.GetUpTime() - Возвращает время работы хаба в секундах.
Аналог API 1: frmHub:GetUpTime()

Core.GetOnlineNonOps() - Возвращает таблицу со всеми таблицами онлайн пользователей без статуса оператора.
Аналог API 1: frmHub:GetOnlineNonOperators()

Core.GetOnlineNonOps(bAllData) - Возвращает таблицу со всеми таблицами онлайн пользователей без статуса оператора. Используйте true для параметра bAllData, если вы хотите, чтобы таблицы содержали все данные.
Аналог API 1: frmHub:GetOnlineNonOperators()

Core.GetOnlineOps() - Возвращает таблицу со всеми таблицами онлайн пользователей со статусом оператора.
Аналог API 1: frmHub:GetOnlineOperators()

Core.GetOnlineOps(bAllData) - Возвращает таблицу со всеми таблицами онлайн пользователей со статусом оператора. Используйте true для параметра bAllData, если вы хотите, чтобы таблицы содержали все данные.
Аналог API 1: frmHub:GetOnlineOperators()

Core.GetOnlineRegs() - Возвращает таблицу со всеми таблицами зарегистрированных (profile > -1) онлайн пользователей.
Аналог API 1: frmHub:GetOnlineRegUsers()

Core.GetOnlineRegs(bAllData) - Возвращает таблицу со всеми таблицами зарегистрированных (profile > -1) онлайн пользователей. Используйте true для параметра bAllData, если вы хотите, чтобы таблицы содержали все данные.
Аналог API 1: frmHub:GetOnlineRegUsers()

Core.GetOnlineUsers() - Возвращает таблицу со всеми таблицами онлайн пользователей.
Аналог API 1: frmHub:GetOnlineUsers()

Core.GetOnlineUsers(bAllData) - Возвращает таблицу со всеми таблицами онлайн пользователей. Используйте true для параметра bAllData, если вы хотите, чтобы таблицы содержали все данные.
Аналог API 1: frmHub:GetOnlineUsers()

Core.GetOnlineUsers(nProfileNumber) - Возвращает таблицу пользователей с указанным профилем.
Аналог API 1: frmHub:GetOnlineUsers(nProfileNumber)

Core.GetOnlineUsers(nProfileNumber, bAllData) - Возвращает таблицу пользователей с указанным профилем. Используйте true для параметра bAllData, если вы хотите, чтобы таблицы содержали все данные.
Аналог API 1: frmHub:GetOnlineUsers(nProfileNumber)

Core.GetUser(sNick) - Возвращает таблицу онлайн пользователя по нику.
Аналог API 1: GetItemByName(sNick)

Core.GetUser(sNick, bAllData) - Возвращает таблицу онлайн пользователя по нику. Используйте true для параметра bAllData, если вы хотите, чтобы таблицы содержали все данные.
Аналог API 1: GetItemByName(sNick)

Core.GetUserAllData(tUser) - Добавляет или обновляет все данные в таблице пользователя. Возвращает nil в случае неудачи (пользователь оффлайн) или true в случае успеха.
Аналог API 1: нету

Core.GetUserData(tUser, nValueId) - Добавляет или обновляет данные с указанным идентификатором в таблице пользователя. Возвращает nil в случае неудачи (пользователь оффлайн) или true в случае успеха.
Аналог API 1: нету

Core.GetUserValue(tUser, nValueId) - Возвращает данные с указанным идентификатором или nil в случае неудачи (пользователь оффлайн).
Аналог API 1: нету

Core.GetUsers(sIP) - Возвращает онлайн пользователей с указанным ip как таблицу с таблицами пользователей или nil в случае, если пользователь с указанным ip не найден или ip введен неверно.
Аналог API 1: нету

Core.GetUsers(sIP, bAllData) - Возвращает онлайн пользователей с указанным ip как таблицу с таблицами пользователей или nil в случае, если пользователь с указанным ip не найден или ip введен неверно. Используйте true для параметра bAllData, если вы хотите, чтобы таблицы содержали все данные.
Аналог API 1: нету

Core.Disconnect(sNick) - Разъединяет пользователя с указанным ником. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: DisconnectByName(sNick)

Core.Disconnect(tUser) - Разъединяет указанного пользователя. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: tUser:Disconnect()

Core.Kick(tUser, sKickerNick, sReason) - Кикает пользователя. Максимальная длина параметра KickerNick - 64 символа, максимальная длина парамерта Reason - 128000 символов. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: tUser:Kick(sKickerNick, sReason)

Core.Redirect(tUser, sAddress, sReason) - Перенаправляет пользователя на указанный адрес с указанной причиной. Максимальная длина параметра Address - 1024 символа. Максимальная длина параметра Reason - 128000 символов. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: tUser:Redirect(sAddress, sReason)

Core.DefloodWarn(tUser) - Предупреждение пользователю по причини флуда. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: нету

Core.SendToAll(sData) - Послать данные всем пользователям. Максимальная длина параметра sData - 128000 символов. Если данные не содержат в конце символа |, то он автоматически добавляется.
Аналог API 1: SendToAll(sData)

Core.SendToNick(sNick, sData) - Послать данные пользователю с указанным ником. Максимальная длина параметра sData - 128000 символов. Если данные не содержат в конце символа |, то он автоматически добавляется.
Аналог API 1: SendToNick(sNick, sData)

Core.SendToOpChat(sData) - Послать данные, как приват сообщение, в ОпЧат. Максимальная длина параметра sData - 128000 символов. Если ОпЧат не разрещен - не посылает ничего.
Аналог API 1: SendToOpChat(sData)

Core.SendToOps(sData) - Послать данные всем операторам. Максимальная длина параметра sData - 128000 символов. Если данные не содержат в конце символа |, то он автоматически добавляется.
Аналог API 1: SendToOps(sData)

Core.SendToProfile(nProfileNumber, sData) - Послать данные пользователям с указанным профилем. Максимальная длина параметра sData - 128000 символов. Если данные не содержат в конце символа |, то он автоматически добавляется.
Аналог API 1: нету

Core.SendToUser(tUser, sData) - Послать данные указанному пользователю. Максимальная длина параметра sData - 128000 символов. Если данные не содержат в конце символа |, то он автоматически добавляется.
Аналог API 1: tUser:SendData(sData)

Core.SendPmToAll(sFromNick, sData) - Послать данные как приват сообщение всем пользователям. Максимальная длина параметра FromNick - 64 символа, максимальная длина параметра Data - 128000 символов.
Аналог API 1: SendPmToAll(sFromNick, sData)

Core.SendPmToNick(sToNick, sFromNick, sData) - Послать данные как приват сообщение пользователю с указанным ником. Максимальная длина параметра FromNick - 64 символа, максимальная длина параметра Data - 128000 символов.
Аналог API 1: SendPmToNick(sToNick, sFromNick, sData)

Core.SendPmToOps(sFromNick, sData) - Послать данные как приват сообщение всем операторам. Максимальная длина параметра FromNick - 64 символа, максимальная длина параметра Data - 128000 символов.
Аналог API 1: SendPmToOps(sFromNick, sData)

Core.SendPmToProfile(nProfileNumber, sFromNick, sData) - Послать данные как приват сообщение пользователям с указанным профилем. Максимальная длина параметра FromNick - 64 символа, максимальная длина параметра Data - 128000 символов.
Аналог API 1: нету

Core.SendPmToUser(tUser, sFromNick, sData) - Послать приват сообщение указанному пользователю. Максимальная длина параметра FromNick - 64 символа, максимальная длина параметра Data - 128000 символов.
Аналог API 1: tUser:SendPM(sFromNick, sData)



-------------------
SetMan.Save() - Принудительно сохраняет настройки.
Аналог API 1: нету

SetMan.GetMOTD() - Возвращает сообщение дня MOTD.
Аналог API 1: frmHub:GetMOTD()

SetMan.SetMOTD(sString) - Устанавливает сообщение дня MOTD. Символ | не допустим в сообщении.
Аналог API 1: frmHub:SetMOTD()

SetMan.GetBool(nBoolId) - Возвращает Булево знаечение парамерта настроек true или nil с указанным идентификатором.
Аналог API 1: нету

SetMan.SetBool(nBoolId, bBoolean) - Устанавливает Булево значение параметру настроек с указанным идентификатором.
Аналог API 1: нету

SetMan.GetNumber(nNumberId) - Возвращает числовое значение параметра с указанным идентификатором.
Аналог API 1: нету

SetMan.SetNumber(nNumberId, nNumber) - Устанавливает числовое значение параметру с указанным идентификатором.
Аналог API 1: нету

SetMan.GetString(nStringId) - Возвращает строковое значение параметра с указанным идентификатором. Возвращает строку или nil.
Аналог API 1: нету

SetMan.SetString(nStringId, sString) - Устанавливает строковое значение параметру с указанным идентификатором.
Аналог API 1: нету

SetMan.GetMinShare() - Возвращает минимальную шару в байтах.
Аналог API 1: frmHub:GetMinShare()

SetMan.SetMinShare(nShareInBytes) - Устанавливает минимальную шару в байтах.
Аналог API 1: frmHub:SetMinShare(nShareInBytes)

SetMan.SetMinShare(nMinShare, nShareUnits) - Устанавливает минимальную шару. Максимальное значение параметра nMinShare - 9999. Параметр nShareUnits может принимать следующие значения: 0 = Б, 1 = КБ, 2 = МБ, 3 = ГБ, 4 = ТБ.
Аналог API 1: frmHub:SetMinShare(nShareInBytes, nShareUnits)

SetMan.GetMaxShare() - Возвращает максимальную шару в байтах.
Аналог API 1: frmHub:GetMaxShare()

SetMan.SetMaxShare(nShareInBytes) - Устанавливает максимальную шару в байтах.
Аналог API 1: frmHub:SetMaxShare(nShareInBytes)

SetMan.SetMaxShare(nMaxShare, nShareUnits) - Устанавливает максимальную шару. Максимальное значение параметра nMinShare - 9999. Параметр nShareUnits может принимать следующие значения: 0 = Б, 1 = КБ, 2 = МБ, 3 = ГБ, 4 = ТБ.
Аналог API 1: frmHub:SetMaxShare(nShareInBytes, nShareUnits)

SetMan.SetHubSlotRatio(nHubs, nSlots) - Устанавливает соотношение хабы/слоты.
Аналог API 1: frmHub:SetHubSlotRatio(nHubs, nSlots)

SetMan.GetOpChat() - Возвращает таблицу ОпЧата с полями: sNick, sDescription, sEmail, bEnabled.
Аналог API 1: нету

SetMan.SetOpChat(bEnabled, sNewOpChatName, sNewDescription, sNewEmail) - Устанавливает параметры ОпЧата. Максимальная длина строковых параметров - 64 символа !!! В нике недопустимы символы: $|<>:?*"/\ и пробел. В параметрах Description и Email недопустимы символы $ и |. Возвращает nil в случае неудачи, иначе возвращает true.
Аналог API 1: frmHub:SetOpChatData(sNewOpChatName, sNewDescription, sNewEmail)

SetMan.GetHubBot() - Возвращает таблицу параметров главного бота с полями: sNick, sDescription, sEmail, bEnabled, bUsedAsHubSecAlias.
Аналог API 1: нету

SetMan.SetHubBot(bEnabled, sNewHubBotName, sNewDescription, sNewEmail, bUseAsHubSecAlias) - Устанавливает параметры главного бота. Максимальная длина строковых параметров - 64 символа !!! В нике недопустимы символы: $|<>:?*"/\ и пробел. В параметрах Description и Email недопустимы символы $ и |. Возвращает nil в случае неудачи, иначе возвращает true.
Аналог API 1: frmHub:SetHubBotData(sNewHubBotName, sNewDescription, sNewEmail)


-------------------
RegMan.Save() - Принудительно сохраняет зарегистрированных пользователей.
Аналог API 1: нету

RegMan.GetRegsByProfile(nProfileNumber) - Возвращает таблицу со всеми зарегистрированными пользователями с указанным профилем как таблицы RegisteredUser.
Аналог API 1: нету

RegMan.GetNonOps() - Возвращает таблицу со всеми зарегистрированными пользователями, которые не имеют статуса оператора как таблицы RegisteredUser.
Аналог API 1: frmHub:GetNonOperators()

RegMan.GetOps() - Возвращает таблицу со всеми зарегистрированными пользователями, которые имеют статус оператора как таблицы RegisteredUser.
Аналог API 1: frmHub:GetOperators()

RegMan.GetReg(sNick) - Возвращает таблицу пользователя как таблицу RegisteredUser или nil, если пользователь с указанным ником не зарегистрирован.
Аналог API 1: нету

RegMan.GetRegs() - Возвращает таблицу со всеми зарегистрированными пользователями, как таблицы RegisteredUser.
Аналог API 1: frmHub:GetRegisteredUsers()

RegMan.AddReg(sNick, sPass, nProfileNumber) - Регистрирует пользователя с указанным ником, паролем и профилем. Символы $|<>:?*"/\ и пробел не допустимы в нике. Символ | не допустим в пароле. Миксимальная длина ника/пароля - 64 символа. Возвращает nil в случае неудачи, true в случае успеха.
Аналог API 1: frmHub:AddRegUser(sNick, sPass, nProfileNumber)

RegMan.DelReg(sNick) - Удаляет регистрацию указанного пользователя. Возвращает nil в случае неудачи, true в случае
успеха.
Аналог API 1: frmHub:DelRegUser(sNick)

RegMan.ChangeReg(sNick, sPass, nProfileNumber) - Изменяет регистрацию указанного пользователя. Возвращает nil в случае неудачи, true в случае успеха.
Аналог API 1: frmHub:ChangeRegUser(sNick, sPass, nProfileNumber)

RegMan.ClrRegBadPass(sNick) - Очищает количество неудачных вводов пароля для указанного ника. Возвращает nil в случае неудачи, true в случае успеха.
Аналог API 1: ClrRegBadPass(sNick)


-------------------
BanMan.Save() - Принудительно cохраняет баны.
Аналог API 1: нету

BanMan.GetBans() - Возвращает таблицу банов.
Аналог API 1: нету

BanMan.GetTempBans() - Возвращает таблицу временных банов.
Аналог API 1: frmHub:GetTempBanList()

BanMan.GetPermBans() - Возвращает таблицу постоянных банов.
Аналог API 1: frmHub:GetPermBanList()

BanMan.GetBan(sNick/sIP) - Возвращает таблицу бана для указанного ника/ip или nil если таковой таблицы нет.
Аналог API 1: нету

BanMan.GetPermBan(sNick/sIP) - Возвращает таблицу постоянного бана для указанного ника/ip или nil если таковой таблицы нет.
Аналог API 1: нету

BanMan.GetTempBan(sNick/sIP) - Возвращает таблицу временного бана для указанного ника/ip или nil если таковой таблицы нет.
Аналог API 1: нету

BanMan.GetRangeBans() - Возвращает таблицу забаненных рангов.
Аналог API 1: нету

BanMan.GetTempRangeBans() - Возвращает таблицу временно забаненных рангов.
Аналог API 1: frmHub:GetTempRangeBans()

BanMan.GetPermRangeBans() - Возвращает таблицу постоянно забаненных рангов.
Аналог API 1: frmHub:GetPermRangeBans()

BanMan.GetRangeBan(sIPFrom, sIPTo) - Возвращает таблицу забаненных рангов для данного ранга или nil в случае отсутствия таковой.
Аналог API 1: нету

BanMan.GetRangePermBan(sIPFrom, sIPTo) - Возвращает таблицу постоянно забаненных рангов для данного ранга или nil в случае отсутствия таковой.
Аналог API 1: нету

BanMan.GetRangeTempBan(sIPFrom, sIPTo) - Возвращает таблицу временно забаненных рангов для данного ранга или nil в случае отсутствия таковой.
Аналог API 1: нету

BanMan.Unban(sNick/sIP) - Снятие бана с указанного ника или ip. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: нету

BanMan.UnbanPerm(sNick/sIP) - Снятие постоянного бана с указанного ника или ip. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: UnBan(sNick/sIP)

BanMan.UnbanTemp(sNick/sIP) - Снятие временного бана с указанного ника или ip. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: TempUnBan(sNick/sIP)

BanMan.UnbanAll(sIP) - Снятие всех банов с указанного ip.
Аналог API 1: нету

BanMan.UnbanPermAll(sIP) - Снятие всех поятоянных банов с указанного ip.
Аналог API 1: нету

BanMan.UnbanTempAll(sIP) - Снятие всех временных банов с указанного ip.
Аналог API 1: нету

BanMan.RangeUnban(sIPFrom, sIPTo) - Снятие бана с указанного ранга. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: RangeUnban(sIPFrom, sIPTo)

BanMan.RangeUnbanPerm(sIPFrom, sIPTo) - Снятие постоянного бана с указанного ранга. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: RangePermUnban(sIPFrom, sIPTo)

BanMan.RangeUnbanTemp(sIPFrom, sIPTo) - Снятие временного бана с указанного ранга. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: RangeTempUnban(sIPFrom, sIPTo)

BanMan.ClearBans() - Очистка таблицы банов.
Аналог API 1: нету

BanMan.ClearPermBans() - Очистка таблицы постоянных банов.
Аналог API 1: ClearPermBans()

BanMan.ClearTempBans() - Очистка таблицы временных банов.
Аналог API 1: ClearTempBans()

BanMan.ClearRangeBans() - Очистка таблицы бан-рангов.
Аналог API 1: ClearRangeBans()

BanMan.ClearRangePermBans() - Очистка таблицы постоянных бан-рангов.
Аналог API 1: ClearRangePermBans()

BanMan.ClearRangeTempBans() - Очистка таблицы временных бан-рангов.
Аналог API 1: ClearRangeTempBans()

BanMan.Ban(tUser, sReason, sBy, bFull) - Дать постоянный бан пользователю. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: tUser:Ban(sReason, sBy, bFull)

BanMan.BanIP(sIP, sReason, sBy, bFull) - Дать постоянный бан пользователям с указанным ip. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: Ban(sIP, sReason, sBy, bFull)

BanMan.BanNick(sNick, sReason, sBy) - Дать постоянный бан пользователю с указанным ником. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: NickBan(sNick, sReason, sBy)

BanMan.TempBan(tUser, nTime, sReason, sBy, bFull) - Дать временный бан пользователю. Параметр nTime - время в минутах (0 = время бана берётся из настроек). Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: tUser:TempBan(nTime, sReason, sBy, bFull)

BanMan.TempBanIP(sIP, nTime, sReason, sBy, bFull) - Дать временный бан пользователям с указанным ip. Параметр nTime - время в минутах (0 = время бана берётся из настроек). Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: TempBan(sIP, nTime, sReason, sBy, bFull)

BanMan.TempBanNick(sNick, nTime, sReason, sBy) - Дать временный бан пользователю с указанным ником. Параметр nTime - время в минутах (0 = время бана берётся из настроек). Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: NickTempBan(sNick, nTime, sReason, sBy)

BanMan.RangeBan(sIPFrom, sIPTo, sReason, sBy, bFull) - Постоянный бан для указанного ранга ip. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: RangeBan(sIPFrom, sIPTo, sReason, sBy, bFull)

BanMan.RangeTempBan(sIPFrom, sIPTo, nTime, sReason, sBy, bFull) - Временный бан для указанного ранга ip. Параметр nTime - время в минутах (0 = время бана берётся из настроек). Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: RangeTempBan(sIPFrom, sIPTo, nTime, sReason, sBy, bFull)


-------------------
ProfMan.AddProfile(sProfileName) - Добавляет профиль в менеджер профилей, возвращает номер профиля в случае успеха или nil, если такой профиль уже есть.
Аналог API 1: AddProfile(sProfileName,0)

ProfMan.RemoveProfile(sProfileName) - Удаляет профиль их менеджера профилей, возвращает true в случае успеха или nil, если указанный профиль не существует или наоборот существует и используется.
Аналог API 1: RemoveProfile(sProfileName)

ProfMan.MoveDown(nProfileNumber) - Сдвиг профиля вниз. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: нету

ProfMan.MoveUp(nProfileNumber) - Сдвиг профиля вверх. Возвращает nil в случае неудачи, true - в случае успеха.
Аналог API 1: нету

ProfMan.GetProfile(sProfileName/nProfileNumber) - Возвращает профиль как таблицу профиля или nil, если такого профиля нет.
Аналог API 1: нету

ProfMan.GetProfiles() - Возвращает таблицу с профилями как профильные таблицы.
Аналог API 1: GetProfiles()

ProfMan.GetProfilePermission(nProfileNumber, nPermissionId) - Возвращает true, если настройка разрешена, иначе возвращает nil.
Аналог API 1: нету

ProfMan.GetProfilePermissions(nProfileNumber) - Возвращает таблицу с настройками профиля.
Аналог API 1: GetProfilePermissions(nProfileNumber)

ProfMan.SetProfileName(nProfileNumber, sProfileName) - Изменяет имя профиля, возвращает true в случае удачи или nil, если указанного профиля не существует.
Аналог API 1: нету

ProfMan.SetProfilePermission(nProfileNumber, nPermissionId, bBoolean) - Изменяет настройку профиля с указанным идентификатором, возвращает true в случае удачи или nil, если указанного профиля не существует.
Аналог API 1: нету


-------------------
TmrMan.AddTimer(nTimerInterval) - Добавляет новый таймер для скрипта. Параметр nTimerInterval - время в милисекундах. Возвращает nil - в случае неудачи или nTimerId - в случае успеха.
Аналог API 1: SetTimer(nTimerInterval) StartTimer()

TmrMan.AddTimer(nTimerInterval, sFunctionName) - Добавляет новый таймер для скрипта. Параметр nTimerInterval - время в милисекундах. Параметр sFunctionName - это имя функции выполняемой таймером. Возвращает nil - в случае неудачи или nTimerId - в случае успеха.
Аналог API 1: нету

TmrMan.RemoveTimer(nTimerId) - Удаляет таймер с указанным идентификатором из скрипта.
Аналог API 1: StopTimer()


-------------------
UDPDbg.Reg(sIp, nPort, bAllData) - Регистрирует получателя данных от PtokaX через UDP, если параметр bAllData равен false, то получать данные только от этого скрипта. Возвращает nil в случае неудачи или true в случае успеха.
Аналог API 1: нету

UDPDbg.Unreg() - Удалить получателя данных.
Аналог API 1: нету

UDPDbg.Send(sData) - Отправить данные через UDP. Если скрипт зарегистрирован, то только от зарегистрированного скрипта, иначе от всех скриптов. Возвращает nil в случае неудачи или true в случае успеха.
Аналог API 1: нету


-------------------
ScriptMan.GetScript() - Возвращает таблицу этого скрипта с полями sName, bEnabled, iMemUsage.
Аналог API 1: нету

ScriptMan.GetScripts() - Возвращает таблицу всех скриптов с полями sName, bEnabled, iMemUsage.
Аналог API 1: нету

ScriptMan.MoveUp(sScriptName) - Сдвинуть указанный скрипт выше. Возвращает nil в случае неудачи или true в случае успеха.
Аналог API 1: нету

ScriptMan.MoveDown(sScriptName) - Сдвинуть указанный скрипт ниже. Возвращает nil в случае неудачи или true в случае успеха.
Аналог API 1: нету

ScriptMan.StartScript(sScriptName) - Запустить скрипт с указанным именем. Возвращает nil в случае неудачи или true в случае успеха.
Аналог API 1: нету

ScriptMan.RestartScript(sScriptName) - Перезапустить указанный скрипт. Возвращает nil в случае неудачи или true в случае успеха.
Аналог API 1: нету

ScriptMan.StopScript(sScriptName) - Остановить указанный скрипт. Возвращает nil в случае неудачи или true в случае успеха.
Аналог API 1: нету

ScriptMan.Restart() - Перезапустить все скрипты.
Аналог API 1: frmHub:RestartScripts()

ScriptMan.Refresh() - Обновить скрипт-лист.
Аналог API 1: нету


-------------------
IP2Country.GetCountryCode(sIP) - Возвращает код страны для указанного ip или nil, если ip не действителен.
Аналог API 1: нету

IP2Country.GetCountryName(sIP) - Возвращает имя страны для указанного ip или nil, если ip не действителен.
Аналог API 1: нету

IP2Country.GetCountryName(tUser) - Возвращает имя страны для указанного пользователя.
Аналог API 1: нету
FallenAngel, Invisible, Ksan, Karumo, Kingston, Sekretchik, Saymon21, Enyby, Damaks, ramzes, MIKHAIL
23.9.2008, 17:05 Функции Для Разработчиков
склад полезных функций
Еще несколько интересных методов. Может кому понадобятся, может кого заинтересует (Я использую их в больших проектах. Они несколько сворачивают длинные выкладки).
Код
tSys={}
function tSys:Table(t)                return type(t)=="table" and t end
function tSys:TableNoVoid(t)             return self:Table(t) and next(t) and t end
function tSys:TableOrDef(t,d)         return self:Table(t) or d or {} end
function tSys:TableNoVoidOrDef(t,d)        return self:TableNoVoid(t) or self:TableOrDef(t,d) end
function tSys:Table2(t,s)             return self:Table(t) and self:Table(t[s]) and t[s] end
function tSys:TableNoVoid2(t,s)         return self:Table2(t,s) and next(t[s]) and t[s] end
function tSys:TableOrDef2(t,s,d)        return self:Table(t) and (self:Table(t[s]) and t[s] or d or rawset(t,s,{}) and t[s]) or {} end
function tSys:TableNoVoidOrDef2(t,d)    return self:TableNoVoid2(t) or self:TableOrDef2(t,d) end
function tSys:String(s)             return type(s)=="string" and s end
function tSys:StringNoVoid(s)         return self:String(s) and s~="" and s end
function tSys:StringOrDef(s,d)         return self:String(s) or d or "" end
function tSys:StringNoVoidOrDef(s,d)     return self:StringNoVoid(s) or self:StringOrDef(s,d) end
function tSys:String2(t,s)             return self:Table(t) and self:String(t[s]) and t[s] end
function tSys:StringNoVoid2(t,s)         return self:String2(t,s) and t[s]~="" and t[s] end
function tSys:StringOrDef2(t,s,d)        return self:Table(t) and (self:String(t[s]) and t[s] or d or rawset(t,s,"") and t[s]) or "" end
function tSys:StringNoVoidOrDef2(s,d)     return self:StringNoVoid2(s) or self:StringOrDef2(s,d) end
function tSys:Number(i)             return type(i)=="number" and i end
function tSys:NumberOrDef(i,d)         return self:Number(i) or d or 0 end
function tSys:StringOrNumber(s)         return self:String(s) or self:Number(s) end
function tSys:NumberOfString(s)         return self:String(s) and tonumber(s) and s end
function tSys:ToNumber(s)             return self:String(s) and tonumber(s) or self:Number(s) end
function tSys:NoVoid(s)             return self:StringNoVoid(s) or self:Number(s) end
function tSys:Eq0(s)                 return self:Number(s) and s==0 and s end
function tSys:Eq1(s)                 return self:Number(s) and s==1 and s end
function tSys:Eq2(s)                 return self:Number(s) and s==2 and s end
function tSys:Eq01(s)                 return self:Number(s) and (s==0 or s==1) and s end

--метод возвращает количество ВСЕХ полей таблицы (а не только количество индексных полей как функции table.getn или table.maxn)
function tSys:GetN(t)
    local c=0 for _ in pairs(t) do c=c+1 end return c
end


P.S. Существуют различия между методами и функциями. tSys:GetN(t) - метод, tSys.GetN(t) - функция
Invisible
22.9.2008, 21:28 Меню
API1, API2 | Меню для всех профилей
Цитата(Cjay @ 22.9.2008, 22:16) *
насколько помню это "$UserCommand 255 3 " блокирует скрипты находящиеся до данного скрипта, лучше переправить на "$UserCommand 1 3 " И всеравно оставить первым в списке скриптов, у меня работает, такой скрипт, правда немного переделанный


Немного неверно ты думаешь. Команда "$UserCommand 255 3" не блокирует (и тем более не скрипты). Она просто стирает контекстные менюшки!

Причем существуют разновидности:
"$UserCommand 255 1", "$UserCommand 255 2", "$UserCommand 255 3", ... , "$UserCommand 255 15"
Для стирания различным менюшек.
Цитата
1 - меню хаба
2 - меню юзера
3 - меню хаба и меню юзера
4 - меню поиска
5 - меню хаба и меню поиска
6 - меню юзера и меню поиска
7 - меню хаба, юзера и поиска
8 - меню файл-листа
9 - меню хаба и файл-листа
10 - меню юзера и файл-листа
11 - меню хаба, юзера и файл-листа
12 - меню поиска и файл-листа
13 - меню хаба, поиска и файл-листа
14 - меню юзера, поиска и файл-листа
15 - меню хаба, юзера, поиска и файл-листа

big_smile.gif
Invisible, Serx
22.9.2008, 15:04 Меню
API1, API2 | Меню для всех профилей
В таблице CmdCfg установить параметр: ClearMenu = "no", вместо "yes" =)
Inkvizitor_ks
15.9.2008, 22:31 Функции Для Разработчиков
склад полезных функций
Функции преобразования ip адреса в число и обратно:
Код
function Ip2Num(sIP)
  local a, b, c, d = sIP:match"^(%d+)%.(%d+)%.(%d+)%.(%d+)$"
  return a * 16777216 + b * 65536 + c * 256 + d
end
function Num2Ip(i)
  i = tonumber(i) or 0
  local r, d, zd = '', '.', "0."
  if i >= 16777216 then r = math.floor(i / 16777216)..d i = math.fmod(i, 16777216) else r = zd end
  if i >= 65536 then r = r..math.floor(i / 65536)..d i = math.fmod(i, 65536) else r = r..zd end
  if i >= 256 then r = r..math.floor(i / 256)..d i = math.fmod(i, 256) else r = r..zd end
  return r..i
end
Можно использовать для проверки рангов ip и для оптимального хранения ip адресов в бд.
Invisible, Saymon21, shullz, Несогласный
14.9.2008, 11:36 Функции Для Разработчиков
склад полезных функций
Функции форматирования шары:
Код
function GetNormalShare(s)
  s = tonumber(s) or 0
  if s >= 1125899906842624 then return (math.floor(1000 * s / 1125899906842624) / 1000).." ПБ"
  elseif s >= 1099511627776 then return (math.floor(1000 * s / 1099511627776) / 1000).." TБ"
  elseif s >= 1073741824 then return (math.floor(1000 * s / 1073741824) / 1000).." ГБ"
  elseif s >= 1048576 then return (math.floor(1000 * s / 1048576) / 1000).." МБ"
  elseif s >= 1024 then return (math.floor(1000 * s / 1024) / 1000).." КБ"
  else return s.." Б" end
end

Код
function GetLongShare(s)
  s = tonumber(s) or 0
  local r = ''
  if s >= 1125899906842624 then r = r ~= '' and r..(" %s ПБ"):format(math.floor(s / 1125899906842624)) or r..math.floor(s / 1125899906842624).." ПБ" s = math.fmod(s, 1125899906842624) end
  if s >= 1099511627776 then r = r ~= '' and r..(" %s ТБ"):format(math.floor(s / 1099511627776)) or r..math.floor(s / 1099511627776).." ТБ" s = math.fmod(s, 1099511627776) end
  if s >= 1073741824 then r = r ~= '' and r..(" %s ГБ"):format(math.floor(s / 1073741824)) or r..math.floor(s / 1073741824).." ГБ" s = math.fmod(s, 1073741824) end
  if s >= 1048576 then r = r ~= '' and r..(" %s МБ"):format(math.floor(s / 1048576)) or r..math.floor(s / 1048576).." МБ" s = math.fmod(s, 1048576) end
  if s >= 1024 then r = r ~= '' and r..(" %s КБ"):format(math.floor(s / 1024)) or r..math.floor(s / 1024).." КБ" s = math.fmod(s, 1024) end
  if s < 1024 then r = r ~= '' and r..(" %s Б"):format(s) or r..s.." Б" end
  return r
end
Invisible, Saymon21
13.9.2008, 18:06 Функции Для Разработчиков
склад полезных функций
Функция приведения к нижнему регистру:
Код
function String2Lower(s)
  local r, b = ''
  s = s:lower()
  for i = 1, s:len() do
    b = s:byte(i)
    if b > 191 and b < 224 then
      b = b + 32
    elseif b == 168 or b == 184 then
      b = 229
    end
    r = r.._G.string.char(b)
  end
  return r
end

Функция приведения к верхнему регистру:
Код
function String2Upper(s)
  local r, b = ''
  s = s:upper()
  for i = 1, s:len() do
    b = s:byte(i)
    if b > 223 then
      b = b - 32
    elseif b == 168 or b == 184 then
      b = 197
    end
    r = r.._G.string.char(b)
  end
  return r
end



Более оптимальные по выполнению функции:
Код
String2Lower = function(s)
  for i = 192, 223 do
    s = s:gsub(_G.string.char(i), _G.string.char(i + 32))
  end
  s = s:gsub(_G.string.char(168), _G.string.char(184))
  return s:lower()
end

Код
String2Upper = function(s)
  for i = 224, 255 do
    s = s:gsub(_G.string.char(i), _G.string.char(i - 32))
  end
  s = s:gsub(_G.string.char(184), _G.string.char(168))
  return s:upper()
end
Invisible, Saymon21, мамин_парень
8.9.2008, 11:32 Weather
API2 | Скрипт погоды.
Коды городов для скрипта
NiKe10
6.9.2008, 15:58 Функции Для Разработчиков
склад полезных функций
Привожу полное преобразование на lua из кодировки cp1251 (Ansi) в utf-8 и обратно, с помощью функций AnsiToUtf8 и Utf8ToAnsi соответственно:

Код
local ansi_decode={
  [128]='\208\130',[129]='\208\131',[130]='\226\128\154',[131]='\209\147',[132]='\226\128\158',[133]='\226\128\166',
  [134]='\226\128\160',[135]='\226\128\161',[136]='\226\130\172',[137]='\226\128\176',[138]='\208\137',[139]='\226\128\185',
  [140]='\208\138',[141]='\208\140',[142]='\208\139',[143]='\208\143',[144]='\209\146',[145]='\226\128\152',
  [146]='\226\128\153',[147]='\226\128\156',[148]='\226\128\157',[149]='\226\128\162',[150]='\226\128\147',[151]='\226\128\148',
  [152]='\194\152',[153]='\226\132\162',[154]='\209\153',[155]='\226\128\186',[156]='\209\154',[157]='\209\156',
  [158]='\209\155',[159]='\209\159',[160]='\194\160',[161]='\209\142',[162]='\209\158',[163]='\208\136',
  [164]='\194\164',[165]='\210\144',[166]='\194\166',[167]='\194\167',[168]='\208\129',[169]='\194\169',
  [170]='\208\132',[171]='\194\171',[172]='\194\172',[173]='\194\173',[174]='\194\174',[175]='\208\135',
  [176]='\194\176',[177]='\194\177',[178]='\208\134',[179]='\209\150',[180]='\210\145',[181]='\194\181',
  [182]='\194\182',[183]='\194\183',[184]='\209\145',[185]='\226\132\150',[186]='\209\148',[187]='\194\187',
  [188]='\209\152',[189]='\208\133',[190]='\209\149',[191]='\209\151'
}
local utf8_decode={
  [128]={[147]='\150',[148]='\151',[152]='\145',[153]='\146',[154]='\130',[156]='\147',[157]='\148',[158]='\132',[160]='\134',[161]='\135',[162]='\149',[166]='\133',[176]='\137',[185]='\139',[186]='\155'},
  [130]={[172]='\136'},
  [132]={[150]='\185',[162]='\153'},
  [194]={[152]='\152',[160]='\160',[164]='\164',[166]='\166',[167]='\167',[169]='\169',[171]='\171',[172]='\172',[173]='\173',[174]='\174',[176]='\176',[177]='\177',[181]='\181',[182]='\182',[183]='\183',[187]='\187'},
  [208]={[129]='\168',[130]='\128',[131]='\129',[132]='\170',[133]='\189',[134]='\178',[135]='\175',[136]='\163',[137]='\138',[138]='\140',[139]='\142',[140]='\141',[143]='\143',[144]='\192',[145]='\193',[146]='\194',[147]='\195',[148]='\196',
    [149]='\197',[150]='\198',[151]='\199',[152]='\200',[153]='\201',[154]='\202',[155]='\203',[156]='\204',[157]='\205',[158]='\206',[159]='\207',[160]='\208',[161]='\209',[162]='\210',[163]='\211',[164]='\212',[165]='\213',[166]='\214',
    [167]='\215',[168]='\216',[169]='\217',[170]='\218',[171]='\219',[172]='\220',[173]='\221',[174]='\222',[175]='\223',[176]='\224',[177]='\225',[178]='\226',[179]='\227',[180]='\228',[181]='\229',[182]='\230',[183]='\231',[184]='\232',
    [185]='\233',[186]='\234',[187]='\235',[188]='\236',[189]='\237',[190]='\238',[191]='\239'},
  [209]={[128]='\240',[129]='\241',[130]='\242',[131]='\243',[132]='\244',[133]='\245',[134]='\246',[135]='\247',[136]='\248',[137]='\249',[138]='\250',[139]='\251',[140]='\252',[141]='\253',[142]='\254',[143]='\255',[144]='\161',[145]='\184',
    [146]='\144',[147]='\131',[148]='\186',[149]='\190',[150]='\179',[151]='\191',[152]='\188',[153]='\154',[154]='\156',[155]='\158',[156]='\157',[158]='\162',[159]='\159'},[210]={[144]='\165',[145]='\180'}
}

local nmdc = {
  [36] = '$',
  [124] = '|'
}

function AnsiToUtf8(s)
  local r, b = ''
  for i = 1, s and s:len() or 0 do
    b = s:byte(i)
    if b < 128 then
      r = r..string.char(b)
    else
      if b > 239 then
        r = r..'\209'..string.char(b - 112)
      elseif b > 191 then
        r = r..'\208'..string.char(b - 48)
      elseif ansi_decode[b] then
        r = r..ansi_decode[b]
      else
        r = r..'_'
      end
    end
  end
  return r
end

function Utf8ToAnsi(s)
  local a, j, r, b = 0, 0, ''
  for i = 1, s and s:len() or 0 do
    b = s:byte(i)
    if b < 128 then
      if nmdc[b] then
        r = r..nmdc[b]
      else
        r = r..string.char(b)
      end
    elseif a == 2 then
      a, j = a - 1, b
    elseif a == 1 then
      a, r = a - 1, r..utf8_decode[j][b]
    elseif b == 226 then
      a = 2
    elseif b == 194 or b == 208 or b == 209 or b == 210 then
      j, a = b, 1
    else
      r = r..'_'
    end
  end
  return r
end

big_smile.gif
Nickolya, intlive, Tsd, Invisible, Alexey, Sekretchik, Saymon21, TiGRpp, RAND(i)M, KCAHDEP, Несогласный
28.8.2008, 11:27 Бомба
API1, API2 | Классная игра на кик
Название скрипта: Bomb
Версия скрипта: 1.5
Версия API: API1 и API2 (универсальный скрипт)
Автор: Setuper
Префиксы команд: +, !, /
Команды: +bomb - подложить бомбу, +helpbomb - помощь
Код: Бинарный и Открытый
Описание скрипта: Подкладываешь бомбу и через установленное время она взрывается (юзера выкидывает или кикает с хаба), если конечно он её не обозвредит.
Настройки скрипта: После первого запуска скрипта создаётся файл "SettingsBomb.dbs", который содержит все настройки скрипта. Итак,
sBot - имя бота. Если не задано или пустая строка, то берется основной бот, иначе регистрируется на хабе указанный;
iTime - время в секундах для разминирования;
iTimer - время, через которое у вас появляются таймеры для бомб (это минимальное время между двумя подкладываниями бомб);
iTimeArmour - задержка перед запросом на установку или снятие бронежилета;
iTop - число позиций в топе;
iTopAll - число позиций в общем топе;
tWire - таблица проводов бомбы (должно быть не меньше 2 проводов);
iAction - действие при взрыве. 1 - дроп, 2 - кик;
sMenuUser - контекстное меню пользователя;
sMenuHub - контекстное меню хаба;
sArmour - контекстное меню установки/снятия бронежилета;
sCheck - контекстное меню проверки состояния бронежилета;
sHelp - контекстное меню помощи;
sTopBombers - контекстное меню топа минёров;
sTopSappers - контекстное меню топа сапёров;
sTopLosers - контекстное меню топа неудачников;
sTopAll - контекстное меню общего топа;
tProfiles - таблица профилей, под которых не подкладываются бомбы.

При возникновении каких то трудностей или ошибок скрипта отписываем сюда, указав ошибку и действие, которое вызвало ошибку.

В скриптах с закрытым кодом есть возможность отсылать цвет провода как в чат, так и в личку боту!
В скриптах с открытым кодом есть возможность отсылать цвет провода только в чат!

Версии с идентификацией по ip:
[attachment=2170:Bomb_by_...er_v_1.5.lua][attachment=2171:Bomb_by_...1.5_open.lua]

Версии с идентификацией по нику:
[attachment=2172:Bomb_by_..._nick_id.lua][attachment=2173:Bomb_by_..._nick_id.lua]

ВНИМАНИЕ!!! Перед запуском очередной новой версии необходимо удалить старый файл настроек для того чтобы появился правильный новый файл настроек!!!

Удачной игры big_smile.gif
FallenAngel, Drakula, EnerGetIck, AfLc
25.8.2008, 0:47 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Вот своял под апи2, но на работоспособность не проверял!
CODE
function OnStartup()
sBot=SetMan.GetString(21)
iTime=60 --Время в минутах, в течение которого нужно отправить подтверждение
tTmp={}
tFriends={} --база друзей
TmrMan.AddTimer(60000,"ClearRequests")
end

function ChatArrival(tUser,sData)
sData=sData:sub(string.len(tUser.sNick)+4,-2)
local _,_,sCmd,sNick=string.find(sData,"[+!/](%S+)%s+(%S+).*")
if sCmd and sNick and sCmd=="friend" then
if sNick==tUser.sNick then
Core.SendToUser(tUser,"*** О боже... Что я вижу... Вы хотите подружиться с собой! Перед тем как подружиться с собой навестите психиатора.")
end
local tUs=Core.GetUser(sNick)
if tUs then
for i,v in pairs(tFriends) do
if v[1]==tUser.sNick and v[2]==sNick or v[2]==tUser.sNick and v[1]==sNick then
Core.SendToUser(tUser,"*** Вы с '"..sNick.."' уже являетесь друзьями!")
return true
end
end
if not tTmp[tUser.sNick] then
tTmp[tUser.sNick]={}
tTmp[tUser.sNick].sNick=sNick
tTmp[tUser.sNick].iTime=os.time()+iTime*60
if tTmp[sNick] and tTmp[sNick].sNick==tUser.sNick then
tTmp[sNick]=nil
tTmp[tUser.sNick]=nil
table.insert(tFriends,{tUser.sNick,sNick}
Core.SendToUser(tUser,"$To: "..tUser.sNick.." From: "..sBot.." $<"..sBot.."> "..
"Запрос подтвержден! Вы с '"..sNick.."' с данного момента являетесь друзьями")
Core.SendToUser(tUs,"$To: "..sNick.." From: "..sBot.." $<"..sBot.."> "..
"Запрос подтвержден! Вы с '"..tUser.sNick.."' с данного момента являетесь друзьями")
else
Core.SendToUser(tUser,"*** Запрос на поддержание дружбы с пользователем '"..sNick..
"' успешно отправлен. Ждите подтверждения!")
end
else
Core.SendToUser(tUser,"*** Запрос на поддержание дружбы уже был отправлен пользователю '"..sNick.."'")
end
Core.SendToUser(tUs,"$To: "..sNick.." From: "..sBot.." $<"..tUser.sNick.."> "..
"Поступил запрос на подтверждение дружбы. Для подтверждения отправьте в чат +friend "..tUser.sNick)
else
Core.SendToUser(tUser,"*** Пользователь '"..sNick.."' оффлайн!")
end
return true
end
end

function ClearRequests()
for i,v in pairs(tTmp) do
if os.time()>v.iTime then
tTmp[i]=nil
end
end
end
мамин_парень
18.8.2008, 13:56 Создание Контекстных Менюшек Средствами Клиента
Сегодня я расскажу как на стороне клиента делать контекстные менюшки.

Открываем свой клиент и заходим: "Файл" - "Настройки" - "Команды-Юзера". Щелкаем добавить.

Видим типы команд:

Разделитель - горизонтальная черта между менюшками.
RAW - RAW команда
Чат - команда, отсылаемая в чат
PM - команда, отсылаемая в личку указанному юзеру

Далее контекст:

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

Далее рассмотрим параметры:

Название: в названии пишем имя контекстной менюшки. Если вы хотите создать подменю, то надо использовать обратные слеши ("\")
Команда: тут надо писать команду.
Хаб IP / DNS: тут надо писать IP или DNS имя хаба, на котором должна появиться и действовать данная команда. Если ничего не указывать, то команда появиться на всех хабах. Если указать "op", то команда появиться на всех хабах, на которых вы являетесь оператором (при условии, что рядом с вашим ником будет ключик, то есть если от хаба к клиенту прийдет команда получения статуса оператора).
К: тут обычно пишется ник получателя лички, если команда является командой типа PM.



Теперь рассмотрим простейший пример написания команд.

Устанавливаем тип команды: "чат"
Контекст: "Меню хаба" и "Меню юзера"
Название: "Меню клиента\Сказать привет"
Команда: "Всем привет"

после нажатия кнопки ОК, на всех ваших хабах появиться менюшка с названием: "Меню клиента", в которой будет менюшка: "Сказать привет". После нажатия на эту менюшку в чат того хаба, на котором была нажата менюшка, отправится фраза: "Всем привет".



Рассмотрим следующий пример:

Тип команды: "чат"
Контекст: "Меню хаба" и "Меню юзера"
Название: "Меню клиента\Послать дату и точное время в чат"
Команда: "Сегодня: %A - %d/%m/%Y. Точное время: %H:%M:%S"

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



Следующий пример:

Тип команды: "чат"
Контекст: "Меню юзера"
Название: "Меню клиента\Сообщения\Сообщения в чат\Шара этого юзера"
Команда: "Шара пользователя %[userNI]: %[userSS] байт"

Список команд сохраняется в файле Favorites.xml в папке Settings вашего клиента.

Приложу мой список команд. Можете скопировать в свой файл Favorites.xml полностью тег <UserCommands> и у вас появятся менюшки на хабах.
Но перед копированием в этот файл сделайте резервную копию этого файла, если у вас ни получиться правильно скопировать, то вернёте свой старый файл. И еще! Перед записью в этот файл (Favorites.xml) нужно закрыть клиент (именно закрыть, а не свернуть!!!)

[attachment=434:Favorites.xml]
Invisible, Uncle_Dif, Saymon21, Тёмич, мамин_парень
7.8.2008, 15:54 Несколько Слов О Захватах И Регулярных Выражениях
исключительно для разработчиков
Итак, я думаю многие сталкивались в скриптах со всевозможными "захватами" и регулярными выражениями.
Почти в каждом скрипте они встречаются.

Сразу же начну с нескольких примеров:
Код
local s, e, a, b, c, d = string.find("11.12.13.14", "^(%d+)%.(%d+)%.(%d+)%.(%d+)$")
local _, _, a, b, c, d = string.find("11.12.13.14 ", "^(%d+)%.(%d+)%.(%d+)%.(%d+)$")
local _, _, a, b, c, d = string.find("10 11.12.13.14 15", "(%d+)%.(%d+)%.(%d+)%.(%d+)")
local _, _, a = string.find("Hello world", "%S+%s(%S+)")
local _, _, a, b, c = string.find("<User> !massmsg hello world", "%b<>%s+(%S)(%S+)%s*(.*)")


Можете ли вы сказать, что тут выполняется??? Если не можете, то слушайте дальше...

Сначала расскажу, что такое захват, и что такое регулярное выражение.
Формально, захват - это нахождение определённый последовательности символов и помещение их в переменную.
Например, возьмём один из примеров, который я написал сверху:
Код
local s, e, a, b, c, d = string.find("11.12.13.14", "^(%d+)%.(%d+)%.(%d+)%.(%d+)$")

этот пример - типичный пример захвата. Функция string.find "захватывает" из строки "11.12.13.14" определённую последовательность символов.
Выражение "^(%d+)%.(%d+)%.(%d+)%.(%d+)$", называется РЕГУЛЯРНЫМ ВЫРАЖЕНИЕМ.
в скобках указываются захваты, то есть тут 4 захвата. Из этой функции данные у нас заносятся в 6 локальных переменных, а именно s, e, a, b, c, d.
В переменную s (s от слова start) заносится начальная позиция захвата, равная 1. У нас строка "11.12.13.14" имеет 11 символов, следовательно 11 позиций. В переменную e (e от слова end) заносится конечная позиция захвата, равная 11. Обычно, в скриптах эти позиции не нужны, тогда, обычно, переменные обозначают одним именем (для сохранения памяти), обычно, обозначают как "_" (чтобы эта переменная была не столь заметна).
Далее в переменные a, b, c, d, соответственно, заносятся захваты (то, что захватывается скобками).
Разберём регулярное выражение: "^(%d+)%.(%d+)%.(%d+)%.(%d+)$".
Символ ^ означает, что следующее действие в регулярном выражении должно быть в начале строки. У нас следующее за символом ^ действие - это захват (%d+), следовательно, захват у нас должен выполняться обязательно с начала строки. Сейчас объясню более понятно на примерах.
Возьмём два регулярных выражения "^(%d+)" и "(%d+)".
Теперь с помощью действий:
Код
local s, e, a1 = string.find("11.12.13.14", "^(%d+)")
local s, e, a2 = string.find("11.12.13.14", "(%d+)")

в переменные a1 и a2 запишутся данные: a1="11" и a2="11".
Теперь изменим исходную строку (дописав вначале строки пробел):
Код
local s, e, a1 = string.find(" 11.12.13.14", "^(%d+)")
local s, e, a2 = string.find(" 11.12.13.14", "(%d+)")

смотрим, что в переменных: a1=nil и a2="11".
Теперь я думаю вам почти понятно в чем вся фишка, осталось только объяснить, что такое (%d+).
(%d+) - это захват числа. Во второй строке вначале стоял пробел, поэтому выражение ^(%d+) не могло захватить число вначале строки, поэтому и функция string.find вернула nil, и записала в переменные s=nil, e=nil, a1=nil, а функция string.find(" 11.12.13.14", "(%d+)") записала в переменные s=1, e=2, a2="11". Заметьте, что хоть мы и захватываем число, но тем не менее оно является строковым числом "11", а не просто 11 !!!!!!!!.
Аналогично дело обстоит с символом $, но только для конца строки.
Таким образом, мы рассмотрели 3 первых примера, которые я предложил вначале.
В первом примере: s=1, e=11, a="11", b="12", c="13", d="14" и захват происходит именно 4 чисел, разделённых точками, и никакой другой комбинации
Во втором: _=nil, a=nil, b=nil, c=nil, d=nil и захвата не произошло из-за пробела в конце.
В третьем: _=14, a="11", b="12", c="13", d="14" захват 4 чисел, разделённых точками, в любом месте (хоть вначале строки, хоть в середине, хоть в конце), и строка не обязана содержать только 4 числа, разделённых точками, в отличие от первых двух примеров.

Идём далее. Выпишу основные регулярные выражения:

Цитата
. - любой символ
%a - латинская буква
%с - контрольный символ
%d - десятичная цифра
%u - латинская буква верхнего регистра
%l - латинская буква нижнего регистра
%p - знак пунктуации
%s - символ пробела
%w - латинская буква или арабская цифра
%z - нулевой символ

%A - не латинская буква
%C - не контрольный символ
%D - не десятичныая цифра
%U - не латинская буква верхнего регистра
%L - не латинская буква нижнего регистра
%P - не знак пунктуации
%S - не символ пробела
%W - не латинская буква и не арабская цифра
%Z - не нулевой символ

вроде становится понятнее, не так ли?

Эквиваленты:
%d эквивалентно [0-9]
%D эквивалентно [^%d]
%w эквивалентно [A-Za-z0-9]
%W эквивалентно [^%w]

в 4 и 5 примерах встречается регулярное выражение %S. Находим в списке выше, и видим: %S - не символ пробела. То есть, это означает, что это не пробел, а следовательно это любой символ, кроме пробела.

Теперь рассмотрим всякие плюсики. Я буду рассматривать их совместно с регулярным выражением %s, то есть с символом пробела.

Цитата
%s - 1 символ пробела
%s+ - 1 или более символов пробела
%s- - 0 или более символов пробела
%s* - 0 или более символов пробела
%s? - 0 или 1 символ пробела


Теперь объясню разницу между * и -
Удобнее всего на следующем примере. Я уже рассказал, что означает точка (смотри выше в списке регулярных выражений: "." - любой символ).
Рассмотрим примеры следующих регулярных выражений:
Цитата
"(.*)" - захват всей строки
"/(.*)/" - захват всего, что находится между КРАЙНИМИ символами /
"/(.-)/" - захват всего, что находится между ПЕРВЫМИ ДВУМЯ символами /


Цитата
%bxy - нахождение, а в случае захвата и захват, всего того, что находится между символами x и y, включая концы x и y


Ну и последнее...

А если, допустим, я хочу захватить точку. Как быть?
Дело в том, что точка является так называемым магическим символом.
Магические символы: ( ) . % + - * ? [ ] ^ $
Перед всеми магическими символами нужно ставить %, то есть все магические символы надо экранировать.
Таким образом, чтобы захватить точку надо написать "(%.)"


На последок ещё несколько часто используемых регулярных выражений:

Цитата
"(%S)" - захват первого не пробельного символа строки;
"(%S*)" - захват первого слова или пустого слова "";
"%S*%s*(%S*)" - захват второго слова;
"(%S*)%s*(%S*)" - захват первого и второго слова;
"(%S%S)" - захват первых двух не пробельных символов;
"(%S+)%s*(%d*)" - захват слова и числа;
"(%d*%.%d*%.%d*%.%d*)" - захват строки из 4 чисел, разделенных точками (например ip адреса);
"%s*(%d*%.%d*%.%d*%.%d*)%s*(%d*)%s*(.*)" - захват чисел, разделенных точками, захват числа, захват всего оставшегося;
"()" - захват номера позиции;
"(why)" - захват слова why (в любом месте);
"^(why)" - захват слова why, только если оно стоит на первых трех (в данном случае) позициях;
"(why)$" - захват слова why, только если оно стоит на последних трех (в данном случае) позициях;
"%b<>%s+(%S)(%S+)%s*(.*)" - захват первого символа, сразу после текста, ограниченного символами < >, второй захват слова сразу после захваченного символа, третий захват - захват всего оставшегося.
[^/]+ - не пустой захват с начала до символа /


Теперь, я думаю, что вы и сами сможете написать, что же получается в примерах 4 и 5???
Nickolya, FallenAngel, Tsd, Invisible, Ksan, Accelerator, Alexey, BeN, Kingston, Sekretchik, L1stin, Saymon21, X-Sky, Stym, TiGRpp, alcorp, bot9ra, RAND(i)M, Damaks, MIKHAIL, мамин_парень
13.7.2008, 23:06 Regme
API1, API2 | Скрипт регистрации
Название скрипта: RegMe
Версия скрипта: 1.5
Версия API: API1 и API2 (универсальный скрипт)
Автор: Setuper
Префиксы команд: +, !, /
Описание скрипта: Скрипт регистрации. Содержит в себе возможности регистрации и перерегистрации. Есть возможность перед регистрацией проходить тест по правилам хаба (не пройдя тест не регистрировать). Есть возможность в случае, если не указывается пароль, давать случайный пароль. За ненадобностью регистрации 1 ник на 1 ip - эту функцию скрипт не содержит (дабы не нагружать память базой пользователей). Скрипт может регистрировать бота (или же оставить главного бота) и устанавливать его параметры, а именно: статус away, описание, email, имя клиента, тэг, шару. Скрипт представляет собой бинарный файл, но все настройки скрипта вынесены в отдельный файл RegMe.dbs, который создаётся при первом запуске скрипта, и который можно открыть с помощью блокнота и править; этот файл содержит все сообщения скрипта и все менюшки, поэтому скрипт легко переводится на другие языки - достаточно только перевести то что написано в этом файле (но будьте осторожны - ошибки в этом файле могут привести не падению скрипта). Также существуют другие файлы, которые создаются после первого обращения к ним - это файл с просьбой зарегистрироваться (для не зарегистрированного), который показывается при входе на хаб (имя файла UnRegInfo.txt) и команды помощи (RegHelp.txt)

Некоторые настройки скрипта:
bShowInfo=1 - показывать дополнительную информацию о том, как можно избежать повторных вводов пароля при входе на хаб
bShowToAll=1 - показывать всем пользователям, что на хабе новый зарегистрированный участник
bQuestions=1 - задавать ли вопросы перед регистрацией
iQuestions=число - сколько правильных ответов нужно для регистрации
bRandomPass=1 - устанавливать случайный пароль в случае его отсутствия
bSendOpReport=1 - отсылать рапорт о регистрации ОПам
iRegProf=число - профиль регистрации (по умолчанию) - обычно 3
iBlocker=число - блокировщик для незарегистрированных:
1-чат
2-ПМ
3-скачку
4-поиск
5-чат и ПМ
6-чат и скачку
7-ПМ и скачку
8-чат и поиск
9-ПМ и поиск
10-скачка и поиск
11-чат, ПМ и скачку
12-чат, ПМ и поиск
13-чат, скачку и поиск
14-ПМ, скачку и поиск
15-чат, ПМ, скачку и поиск

[attachment=1607:RegMe_v1.5.lua]
MIKHAIL
10.7.2008, 19:39 Вопросы Разработчикам Скриптов
вопросы по скриптам (мелкие вопросы)
Код
function String2Lower( sText )
    local sReturn, iByte = ""
    if sText then
        sText = string.lower( sText )
        for i = 1, string.len( sText ) do
            iByte = string.byte( sText, i )
            if iByte > 191 and iByte < 224 then
                iByte = iByte + 32
            elseif iByte == 168 or iByte == 184 then
                iByte = 229
            end
            sReturn = sReturn..string.char( iByte )
        end
    end
    return sReturn
end
Saymon21, MIKHAIL, мамин_парень
1.7.2008, 23:09 Функции ===> Читаем, Дабы Не Задавать Вопросов <===
Скрипт-интерфейс PtokaX Lua. ВСЕ СКРИПТОВЫЕ ФУНКЦИИ PtokaX API
SupportsArrival(tUser, sData)
Важная функция (с её помошью я смог устроить автоматическую регистрация по ip).
В данной функции происходить объявление основных полей таблицы пользователя, а также проверяется поддержка дополнений.
пример команды: "$Supports UserCommand NoGetINFO NoHello UserIP2 TTHSearch ZPipe0 |" - клиент говорит, что он поддерживает:
  • UserCommand - контекстные команды менюшек,
  • NoGetINFO - не нужна отсылка команды GetINFO для получения MyINFO,
  • NoHello - не обязательна отсылка команд $Hello и $NickList,
  • UserIP2 - поддержка технологии UserIP2,
  • TTHSearch - поддержка поиска по TTH,
  • ZPipe0 - поддержка команды $ZOn - команды сжатия данных (библиотека zlib)
Invisible, Sekretchik, Saymon21
1.7.2008, 22:00 Создание Dll
Принципы построения, создания и использования Dynamic Link Library (DLL)

Среды разработки и языки: Borland С++ Builder 6, lua 5, PtokaX 3.6.*.*


Немного теории.

DLL - это один или несолько участков кода, хранимых в файле с расширением .dll. Код, содержащийся в dll, может быть вызван из испольняемой программы, но сама dll не является программой. DLL может содержать функции, классы и ресурсы. Прежде чем использовать dll, её нужно загрузить в память. Существуют два вида загрузки dll: статическая и динамическая. Статическая загрузка означает, что dll автоматически загружается при запуске приложения. DLL содержит экспортируемые функции, а описания этих функций находятся в библиотеке импорта (import library). Библиотеки импорта имеют имя, совпадающее с именем соответствующей dll, и расширение .lib. Для использования статической загрузки необходимо на этапе компоновки к проекту подключить lib-файл для dll. DLL загружается при загрузке приложения и можно вызывать экспортируемые функции так же, как и любые другие функции. Это самый лёгкий подход. Недостаток его в том, что при отсутствие необходимой dll программа не будет загружаться ваобще. Второй тип загрузки - Динамическая загрузка. Означает, что DLL загружается при необходимости и выгружается по окончанию использования. Достоинством является то, что dll находится в памяти до тех пор, пока она нужна, что приводит к более эффективному использованию памяти. В lua мы используем динамический вид загрузки.

Ещё немного о содержании dll библиотек.
Как же прсмотреть содержимо dll библиотеки? Ведь dll файл нельзя ничем открыть. Для просмотра содержимого dll существуют специальные утилиты. Я использую Борнандовскую утилиту tdump (находится в папке bin вместе с bcb.exe).

Далее писать теорию влом. Если что, то спрашивайте попробую объяснить)))

Приступим к написанию.

1. Открываем Builder C++ 6
2. Закрываем автоматически созданную форму (file -> close all)
3. Создаём новый проект (file -> new -> Other -> dll wizard) указываем тип "C" (в противном случае будут необходимы некоторые манипуляции с extern "C") я уще обычно ставлю галку vc++ style dll (но это не принципиально, просто будет различаться имя основной функции dll).
4. Далее в созданном проекте видим огромный коммент -> стираем его нах (в кратце он говорит о том что для того чтобы использовать библиотеку srting необходим дополнительный гемор).
5. функцию DllMain не трогаем, а пишем выше (или ниже) следующий код (данный код является самым простейшим):
Код
#include <windows.h>
#pragma comment(lib, "PXLua.lib")
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

int __declspec(dllexport) lua_helloworld (lua_State *L)
{
        lua_pushstring(L, "Hello World!");
        return 1;
}


6. сохраняем проект (file -> save project). вам будет сначало предложено сохранить юнит, а потом уже проект.
7. для компиляции нужны заголовочные файлы (из исходников),а именно файлы: "lua.h", "lualib.h", "lauxlib.h" и "luaconf.h".
8. все эти файлы можно найти скачав исходники lua.
9. эти файлы надо поместить в директорию проекта.
10. также нужна библиотека статической загрузки "PXLua.lib"
11. создаем dll (project -> build all)
12. копируем dll из папки проекта в папку с PtokaX (dll обычно имеет имя проекта. по умолчанию "project1.dll")
13. пишем скрипт
Код
libinit = package.loadlib("project1.dll", "_lua_helloworld")
SendToAll(libinit())

тут функция содержит впереди символ подчеркивания - это "украшения" компилятора))) (хотя существуют способы убрать этот символ, но я их тут рассматривать не буду). Просмотреть названия функций в библиотеке можно опять же воспользовавшись утилитой tdump.exe
14. заходим на хаб и перезагружаем скрипт. должно появиться "Hello World!".

p.s. для написания dll для PtokaX 0.4.*.* необходима библиотека статической загрузки "PXLua.lib" для данной версии и соответственно изменить SendToAll на Core.SendToAll

p.p.s. чуть позже выложу более сложные функции (ща влом писать)

"PXLua.lib" [для PtokaX 0.3.6.0] [attachment=256:PXLua.zip]
"Заголовочные файлы" [attachment=257:lua.zip]
Invisible

23 страниц V  « < 10 11 12 13 14 > » 
RSS Сейчас: 23.11.2024, 19:30