Magnet Link Library 3.0 LUA 5.1

Magnet Link Library 3.0 LUA 5.1

Started by lUk3f1l3w4lK3R, 15 May, 2010, 17:30:50

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.


Hi everybody,

first of all this script is originally written by St0ne db and i use it since a few years now.
For the fact that it version 2.0 from this script dont work with the newest version from PtokaX
i thought its time to start learning LUA myself and convert this amazing script.

And now here it is: Magnet Link Library 3.0

Its not only converted - i have also added and changed some things in this script (read more about it in the script).

For everybody who dont know this script:
This is a Release & Request bot with alot of features
- Add/Remove Categories
- Add/Remove Releases
- Add/Remove Requests
- Add comments to releases
- Vote for the releases
- Add a description to the releases
- Add Magnet links to the releases
- Add Weblinks to the releases
- Nuke releases
- Ranking system

I have tested it alot (cause its the first time i converted a script) and couldnt find any error in it.
If you find any error let me know. And also feedback is welcome.

best regards

I have noticed that i had attached the wrong version to this post.
The one i had attached didnt send the RCMenu to registered users (only to op and higher).
I have updated the attachment with the correct version.



-- Mlink.Library.v3.0a.LUA5.X-PtokaX         				[ by: St0ne db ] [Modded by: lUk3f1l3w4lK3R]
--  A new kind of release and request bot.
----[ Tested With ]--------------------------------------------------------------------------------------
--		PtokaX v0.3.5.1c & PtokaX v0.3.5.1d - [ Lua 5.0.3 and Lua 5.1.1 ]
--		Version 3.0 tested with
--		PtokaX v0.4.1.2
----[ Version 3.0a Change Log ]-[by lUk3f1l3w4lK3R]----------------------------------------
--		Fixed: Bug in change skin
----[ Version 3.0 Change Log ]-[by lUk3f1l3w4lK3R]-----------------------------------------
--		Added: Error report to OP in pm
--		Added: Memory use report in pm (when script is started and stopped)
--		Added: Message to user that RC commands are enabled (Send in main)
--		Added: RC SubMenu - taken from scriptname or use "Custom Name"
--		Changed: RC Menu - is now taken from hubname or use "Custom Name"
--		Added: Help (sends available commands to user in main)
--		Added: Converted to new API

Attachment in first post updated


Thank you, this looks like a cool enhancement on freshstuff. I'll give it a whirl on ADCH++.

Update: Do you think it would be possible to implement the possibility to change releases without deleting them? That would make things a lot easier. Thanks for considering this!


I'm implementing this script for my hub (was trying freshstuff but this is superior) and it is revolutionizing how our entire hub works. It is amazing!

There's one major thing we're looking for though, and that's editing existing releases. (the release name, and also contents of the release info).

Currently we can only change something by deleting and re-adding, a cumbersome process.

Like jorgo suggested, is there a chance this might be possible? I am not sure how complicated adding an 'edit release' function would be, it seems pretty central to the script with a lot to do with the database and maintaining it etc...but maybe it's not that complicated :)...

Many thanks!!!!


I will try to add this option but this can take some time cause i just started learning LUA.

Btw there is allready something like this, not exactly an edit option,
but when using the wizard to add a release/request
you can allways type:
back - for going a page back

and there is the verification of the release/request information you wanna post.
At this point of the wizard you get a preview of your post.
If something is wrong just type back and edit the things you wanna edit.

Anyway thx for the feedback and suggestion.


Brilliant, thank you!! <3

If there's any way I can help, testing etc, let me know.

Patiently waiting, and glad to know you're onto it!! :D

thanks for this :)


First of all, this is an awesome request/release bot and it is much appreciated that you took the time to update it. A couple of things for the next release:

What this script is really missing is a way to "fill" requests. Right now I don't see any way of doing that so the requests just stay in the requests section until they expire, filled or not. What this script needs is a "FillReq" wizard.

The help should be dynamically served based on what privileges the user has. Also, it doesn't reflect any changes you might make to the commands at the top of the script.

Lastly, the right click menu doesn't take into account the fact that the user of the script may want to give users less power and make some more functions inaccessible to them. The RC menu is hard-coded much like the help in that if you change variables at the top, users will get RC commands they won't be able to use.


EDIT: The tweaks here will work on an unmodified version of MLink Lib 3.0a. I have released my fully modified version with all these tweaks and more farther down.


Add this table to the config area at the top of the script:
tHelp = {
	--Syntax = {<command>, <permission (must return pUser/pAdmin)>, <description>, <RC location + name>, <RC params (include a space before the params)>},
	--Wizard commands
	{tCmd.sAddRel, wAccess["AddRel"], "Add a release", "Add Release", ""},
	{tCmd.sReq, wAccess["AddReq"], "Add a request", "Add Request", ""},
	{tCmd.sDelRel, wAccess["DelRel"], "Delete a release/request", "Delete Release/Request", ""},
	{tCmd.sShowRel, wAccess["ShowRel"], "Show releases", "Show Releases", ""},
	{tCmd.sAddCat, wAccess["AddCat"], "Add a release category", "Categories\\Add Category", ""},
	{tCmd.sDelCat, wAccess["DelCat"], "Delete a release category", "Categories\\Delete Category", ""},
	--Quick commands
	{tCmd.qComment, tAccess[tCmd.qComment], "Show your releases comments", "Show My Comments", ""},
	{tCmd.qMag, tAccess[tCmd.qMag], "Show all releases with maglinks", "Show MagLinks", ""},
	{tCmd.qRank, tAccess[tCmd.qRank], "Show your releases and rank", "Show My Profile", ""},
	{tCmd.qClean, tAccess[tCmd.qClean], "Clean the release list", "Clean Releases", ""},

NOTES: This table is needed for both the help and RC fixes. Also, I removed some features (quick commands, URLs, skinning, etc.) from my version of MLink Lib so some commands are not in the tHelp table, put them in using the proper format (listed) if you use them.

Use the following method to return the help string to send to the user
--Returns a string containing help on using MLink Lib's functions
getHelp = function (user, param)
	local str = "\n\n\tRELEASE/REQUEST HELP:\n"
	if param == nil or param == "" then
		--General help
		for _, item in ipairs (tHelp) do
			if (item[2][user.iProfile] == 1) then
				local a = item[1]
				if string.len(a) < 7 then
					a = a .. "\t"
				str = str.."\n\t"..tVar.sTrig..a.."\t\t"..item[3]
		return str.."\n\n\tType "..tVar.sTrig..tCmd.qHelp.." <command> for info on that specific command\n"
		--look for specific match
		for _, item in ipairs (tHelp) do
			if (param == item[1] and item[2][user.iProfile] == 1) then
				return str.."\n\tCommand: "..tVar.sTrig..item[1].."\n\tDescription: "..item[3].."\n\
		--filter by text
		str = str.."\n\tCommands filtered by '"..param.."':\n"
		local found = false
		for _, item in ipairs (tHelp) do
			local a = item[1]
			if (string.find(a, param) and item[2][user.iProfile] == 1) then
				if string.len(a) < 7 then
					a = a .. "\t"
				found = true
				str = str.."\n\t"..tVar.sTrig..a.."\t\t"..item[3]
		if found then
			return str.."\n\n\tType "..tVar.sTrig..tCmd.qHelp.." <command> for info on that specific command\n"
			return str.."\n\tSorry, no commands found, try just '"..tVar.sTrig..tCmd.qHelp.."'\n"

HELP NOTES: You will have to do some coding to integrate it into your script. It does not directly output the help, but instead returns it as a string. You will have to use
Core.SendToUser(user, getHelp(user, param))
to send the data. It can optionally take in a param that can be used to search commands or show more details for a specific one.

Replace the
if string.lower(tVar.sRC) == "on" then
block in the UserConnected function with the following:
if string.lower(tVar.sRC) == "on" then
	if Core.GetUserValue(user,12) then
		local str = ""
		for _, item in ipairs (tHelp) do
			if (item[2][user.iProfile] == 1) then
				str = str.."$UserCommand 1 3 "..tVar.sRCMenu.."\\"..tVar.sRCSubMenu.."\\"..item[4].."$<%[mynick]> "..tVar.sTrig..item[1]..item[5].."&#124;|"
		Core.SendToUser(user, str.."<".tVar.sBot.."> Welcome "..user.sNick.." MLinkLib 3.0 commands enabled. Right click hub tab or user list for menu.|")

I kept running into a bug while using the voting feature (it would crash when you had already voted on a release, then tried to vote again, while skipping the comment. I have traced the bug to the Wizard.AddVote method (in Wizard.lua). It tries to call the
method (the finish screen) which doesn't exist. Also, if it DID call it, it wouldn't find the file AddVote5.txt (not included in any of the skins). To fix this I added the Wizard.AddVote[5](skin) method below:
[5] = function(skin)
	return doLoadFile("skin/""/AddVote5.txt");

Then went into every skin folder and renamed Vote5.txt to AddVote5.txt. You can delete the other Vote#.txt files, they aren't used anywhere in the script. Personally, I even changed the
elseif step == 5 and string.lower(data) == "yes" then

block to
elseif step == 5 and string.lower(data) == "yes" then
     msg = Wizard.AddVote[5]();

This effectively quits the user after they have rated a release, instead of showing the release list again.

When you have already voted (so you cant again and it skips you to the comment step), at the comment step, all you have to do is type 'b' or 'back' to go back and edit your rating. This messes up the rating count because you have edited your rating, but also added 1 to the rating count. Using this fix, users will still be allowed to go back and input a rating, but it won't make any difference. Simply add the following code to the bottom of the
elseif step == 4 then
block in the Wizard.AddVote["Start"] method.
if Library[tonumber(]["items"][tonumber(temp.rel.var)]["voted"][user.sNick] then = "Not Rated";

This simply checks again if the user has already voted right before the they confirm the data and it gets sent to the LibTask.Vote() method and changes it without the possibility of the user modifying it.

DISCLAIMER: My version of MLink has been heavily edited and tweaked so if something doesn't work, thats why. I've tried to make these snippits compatible with the original, but I may have missed something.

I will post my complete script once I have finished adding the features I want to it. EDIT: Posted


Glad to see this script has been translated.  ;D
Respect to lUk3f1l3w4lK3R and pR0Ps for their work.



All the tweaks I was doing were getting really hard to keep separate and post for an unmodified version of the script so I'm just going to post the entire thing here as a mod. It includes all the tweaks above, plus some more features. On the other hand, it also removes a lot of features because I made this for my personal hub and took out anything I didn't want/need. I present to you: Magnet Link Library 3.0a - pR0PsMod LUA 5.1

Quick Changelog:

Fixed: Voting bug
Removed: Skinning option and built in skin (only the 'simple' skin now)
Removed: Option for custom help command (is now !help)
Removed: Reporting memory usage
Removed: URLs from releases
Removed: Seperate notification bot (all through main Library bot now)
Removed: All quick commands that have wizard counterparts
Changed: The main skin was modified in places
Changed: New release notifications are now only one line (less obtrusive)
Changed: Less obtrusive authorization errors
Changed: Permissions are now true/false, not 1/0 (easier if statement checking)
Changed: The ChatArrival function now displays help and passes the command through to the hubsoft (you get both help texts)
Changed: Countless minor tweaks
Added: Dynamic help system
Added: Dynamic right click menu
Added: Option for multiple command triggers with a default for displaying within help
Added: Mechanism for filling requests (with skin)
Added: Optional integration of offline request filled notifications (use your own script)
Added: Library method for adding points to a users' rank

Complete script is attached

EDIT: Bug was found and fixed, see later post for script



Scope: This effects the non-modded version by lUk3f1l3w4lK3R as well as the pR0PsMod.

Cause: Special characters (characters represented by %[hex value], like %5D represents '[') being inputted into the bot (in release names, magnet links, etc.)

Effect: In some cases it causes the script to not display the entire message the special character was encompassed in.

Temporary fix: Manually edit the database, replacing all the %[hex value]s with their character equivalent, then restart the script.

A permanent fix is in the works (when I finish exams), If you find any more bugs, let me know. Also, if you have a fix for it, post it below.


Fix this bug, try convert magnet-link utf8ToAnsi
Add in main script
url = require("socket.url")

local ansi_decode={
local utf8_decode={

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)
      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]
        r = r..'_'
  return r

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]
        r = r..string.char(b)
    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
      r = r..'_'
  return r

["LatestRel"] = function(temp)
			--local s = "\tID:\tИнформация:\n\t"..string.rep("-",160)
			local s = ""
                                          local d = Wizard.Show.Divider(;
			for z = TableMaxSize(LibLast), 1, -1 do
				local i = tonumber(LibLast[z]["cat"]);
				local n = tonumber(LibLast[z]["rel"]);
				local mLink = Library[i]["items"][n]["mlink"];
				local name = Library[i]["items"][n]["name"];
				if mLink == "Не задано" then 
					name = url.unescape(name);
					name = Utf8ToAnsi(name);
					mLink = ""
					mLink = url.unescape(mLink);
					mLink = Utf8ToAnsi(mLink);
					mLink = "\n\t\tMagnet: "..mLink
				local r = "\n\t"..i.."."..n.."\t"
				.." из категории: "..Library[i]["cname"]
				..". Автор: "..Library[i]["items"][n]["poster"]..", дата "..Library[i]["items"][n]["date"]..mLink
				s = s..string.gsub(d,"{release}",r);
				--s = string.gsub(d,"{release}",r);
			return s;

Use this in all places where it's need.


Fixed the major bug.

EDIT: Removed dependencies on custom "fcns" library


Hi. I'm getting this error :
[01:13] Syntax ...cripts\MLinkLib.v3.1-pR0PsMod.LUA5.0X-PtokaX.lua.lua:115: module 'fcns' not found:
   no field package.preload['fcns']
   no file 'C:\Huburi & radio\Huburi\Huburi\Ptokax412+Leviathan6.2FINAL\fcns.lua'
   no file 'C:\Huburi & radio\Huburi\Huburi\Ptokax412+Leviathan6.2FINAL\libs\fcns.lua'
   no file 'C:\Huburi & radio\Huburi\Huburi\Ptokax412+Leviathan6.2FINAL\scripts\libs\fcns.lua'
   no file 'C:\Huburi & radio\Huburi\Huburi\Ptokax412+Leviathan6.2FINAL\fcns.dll'
   no file 'C:\Huburi & radio\Huburi\Huburi\Ptokax412+Leviathan6.2FINAL\libs\fcns.dll'
   no file 'C:\Huburi & radio\Huburi\Huburi\Ptokax412+Leviathan6.2FINAL\scripts\libs\fcns.dll'

From where can i get the fcns.dll ?
We are captives of our own identities, living in prisons of our own creation


Sorry, I forgot to remove the dependencies on the "fcns" library that I use. File in this post is now fixed.


Hey everyone, doing a bit of necroposting here.

I'm using the pR0Psmod version of this, and am the owner of my hub, even by profile.
Loading the script from scratch with PtokaX and trying to add a new category (or anything else for that matter), I kept getting access denied.

There are two concerns I have;
For one, I had a look in the script and am not entirely sure what to put where when defining profiles by numbers.
Second, trying to check what profile the script thinks I have, using !myrank, it crashes with this:
[16:09:40] Syntax .../C_/Program Files/PtokaX/scripts/MLinkLib/Wizard.lua:1777: attempt to concatenate local 'skin' (a nil value)

That line is:
return doLoadFile("skin/""/Denial.txt") or s;

What am I completely and totally missing here?


You missed an update, line should be "return doLoadFile("skin/Denial.txt")"
keep on sharing :)


Thank you! Thank you so much!

I'm gonna keep on tinkering with this thing.
Now that I've actually gotten it to work and seen it in action, I may actually be able to learn something from it.
Thanks again for the help. :)



can someone post full working script in lua format  for ptokax version

thanks in advance


Where is the script attachment ?? I want to download the script but I can't see it.....i am new to this so help me...!!

SMF spam blocked by CleanTalk