--[[
TopHubbers 2.03 - LUA 5.1x [Strict][API 2] by jiten
???????????????????????????????????????????????????
Based on: OnHub Time Logger 1.65 by chill and Robocop's layout
Usage: !tophubbers; !tophubbers x-y; !hubtime <nick>; !myhubtime
RECENT CHANGELOG:
?????????????????
Changed: Script converted to API 2 (11/24/2007)
Fixed: Changed Serialize function (12/23/2007)
]]--
hey jiten
Just have some suggestions for somthing to add in this nice script
could it show:
Monthly uptime
and daily/monthly/total uptime in the !tophubbers
and maybe the Top 10 worst tophubbers :D
would be nice if it was possible
just a little suggestion
hello,
Wish every1 a Happy and Prosperous New Year!
making some suggestions
can the ranks in this script be just 1 2 3... and so on instead of the present 1s
and can u please add there +rank to check rank of user like
+rank to show my rank and hubtime in 1 line and above it the hubtime of previous ranker and below the rank of next ranker
and
+rank username to the same as above for the given name
can the script also be such that the +hubtime to show my own hubtime to me
thanking you for help
a little request from here, is it possbile to update the script so that the messages comes in the hub bot window instead of in mainchat, an true/false setting maybe??
yup, here you go :D
thx m8 :)
hmm i have tested it about 1 month now and it doesnt show the correct uptime on all users i tryied to show tophubbers 1-200 seems that some of the many last tophubbers, the time wont count
It works fine here, but anyway, if you are showing the 200 tophubbers, i won?t call it TOPhubbers anymore, just onlinetime for hubbers :)
You must use a shitload of memory to list that many
gnuff it also works here, there was just an user that changed nick hehe, so his uptime is always the same *G* but actually the hub has been running for approx 14 days without reboot and runs fine :)
Well, if he has changed his nick, then the old nick, will fall back in list, unless you are showing 200 users, with 10 users he should be gone from the list soon :D
how do i reset the tophubbers??
Quote from: ExtreeM on 27 February, 2008, 15:24:18
how do i reset the tophubbers??
Delete the 2 .tbl files in script folder relating to the script.
Not on top of the list, since you need to reset? ;D
Hi
I know one should not reply to old threads, but since the script is already attached here and my question is about this particular script I thought this would be worth trying. Im sorry if the correct way would have been to start a new thread instead.
Anyway... the script "TopHubbers 2.03 - LUA 5.1x [Strict][API 2]" seems, as far as I understand save the userdata to the .tbl-file only when a user exits the hub. We are using this script to maintain a certain minimum uptime in our hub and a few days ago there was a malfunction in the hub computer which caused an "all of a sudden" reboot, like pressing the Reset button. Because of this boot we lost 14 days of uptime data for those users who had not logged off during that time. Would it be possible to add a kind of timer to autosave the userdata even tho the user has not logged off, for instance once/day. That would be a good way to prevent datalosses in case of similar insidents, that happened to me.
Im very greatful for any help I can get. I do not yet know enough of scripting to be able to fix this on my own :)
Maybe this will help you out.
Quote
-- Set your interval time to save data(in Hours)
iInterval = 24,
Thank you sooo much :)
The change you displayed in the example is what I expected to be done but the rest is still a little too difficult. This a good opportunity for me to find out what you changed and what you added. I really want to learn lua and I dont think it is too difficult, not even for me ;D
Once again, thank you :)
Hi,
Request if possible.
I would like to have a message returned with the command Show my stats: This is what the command returns now. Instead of the bot twice I would like to have a message like --> Hello usernick "message" where I could just open the script and put whatever I wanted there.
Say, Hello merlin_xl54, Remember to remain a VIP your daily AUT must be above 12 hours.
Is this possible?
TIA,
M
[10:19:29] <HubBot> <HubBot>
========================================
Stats:
--------------------------------------------------------------------------------
- Nick: Usernick
- Total uptime: 1 day(s), 4 hour(s), 13 minute(s)
- Daily average uptime: 23 hour(s), 52 minute(s)
- Current Rank: Jester
Edit: I replaced line 324 on my modified script - return "<"..tSettings.sBot.."> ".. sMsg
with - return "Here are the stats you requested for "..nick..", Remember to keep your AUT above 16 Hours" ..sMsg
It seems to work for me does this seem to be correct? It returns the following.
Bot> Here are the stats you requested for merlin_xl54, Remember to keep your AUT above 16 Hours
========================================
Stats:
--------------------------------------------------------------------------------
- Nick: merlin_xl54
- Total uptime: 2 day(s), 15 hour(s), 5 minute(s)
- Daily average uptime: 23 hour(s), 18 minute(s)
- Current Rank: Jester
Hi,
I use this script with the changes that have been made on this post. * Reply in PM and Save interval data time. My question is regarding the Average uptime AUT. When I call for top hubbers it displays all info including the Rank set in --Daily average uptime rank table. (I'll focus on 16 H), and Top Hubbers gives the Rank set to 16 H. But when I call for Show a Users stats the Daily AUT does not match and in most cases is less than the 16 H setting.
The Minimum AUT we're trying to maintain is the 16 H'rs. Is there a way to show the AUT in the tables for Show Top Hubbers and Show x-y? or fix the Rank now shown in the top Hubbers.
Am I misunderstanding the use for --Daily average uptime rank table. I thought if you set a Name for AUT of 16 H the rank in the top hubbers would show the Daily AUT assigned to that rank etc.
TIA,
M
I get this when Im trying to upload: TopHubbers.lua:47: attempt to index global 'SetMan' (a nil value)
The hub should run before you start the script. The script cannot pull out the hub name from a hub not running.
can someone add reply in pm for this script.
Quote from: ?StIfFLEr?? on 23 January, 2009, 05:09:56
can someone add reply in pm for this script.
This is the version I use. It has the save interval and it sends the stats in chat or PM. I also left your custom message and profiles intact.
M
Friends i came across with a problem using this script.
when the hubtime crosses 1 month and some days after that the whole hubtime resets.
can anyone sort out this problem.
Hello Team,
I have problem too. I download and use this script "TopHubbers2.03A2modifiedPM.lua". When i reboot my PC, the Total Online time in TopHubbers is reset to 000 ...
I put this script in "scripts" folder in main PtokaX's folder. After i start PtokaX, the file "tOnliners.tbl" is creating in main PtokaX folder, not in "script" folder. Is that right?
Maybe i make somewhere mistake, please help me to resolve this problem.
Thanks in advance!
Best Regards
P.S
I was make some probe and i think that i find the problem. When PtokaX is not stoped correctly from Start/Stop button, for example Windows crash and auto reboot, the file tOnliners.tbl in main folder on PtokaX can't write properly and i lose any currently online time to this moment.
What you says about that?
I am not a scripter but have used this script for the past 7 months and have not lost any time. In the tSettings I use 24 and the scripts saves the data each day. I also changed the location of the fOnline to "scripts/tOnliners.tbl" That seems to keep it in the scripts folder for me. Hope that helps.
M
Quote from: BIJ on 16 March, 2009, 12:00:25
P.S
I was make some probe and i think that i find the problem. When PtokaX is not stoped correctly from Start/Stop button, for example Windows crash and auto reboot, the file tOnliners.tbl in main folder on PtokaX can't write properly and i lose any currently online time to this moment.
What you says about that?
There is no fix for that. Settings are saved OnExit which is called when the script is properly stopped. A crash of your operating system will cause that function to be skipped (just like any other function). Compare it with a power outage, nothing will be saved.
Ok! Thanks for the answers mates :)
I be clear about this problem already ;)
Regards
Is it possible and is there anyone willing to add a R Click command to this script so a specific profile (say Master/Op) can request a list in a PM that would display users with a Daily Average Uptime AUT below an certain number? If I would enter say 8 or 10 or any given #.
The script will now list individual daily AUT but I was looking to get a list.
Show My Stats
========================================
Stats:
--------------------------------------------------------------------------------
- Nick: merlin_xl54
- Total uptime: 9 month(s), 24 day(s), 9 hour(s), 19 minute(s)
- Daily average uptime: 23 hour(s), 31 minute(s)
TIA
M
I have been using this script for a year now. For some reason it is starting over when a users total time hits 1 year? The rank info is set for 1 year average and that is working. Is there a way to display years in total time?
TIA
M
================================================================================================================
Nr. Total: Session: Entered Hub: Left Hub: Rank: Status: Name:
-------------------------------------------------------------------------------------------------------------------------------------
1. 0 month(s), 0 day(s), 3 hour(s), 34 minute(s)10865 min 07/18/09 06:40:17 07/17/09 05:21:24 Conqueror *Online* merlin_xl54
2. 0 month(s), 0 day(s), 2 hour(s), 37 minute(s)10865 min 07/18/09 06:40:33 07/17/09 05:21:24 Conqueror *Online* nick
3. 11 month(s), 30 day(s), 4 hour(s), 24 minute(s)6002 min 07/21/09 15:43:50 07/21/09 15:42:43 Conqueror *Online* nick
Quote from: merlin_xl54 on 26 July, 2009, 03:03:52
I have been using this script for a year now. For some reason it is starting over when a users total time hits 1 year? The rank info is set for 1 year average and that is working. Is there a way to display years in total time?
Try this...
Can a rank function be added to this script according to user's total hubtime..
[13:03:47] <Bot> Nick: DeAn THT: 1 days, 11 hours, 57 minutes AHT: 2 hours, 36 minutes Status: Newbie Rank: 200
[13:03:47] <DeAn> +hubtime
QuoteCan a rank function be added to this script according to user's total hubtime..
Use the last updated Script.
You might find a display like this.
Quote
========================================
Stats:
--------------------------------------------------------------------------------
- Nick: ll-T-z-B-ll
- Total uptime: 3 month(s), 15 day(s), 22 hour(s), 22 minute(s)
- Daily average uptime: 5 hour(s), 52 minute(s)
- Current Rank: ?Hub GoD?
For Numeric rank you can always use top 20 hub timers option available to you.
Quote from: merlin_xl54 on 26 July, 2009, 16:13:54
I've combined all the changes on this thread into one version. I hope this will help. Thanks to all who've kept this going.
M
1, Sends messages in PM
2, Saves data on regular intervals
3, Kicks user below Minimum Average uptime
4, Table to exclude certain nicks from kick
5, Shows total years added in displayed times
Sorry, but the link for this file "TopHubbers 2.03b.lua" (14.69 KB) don't work for me.
Please help me, where can i download this file?
Thanks in advance!
Fixed, should work now :D
Quote from: Psycho_Chihuahua on 16 October, 2009, 20:07:12
Fixed, should work now :D
Great thanks for the fixing :D
I was download and try the last updated script "TopHubbers 2.03b.lua", but i get this error message in PtokaX 0.4.1.1 when tick the script:
[08:19] Syntax D:\PtokaX 0.4.1.1 Last\0.4.1.1\scripts\TopHubbers 2.03b.lua:128: '}' expected (to close '{' at line 51) near 'tOnline'
::)
changing Line 77 from
tProfiles = { [-1] = 0, [0] = 1, [1] = 1, [2] = 1, [3] = 1,
to
tProfiles = { [-1] = 0, [0] = 1, [1] = 1, [2] = 1, [3] = 1, }
should fix that problem, not tested but it looks better in notepad++ tht way ;)
Quote from: Psycho_Chihuahua on 18 October, 2009, 08:12:10
changing Line 77 from
tProfiles = { [-1] = 0, [0] = 1, [1] = 1, [2] = 1, [3] = 1,
to
tProfiles = { [-1] = 0, [0] = 1, [1] = 1, [2] = 1, [3] = 1, }
should fix that problem, not tested but it looks better in notepad++ tht way ;)
Now get me this:
[09:16] Syntax D:\PtokaX 0.4.1.1 Last\0.4.1.1\scripts\TopHubbers 2.03b.lua:80: '}' expected (to close '{' at line 51) near 'sCriteria'
ok try this
--[[
TopHubbers 2.03b - LUA 5.1.2 [Strict][API 2] by jiten
????????????????????????????????????????????????????
Based on: OnHub Time Logger 1.65 by chill and Robocop's layout
Usage: !tophubbers; !tophubbers x-y; !hubtime <nick>; !myhubtime
CHANGELOG:
??????????
Fixed: Typo in table.sort function;
Added: OnExit (3/21/2006)
Fixed: Missing pairs() in SaveToFile
Changed: Removed iGlobalTime and added TotalTime count to OnTimer
Changed: SecondsToTime function values (3/24/2006)
Changed: math.floor/mod in TopHubbers' function; (3/5/2006)
Changed: SecondsToTime month value (4/17/2006);
Added: !hubtime <nick> - requested by speedX;
Changed: SecondsToTime function and small code bits (8/16/2006)
Changed: Table indexes;
Changed: SecondsToTime function to MinutesToTime;
Fixed: Inaccurate average uptime stuff (8/17/2006)
Changed: Average uptime function;
Changed: Session time for offline users doesn't get reset;
Added: Average uptime warning on connect - requested by speedX (8/20/2006)
Added: Customized profiles - requested by Naithif (8/20/2006)
Added: User Commands - requested by TT;
Added: Rankings and related commands [!myrank & !topranks] - requested by speedX;
Added: Toggle rank info on connect - requested by TT;
Fixed: !tophubbers x-y;
Added: Comments to the code;
Changed: Some code bits;
Added: Toggle between total and average uptime (8/24/2006)
Fixed: Minimum average uptime warning - reported by speedX;
Added: Maximum shown hubbers - requested by Naithif (8/29/2006)
Fixed: LUA 5.0/5.1 compatibility - reported by speedX (11/8/2006)
Added: string.lower check - requested by SwapY and speedX (11/10/2006)
Changed: Script converted to API 2 (11/24/2007)
Fixed: Changed Serialize function (12/23/2007)
+Changes from 2.03a 07/26/09
Added: Send messages in PM (01/22/2008) by speedX
Added: Timer to save data on regular intervals (07/18/2008) by speedX
Added: Kick user below Minimum Average uptime (iMin) (6/20/2009) by merlin_xl54-CrazyGuy
Added: Table to exclude certain nicks from kick (tExc) (6/24/2009) by merlin_xl54-CrazyGuy
Added: Show total years added in displayed times (7/26/2009) by speedX
]]--
tSettings = {
-- Bot Name
sBot = SetMan.GetString(21),
-- Top Hubbers' DB
fOnline = "scripts/tOnliners.tbl",
-- RightClick Menu
sMenu = "Top Hubbers",
-- Maximum hubbers to show when using !tophubbers
iMax = 15,
-- Send message to users with lower than specified Average uptime (AUT) [true = on; false = off]
bWarning = true,
-- Minimum Average uptime (hours) that triggers the warning
iAUT = 12,
-- Minimum Average uptime (hours) that triggers the kick [Disable = 0]
iMin = 2,
-- Send hubtime stats on connect [true = on; false = off]
bRankOnConnect = false,
-- Profiles checked [0 = off; 1 = on]
tProfiles = { [-1] = 0, [0] = 1, [1] = 1, [2] = 1, [3] = 1, },
-- Ranks criteria ["average" = Average total uptime; "total" = Total uptime]
sCriteria = "average",
-- Reply in PM ?
sPmOnly = true,
-- Set your interval time to save data(in Hours)
iInterval = "24",
--Exclude from kick
tExc = {
["merlin_xl54"] = true,
["yournickhere"] = true,
},
-- Ranks
tRanks = {
--[[
The ranks must be added in ascending order [from the lowest to the highest]
{ "Rank", [time][string] }
[time] must be 1 or more digit(s)
[string] must be: s = second; m = minute; h = hour; D = day; W = week; M = month; Y = year
Example: { "God", "1M, 2D, 10s" }
Meaning: To become a God, your total uptime must be equal or higher than 1 month, 2 days and 10 seconds
]]--
-- Total uptime rank table
total = {
{ "Newbie", "1D, 1h, 1m, 1s" }, { "Member", "2D" }, { "Cool Member", "5D" },
{ "Hub As", "10D" }, { "Smart As", "20D" }, { "Double As", "1M" },
{ "Triple As", "2M" }, { "Conqueror", "3M" }, { "Viking", "4M" },
{ "King", "6M" }, { "Emperor", "8M" }, { "Hub Legend", "10M" },
{ "Hub God", "11M" }, { "God", "1Y, 1h, 1m, 1s" },
},
-- Daily average uptime rank table
average = {
{ "Newbie", "1h" }, { "Member", "6h" }, { "Cool Member", "12h" },
{ "Hub-As", "1D" }, { "Smart As", "5D" }, { "Double-As", "15D" },
{ "Triple-As", "1M" }, { "Conqueror", "2M" }, { "Viking", "3M" },
{ "King", "4M" }, { "Emperor", "6M" }, { "Hub Legend", "9M" },
{ "Hub God", "11M" }, { "God", "1Y" },
},
},
}
tOnline = {}
OnStartup = function()
-- Register BotName if not registered
if tSettings.sBot ~= SetMan.GetString(21) then Core.RegBot(tSettings.sBot,"","",true) end
-- Load DB content
if loadfile(tSettings.fOnline) then dofile(tSettings.fOnline) end
-- Set and Start Timer
tSettings.iTimer = TmrMan.AddTimer(60*1000)
--Save Data Interval
tSettings.SaveData = TmrMan.AddTimer(tSettings.iInterval*60*60*1000)
end
OnTimer = function(iID)
if tSettings.iTimer and iID == tSettings.iTimer then
-- For each hubber
for i, v in pairs(tOnline) do
-- Online
if Core.GetUser(i) then
-- Sum
v.SessionTime = v.SessionTime + 1; v.TotalTime = v.TotalTime + 1
end
end
elseif tSettings.SaveData and iID == tSettings.SaveData then
local hFile = io.open(tSettings.fOnline, "w+") Serialize(tOnline, "tOnline", hFile); hFile:close()
end
end
OnExit = function()
-- Save
local hFile = io.open(tSettings.fOnline, "w+") Serialize(tOnline, "tOnline", hFile); hFile:close()
end
UserConnected = function(user)
-- If profile has permission to be logged
if tSettings.tProfiles[user.iProfile] and tSettings.tProfiles[user.iProfile] == 1 then
local tNick = GetOnliner(user.sNick)
-- User already in DB
if tNick then
-- Warning on connect
if tSettings.bWarning then
-- Days since first login
local iAverage = os.difftime(os.time(os.date("!*t")), tNick.Julian)/(60*60*24)
if iAverage < 1 then iAverage = 1 end
-- Less than allowed
if tNick.TotalTime/iAverage < tSettings.iMin*60 then
-- Kick if not excluded
if not tSettings.tExc[user.sNick] then
-- Add any custom message to kick
Core.Kick(user, tSettings.sBot, "*** Your Average uptime (AUT) is less than "..tSettings.iMin..
" hour(s). Please post to our forum before you try to connect again!")
end
end
-- Warn if not kicked
if tNick.TotalTime/iAverage < tSettings.iAUT*60 then
-- Add any custom message to warning
Core.SendPmToNick(user.sNick, tSettings.sBot, "*** Your Average uptime (AUT) is less than "..tSettings.iAUT..
" hour(s). Users above this average will be considered for VIP, and may log in when the Hub is full!")
end
--Warn if between iMin & iAUT and excluded from kick
else
if tNick.TotalTime/iAverage < tSettings.iAUT*60 then
if tNick.TotalTime/iAverage > tSettings.iMin*60 then
if tSettings.tExc[user.sNick] then
-- Add any custom message to warning
Core.SendPmToNick(user.sNick, tSettings.sBot, "*** Your Average uptime (AUT) is less than "..tSettings.iAUT..
" hour(s). Users above this average will be considered for VIP, and may log in when the Hub is full!")
end
end
end
end
-- Reset and save time
tNick.SessionTime = 0; tNick.Enter = os.date()
-- Send rank info on connect
if tSettings.bRankOnConnect then tCommands["myhubtime"].fFunction(user) end
else
-- Create new entry
tOnline[user.sNick] = { Julian = os.time(os.date("!*t")), Enter = os.date(), SessionTime = 0, TotalTime = 0, Leave = os.date() }
end
end
-- Supports UserCommands
if Core.GetUserValue(user,12) then
-- For each entry in table
for i, v in pairs(tCommands) do
-- If member
if v.tLevels[user.iProfile] then
-- For each type
for n in ipairs(v.tRC) do
-- Send
Core.SendToNick(user.sNick, "$UserCommand 1 3 "..tSettings.sMenu.."\\"..v.tRC[n][1]..
"$<%[mynick]> !"..i..v.tRC[n][2].."|")
end
end
end
end
end
OpConnected = UserConnected
RegConnected = UserConnected
UserDisconnected = function(user)
local tNick = GetOnliner(user.sNick)
-- If profile must be logged and user is in DB
if tSettings.tProfiles[user.iProfile] and tSettings.tProfiles[user.iProfile] == 1 and tNick then
-- Log date
tNick.Leave = os.date()
end
end
OpDisconnected = UserDisconnected
RegDisconnected = UserDisconnected
ChatArrival = function(user,data)
local _,_, to = data:find("^$To:%s(%S+)%s+From:")
local _,_, msg = data:find("%b<>%s(.*)|$")
-- Message sent to Bot or in Main
if (to and to == tSettings.sBot) or not to then
-- Parse command
local _,_, cmd = msg:find("^%p(%S+)")
-- Exists
if cmd and tCommands[cmd:lower()] then
cmd = cmd:lower()
-- If user has permission
if tCommands[cmd].tLevels[user.iProfile] then
if to and to == tSettings.sBot then
return Core.SendPmToNick(user.sNick, tSettings.sBot, tCommands[cmd].fFunction(user, msg)), true
else
if tSettings.sPmOnly then
return Core.SendPmToNick(user.sNick, tSettings.sBot, tCommands[cmd].fFunction(user, msg)), true
else
return Core.SendToNick(user.sNick, "<"..tSettings.sBot.."> "..tCommands[cmd].fFunction(user, msg)), true
end
end
else
if to and to == tSettings.sBot then
return Core.SendPmToNick(user.sNick, tSettings.sBot, "*** Error: You are not allowed to use this command!"), true
else
return Core.SendToNick(user.sNick, "<"..tSettings.sBot.."> *** Error: You are not allowed to use this command!"), true
end
end
end
end
end
ToArrival = ChatArrival
tCommands = {
tophubbers = {
fFunction = function(user, data)
-- Table isn't empty
if next(tOnline) then
-- Parse limits
local _,_, iStart, iEnd = data:find("^%S+%s+(%d+)%-(%d+)$")
-- Set if not set
iStart, iEnd = (iStart or 1), (iEnd or tSettings.iMax)
-- Header
local tCopy, msg = {}, "\r\n\t"..string.rep("=", 137).."\r\n\tNr. Total:\t\t\t\t\tSession:\t"..
"Entered Hub:\tLeft Hub:\t\tRank:\t\tStatus:\tName:\r\n\t"..string.rep("-", 240).."\r\n"
-- Loop through hubbers
for i, v in pairs(tOnline) do
-- Insert stats to temp table
table.insert(tCopy, { sEnter = v.Enter, iSessionTime = tonumber(v.SessionTime),
iTotalTime = tonumber(v.TotalTime), sLeave = v.Leave, sNick = i, sRank = GetRank(i) } )
end
-- Sort by total time
table.sort(tCopy, function(a, b) return (a.iTotalTime > b.iTotalTime) end)
-- Loop through temp table
for i = iStart, iEnd, 1 do
-- i exists
if tCopy[i] then
-- Populate
local sStatus, v = "*Offline*", tCopy[i]; local sRank = v.sRank
if Core.GetUser(v.sNick) then sStatus = "*Online*" end
if v.sRank:len() < 9 then sRank = sRank.."\t" end
msg = msg.."\t"..i..". "..MinutesToTime(v.iTotalTime).."\t"..v.iSessionTime..
" min\t"..v.sEnter.."\t"..v.sLeave.."\t"..sRank.."\t"..sStatus.."\t"..v.sNick.."\r\n"
end
end
msg = msg.."\t"..string.rep("-", 240)
-- Send
return "Current Top Hubbers:\r\n"..msg.."\r\n"
else
return "*** Error: Top Hubbers' table is currently empty!"
end
end,
tLevels = {
[-1] = 0, [0] = 1, [1] = 1, [2] = 1, [3] = 1,
},
tRC = { { "Show Top "..tSettings.iMax.." Hubbers", "" }, { "Show Top x-y Hubbers", " %[line:x-y]" } }
},
hubtime = {
fFunction = function(user, data)
-- Parse nick
local _,_, nick = data:find("^%S+%s+(%S+)$")
-- Exists
if nick then
-- Return
return BuildStats(user, nick)
else
return "*** Syntax Error: Type !hubtime <nick>"
end
end,
tLevels = {
[-1] = 0, [0] = 1, [1] = 1, [2] = 1, [3] = 1,
},
tRC = { { "Show a User's Stats", " %[line:Nick]" } }
},
myhubtime = {
fFunction = function(user)
-- Return
return BuildStats(user, user.sNick)
end,
tLevels = {
[-1] = 0, [0] = 1, [1] = 1, [2] = 1, [3] = 1,
},
tRC = { { "Show My Stats", "" } }
},
}
BuildStats = function(user, nick)
local tNick = GetOnliner(nick)
-- In DB
if tNick then
-- Average uptime in days
local iAverage = os.difftime(os.time(os.date("!*t")), tNick.Julian)/(60*60*24)
if iAverage < 1 then iAverage = 1 end
-- Generate message
local sMsg = "\r\n\r\n\t"..string.rep("=", 51).."\r\n\t\t\tStats:\r\n\t"..
string.rep("-", 89).."\r\n\t- Nick: "..nick.."\r\n\t- Total uptime: "..
MinutesToTime(tNick.TotalTime, true).."\r\n\t- Daily average uptime (AUT): "..
MinutesToTime((tNick.TotalTime/iAverage), true).."\r\n\t- Current Rank: "..GetRank(nick).."\r\n"
-- Send stats
--Add any custom message
return "Here are the stats you requested for "..nick..". Remember, users with over "..tSettings.iAUT.." hour(s) (AUT) will be considered for VIP and may bypass the Hub full rule. Those below "..tSettings.iMin.." hour(s) (AUT) will be disconnected!" ..sMsg
else
return "*** Error: No record found for '"..nick.."'!"
end
end
GetRank = function(nick)
local tNick = GetOnliner(nick)
if tNick then
-- Custom time table
local tTime, sRank, iAverage = { s = 1/60, m = 1, h = 60, D = 60*24, W = 60*24*7, M = 60*24*30, Y = 60*24*30*12 }, tSettings.tRanks[tSettings.sCriteria:lower()][1][1]
-- Average enabled
if tSettings.bAverage then
-- Days since first login
iAverage = os.difftime(os.time(os.date("!*t")), tNick.Julian)/(60*60*24)
if iAverage < 1 then iAverage = 1 end
end
-- For each rank
for n in ipairs(tSettings.tRanks[tSettings.sCriteria:lower()]) do
local iTime = 0
-- For each digit and time string
for i, v in tSettings.tRanks[string.lower(tSettings.sCriteria)][n][2]:gmatch("(%d+)(%w)") do
-- Process
if i and tTime[v] then iTime = iTime + i*tTime[v] end
end
local iValue = tNick.TotalTime
-- Average
if tSettings.bAverage then iValue = iValue/iAverage end
-- Process rank if user hasn't logged in for the first time today
if os.date("%d%m%y", tNick.Julian) ~= os.date("%d%m%y") and iValue > iTime then
sRank = tSettings.tRanks[tSettings.sCriteria:lower()][n][1]
end
end
return sRank
end
end
MinutesToTime = function(iSeconds, bSmall)
-- Build table with time fields
local T = os.date("!*t", tonumber(iSeconds*60));
-- Format to string
local sTime = string.format("%i year(s), %i month(s), %i day(s), %i hour(s), %i minute(s)", T.year-1970, T.month-1, T.day-1, T.hour, T.min)
-- Small stat?
if bSmall then
-- For each digit
for i in sTime:gmatch("%d+") do
-- Reduce if is preceeded by 0
if tonumber(i) == 0 then sTime = sTime:gsub("^"..i.."%s(%S+),%s", "") end
end
end
-- Return
return sTime
end
GetOnliner = function(user)
-- For each hubber
for i, v in pairs(tOnline) do
-- Compare
if i:lower() == user:lower() then
-- Return
return tOnline[i]
end
end
end
Serialize = function(tTable, sTableName, hFile, sTab)
sTab = sTab or "";
hFile:write(sTab..sTableName.." = {\n");
for key, value in pairs(tTable) do
if (type(value) ~= "function") then
local sKey = (type(key) == "string") and string.format("[%q]", key) or string.format("[%d]", key);
if(type(value) == "table") then
Serialize(value, sKey, hFile, sTab.."\t");
else
local sValue = (type(value) == "string") and string.format("%q", value) or tostring(value);
hFile:write(sTab.."\t"..sKey.." = "..sValue);
end
hFile:write(",\n");
end
end
hFile:write(sTab.."}");
end
now is OK :D
Thanks a lot
Best Regards
I would like to have a function which returns numeric rank of the user on command +hubtime like the script which is posted on the 4th page of Top-Hubbers script in Lua 5.1 Finished Scripts section.
http://forum.ptokax.org/index.php?topic=5860.msg68904#msg68904
What is mean this message when i check for syntax:
Syntax [string "--[[..."]:53: attempt to index global 'SetMan' (a nil value)
This is on "TopHubbers 2.03b.lua"
The PtokaX is in running state and i load the file in the scripts editor window, then click on Check Syntax button.
:-\
On this last script posted, i get:
429: attempt to index local 'hFile' (a nil value)
try to create manually stats file - scripts/tOnliners.tbl
i have this error in scripts log:
Top_Hubbers2.03.lua:189: attempt to perform arithmetic on global 'iAverage' (a nil value)
looks like everything work fine except i dont see script menu in hub right click
edit: i figure out why script is not visible in right click. it is when bWarning = false
anyone can fix it?
Quote from: The Undertaker on 10 January, 2010, 06:53:19
try to create manually stats file - scripts/tOnliners.tbl
i have this error in scripts log:
Top_Hubbers2.03.lua:189: attempt to perform arithmetic on global 'iAverage' (a nil value)
looks like everything work fine except i dont see script menu in hub right click
edit: i figure out why script is not visible in right click. it is when bWarning = false
anyone can fix it?
Try this. I never tested it with bWarning false. I'm not the best at coding :-[
works :-*
That script wont work.
I get Syntax [string "--[[..."]:54: attempt to index global 'SetMan' (a nil value)
Quote from: Dreams on 11 January, 2010, 18:06:05
That script wont work.
I get Syntax [string "--[[..."]:54: attempt to index global 'SetMan' (a nil value)
Can you at least add some more information. Perhaps what you have on line 54? etc...
I use it on 0.4.1.1 without issue.
So i didnt bother, but now i have tested this script a bit more, and this is what doesnt work for me:
* Everytime i change something in the Tophubbers script, i have to reset the profiles several times in ptokax, otherwise it aint workin.
* The tLevels that is set for the RC commands aint workin, ex: even if i set all profiles on Show A Users Stats to 0, i can still show it in the RC on every profile in the ptokax.
And something i was thinking about.
How do i set the Kick Trigger to a specific date? the users should have atleast 2-3 weeks to fullfill the 25h a month without getting kicked out the first time they login.
And i get this error on startup 429: attempt to index local 'hFile' (a nil value)
Quote from: Dreams on 16 January, 2010, 11:20:17
* Everytime i change something in the Tophubbers script, i have to reset the profiles several times in ptokax, otherwise it aint workin.
Not sure about that?
Quote
* The tLevels that is set for the RC commands aint workin, ex: even if i set all profiles on Show A Users Stats to 0, i can still show it in the RC on every profile in the ptokax.
If you're using the new PtokaX set them to true/false
Quote
And something i was thinking about.
How do i set the Kick Trigger to a specific date? the users should have atleast 2-3 weeks to fullfill the 25h a month without getting kicked out the first time they login.
The warning/kick is for daily average uptimes...
Alright :) i understand now.
But is there a way to remove the kick and add a delreg instead that delregs in the end of the month on the total time?
Or just adding a kick in the end of the month on the total time?
just a thought i had, would be nice if possible.
Regards //Dreams
Anyone who can get this script to work.
I just cant get it to work, yesterday it worked, today it is not working.
I dont know how to make it work, im using ptokax 0.4.1.2
Some days it works.. and some not.
I can use the RightClicks, but it wont send the Warning on login.
Ill post the whole script so that anyone can look at it.
Quote from: Dreams on 20 January, 2010, 14:31:22
Anyone who can get this script to work.
I can use the RightClicks, but it wont send the Warning on login.
Ill post the whole script so that anyone can look at it.
As I said before, the warning/kick is for "Daily" average up times. You have 25 as the trigger. Our Hub is set to 14. Any user who's average uptime is under 14 hours (Per day), gets a warning upon connect.
M
Quote from: DeAn on 18 October, 2009, 14:45:05
I would like to have a function which returns numeric rank of the user on command +hubtime
try this....
--[[
TopHubbers 2.03b - LUA 5.1.2 [Strict][API 2] by jiten
????????????????????????????????????????????????????
Based on: OnHub Time Logger 1.65 by chill and Robocop's layout
Usage: !tophubbers; !tophubbers x-y; !hubtime <nick>; !myhubtime
CHANGELOG:
??????????
Fixed: Typo in table.sort function;
Added: OnExit (3/21/2006)
Fixed: Missing pairs() in SaveToFile
Changed: Removed iGlobalTime and added TotalTime count to OnTimer
Changed: SecondsToTime function values (3/24/2006)
Changed: math.floor/mod in TopHubbers' function; (3/5/2006)
Changed: SecondsToTime month value (4/17/2006);
Added: !hubtime <nick> - requested by speedX;
Changed: SecondsToTime function and small code bits (8/16/2006)
Changed: Table indexes;
Changed: SecondsToTime function to MinutesToTime;
Fixed: Inaccurate average uptime stuff (8/17/2006)
Changed: Average uptime function;
Changed: Session time for offline users doesn't get reset;
Added: Average uptime warning on connect - requested by speedX (8/20/2006)
Added: Customized profiles - requested by Naithif (8/20/2006)
Added: User Commands - requested by TT;
Added: Rankings and related commands [!myrank & !topranks] - requested by speedX;
Added: Toggle rank info on connect - requested by TT;
Fixed: !tophubbers x-y;
Added: Comments to the code;
Changed: Some code bits;
Added: Toggle between total and average uptime (8/24/2006)
Fixed: Minimum average uptime warning - reported by speedX;
Added: Maximum shown hubbers - requested by Naithif (8/29/2006)
Fixed: LUA 5.0/5.1 compatibility - reported by speedX (11/8/2006)
Added: string.lower check - requested by SwapY and speedX (11/10/2006)
Changed: Script converted to API 2 (11/24/2007)
Fixed: Changed Serialize function (12/23/2007)
+Changes from 2.03a 07/26/09
Added: Send messages in PM (01/22/2008) by speedX
Added: Timer to save data on regular intervals (07/18/2008) by speedX
Added: Kick user below Minimum Average uptime (iMin) (6/20/2009) by merlin_xl54-CrazyGuy
Added: Table to exclude certain nicks from kick (tExc) (6/24/2009) by merlin_xl54-CrazyGuy
Added: Show total years added in displayed times (7/26/2009) by speedX
]]--
tSettings = {
-- Bot Name
sBot = SetMan.GetString(21),
-- Top Hubbers' DB
fOnline = "scripts/tOnliners.tbl",
-- RightClick Menu
sMenu = "Top Hubbers",
-- Maximum hubbers to show when using !tophubbers
iMax = 15,
-- Send message to users with lower than specified Average uptime (AUT) [true = on; false = off]
bWarning = true,
-- Minimum Average uptime (hours) that triggers the warning
iAUT = 12,
-- Minimum Average uptime (hours) that triggers the kick [Disable = 0]
iMin = 0,
-- Send hubtime stats on connect [true = on; false = off]
bRankOnConnect = false,
-- Profiles checked [0 = off; 1 = on]
tProfiles = { [-1] = 0, [0] = 1, [1] = 1, [2] = 1, [3] = 1, },
-- Ranks criteria ["average" = Average total uptime; "total" = Total uptime]
sCriteria = "average",
-- Reply in PM ?
bPmOnly = true,
-- Set your interval time to save data(in Hours)
iInterval = 24,
--Exclude from kick
tExc = {
["merlin_xl54"] = true,
["yournickhere"] = true,
},
-- Ranks
tRanks = {
--[[
The ranks must be added in ascending order [from the lowest to the highest]
{ "Rank", [time][string] }
[time] must be 1 or more digit(s)
[string] must be: s = second; m = minute; h = hour; D = day; W = week; M = month; Y = year
Example: { "God", "1M, 2D, 10s" }
Meaning: To become a God, your total uptime must be equal or higher than 1 month, 2 days and 10 seconds
]]--
-- Total uptime rank table
total = {
{ "Newbie", "1D, 1h, 1m, 1s" }, { "Member", "2D" }, { "Cool Member", "5D" },
{ "Hub As", "10D" }, { "Smart As", "20D" }, { "Double As", "1M" },
{ "Triple As", "2M" }, { "Conqueror", "3M" }, { "Viking", "4M" },
{ "King", "6M" }, { "Emperor", "8M" }, { "Hub Legend", "10M" },
{ "Hub God", "11M" }, { "God", "1Y, 1h, 1m, 1s" },
},
-- Daily average uptime rank table
average = {
{ "Newbie", "1h" }, { "Member", "6h" }, { "Cool Member", "12h" },
{ "Hub-As", "1D" }, { "Smart As", "5D" }, { "Double-As", "15D" },
{ "Triple-As", "1M" }, { "Conqueror", "2M" }, { "Viking", "3M" },
{ "King", "4M" }, { "Emperor", "6M" }, { "Hub Legend", "9M" },
{ "Hub God", "11M" }, { "God", "1Y" },
},
},
}
tOnline = {}
OnStartup = function()
-- Register BotName if not registered
if tSettings.sBot ~= SetMan.GetString(21) then Core.RegBot(tSettings.sBot,"","",true) end
-- Load DB content
if loadfile(tSettings.fOnline) then dofile(tSettings.fOnline) end
-- Set and Start Timer
tSettings.iTimer = TmrMan.AddTimer(60*1000)
--Save Data Interval
tSettings.SaveData = TmrMan.AddTimer(tSettings.iInterval*60*60*1000)
end
OnTimer = function(iID)
if tSettings.iTimer and iID == tSettings.iTimer then
-- For each hubber
for i, v in pairs(tOnline) do
-- Online
if Core.GetUser(i) then
-- Sum
v.SessionTime = v.SessionTime + 1; v.TotalTime = v.TotalTime + 1
end
end
elseif tSettings.SaveData and iID == tSettings.SaveData then
local hFile = io.open(tSettings.fOnline, "w+") Serialize(tOnline, "tOnline", hFile); hFile:close()
end
end
OnExit = function()
-- Save
local hFile = io.open(tSettings.fOnline, "w+") Serialize(tOnline, "tOnline", hFile); hFile:close()
end
UserConnected = function(user)
-- If profile has permission to be logged
if tSettings.tProfiles[user.iProfile] and tSettings.tProfiles[user.iProfile] == 1 then
local tNick = GetOnliner(user.sNick)
-- User already in DB
if tNick then
-- Warning on connect
if tSettings.bWarning then
-- Days since first login
local iAverage = os.difftime(os.time(os.date("!*t")), tNick.Julian)/(60*60*24)
if iAverage < 1 then iAverage = 1 end
-- Less than allowed
if tNick.TotalTime/iAverage < tSettings.iMin*60 then
-- Kick if not excluded
if not tSettings.tExc[user.sNick] then
-- Add any custom message to kick
Core.Kick(user, tSettings.sBot, "*** Your Average uptime (AUT) is less than "..tSettings.iMin..
" hour(s). Please post to our forum before you try to connect again!")
end
end
-- Warn if not kicked
if tNick.TotalTime/iAverage < tSettings.iAUT*60 then
-- Add any custom message to warning
Core.SendPmToNick(user.sNick, tSettings.sBot, "*** Your Average uptime (AUT) is less than "..tSettings.iAUT..
" hour(s). Users above this average will be considered for VIP, and may log in when the Hub is full!")
end
--Warn if between iMin & iAUT and excluded from kick
else
if tNick.TotalTime/iAverage < tSettings.iAUT*60 then
if tNick.TotalTime/iAverage > tSettings.iMin*60 then
if tSettings.tExc[user.sNick] then
-- Add any custom message to warning
Core.SendPmToNick(user.sNick, tSettings.sBot, "*** Your Average uptime (AUT) is less than "..tSettings.iAUT..
" hour(s). Users above this average will be considered for VIP, and may log in when the Hub is full!")
end
end
end
end
-- Reset and save time
tNick.SessionTime = 0; tNick.Enter = os.date()
-- Send rank info on connect
if tSettings.bRankOnConnect then tCommands["myhubtime"].fFunction(user) end
else
-- Create new entry
tOnline[user.sNick] = { Julian = os.time(os.date("!*t")), Enter = os.date(), SessionTime = 0, TotalTime = 0, Leave = os.date() }
end
end
-- Supports UserCommands
if Core.GetUserValue(user,12) then
-- For each entry in table
for i, v in pairs(tCommands) do
-- If member
if v.tLevels[user.iProfile] then
-- For each type
for n in ipairs(v.tRC) do
-- Send
Core.SendToNick(user.sNick, "$UserCommand 1 3 "..tSettings.sMenu.."\\"..v.tRC[n][1]..
"$<%[mynick]> !"..i..v.tRC[n][2].."|")
end
end
end
end
end
OpConnected = UserConnected
RegConnected = UserConnected
UserDisconnected = function(user)
local tNick = GetOnliner(user.sNick)
-- If profile must be logged and user is in DB
if tSettings.tProfiles[user.iProfile] and tSettings.tProfiles[user.iProfile] == 1 and tNick then
-- Log date
tNick.Leave = os.date()
end
end
OpDisconnected = UserDisconnected
RegDisconnected = UserDisconnected
ChatArrival = function(user,data)
local _,_, to = data:find("^$To:%s(%S+)%s+From:")
local _,_, msg = data:find("%b<>%s(.*)|$")
-- Message sent to Bot or in Main
if (to and to == tSettings.sBot) or not to then
-- Parse command
local _,_, cmd = msg:find("^%p(%S+)")
-- Exists
if cmd and tCommands[cmd:lower()] then
cmd = cmd:lower()
-- If user has permission
if tCommands[cmd].tLevels[user.iProfile] then
if to and to == tSettings.sBot then
return Core.SendPmToNick(user.sNick, tSettings.sBot, tCommands[cmd].fFunction(user, msg)), true
else
if tSettings.bPmOnly then
return Core.SendPmToNick(user.sNick, tSettings.sBot, tCommands[cmd].fFunction(user, msg)), true
else
return Core.SendToNick(user.sNick, "<"..tSettings.sBot.."> "..tCommands[cmd].fFunction(user, msg)), true
end
end
else
if to and to == tSettings.sBot then
return Core.SendPmToNick(user.sNick, tSettings.sBot, "*** Error: You are not allowed to use this command!"), true
else
return Core.SendToNick(user.sNick, "<"..tSettings.sBot.."> *** Error: You are not allowed to use this command!"), true
end
end
end
end
end
ToArrival = ChatArrival
tCommands = {
tophubbers = {
fFunction = function(user, data)
-- Table isn't empty
if next(tOnline) then
-- Parse limits
local _,_, iStart, iEnd = data:find("^%S+%s+(%d+)%-(%d+)$")
-- Set if not set
iStart, iEnd = (iStart or 1), (iEnd or tSettings.iMax)
-- Header
local tCopy, msg = {}, "\r\n\t"..string.rep("=", 137).."\r\n\tNr. Total:\t\t\t\t\tSession:\t"..
"Entered Hub:\tLeft Hub:\t\tRank:\t\tStatus:\tName:\r\n\t"..string.rep("-", 240).."\r\n"
-- Loop through hubbers
for i, v in pairs(tOnline) do
-- Insert stats to temp table
table.insert(tCopy, { sEnter = v.Enter, iSessionTime = tonumber(v.SessionTime),
iTotalTime = tonumber(v.TotalTime), sLeave = v.Leave, sNick = i, sRank = GetRank(i) } )
end
-- Sort by total time
table.sort(tCopy, function(a, b) return (a.iTotalTime > b.iTotalTime) end)
-- Loop through temp table
for i = iStart, iEnd, 1 do
-- i exists
if tCopy[i] then
-- Populate
local sStatus, v = "*Offline*", tCopy[i]; local sRank = v.sRank
if Core.GetUser(v.sNick) then sStatus = "*Online*" end
if v.sRank:len() < 9 then sRank = sRank.."\t" end
msg = msg.."\t"..i..". "..MinutesToTime(v.iTotalTime).."\t"..v.iSessionTime..
" min\t"..v.sEnter.."\t"..v.sLeave.."\t"..sRank.."\t"..sStatus.."\t"..v.sNick.."\r\n"
end
end
msg = msg.."\t"..string.rep("-", 240)
-- Send
return "Current Top Hubbers:\r\n"..msg.."\r\n"
else
return "*** Error: Top Hubbers' table is currently empty!"
end
end,
tLevels = {
[-1] = 0, [0] = 1, [1] = 1, [2] = 1, [3] = 1,
},
tRC = { { "Show Top "..tSettings.iMax.." Hubbers", "" }, { "Show Top x-y Hubbers", " %[line:x-y]" } }
},
hubtime = {
fFunction = function(user, data)
-- Parse nick
local _,_, nick = data:find("^%S+%s+(%S+)$")
-- Exists
if nick then
-- Return
return BuildStats(user, nick)
else
return "*** Syntax Error: Type !hubtime <nick>"
end
end,
tLevels = {
[-1] = 0, [0] = 1, [1] = 1, [2] = 1, [3] = 1,
},
tRC = { { "Show a User's Stats", " %[line:Nick]" } }
},
myhubtime = {
fFunction = function(user)
-- Return
return BuildStats(user, user.sNick)
end,
tLevels = {
[-1] = 0, [0] = 1, [1] = 1, [2] = 1, [3] = 1,
},
tRC = { { "Show My Stats", "" } }
},
}
BuildStats = function(user, nick)
local tNick = GetOnliner(nick)
-- In DB
if tNick then
-- Average uptime in days
local iAverage = os.difftime(os.time(os.date("!*t")), tNick.Julian)/(60*60*24)
if iAverage < 1 then iAverage = 1 end
-- Generate message
local sMsg = "\r\n\r\n\t"..string.rep("=", 51).."\r\n\t\t\tStats:\r\n\t"..
string.rep("-", 89).."\r\n\t- Nick: "..nick.."\r\n\t- Total uptime: "..
MinutesToTime(tNick.TotalTime, true).."\r\n\t- Daily average uptime (AUT): "..
MinutesToTime((tNick.TotalTime/iAverage), true).."\r\n\t- Status: "..GetRank(nick).." Rank: "..GetNumber(nick).."\r\n"
-- Send stats
--Add any custom message
return "Here are the stats you requested for "..nick..". Remember, users with over "..tSettings.iAUT.." hour(s) (AUT) will be considered for VIP and may bypass the Hub full rule. Those below "..tSettings.iMin.." hour(s) (AUT) will be disconnected!" ..sMsg
else
return "*** Error: No record found for '"..nick.."'!"
end
end
GetRank = function(nick)
local tNick = GetOnliner(nick)
if tNick then
-- Custom time table
local tTime, sRank, iAverage = { s = 1/60, m = 1, h = 60, D = 60*24, W = 60*24*7, M = 60*24*30, Y = 60*24*30*12 }, tSettings.tRanks[tSettings.sCriteria:lower()][1][1]
-- Average enabled
if tSettings.bAverage then
-- Days since first login
iAverage = os.difftime(os.time(os.date("!*t")), tNick.Julian)/(60*60*24)
if iAverage < 1 then iAverage = 1 end
end
-- For each rank
for n in ipairs(tSettings.tRanks[tSettings.sCriteria:lower()]) do
local iTime = 0
-- For each digit and time string
for i, v in tSettings.tRanks[string.lower(tSettings.sCriteria)][n][2]:gmatch("(%d+)(%w)") do
-- Process
if i and tTime[v] then iTime = iTime + i*tTime[v] end
end
local iValue = tNick.TotalTime
-- Average
if tSettings.bAverage then iValue = iValue/iAverage end
-- Process rank if user hasn't logged in for the first time today
if os.date("%d%m%y", tNick.Julian) ~= os.date("%d%m%y") and iValue > iTime then
sRank = tSettings.tRanks[tSettings.sCriteria:lower()][n][1]
end
end
return sRank
end
end
GetNumber = function(nick)
if next(tOnline) then
local tCopy,iCount = {},0
for i, v in pairs(tOnline) do
table.insert(tCopy, { iTotalTime = tonumber(v.TotalTime), sNick = i } )
iCount = iCount + 1
end
table.sort(tCopy, function(a, b) return (a.iTotalTime > b.iTotalTime) end)
for i = 1, iCount do
if tCopy[i] then
local v = tCopy[i]
if v.sNick:lower() == nick:lower() then
return i
end
end
end
end
end
MinutesToTime = function(iSeconds, bSmall)
-- Build table with time fields
local T = os.date("!*t", tonumber(iSeconds*60));
-- Format to string
local sTime = string.format("%i year(s), %i month(s), %i day(s), %i hour(s), %i minute(s)", T.year-1970, T.month-1, T.day-1, T.hour, T.min)
-- Small stat?
if bSmall then
-- For each digit
for i in sTime:gmatch("%d+") do
-- Reduce if is preceeded by 0
if tonumber(i) == 0 then sTime = sTime:gsub("^"..i.."%s(%S+),%s", "") end
end
end
-- Return
return sTime
end
GetOnliner = function(user)
-- For each hubber
for i, v in pairs(tOnline) do
-- Compare
if i:lower() == user:lower() then
-- Return
return tOnline[i]
end
end
end
Serialize = function(tTable, sTableName, hFile, sTab)
sTab = sTab or "";
hFile:write(sTab..sTableName.." = {\n");
for key, value in pairs(tTable) do
if (type(value) ~= "function") then
local sKey = (type(key) == "string") and string.format("[%q]", key) or string.format("[%d]", key);
if(type(value) == "table") then
Serialize(value, sKey, hFile, sTab.."\t");
else
local sValue = (type(value) == "string") and string.format("%q", value) or tostring(value);
hFile:write(sTab.."\t"..sKey.." = "..sValue);
end
hFile:write(",\n");
end
end
hFile:write(sTab.."}");
end
Thanks speedX for your effort. The script is working great. Just one thing I noticed in this is that the right click menu can only be seen by unregistered users. So I checked the profile permissions at the beginning. I changed
-- Profiles checked [0 = off; 1 = on]
tProfiles = { [-1] = 0, [0] = 1, [1] = 1, [2] = 1, [3] = 1, },
to
-- Profiles checked [0 = off; 1 = on]
tProfiles = { [-1] = 0, [0] = 0, [1] = 0, [2] = 0, [3] = 0, },
and now I'm able to see the right click menu. Not a big issue but I got it. Thanks.
Thanks,
DeAn
Quote from: DeAn on 28 March, 2010, 04:05:15
Thanks speedX for your effort. The script is working great. Just one thing I noticed in this is that the right click menu can only be seen by unregistered users. So I checked the profile permissions at the beginning. I changed
-- Profiles checked [0 = off; 1 = on]
tProfiles = { [-1] = 0, [0] = 1, [1] = 1, [2] = 1, [3] = 1, },
to
-- Profiles checked [0 = off; 1 = on]
tProfiles = { [-1] = 0, [0] = 0, [1] = 0, [2] = 0, [3] = 0, },
and now I'm able to see the right click menu. Not a big issue but I got it. Thanks.
Thanks,
DeAn
You've changed what profiles should be checked. The R Click options are set in "tCommands". Try this, it has been changed for the new PtokaX 0.4.1.2
M
--[[
TopHubbers 2.03b - LUA 5.1.2 [Strict][API 2] by jiten
????????????????????????????????????????????????????
Based on: OnHub Time Logger 1.65 by chill and Robocop's layout
Usage: !tophubbers; !tophubbers x-y; !hubtime <nick>; !myhubtime
CHANGELOG:
??????????
Fixed: Typo in table.sort function;
Added: OnExit (3/21/2006)
Fixed: Missing pairs() in SaveToFile
Changed: Removed iGlobalTime and added TotalTime count to OnTimer
Changed: SecondsToTime function values (3/24/2006)
Changed: math.floor/mod in TopHubbers' function; (3/5/2006)
Changed: SecondsToTime month value (4/17/2006);
Added: !hubtime <nick> - requested by speedX;
Changed: SecondsToTime function and small code bits (8/16/2006)
Changed: Table indexes;
Changed: SecondsToTime function to MinutesToTime;
Fixed: Inaccurate average uptime stuff (8/17/2006)
Changed: Average uptime function;
Changed: Session time for offline users doesn't get reset;
Added: Average uptime warning on connect - requested by speedX (8/20/2006)
Added: Customized profiles - requested by Naithif (8/20/2006)
Added: User Commands - requested by TT;
Added: Rankings and related commands [!myrank & !topranks] - requested by speedX;
Added: Toggle rank info on connect - requested by TT;
Fixed: !tophubbers x-y;
Added: Comments to the code;
Changed: Some code bits;
Added: Toggle between total and average uptime (8/24/2006)
Fixed: Minimum average uptime warning - reported by speedX;
Added: Maximum shown hubbers - requested by Naithif (8/29/2006)
Fixed: LUA 5.0/5.1 compatibility - reported by speedX (11/8/2006)
Added: string.lower check - requested by SwapY and speedX (11/10/2006)
Changed: Script converted to API 2 (11/24/2007)
Fixed: Changed Serialize function (12/23/2007)
+Changes from 2.03a 07/26/09
Added: Send messages in PM (01/22/2008) by speedX
Added: Timer to save data on regular intervals (07/18/2008) by speedX
Added: Kick user below Minimum Average uptime (iMin) (6/20/2009) by merlin_xl54-CrazyGuy
Added: Table to exclude certain nicks from kick (tExc) (6/24/2009) by merlin_xl54-CrazyGuy
Added: Show total years added in displayed times (7/26/2009) by speedX
Fixed: Error when bWarning is false (1-10-2010) by merlin_xl54
Update for profile permission changes in PxLua API [version 0.4.1.2 and later] (1/22/2010) by merlin_xl54
Added: Option to return stats by selecting nick in user list (3/1/2010) by merlin_xl54
Added: Numeric rank in the hub stats for total time connected (3/17/2010) by speedX
]]--
tSettings = {
-- Bot Name
sBot = SetMan.GetString(21),
-- Top Hubbers' DB
fOnline = "scripts/tOnliners.tbl",
-- RightClick Menu
sMenu = "Top Hubbers",
-- Maximum hubbers to show when using !tophubbers
iMax = 15,
-- Send message to users with lower than specified Average uptime (AUT) [true = on; false = off]
bWarning = true,
-- Minimum Average uptime (hours) that triggers the warning
iAUT = 12,
-- Minimum Average uptime (hours) that triggers the kick [Disable = 0]
iMin = 0,
-- Send hubtime stats on connect [true = on; false = off]
bRankOnConnect = false,
-- Profiles checked [false = off; true = on]
tProfiles = { [-1] = false, [0] = true, [1] = true, [2] = true, [3] = true, [4] = true },
-- Ranks criteria ["average" = Average total uptime; "total" = Total uptime]
sCriteria = "average",
-- Reply in PM ?
sPmOnly = true,
-- Set your interval time to save data(in Hours)
iInterval = "24",
--Exclude from kick
tExc = {
["yournickhere"] = true,
},
-- Ranks
tRanks = {
--[[
The ranks must be added in ascending order [from the lowest to the highest]
{ "Rank", [time][string] }
[time] must be 1 or more digit(s)
[string] must be: s = second; m = minute; h = hour; D = day; W = week; M = month; Y = year
Example: { "God", "1M, 2D, 10s" }
Meaning: To become a God, your total uptime must be equal or higher than 1 month, 2 days and 10 seconds
]]--
-- Total uptime rank table
total = {
{ "Newbie", "1D, 1h, 1m, 1s" }, { "Member", "2D" }, { "Cool Member", "5D" },
{ "Hub As", "10D" }, { "Smart As", "20D" }, { "Double As", "1M" },
{ "Triple As", "2M" }, { "Conqueror", "3M" }, { "Viking", "4M" },
{ "King", "6M" }, { "Emperor", "8M" }, { "Hub Legend", "10M" },
{ "Hub God", "11M" }, { "God", "1Y, 1h, 1m, 1s" },
},
-- Daily average uptime rank table
average = {
{ "Newbie", "1h" }, { "Member", "6h" }, { "Cool Member", "12h" },
{ "Hub-As", "1D" }, { "Smart As", "5D" }, { "Double-As", "15D" },
{ "Triple-As", "1M" }, { "Conqueror", "2M" }, { "Viking", "3M" },
{ "King", "4M" }, { "Emperor", "6M" }, { "Hub Legend", "9M" },
{ "Hub God", "11M" }, { "God", "1Y" },
},
},
}
tOnline = {}
OnStartup = function()
-- Register BotName if not registered
if tSettings.sBot ~= SetMan.GetString(21) then Core.RegBot(tSettings.sBot,"","",true) end
-- Load DB content
if loadfile(tSettings.fOnline) then dofile(tSettings.fOnline) end
-- Set and Start Timer
tSettings.iTimer = TmrMan.AddTimer(60*1000)
--Save Data Interval
tSettings.SaveData = TmrMan.AddTimer(tSettings.iInterval*60*60*1000)
end
OnTimer = function(iID)
if tSettings.iTimer and iID == tSettings.iTimer then
-- For each hubber
for i, v in pairs(tOnline) do
-- Online
if Core.GetUser(i) then
-- Sum
v.SessionTime = v.SessionTime + 1; v.TotalTime = v.TotalTime + 1
end
end
elseif tSettings.SaveData and iID == tSettings.SaveData then
local hFile = io.open(tSettings.fOnline, "w+") Serialize(tOnline, "tOnline", hFile); hFile:close()
end
end
OnExit = function()
-- Save
local hFile = io.open(tSettings.fOnline, "w+") Serialize(tOnline, "tOnline", hFile); hFile:close()
end
UserConnected = function(user)
-- If profile has permission to be logged
if tSettings.tProfiles[user.iProfile] and tSettings.tProfiles[user.iProfile] == true then
local tNick = GetOnliner(user.sNick)
-- User already in DB
if tNick then
-- Warning on connect
if tSettings.bWarning then
-- Days since first login
local iAverage = os.difftime(os.time(os.date("!*t")), tNick.Julian)/(60*60*24)
if iAverage < 1 then iAverage = 1 end
-- Less than allowed
if tNick.TotalTime/iAverage < tSettings.iMin*60 then
-- Kick if not excluded
if not tSettings.tExc[user.sNick] then
-- Add any custom message to kick
Core.Kick(user, tSettings.sBot, "*** Your Average uptime (AUT) is less than "..tSettings.iMin..
" hour(s). Please post to our forum before you try to connect again!")
end
end
-- Warn if not kicked
if tNick.TotalTime/iAverage < tSettings.iAUT*60 then
-- Add any custom message to warning
Core.SendPmToNick(user.sNick, tSettings.sBot, "*** Your Average uptime (AUT) is less than "..tSettings.iAUT..
" hour(s). Users above this average will be considered for VIP, and may log in when the Hub is full. Those below "..tSettings.iMin.." hour(s) (AUT) will be disconnected!")
--Warn if between iMin & iAUT and excluded from kick
else
if tNick.TotalTime/iAverage < tSettings.iAUT*60 then
if tNick.TotalTime/iAverage > tSettings.iMin*60 then
if tSettings.tExc[user.sNick] then
-- Add any custom message to warning
Core.SendPmToNick(user.sNick, tSettings.sBot, "*** Your Average uptime (AUT) is less than "..tSettings.iAUT..
" hour(s). Users above this average will be considered for VIP, and may log in when the Hub is full. Those below "..tSettings.iMin.." hour(s) (AUT) will be disconnected!")
end
end
end
end
end
-- Reset and save time
tNick.SessionTime = 0; tNick.Enter = os.date()
-- Send rank info on connect
if tSettings.bRankOnConnect then tCommands["myhubtime"].fFunction(user) end
else
-- Create new entry
tOnline[user.sNick] = { Julian = os.time(os.date("!*t")), Enter = os.date(), SessionTime = 0, TotalTime = 0, Leave = os.date() }
end
end
-- Supports UserCommands
if Core.GetUserValue(user,12) then
-- For each entry in table
for i, v in pairs(tCommands) do
-- If member
if v.tLevels[user.iProfile] then
-- For each type
for n in ipairs(v.tRC) do
-- Send
Core.SendToNick(user.sNick, "$UserCommand 1 3 "..tSettings.sMenu.."\\"..v.tRC[n][1]..
"$<%[mynick]> !"..i..v.tRC[n][2].."|")
end
end
end
end
end
OpConnected = UserConnected
RegConnected = UserConnected
UserDisconnected = function(user)
local tNick = GetOnliner(user.sNick)
-- If profile must be logged and user is in DB
if tSettings.tProfiles[user.iProfile] and tSettings.tProfiles[user.iProfile] == true and tNick then
-- Log date
tNick.Leave = os.date()
end
end
OpDisconnected = UserDisconnected
RegDisconnected = UserDisconnected
ChatArrival = function(user,data)
local _,_, to = data:find("^$To:%s(%S+)%s+From:")
local _,_, msg = data:find("%b<>%s(.*)|$")
-- Message sent to Bot or in Main
if (to and to == tSettings.sBot) or not to then
-- Parse command
local _,_, cmd = msg:find("^%p(%S+)")
-- Exists
if cmd and tCommands[cmd:lower()] then
cmd = cmd:lower()
-- If user has permission
if tCommands[cmd].tLevels[user.iProfile] then
if to and to == tSettings.sBot then
return Core.SendPmToNick(user.sNick, tSettings.sBot, tCommands[cmd].fFunction(user, msg)), true
else
if tSettings.sPmOnly then
return Core.SendPmToNick(user.sNick, tSettings.sBot, tCommands[cmd].fFunction(user, msg)), true
else
return Core.SendToNick(user.sNick, "<"..tSettings.sBot.."> "..tCommands[cmd].fFunction(user, msg)), true
end
end
else
if to and to == tSettings.sBot then
return Core.SendPmToNick(user.sNick, tSettings.sBot, "*** Error: You are not allowed to use this command!"), true
else
return Core.SendToNick(user.sNick, "<"..tSettings.sBot.."> *** Error: You are not allowed to use this command!"), true
end
end
end
end
end
ToArrival = ChatArrival
tCommands = {
tophubbers = {
fFunction = function(user, data)
-- Table isn't empty
if next(tOnline) then
-- Parse limits
local _,_, iStart, iEnd = data:find("^%S+%s+(%d+)%-(%d+)$")
-- Set if not set
iStart, iEnd = (iStart or 1), (iEnd or tSettings.iMax)
-- Header
local tCopy, msg = {}, "\r\n\t"..string.rep("=", 137).."\r\n\tNr. Total:\t\t\t\t\t\tSession:\t"..
"Entered Hub:\tLeft Hub:\t\tRank:\t\tStatus:\tName:\r\n\t"..string.rep("-", 240).."\r\n"
-- Loop through hubbers
for i, v in pairs(tOnline) do
-- Insert stats to temp table
table.insert(tCopy, { sEnter = v.Enter, iSessionTime = tonumber(v.SessionTime),
iTotalTime = tonumber(v.TotalTime), sLeave = v.Leave, sNick = i, sRank = GetRank(i) } )
end
-- Sort by total time
table.sort(tCopy, function(a, b) return (a.iTotalTime > b.iTotalTime) end)
-- Loop through temp table
for i = iStart, iEnd, 1 do
-- i exists
if tCopy[i] then
-- Populate
local sStatus, v = "*Offline*", tCopy[i]; local sRank = v.sRank
if Core.GetUser(v.sNick) then sStatus = "*Online*" end
if v.sRank:len() < 9 then sRank = sRank.."\t" end
msg = msg.."\t"..i..". "..MinutesToTime(v.iTotalTime).."\t"..v.iSessionTime..
" min\t"..v.sEnter.."\t"..v.sLeave.."\t"..sRank.."\t"..sStatus.."\t"..v.sNick.."\r\n"
end
end
msg = msg.."\t"..string.rep("-", 240)
-- Send
return "Current Top Hubbers:\r\n"..msg.."\r\n"
else
return "*** Error: Top Hubbers' table is currently empty!"
end
end,
tLevels = {
[-1] = false, [0] = true, [1] = true, [2] = true, [3] = true, [4] = true,
},
tRC = { { "Show Top "..tSettings.iMax.." Hubbers", "" }, { "Show Top x-y Hubbers", " %[line:x-y]" } }
},
hubtime = {
fFunction = function(user, data)
-- Parse nick
local _,_, nick = data:find("^%S+%s+(%S+)$")
-- Exists
if nick then
-- Return
return BuildStats(user, nick)
else
return "*** Select a user in the nick list!"
end
end,
tLevels = {
[-1] = false, [0] = true, [1] = true, [2] = true, [3] = true, [4] = true,
},
tRC = { { "Click on any User to see their Stats", " %[nick]" }, { "Show a User's Stats [Enter Nick]", " %[line:Nick]" } }
},
myhubtime = {
fFunction = function(user)
-- Return
return BuildStats(user, user.sNick)
end,
tLevels = {
[-1] = false, [0] = true, [1] = true, [2] = true, [3] = true, [4] = true,
},
tRC = { { "Show My Stats", "" } }
},
}
BuildStats = function(user, nick)
local tNick = GetOnliner(nick)
-- In DB
if tNick then
-- Average uptime in days
local iAverage = os.difftime(os.time(os.date("!*t")), tNick.Julian)/(60*60*24)
if iAverage < 1 then iAverage = 1 end
-- Generate message
local sMsg = "\r\n\r\n\t"..string.rep("=", 51).."\r\n\t\t\tStats:\r\n\t"..
string.rep("-", 89).."\r\n\t- Nick: "..nick.."\r\n\t- Total uptime: "..
MinutesToTime(tNick.TotalTime, true).."\r\n\t- Daily average uptime (AUT): "..
MinutesToTime((tNick.TotalTime/iAverage), true).."\r\n\t- Current Rank: "..GetRank(nick).."\n\t- Hub Standing: "..GetNumber(nick).."\r\n"
-- Send stats
--Add any custom message
return "Here are the stats you requested for "..nick..". Remember, users with over "..tSettings.iAUT.." hour(s) (AUT) will be considered for VIP, and may bypass the Hub full rule. Those below "..tSettings.iMin.." hour(s) (AUT) will be disconnected!" ..sMsg
else
return "*** Error: No record found for '"..nick.."'!"
end
end
GetRank = function(nick)
local tNick = GetOnliner(nick)
if tNick then
-- Custom time table
local tTime, sRank, iAverage = { s = 1/60, m = 1, h = 60, D = 60*24, W = 60*24*7, M = 60*24*30, Y = 60*24*30*12 }, tSettings.tRanks[tSettings.sCriteria:lower()][1][1]
-- Average enabled
if tSettings.bAverage then
-- Days since first login
iAverage = os.difftime(os.time(os.date("!*t")), tNick.Julian)/(60*60*24)
if iAverage < 1 then iAverage = 1 end
end
-- For each rank
for n in ipairs(tSettings.tRanks[tSettings.sCriteria:lower()]) do
local iTime = 0
-- For each digit and time string
for i, v in tSettings.tRanks[string.lower(tSettings.sCriteria)][n][2]:gmatch("(%d+)(%w)") do
-- Process
if i and tTime[v] then iTime = iTime + i*tTime[v] end
end
local iValue = tNick.TotalTime
-- Average
if tSettings.bAverage then iValue = iValue/iAverage end
-- Process rank if user hasn't logged in for the first time today
if os.date("%d%m%y", tNick.Julian) ~= os.date("%d%m%y") and iValue > iTime then
sRank = tSettings.tRanks[tSettings.sCriteria:lower()][n][1]
end
end
return sRank
end
end
GetNumber = function(nick)
if next(tOnline) then
local tCopy,iCount = {},0
for i, v in pairs(tOnline) do
table.insert(tCopy, { iTotalTime = tonumber(v.TotalTime), sNick = i } )
iCount = iCount + 1
end
table.sort(tCopy, function(a, b) return (a.iTotalTime > b.iTotalTime) end)
for i = 1, iCount do
if tCopy[i] then
local v = tCopy[i]
if v.sNick:lower() == nick:lower() then
return i
end
end
end
end
end
MinutesToTime = function(iSeconds, bSmall)
-- Build table with time fields
local T = os.date("!*t", tonumber(iSeconds*60));
-- Format to string
local sTime = string.format("%i year(s), %i month(s), %i day(s), %i hour(s), %i minute(s)", T.year-1970, T.month-1, T.day-1, T.hour, T.min)
-- Small stat?
if bSmall then
-- For each digit
for i in sTime:gmatch("%d+") do
-- Reduce if is preceeded by 0
if tonumber(i) == 0 then sTime = sTime:gsub("^"..i.."%s(%S+),%s", "") end
end
end
-- Return
return sTime
end
GetOnliner = function(user)
-- For each hubber
for i, v in pairs(tOnline) do
-- Compare
if i:lower() == user:lower() then
-- Return
return tOnline[i]
end
end
end
Serialize = function(tTable, sTableName, hFile, sTab)
sTab = sTab or "";
hFile:write(sTab..sTableName.." = {\n");
for key, value in pairs(tTable) do
if (type(value) ~= "function") then
local sKey = (type(key) == "string") and string.format("[%q]", key) or string.format("[%d]", key);
if(type(value) == "table") then
Serialize(value, sKey, hFile, sTab.."\t");
else
local sValue = (type(value) == "string") and string.format("%q", value) or tostring(value);
hFile:write(sTab.."\t"..sKey.." = "..sValue);
end
hFile:write(",\n");
end
end
hFile:write(sTab.."}");
end
[\code]
Thanks merlin_xl54. But the script in API 1 version had this thing which I found missing in the API 2 version.
bastya_elvtars:
Changed: any user can use the hubtime command (01/27/2007)
Changed:!hubtime without nick returns own hubtime (myhubtime kept for legacy reasons) (01/27/2007)
Changed: + can also be used as a comand prefix (01/27/2007)
!hubtime without nick returns own hubtime
Can this be added ? Thanks in advance.
Quote from: DeAn on 30 March, 2010, 16:05:01
Thanks merlin_xl54. But the script in API 1 version had this thing which I found missing in the API 2 version.
!hubtime without nick returns own hubtime
Can this be added ? Thanks in advance.
This script has "!myhubtime" which returns your own hubtime.
M
-- Send hubtime stats on connect [true = on; false = off]
bRankOnConnect = false,
Even if I made this true, hubtime stats are not shown on startup. Any fix ?
Hi all
I have come across a strange problem.
If a user has the Away message activated and he/she checks his/her own uptime, he/she gets disconnected from the hub.
The hub is using PtokaX 0.4.1.1 as hubsoft and the script is a slightly modyfied version of the original Tophubbers 2.03 (additional profiles has been added).
It seems that the number of the profile is not the issue, since also Crew members with profile nr 1 (Operator) are getting disconnected for the same reason.
Anyone here who has experienced the same kind of behavior?
All help/advice is mostly appreciated :)
Regards
Quote from: DeAn on 31 March, 2010, 20:44:37
Even if I made this true, hubtime stats are not shown on startup. Any fix ?
try this...
--[[
TopHubbers 2.03b - LUA 5.1.2 [Strict][API 2] by jiten
????????????????????????????????????????????????????
Based on: OnHub Time Logger 1.65 by chill and Robocop's layout
Usage: !tophubbers; !tophubbers x-y; !hubtime <nick>; !myhubtime
CHANGELOG:
??????????
Fixed: Typo in table.sort function;
Added: OnExit (3/21/2006)
Fixed: Missing pairs() in SaveToFile
Changed: Removed iGlobalTime and added TotalTime count to OnTimer
Changed: SecondsToTime function values (3/24/2006)
Changed: math.floor/mod in TopHubbers' function; (3/5/2006)
Changed: SecondsToTime month value (4/17/2006);
Added: !hubtime <nick> - requested by speedX;
Changed: SecondsToTime function and small code bits (8/16/2006)
Changed: Table indexes;
Changed: SecondsToTime function to MinutesToTime;
Fixed: Inaccurate average uptime stuff (8/17/2006)
Changed: Average uptime function;
Changed: Session time for offline users doesn't get reset;
Added: Average uptime warning on connect - requested by speedX (8/20/2006)
Added: Customized profiles - requested by Naithif (8/20/2006)
Added: User Commands - requested by TT;
Added: Rankings and related commands [!myrank & !topranks] - requested by speedX;
Added: Toggle rank info on connect - requested by TT;
Fixed: !tophubbers x-y;
Added: Comments to the code;
Changed: Some code bits;
Added: Toggle between total and average uptime (8/24/2006)
Fixed: Minimum average uptime warning - reported by speedX;
Added: Maximum shown hubbers - requested by Naithif (8/29/2006)
Fixed: LUA 5.0/5.1 compatibility - reported by speedX (11/8/2006)
Added: string.lower check - requested by SwapY and speedX (11/10/2006)
Changed: Script converted to API 2 (11/24/2007)
Fixed: Changed Serialize function (12/23/2007)
+Changes from 2.03a 07/26/09
Added: Send messages in PM (01/22/2008) by speedX
Added: Timer to save data on regular intervals (07/18/2008) by speedX
Added: Kick user below Minimum Average uptime (iMin) (6/20/2009) by merlin_xl54-CrazyGuy
Added: Table to exclude certain nicks from kick (tExc) (6/24/2009) by merlin_xl54-CrazyGuy
Added: Show total years added in displayed times (7/26/2009) by speedX
Fixed: Error when bWarning is false (1-10-2010) by merlin_xl54
Update for profile permission changes in PxLua API [version 0.4.1.2 and later] (1/22/2010) by merlin_xl54
Added: Option to return stats by selecting nick in user list (3/1/2010) by merlin_xl54
Added: Numeric rank in the hub stats for total time connected (3/17/2010) by speedX
Fixed: Option for RankOnConnect (5\6\2010) by speedX
]]--
tSettings = {
-- Bot Name
sBot = SetMan.GetString(21),
-- Top Hubbers' DB
fOnline = "scripts/tOnliners.tbl",
-- RightClick Menu
sMenu = "Top Hubbers",
-- Maximum hubbers to show when using !tophubbers
iMax = 15,
-- Send message to users with lower than specified Average uptime (AUT) [true = on; false = off]
bWarning = false,
-- Minimum Average uptime (hours) that triggers the warning
iAUT = 12,
-- Minimum Average uptime (hours) that triggers the kick [Disable = 0]
iMin = 0,
-- Send hubtime stats on connect [true = on; false = off]
bRankOnConnect = true,
-- Profiles checked [false = off; true = on]
tProfiles = { [-1] = false, [0] = true, [1] = true, [2] = true, [3] = true, [4] = true },
-- Ranks criteria ["average" = Average total uptime; "total" = Total uptime]
sCriteria = "average",
-- Reply in PM ?
bPmOnly = true,
-- Set your interval time to save data(in Hours)
iInterval = 24,
--Exclude from kick
tExc = {
["yournickhere"] = true,
},
-- Ranks
tRanks = {
--[[
The ranks must be added in ascending order [from the lowest to the highest]
{ "Rank", [time][string] }
[time] must be 1 or more digit(s)
[string] must be: s = second; m = minute; h = hour; D = day; W = week; M = month; Y = year
Example: { "God", "1M, 2D, 10s" }
Meaning: To become a God, your total uptime must be equal or higher than 1 month, 2 days and 10 seconds
]]--
-- Total uptime rank table
total = {
{ "Newbie", "1D, 1h, 1m, 1s" }, { "Member", "2D" }, { "Cool Member", "5D" },
{ "Hub As", "10D" }, { "Smart As", "20D" }, { "Double As", "1M" },
{ "Triple As", "2M" }, { "Conqueror", "3M" }, { "Viking", "4M" },
{ "King", "6M" }, { "Emperor", "8M" }, { "Hub Legend", "10M" },
{ "Hub God", "11M" }, { "God", "1Y, 1h, 1m, 1s" },
},
-- Daily average uptime rank table
average = {
{ "Newbie", "1h" }, { "Member", "6h" }, { "Cool Member", "12h" },
{ "Hub-As", "1D" }, { "Smart As", "5D" }, { "Double-As", "15D" },
{ "Triple-As", "1M" }, { "Conqueror", "2M" }, { "Viking", "3M" },
{ "King", "4M" }, { "Emperor", "6M" }, { "Hub Legend", "9M" },
{ "Hub God", "11M" }, { "God", "1Y" },
},
},
}
tOnline = {}
OnStartup = function()
-- Register BotName if not registered
if tSettings.sBot ~= SetMan.GetString(21) then Core.RegBot(tSettings.sBot,"","",true) end
-- Load DB content
if loadfile(tSettings.fOnline) then dofile(tSettings.fOnline) end
-- Set and Start Timer
tSettings.iTimer = TmrMan.AddTimer(60*1000)
--Save Data Interval
tSettings.SaveData = TmrMan.AddTimer(tSettings.iInterval*60*60*1000)
end
OnTimer = function(iID)
if tSettings.iTimer and iID == tSettings.iTimer then
-- For each hubber
for i, v in pairs(tOnline) do
-- Online
if Core.GetUser(i) then
-- Sum
v.SessionTime = v.SessionTime + 1; v.TotalTime = v.TotalTime + 1
end
end
elseif tSettings.SaveData and iID == tSettings.SaveData then
local hFile = io.open(tSettings.fOnline, "w+") Serialize(tOnline, "tOnline", hFile); hFile:close()
end
end
OnExit = function()
-- Save
local hFile = io.open(tSettings.fOnline, "w+") Serialize(tOnline, "tOnline", hFile); hFile:close()
end
UserConnected = function(user)
-- If profile has permission to be logged
if tSettings.tProfiles[user.iProfile] and tSettings.tProfiles[user.iProfile] == true then
local tNick = GetOnliner(user.sNick)
-- User already in DB
if tNick then
-- Warning on connect
if tSettings.bWarning then
-- Days since first login
local iAverage = os.difftime(os.time(os.date("!*t")), tNick.Julian)/(60*60*24)
if iAverage < 1 then iAverage = 1 end
-- Less than allowed
if tNick.TotalTime/iAverage < tSettings.iMin*60 then
-- Kick if not excluded
if not tSettings.tExc[user.sNick] then
-- Add any custom message to kick
Core.Kick(user, tSettings.sBot, "*** Your Average uptime (AUT) is less than "..tSettings.iMin..
" hour(s). Please post to our forum before you try to connect again!")
end
end
-- Warn if not kicked
if tNick.TotalTime/iAverage < tSettings.iAUT*60 then
-- Add any custom message to warning
Core.SendPmToNick(user.sNick, tSettings.sBot, "*** Your Average uptime (AUT) is less than "..tSettings.iAUT..
" hour(s). Users above this average will be considered for VIP, and may log in when the Hub is full. Those below "..tSettings.iMin.." hour(s) (AUT) will be disconnected!")
--Warn if between iMin & iAUT and excluded from kick
else
if tNick.TotalTime/iAverage < tSettings.iAUT*60 then
if tNick.TotalTime/iAverage > tSettings.iMin*60 then
if tSettings.tExc[user.sNick] then
-- Add any custom message to warning
Core.SendPmToNick(user.sNick, tSettings.sBot, "*** Your Average uptime (AUT) is less than "..tSettings.iAUT..
" hour(s). Users above this average will be considered for VIP, and may log in when the Hub is full. Those below "..tSettings.iMin.." hour(s) (AUT) will be disconnected!")
end
end
end
end
end
-- Reset and save time
tNick.SessionTime = 0; tNick.Enter = os.date()
-- Send rank info on connect
if tSettings.bRankOnConnect then Core.SendToNick(user.sNick,"<"..tSettings.sBot.."> "..tCommands["myhubtime"].fFunction(user)) end
else
-- Create new entry
tOnline[user.sNick] = { Julian = os.time(os.date("!*t")), Enter = os.date(), SessionTime = 0, TotalTime = 0, Leave = os.date() }
end
end
-- Supports UserCommands
if Core.GetUserValue(user,12) then
-- For each entry in table
for i, v in pairs(tCommands) do
-- If member
if v.tLevels[user.iProfile] then
-- For each type
for n in ipairs(v.tRC) do
-- Send
Core.SendToNick(user.sNick, "$UserCommand 1 3 "..tSettings.sMenu.."\\"..v.tRC[n][1]..
"$<%[mynick]> !"..i..v.tRC[n][2].."|")
end
end
end
end
end
OpConnected = UserConnected
RegConnected = UserConnected
UserDisconnected = function(user)
local tNick = GetOnliner(user.sNick)
-- If profile must be logged and user is in DB
if tSettings.tProfiles[user.iProfile] and tSettings.tProfiles[user.iProfile] == true and tNick then
-- Log date
tNick.Leave = os.date()
end
end
OpDisconnected = UserDisconnected
RegDisconnected = UserDisconnected
ChatArrival = function(user,data)
local _,_, to = data:find("^$To:%s(%S+)%s+From:")
local _,_, msg = data:find("%b<>%s(.*)|$")
-- Message sent to Bot or in Main
if (to and to == tSettings.sBot) or not to then
-- Parse command
local _,_, cmd = msg:find("^%p(%S+)")
-- Exists
if cmd and tCommands[cmd:lower()] then
cmd = cmd:lower()
-- If user has permission
if tCommands[cmd].tLevels[user.iProfile] then
if to and to == tSettings.sBot then
return Core.SendPmToNick(user.sNick, tSettings.sBot, tCommands[cmd].fFunction(user, msg)), true
else
if tSettings.bPmOnly then
return Core.SendPmToNick(user.sNick, tSettings.sBot, tCommands[cmd].fFunction(user, msg)), true
else
return Core.SendToNick(user.sNick, "<"..tSettings.sBot.."> "..tCommands[cmd].fFunction(user, msg)), true
end
end
else
if to and to == tSettings.sBot then
return Core.SendPmToNick(user.sNick, tSettings.sBot, "*** Error: You are not allowed to use this command!"), true
else
return Core.SendToNick(user.sNick, "<"..tSettings.sBot.."> *** Error: You are not allowed to use this command!"), true
end
end
end
end
end
ToArrival = ChatArrival
tCommands = {
tophubbers = {
fFunction = function(user, data)
-- Table isn't empty
if next(tOnline) then
-- Parse limits
local _,_, iStart, iEnd = data:find("^%S+%s+(%d+)%-(%d+)$")
-- Set if not set
iStart, iEnd = (iStart or 1), (iEnd or tSettings.iMax)
-- Header
local tCopy, msg = {}, "\r\n\t"..string.rep("=", 137).."\r\n\tNr. Total:\t\t\t\t\t\tSession:\t"..
"Entered Hub:\tLeft Hub:\t\tRank:\t\tStatus:\tName:\r\n\t"..string.rep("-", 240).."\r\n"
-- Loop through hubbers
for i, v in pairs(tOnline) do
-- Insert stats to temp table
table.insert(tCopy, { sEnter = v.Enter, iSessionTime = tonumber(v.SessionTime),
iTotalTime = tonumber(v.TotalTime), sLeave = v.Leave, sNick = i, sRank = GetRank(i) } )
end
-- Sort by total time
table.sort(tCopy, function(a, b) return (a.iTotalTime > b.iTotalTime) end)
-- Loop through temp table
for i = iStart, iEnd, 1 do
-- i exists
if tCopy[i] then
-- Populate
local sStatus, v = "*Offline*", tCopy[i]; local sRank = v.sRank
if Core.GetUser(v.sNick) then sStatus = "*Online*" end
if v.sRank:len() < 9 then sRank = sRank.."\t" end
msg = msg.."\t"..i..". "..MinutesToTime(v.iTotalTime).."\t"..v.iSessionTime..
" min\t"..v.sEnter.."\t"..v.sLeave.."\t"..sRank.."\t"..sStatus.."\t"..v.sNick.."\r\n"
end
end
msg = msg.."\t"..string.rep("-", 240)
-- Send
return "Current Top Hubbers:\r\n"..msg.."\r\n"
else
return "*** Error: Top Hubbers' table is currently empty!"
end
end,
tLevels = {
[-1] = false, [0] = true, [1] = true, [2] = true, [3] = true, [4] = true,
},
tRC = { { "Show Top "..tSettings.iMax.." Hubbers", "" }, { "Show Top x-y Hubbers", " %[line:x-y]" } }
},
hubtime = {
fFunction = function(user, data)
-- Parse nick
local _,_, nick = data:find("^%S+%s+(%S+)$")
-- Exists
if nick then
-- Return
return BuildStats(user, nick)
else
return "*** Select a user in the nick list!"
end
end,
tLevels = {
[-1] = false, [0] = true, [1] = true, [2] = true, [3] = true, [4] = true,
},
tRC = { { "Click on any User to see their Stats", " %[nick]" }, { "Show a User's Stats [Enter Nick]", " %[line:Nick]" } }
},
myhubtime = {
fFunction = function(user)
-- Return
return BuildStats(user, user.sNick)
end,
tLevels = {
[-1] = false, [0] = true, [1] = true, [2] = true, [3] = true, [4] = true,
},
tRC = { { "Show My Stats", "" } }
},
}
BuildStats = function(user, nick)
local tNick = GetOnliner(nick)
-- In DB
if tNick then
-- Average uptime in days
local iAverage = os.difftime(os.time(os.date("!*t")), tNick.Julian)/(60*60*24)
if iAverage < 1 then iAverage = 1 end
-- Generate message
local sMsg = "\r\n\r\n\t"..string.rep("=", 51).."\r\n\t\t\tStats:\r\n\t"..
string.rep("-", 89).."\r\n\t- Nick: "..nick.."\r\n\t- Total uptime: "..
MinutesToTime(tNick.TotalTime, true).."\r\n\t- Daily average uptime (AUT): "..
MinutesToTime((tNick.TotalTime/iAverage), true).."\r\n\t- Current Rank: "..GetRank(nick).."\n\t- Hub Standing: "..GetNumber(nick).."\r\n"
-- Send stats
--Add any custom message
return "Here are the stats you requested for "..nick..". Remember, users with over "..tSettings.iAUT.." hour(s) (AUT) will be considered for VIP, and may bypass the Hub full rule. Those below "..tSettings.iMin.." hour(s) (AUT) will be disconnected!" ..sMsg
else
return "*** Error: No record found for '"..nick.."'!"
end
end
GetRank = function(nick)
local tNick = GetOnliner(nick)
if tNick then
-- Custom time table
local tTime, sRank, iAverage = { s = 1/60, m = 1, h = 60, D = 60*24, W = 60*24*7, M = 60*24*30, Y = 60*24*30*12 }, tSettings.tRanks[tSettings.sCriteria:lower()][1][1]
-- Average enabled
if tSettings.bAverage then
-- Days since first login
iAverage = os.difftime(os.time(os.date("!*t")), tNick.Julian)/(60*60*24)
if iAverage < 1 then iAverage = 1 end
end
-- For each rank
for n in ipairs(tSettings.tRanks[tSettings.sCriteria:lower()]) do
local iTime = 0
-- For each digit and time string
for i, v in tSettings.tRanks[string.lower(tSettings.sCriteria)][n][2]:gmatch("(%d+)(%w)") do
-- Process
if i and tTime[v] then iTime = iTime + i*tTime[v] end
end
local iValue = tNick.TotalTime
-- Average
if tSettings.bAverage then iValue = iValue/iAverage end
-- Process rank if user hasn't logged in for the first time today
if os.date("%d%m%y", tNick.Julian) ~= os.date("%d%m%y") and iValue > iTime then
sRank = tSettings.tRanks[tSettings.sCriteria:lower()][n][1]
end
end
return sRank
end
end
GetNumber = function(nick)
if next(tOnline) then
local tCopy,iCount = {},0
for i, v in pairs(tOnline) do
table.insert(tCopy, { iTotalTime = tonumber(v.TotalTime), sNick = i } )
iCount = iCount + 1
end
table.sort(tCopy, function(a, b) return (a.iTotalTime > b.iTotalTime) end)
for i = 1, iCount do
if tCopy[i] then
local v = tCopy[i]
if v.sNick:lower() == nick:lower() then
return i
end
end
end
end
end
MinutesToTime = function(iSeconds, bSmall)
-- Build table with time fields
local T = os.date("!*t", tonumber(iSeconds*60));
-- Format to string
local sTime = string.format("%i year(s), %i month(s), %i day(s), %i hour(s), %i minute(s)", T.year-1970, T.month-1, T.day-1, T.hour, T.min)
-- Small stat?
if bSmall then
-- For each digit
for i in sTime:gmatch("%d+") do
-- Reduce if is preceeded by 0
if tonumber(i) == 0 then sTime = sTime:gsub("^"..i.."%s(%S+),%s", "") end
end
end
-- Return
return sTime
end
GetOnliner = function(user)
-- For each hubber
for i, v in pairs(tOnline) do
-- Compare
if i:lower() == user:lower() then
-- Return
return tOnline[i]
end
end
end
Serialize = function(tTable, sTableName, hFile, sTab)
sTab = sTab or "";
hFile:write(sTab..sTableName.." = {\n");
for key, value in pairs(tTable) do
if (type(value) ~= "function") then
local sKey = (type(key) == "string") and string.format("[%q]", key) or string.format("[%d]", key);
if(type(value) == "table") then
Serialize(value, sKey, hFile, sTab.."\t");
else
local sValue = (type(value) == "string") and string.format("%q", value) or tostring(value);
hFile:write(sTab.."\t"..sKey.." = "..sValue);
end
hFile:write(",\n");
end
end
hFile:write(sTab.."}");
end
The script is working great. Thanks a lot speedX :)