Ulysses

Ulysses Stuff => Suggestions => Topic started by: kropp on June 30, 2011, 06:19:57 PM

Title: Temporary user group change
Post by: kropp on June 30, 2011, 06:19:57 PM
I need a system so you can promote some one to a rank lets say for a month then they will be demoted after that.

Example: VIP you get VIP for a month and after that month is up its gone.

Maybe Like a trial VIP. You get VIP for 5 hours and after that you get guest.

Please let me know if this is possible or if you can do it for me.

I will pay for a system like this.

[JamminR-EDIT] - Edited title - "Needed System" to more descriptive
Title: Re: needed system!
Post by: JamminR on June 30, 2011, 07:00:22 PM
Searching for 'temp' on the forum finds this (OLD NON-WORKING for current ULX version) release
http://forums.ulyssesmod.net/index.php/topic,3825.0.html

Perhaps rather than making the suggestion that's already been made in this area a few times (and easily found in several other areas of the forum by searching for the word 'temp'), you can reply to his thread (Mr President is still quite active, and more experienced with Lua now too) and encourage him to upgrade to latest ULX compatibility, and add the time feature you and so many others there suggested.
Title: Re: Temporary user group change
Post by: MrPresident on July 01, 2011, 12:52:08 AM
I am not obligating myself to this by any means, but I have an idea on how to make this work... How would something like this work for you:


ulx tempuser <player> <group1> <group2> <time>

group 1 - group they are temporarily in
group 2 - group they will be moved to after the time
time - in seconds. This will be tracked based on epoch time, so it'll be fairly accurate and leaving the server shouldn't have any adverse effect.

The data will be stored via sqlite. This will allow the script to quickly query the db when a player joins the server to check and see if a temporary membership/group has expired since they last played and also so that the server can query every set amount of time (most likely every 1 minute - possibly configurable) for players connected to see if a membership/group has expired while they are playing.

This should be fairly easy to write actually. I'll see what I can do tomorrow. Let me know if this is what you were looking for.


And as always, I code gmod for fun, not for profit.
Title: Re: Temporary user group change
Post by: kropp on July 01, 2011, 12:18:43 PM
That sounds perfect this is so when people buy VIP for a month I can have something keep track of it for me.
This sounds amazing! ;D
Title: Re: Temporary user group change
Post by: Stickly Man! on July 01, 2011, 01:39:22 PM
also so that the server can query every set amount of time (most likely every 1 minute - possibly configurable)

Wouldn't it be easier to just have a single timer per player with a temp group? Timers would be created when the server starts or when a new player is given a temp group, and removed only if the player's time or group is changed? You'd obviously store the users by SteamIDs, so you can use add/removeuserid and have the players temp group expire even when they're not on the server.

Oh, and then you don't have to have a repeated query :)
Title: Re: Temporary user group change
Post by: MrPresident on July 01, 2011, 03:05:06 PM
That would be good for small scale. I don't know what would be more resource intense... running a query on connected players that have temp groups every x minutes or potentially having a hundred timers running at the same time.


I could query the db when a player joins and create a timer for that player only and have it stop when they leave the server. Combining this with checking when they join could keep the timers from needing to change groups while the player isn't connected.

That also brings up another concern... how would I go about detecting if the players group has been changed.. is there is groupchanged hook? lol.. otherwise you could permanently change someone's group while their in a temp group and the script would change their group to whatever you had set it to even though it shouldn't.
Title: Re: Temporary user group change
Post by: JamminR on July 01, 2011, 08:07:27 PM
I could query the db when a player joins and create a timer for that player only and have it stop when they leave the server. Combining this with checking when they join could keep the timers from needing to change groups while the player isn't connected.

Just outloud thoughts. One of you geniuses will figure out better/more efficient way.
Store the steamid, original group, temp group, time allotted. (I still prefer text, but sure, have it SQL capable for those 'real' servers)
Run a timer where every 6(?) hours, the server checks and loads the next 6 hours of expirations..load those as timers.
Add 'feature' that if a player joins that is in that table during those 6 hours...the host can have that user warned to go beg for more status/pay more money, whatever.

That also brings up another concern... how would I go about detecting if the players group has been changed.. is there is groupchanged hook? lol.. otherwise you could permanently change someone's group while their in a temp group and the script would change their group to whatever you had set it to even though it shouldn't.

Not specifically group changed hook, but, extremely useful.
http://ulyssesmod.net/docs/files/lua/ulib/shared/defines-lua.html#UCLChanged

You should also monitor for bans (auto remove), or kicks (allow 'feature' to have temp group removed, optional (in case they have admin kick wars, etc))

If banned, remove from table (and existing timers) entirely (same as with kick if auto remove enabled)
If promoted, if promo group = temp group, remove from table/timers.
If promoted, if not promo group = temp, change "original group" table to 'new/promo group'.

The only challenge I see after that is having your function determine that the UCLChanged hook your running isn't the changes it may be doing itself.
>Heh. We could almost move this topic to Devs corner.
Title: Re: Temporary user group change
Post by: MrPresident on July 01, 2011, 08:53:29 PM
Quote
UCLChanged

Called on both server and client when anything in ULib.ucl.users, ULib.ucl.authed, or ULib.ucl.groups changes.  No parameters are passed to callbacks.
Revisions
v2.40   Initial


this hook just simply is called when something in one of those tables changes. I don't know how this could help me with the specific issue of determining if a specific players group was changed, any ideas?
Title: Re: Temporary user group change
Post by: JamminR on July 01, 2011, 10:36:02 PM
Now that I look closer, my idea isn't extremely efficient, but, I think it would still work. As always, it's just to build on.
UCLChanged as it stands -
Code: [Select]
local function UCLChanged()
ULib.clientRPC( _, "ULib.ucl.initClientUCL", ucl.authed, ucl.groups ) -- Send all UCL data (minus offline users) to all loaded users
ULib.clientRPC( _, "hook.Call", ULib.HOOK_UCLCHANGED ) -- Call hook on client
end
hook.Add( ULib.HOOK_UCLCHANGED, "ULibSendUCLToClients", UCLChanged )

Bah, I just spent 10 minutes in this post writing logic that ended up looping itself several times.
I nixed it.
It's possible, just lots of checks I couldn't figure out in a reasonable amount of time on my part.

Just monitor ULibPostTranslatedCommand (http://ULibPostTranslatedCommand) for any 'ulx <command that might change user access>' and act on it accordingly if one of the temp players is in the translated args table.
At least it gets passed some parameters to check, and probably more efficient to find the temp player in it.
Title: Re: Temporary user group change
Post by: Stickly Man! on July 02, 2011, 08:48:23 AM
Store the steamid, original group, temp group, time allotted. (I still prefer text, but sure, have it SQL capable for those 'real' servers)
Run a timer where every 6(?) hours, the server checks and loads the next 6 hours of expirations..load those as timers.

This works too-- I do the same thing in XGUI for checking when ULX bans expire, except I have a timer that runs every hour that creates timers for bans that expire in under an hour.


I don't know how this could help me with the specific issue of determining if a specific players group was changed, any ideas?

ULibPostTranslatedCommand on the adduser, removeuser, adduserid, and removeuserid commands works fine, but if a third party makes a ulx command that changes group without calling the ulx commands, you could just add your code to the end of ULib.ucl.addUser and ULib.ucl.removeUser.


I could query the db when a player joins and create a timer for that player only and have it stop when they leave the server. Combining this with checking when they join could keep the timers from needing to change groups while the player isn't connected.

I'm all for making sure that temp group "demotions" are executed exactly when they need to be-- If I temporarily promote "bob" to superadmin for a day, but then he never joins the server again, weeks later he will show up in the "superadmin" group even though he's really not in that group anymore.
Title: Re: Temporary user group change
Post by: Megiddo on July 02, 2011, 09:05:44 AM
I could look into passing parameters thru UCLChanged to specify what's changing. I don't remember if I didn't do this originally out of laziness or some technical reason. :P
Title: Re: Temporary user group change
Post by: JamminR on July 02, 2011, 11:40:00 AM
Meg, if there's not a technical reason, I could see this being helpful.
Perhaps a 'diff' table combined with a 'whodunnit'
whodunnit;whogotit;whatitwas;whatitnowis
That's extremely simplified of course, but ya get what i mean.
Title: Re: Temporary user group change
Post by: MrPresident on July 02, 2011, 01:08:47 PM
I'm all for making sure that temp group "demotions" are executed exactly when they need to be-- If I temporarily promote "bob" to superadmin for a day, but then he never joins the server again, weeks later he will show up in the "superadmin" group even though he's really not in that group anymore.
Well, he wouldn't. The way it would work is that the script would query against the database when the player authenticates and then would set the group accordingly. I suppose that for a split second he would be considered to be in the temp group but this wouldn't be noticeable to either the client or the server.

I do like the idea of checking for new groups of people every 3 hours or so and creating timers accordingly. This seems to be an efficient way of doing it without creating timers for everyone who is in a temp group.

My only thing at this point is still how to detect if someone has had their group changed with standard ULib.ucl.addUser or ULib.ucl.removeUser. I suppose that I could modify the original code for now until (if possible) Megiddo can write the appropriate info into the hook.

Question: If I modify the adduser and removeuser functions in a module that I create as an addon, will that overwrite the original functions or will they conflict?
Title: Re: Temporary user group change
Post by: JamminR on July 02, 2011, 01:37:38 PM
Question: If I modify the adduser and removeuser functions in a module that I create as an addon, will that overwrite the original functions or will they conflict?

It's my understanding that if a a function is local, they run in conjunction (not directly conflict) with the others.
(with possibility to conflict if using global vars of course)
Meg/Stick, back me up/correct me on this?
It's a quick easy test anyway... write;
Code: [Select]
local function ulx.adduser(I,forget,real,vars)
--print to console "this worked"
end
local adduser = <standard ULX command object and parms>
adduser:<standard ULX command object and parms>
adduser:<standard ULX command object and parms>
run the server. addyourself to another group, see if you get added and that the object ran.

Why overwrite though?
If you're going to use exact same command names, use PostTranslatedCommand or CommandCalled (if needed pre)

Stick brings up a good point previously though. If someone else writes a command that modifies ULib.ucl.<groups||users>, your add/removeuser overwrite won't see it.
Might as well write custom checks into a long drawn out UCLChanged hook function (which, Megiddo is probably willing to 'update' to contain more, with some consideration of what might break of course)
Title: Re: Temporary user group change
Post by: Stickly Man! on July 02, 2011, 01:57:12 PM
Well, he wouldn't. The way it would work is that the script would query against the database when the player authenticates and then would set the group accordingly. I suppose that for a split second he would be considered to be in the temp group but this wouldn't be noticeable to either the client or the server.

I think I'm still a bit confused on how you're planning on having this work lol-- I'm under the impression that when someone is temporarily promoted into any given group, they're immediately adduser'd to that group, then their record of promotion is stored in your database. Then whenever that player joins, their record is checked to see if they've expired or not? If that's how it's set up, then it was as I was saying earlier, if "bob" never joins for weeks, admins will always see "bob" in the list of superadmins (XGUI) even though it's past expiration.


Question: If I modify the adduser and removeuser functions in a module that I create as an addon, will that overwrite the original functions or will they conflict?

Just "hijack" the function-- I do it in XGUI a couple of times, especially with ban functions. It works like this:
Code: [Select]
local tempfunc = ULib.ucl.adduser
ULib.ucl.adduser = function( id, allows, denies, group )
   tempfunc( id, allows, denies, group ) --Call the original adduser function
   --Add your code here
end

Thus, the function remains unmodified, and your code gets executed. Obviously, if some mod were to overwrite the adduser function entirely, and it's overwritten AFTER you hijack the function, then you would have issues. Having more information with UCLChanged would also work nicely :)
Title: Re: Temporary user group change
Post by: Megiddo on July 02, 2011, 03:08:10 PM
What Stickly said, I don't see any problem with "hijacking" a function like that. I do it with some of the default gmod functions in fact. As long as you're still calling the original function, it's pretty much like a very specific hook. It's just not something I recommend in general since very few people can even get return values from hooks right...
Title: Re: Temporary user group change
Post by: Megiddo on July 03, 2011, 09:12:01 AM
After reviewing the source, I remember why I didn't have UCLCHANGED pass in more information. Each place I call it (about ten locations) would be using a slightly different format for the hook parameters. I'd be implementing a function-level hook, so it's way easier for both me and other devs to hook into the function as discussed above.

They're designed to be easy to hook into! All functions throw errors on invalid calls, so you don't need to worry about picking up on a false positive. The exception to this is userallow and groupallow which will return a boolean stating whether or not anything actually changed.

EDIT: Basically, the ucl changed hook was only meant as a high level, "Hey! Access has changed! You should refresh your cache!", so that you don't have to hook into these ten different functions.