This is a script that checks shares, works better than built in to keep out mldonkey clients with only 11 meg shares. It also allows you to set different share limits for Ops, VIP's, and Regular users. I did not write this script, but it works fine for me on TD4
kb = 1024
mb = kb*kb
gb = kb*kb*kb
bot_name = "-ShareChecker-"
redirect_on_failed = 1 -- nil or 1 to redirect on when user fails to meet the criteria
hubCheckMethod = 3 -- DC++0.24 Hubs notation 1=x, 2=x/y, 3=x/y/z
checkSets = {
op = {
minShare = 0 * gb,
minShareFormatted = "0 GB",
minVersion = nil,
maxHubs = nil,
minSlotsPerHub = nil,
minSlots = nil,
maxSlots = 20,
allowNmdc = 1,
disallowPassive = nil,
},
vip = {
minShare = 100 * gb,
minShareFormatted = "100 GB",
minVersion = 0.181,
maxHubs = 5,
minSlotsPerHub = 1,
minSlots = 1,
maxSlots = nil,
allowNmdc = 1,
disallowPassive = nil,
},
user = {
minShare = 5 * gb,
minShareFormatted = "5 GB",
minVersion = nil,
maxHubs = 35,
minSlotsPerHub = nil,
minSlots = 1,
maxSlots = 20,
allowNmdc = 1,
disallowPassive = nil,
},
}
msg = {
["bad myinfo"] = "We couldn't parse your MyINFO string. Get the steppin'",
["no nmdc"] = "We don't like crappy old software, go download DC++",
["low version"] = "The ++ version you are using is too old. Minimum is [V]",
["no pasv"] = "We don't allow passive users in here. You people put too much load on the hub.",
["many hubs"] = "You are in too many hubs. Max hubs allowed is [H]. Disconnect from some and try again.",
["slots and hubs"] = "You do not meet the slots/hubs requirements. MinSlots = [mS], MaxSlots = [MS], Min slots "..
"per hub = [mSpH]",
["low share"] = "The minimum share here is [share].",
["you are not a vip"] = "You are not a VIP here. Get lost!",
["redirected"] = "You are being redirected to [H]",
}
function has_a_vip_name( name ) return strlower( strsub( name, 1, 5 ) ) == "[vip]" end
--// start //--
vipusers = {}
--// This function is fired at the serving start
function Main()
guardGlobals()
end
--// This function is fired when a new data arrives
function DataArrival( curUser, data )
--// a mypass is a sign that the user is registered
if strsub( data, 1, 8 ) == "$MyPass " then
--// if it's a vip, we save his name
if has_a_vip_name( curUser.sName ) then
vipusers[curUser.sName] = 1
end
--// whenever myinfo is sent, we check the user
elseif strsub( data, 1, 8 ) == "$MyINFO " then
CheckMyInfo( curUser, strsub( data, 1, strlen( data ) - 1 ) )
end
end
--// This function is fired when a new user finishes the login
function CheckMyInfo( curUser, myinfo )
--// the set of rules we want to test the user against
local checkSet
--// what action do we want on criteria mismatch?
if redirect_on_failed then
curUser.FailedLogin = function( o )
local addr = frmHub:GetRedirectAddress()
local warning = gsub( msg["redirected"], "%[H%]", addr, 1 )
o:SendData( bot_name, warning )
o:SendData( "$ForceMove "..addr )
o:Disconnect()
end
else
curUser.FailedLogin = curUser.Disconnect
end
--// define rules for usergroups
if curUser.bOperator then
checkSet = checkSets["op"]
elseif vipusers[curUser.sName] then
checkSet = checkSets["vip"]
elseif has_a_vip_name( curUser.sName ) then
curUser:SendData( bot_name, msg["you are not a vip"] )
curUser:FailedLogin()
return
else
checkSet = checkSets["user"]
end
--// get needed info from string
local ret,c,V,M,H,S,O,share = strfind( myinfo,
-- V:0123 M:P|A H:0-99 S:0-99 O:0-99 share
"<%+%+ V:([^,]+),M:(.),H:([^,]+),S:([^,]+),O:([^,>]+).*>$ $[^$]*%$[^$]*%$(%d+)%$$" ) -- dc++, with O
if not ret then
ret,c,V,M,H,S,share = strfind( myinfo,
-- V:0123 M:P|A H:0-99 S:0-99 share
"<%+%+ V:([^,]+),M:(.),H:([^,]+),S:([^,>]+).*>$ $[^$]*%$[^$]*%$(%d+)%$$" ) -- dc++, without O
end
if not ret then
ret,c,share = strfind( myinfo,
-- share
"%$(%d+)%$$" ) -- nmdc/other, non <++ V:
end
if not ret then
-- info seems to be messed up, disconnect the bastard
curUser:SendData( bot_name, msg["bad myinfo"] )
curUser:FailedLogin()
return
end
--// do we allow nmdc?
if not V and not checkSet.allowNmdc then
curUser:SendData( bot_name, msg["no nmdc"] )
curUser:FailedLogin()
return
end
--// check ++version
if V and checkSet.minVersion then
local n = tonumber( V )
if not n then -- we can't parse the version number, let the OPs handle it
SendPmToOps( bot_name, "warning, couldn't parse version V:"..V.." for user "..curUser.sName.." -- "..
"skipping version check" )
elseif n < checkSet.minVersion then
local warning = gsub( msg["low version"], "%[V%]", tostring( checkSet.minVersion ), 1 )
curUser:SendData( bot_name, warning )
curUser:FailedLogin()
return
end
end
--// check active/passive
if M == "P" and checkSet.disallowPassive then
curUser:SendData( bot_name, msg["no pasv"] )
curUser:FailedLogin()
return
end
--// fix new DC024 H:x/y/z notation
if H then
local Hn = {0} -- crappy-ass lua4 workaround
gsub( H, "(%d+)", function( x ) %Hn[1] = %Hn[1] + tonumber( x ) end, hubCheckMethod )
H = Hn[1]
end
--// fix slots while we're at it, no need for multiple tonumber()'s
if S then
S = tonumber( S )
end
--// check hubs
if H and checkSet.maxHubs then
if H > checkSet.maxHubs then
local warning = gsub( msg["many hubs"], "%[H%]", tostring( checkSet.maxHubs ), 1 )
curUser:SendData( bot_name, warning )
curUser:FailedLogin()
return
end
end
--// check slots / slots/hub
if H and S then
local dis = nil
if checkSet.minSlots and S < checkSet.minSlots then dis = 1
elseif checkSet.maxSlots and S > checkSet.maxSlots then dis = 1
elseif checkSet.minSlotsPerHub and S < ( H * checkSet.minSlotsPerHub ) then dis = 1
end
if dis then
local minSlots = checkSet.minSlots or "(void)"
local maxSlots = checkSet.maxSlots or "(void)"
local minSlotsPerHub = checkSet.minSlotsPerHub or "(void)"
local warning = gsub( gsub( gsub( msg["slots and hubs"], "%[mS%]", minSlots ), "%[MS%]", maxSlots ),
"%[mSpH%]", minSlotsPerHub )
curUser:SendData( bot_name, warning )
curUser:FailedLogin()
return
end
end
--// finally check the share and kick the user if lower
if tonumber( share ) < checkSet.minShare then
local warning = gsub( msg["low share"], "%[share%]", checkSet.minShareFormatted )
curUser:SendData( bot_name, warning )
curUser:FailedLogin()
return
end
end
function UserDisconnected( curUser )
--// clean up
vipusers[curUser.sName] = nil
end
function OpDisconnected( curUser )
--// clean up
vipusers[curUser.sName] = nil
end
--// debug functions
function _assign_undef_global( varname, newvalue )
error( "assignment to undefined global `"..varname.."'" )
end
--function _safe_get_global( varname )
-- -- access the table of globals
-- local value = rawgetglobal( varname )
-- if not value then error( "requesting undefined global variable `"..varname.."'" ) return end
-- local tm = gettagmethod( tag( value ), "getglobal")
-- if not tm then
-- if ret then return ret else error( "requesting undefined global variable `"..varname.."'" ) end
-- return value
-- else
-- return tm( varname, value )
-- end
--end
function guardGlobals()
settagmethod( tag(nil), "setglobal", _assign_undef_global )
-- settagmethod( tag(nil), "getglobal", _safe_get_global )
end
Hey.. Hm... my Ptokax hub does not display a "usename" / The bot name in the hub ?
QuoteOriginally posted by HartmannX
Hey.. Hm... my Ptokax hub does not display a "usename" / The bot name in the hub ?
replace function Main() for this 1.
--// This function is fired at the serving start
function Main()
guardGlobals()
frmHub:RegBot(bot_name)
end
plop
Is it possible to "controll" passive and actives ?
I mean , having for example:
- 5G for passive mode users
-20G for active mode users
Since "the mode" appears in the TAG , i'm hopping it's possible. :D
Can someone help please?
Is this feature about passive/actvie shares impossible to implemment ?
Anyone ? (please)
i hope some1 willing 2 learn picks this up as it's not that hard.
search for the M:(%S) in the tag, if P is found then use the 5GB min share else use 20GB.
plop
QuoteOriginally posted by plop
...some1 willing 2 learn...
me , me , ME !!! :]
I AM willing to learn. :D
I understand your tips and after reading (many times) the script , i think i can "take a shot".
Since i don't understand very well scripting...let's assume , "disallowPassive = nil". :P
So....if a passive user with 6G enters the hub , with this "settings":
user = {
minShare = 5 * gb,
minpassive = 10 * gb, -- ADDED THIS ONE (MIN PASSIVE SHARE)
minShareFormatted = "5 GB",
minVersion = nil,
maxHubs = 35,
minSlotsPerHub = nil,
minSlots = 1,
maxSlots = 20,
allowNmdc = 1,
disallowPassive = nil, -- REMEMBER THIS MUST BE nil TO WORK !!!
},
He should be kiked because he doesn't have 10G...
-- ADDED MESSAGE TO MIN PASSIVE SHARE
msg = {
["low passive share"] = "The minimum passive share here is [share].",
}
+
--// finally check the share and kick the user if lower
if tonumber( share ) < checkSet.minShare then
local warning = gsub( msg["low share"], "%[share%]", checkSet.minShareFormatted )
curUser:SendData( bot_name, warning )
curUser:FailedLogin()
return
end
if M == "P" then -- ADDED THIS LINES !!
if tonumber( share ) < checkSet.minpassive then
local warning = gsub( msg["low passive share"], "%[share%]", checkSet.minShareFormatted )
curUser:SendData( bot_name, warning )
curUser:FailedLogin()
return
end
end
end
...but he wasn't. Those "added features" are not working , lol.
Were my thoughts right ? Am i on the right path ? :D
your on the right path, just you mixed up the order of the checks.
but have a double hint for you.
if mode == passive then
minshare = checkSet.minpassive
else
minshare = checkSet.minShare
end
if tonumber( share ) < minshare then
local warning = gsub( msg["low share"], "%[share%]", checkSet.minShareFormatted )
curUser:SendData( bot_name, warning )
curUser:FailedLogin()
return
end
this needs some mods before it works, but the final code makes it easyer.
1st do a check which minshare is needed then do the actual check with the returned vallue.
plop
QuoteOriginally posted by plop
...have a double hint for you...
:D :D :D
The hints were wonderfull !!!! I have made some changes because i've wanted to show both messages:
local warning = gsub( msg["low passive share"], "%[share%]", checkSet.minPassiveFormatted )
local warning = gsub( msg["low share"], "%[share%]", checkSet.minShareFormatted )
I think i'd better post the entire script because i've made some changes.
Since there's no need for "preventing" passive users , i've removed that check .
I've added
minPassive and
msg["low passive share"] ADDED new code from
plop to allow all clients with TAGs.
kb = 1024
mb = kb*kb
gb = kb*kb*kb
bot_name = "-ShareChecker-"
redirect_on_failed = 1 -- nil or 1 to redirect on when user fails to meet the criteria
hubCheckMethod = 3 -- DC++0.24 Hubs notation 1=x, 2=x/y, 3=x/y/z
checkSets = {
op = {
minShare = 0 * gb,
minShareFormatted = "0 GB",
minPassive = 0 * gb,
minPassiveFormatted = "0 GB",
minVersion = nil,
maxHubs = nil,
minSlotsPerHub = nil,
minSlots = nil,
maxSlots = 20,
allowNmdc = 1,
},
vip = {
minShare = 5 * gb,
minShareFormatted = "5 GB",
minPassive = 10 * gb,
minPassiveFormatted = "10 GB",
minVersion = 0.181,
maxHubs = 5,
minSlotsPerHub = 1,
minSlots = 1,
maxSlots = nil,
allowNmdc = 1,
},
user = {
minShare = 10 * gb,
minShareFormatted = "10 GB",
minPassive = 25 * gb,
minPassiveFormatted = "25 GB",
minVersion = nil,
maxHubs = 35,
minSlotsPerHub = nil,
minSlots = 1,
maxSlots = 20,
allowNmdc = 1,
},
}
msg = {
["bad myinfo"] = "We couldn't parse your MyINFO string. Get the steppin'",
["no nmdc"] = "We don't like crappy old software, go download DC++",
["low version"] = "The ++ version you are using is too old. Minimum is [V]",
["no pasv"] = "We don't allow passive users in here. You people put too much load on the hub.",
["many hubs"] = "You are in too many hubs. Max hubs allowed is [H]. Disconnect from some and try again.",
["slots and hubs"] = "You do not meet the slots/hubs requirements. MinSlots = [mS], MaxSlots = [MS], Min slots ".. "per hub = [mSpH]",
["low share"] = "The minimum share here is [share].",
["low passive share"] = "The minimum passive share here is [share].",
["you are not a vip"] = "You are not a VIP here. Get lost!",
["redirected"] = "You are being redirected to [H]",
}
--// start //--
function has_a_vip_name( name ) return strlower( strsub( name, 1, 5 ) ) == "[vip]" end
vipusers = {}
--// This function is fired at the serving start
function Main()
guardGlobals()
end
--// This function is fired when a new data arrives
function DataArrival( curUser, data )
--// a mypass is a sign that the user is registered
if strsub( data, 1, 8 ) == "$MyPass " then
--// if it's a vip, we save his name
if has_a_vip_name( curUser.sName ) then
vipusers[curUser.sName] = 1
end
--// whenever myinfo is sent, we check the user
elseif strsub( data, 1, 8 ) == "$MyINFO " then
CheckMyInfo( curUser, strsub( data, 1, strlen( data ) - 1 ) )
end
end
--// This function is fired when a new user finishes the login
function CheckMyInfo( curUser, myinfo )
--// the set of rules we want to test the user against
local checkSet
--// what action do we want on criteria mismatch?
if redirect_on_failed then
curUser.FailedLogin = function( o )
local addr = frmHub:GetRedirectAddress()
local warning = gsub( msg["redirected"], "%[H%]", addr, 1 )
o:SendData( bot_name, warning )
o:SendData( "$ForceMove "..addr )
o:Disconnect()
end
else
curUser.FailedLogin = curUser.Disconnect
end
--// define rules for usergroups
if curUser.bOperator then
checkSet = checkSets["op"]
elseif vipusers[curUser.sName] then
checkSet = checkSets["vip"]
elseif has_a_vip_name( curUser.sName ) then
curUser:SendData( bot_name, msg["you are not a vip"] )
curUser:FailedLogin()
return
else
checkSet = checkSets["user"]
end
--// get needed info from string
local ret,c,V,M,H,S,O,share = strfind( myinfo,
-- V:0123 M:P|A H:0-99 S:0-99 O:0-99 share
"<%S+%sV:([^,]+),M:(.),H:([^,]+),S:([^,]+),O:([^,>]+).*>$ $[^$]*%$[^$]*%$(%d+)%$$" ) -- dc++, with O
if not ret then
ret,c,V,M,H,S,share = strfind( myinfo,
-- V:0123 M:P|A H:0-99 S:0-99 share
"<%S+%sV:([^,]+),M:(.),H:([^,]+),S:([^,>]+).*>$ $[^$]*%$[^$]*%$(%d+)%$$" ) -- dc++, without O
end
if not ret then
ret,c,share = strfind( myinfo,
-- share
"%$(%d+)%$$" ) -- nmdc/other, non <++ V:
end
if not ret then
-- info seems to be messed up, disconnect the bastard
curUser:SendData( bot_name, msg["bad myinfo"] )
curUser:FailedLogin()
return
end
--// do we allow nmdc?
if not V and not checkSet.allowNmdc then
curUser:SendData( bot_name, msg["no nmdc"] )
curUser:FailedLogin()
return
end
--// check ++version
if V and checkSet.minVersion then
local n = tonumber( V )
if not n then -- we can't parse the version number, let the OPs handle it
SendPmToOps( bot_name, "warning, couldn't parse version V:"..V.." for user "..curUser.sName.." -- ".. "skipping version check" )
elseif n < checkSet.minVersion then
local warning = gsub( msg["low version"], "%[V%]", tostring( checkSet.minVersion ), 1 )
curUser:SendData( bot_name, warning )
curUser:FailedLogin()
return
end
end
--// fix new DC024 H:x/y/z notation
if H then
local Hn = {0} -- crappy-ass lua4 workaround
gsub( H, "(%d+)", function( x ) %Hn[1] = %Hn[1] + tonumber( x ) end, hubCheckMethod )
H = Hn[1]
end
--// fix slots while we're at it, no need for multiple tonumber()'s
if S then
S = tonumber( S )
end
--// check hubs
if H and checkSet.maxHubs then
if H > checkSet.maxHubs then
local warning = gsub( msg["many hubs"], "%[H%]", tostring( checkSet.maxHubs ), 1 )
curUser:SendData( bot_name, warning )
curUser:FailedLogin()
return
end
end
--// check slots / slots/hub
if H and S then
local dis = nil
if checkSet.minSlots and S < checkSet.minSlots then dis = 1
elseif checkSet.maxSlots and S > checkSet.maxSlots then dis = 1
elseif checkSet.minSlotsPerHub and S < ( H * checkSet.minSlotsPerHub ) then dis = 1
end
if dis then
local minSlots = checkSet.minSlots or "(void)"
local maxSlots = checkSet.maxSlots or "(void)"
local minSlotsPerHub = checkSet.minSlotsPerHub or "(void)"
local warning = gsub( gsub( gsub( msg["slots and hubs"], "%[mS%]", minSlots ), "%[MS%]", maxSlots ), "%[mSpH%]", minSlotsPerHub )
curUser:SendData( bot_name, warning )
curUser:FailedLogin()
return
end
end
--// finally check the mode and share then kick the user if lower
if M == "P" then
if tonumber( share ) < checkSet.minPassive then
local warning = gsub( msg["low passive share"], "%[share%]", checkSet.minPassiveFormatted )
curUser:SendData( bot_name, warning )
curUser:FailedLogin()
return
end
else
if tonumber( share ) < checkSet.minShare then
local warning = gsub( msg["low share"], "%[share%]", checkSet.minShareFormatted )
curUser:SendData( bot_name, warning )
curUser:FailedLogin()
return
end
end
end
function UserDisconnected( curUser )
--// clean up
vipusers[curUser.sName] = nil
end
function OpDisconnected( curUser )
--// clean up
vipusers[curUser.sName] = nil
end
--// debug functions
function _assign_undef_global( varname, newvalue )
error( "assignment to undefined global `"..varname.."'" )
end
--function _safe_get_global( varname )
-- -- access the table of globals
-- local value = rawgetglobal( varname )
-- if not value then error( "requesting undefined global variable `"..varname.."'" ) return end
-- local tm = gettagmethod( tag( value ), "getglobal")
-- if not tm then
-- if ret then return ret else error( "requesting undefined global variable `"..varname.."'" ) end
-- return value
-- else
-- return tm( varname, value )
-- end
--end
function guardGlobals()
settagmethod( tag(nil), "setglobal", _assign_undef_global )
-- settagmethod( tag(nil), "getglobal", _safe_get_global )
end
Thanks a million
plop , for encouraging me !!!! :P
btw: With all the entusiasm , i forgot to ask if the script is ok ?
Here it seems ok , i also kicked my OPs , lol. :]
***EDITED****
Added code from plop , from this post ---> (click here) (http://board.univ-angers.fr/thread.php?threadid=1696&boardid=13&sid=e83a4e54cba8a39f4b19d605e25d9ea4&page=1#2)
***EDITED****
QuoteOriginally posted by [PT]CableGuy
QuoteOriginally posted by plop
...have a double hint for you...
:D :D :D
The hints were wonderfull !!!!
Thanks a million plop , for encouraging me !!!! :P
btw: With all the entusiasm , i forgot to ask if the script is ok ?
Here it seems ok , i also kicked my OPs , lol. :]
haven't checked if it worked, but if it works on you i trust you on that.
but i have some more tips on how 2 make the script better, but want you 2 do something before i give them.
may sound weird but it's a very handy thing as it makes the script more readable.
the thing is called tabbing.
function NewUserConnected(user)
for a,b in text._entry do
if text._entry[a][user.iProfile] then
showtext(user, a, (text._entrywhere[a] or text._default))
end
end
end
plop
:rolleyes: :rolleyes: :rolleyes: Hehehehe....i thought of doing that , but didn't. :(
I've re-edited the above post but it seems im a bit lost with the "if...then....return " procedure. ;(
Well...i gave it a shot :] and you're right , it's a LOT easyer to understand the script. :P
Thanks again plop .
Hi again:
I've re-edited the above post (with the script) , because it was bad formated. :D
I've also added , "new code" from plop .View in this topic ---> (click here) (http://board.univ-angers.fr/thread.php?threadid=1696&boardid=13&sid=e83a4e54cba8a39f4b19d605e25d9ea4&page=1#2)
Thanks again "Emperor" plop . :D (hehehehe)
QuoteOriginally posted by [PT]CableGuy
:rolleyes: :rolleyes: :rolleyes: Hehehehe....i thought of doing that , but didn't. :(
I've re-edited the above post but it seems im a bit lost with the "if...then....return " procedure. ;(
Well...i gave it a shot :] and you're right , it's a LOT easyer to understand the script. :P
Thanks again plop .
it's not that hard, return stops a function and send something back.
so you place it right above the end.
here's an example of what a return can do, execute it with the lua command line.
function number1(string)
if string == "string1" then
return "this"
elseif string == "string2" then
return "that"
else
return "something"
end
end
for index=1,3 do -- start a simple loop
-- next line is a bit more complex
-- 1st we call the function number1
-- next we use the string "string" and add a number 2 it
-- this because those are used in the function number1
print(number1( "string"..index ) )
end
return 1 is something special, that can fully stop the script from being procest but only works that way on the main functions from ptokax (DataArival, Main, etc....).
plop