UserGroups

Hi,

I’m experiencing the problem of user groups not taking effect. I have the following code:

[lua] // Match the flags to usergroups.
if ( SF.Flags.Has( pl, “Y” ) ) then

	// Y = superadmin.
	pl:SetUserGroup( "superadmin" );
	SF.Utility.Debug( "Making " .. pl:SteamID() .. " (" .. pl:Name() .. ") a superadmin!" );
	
elseif ( SF.Flags.Has( pl, "M" ) ) then
	
	// M = admin.
	pl:SetUserGroup( "admin" );
	SF.Utility.Debug( "Making " .. pl:SteamID() .. " (" .. pl:Name() .. ") an admin!" );
	
end[/lua]

which is inside a function hooked to PlayerInitialSpawn. The debug works and it logs to console that I’ve been set as a superadmin, yet it doesn’t appear to work in-game (for example, FPP doesn’t think I’m a superadmin).

Does this need to be in a PlayerSpawn hook rather than PlayerInitialSpawn, or is my code just completely off?

Regards,
Elf.

ULX is known for breaking such things. Update ULX to the latest SVN.

I’m not using ULX is the problem… Oh wait, I think the Data files may still be there. Hang on.

[editline]17:53[/editline]

Nope, still broken. No ULX files remain on the server,

Bump.

It still refuses to work… Any ideas what’s wrong/where there could be hidden ULX/ULiB folders?

Use the method of the player metatable: IsAdmin
function _R.Player:IsAdmin()

IsAdmin isn’t a metatable, it is a method of the player metatable.

Argh, i failed, anyway, i use that method and it works.

Yes… I’m trying to make them admin. Not check if they’re an admin.

Thanks for the help anyway…

I failed.

Are you mentally defected or something?

IsAdmin will return TRUE if they’re an ADMIN. I’m trying to MAKE THEM AN ADMIN not see if they’re an admin, I know what IsAdmin does thanks.

The problem is I’m setting them as admin through usergroups but any other mod that uses IsAdmin() or IsUserGroup( “admin” ) just returns false even when in my mod they are.

Sigh, I still haven’t figured this out.

Well I honestly can’t see why you’re unable to make players admins. If I were you I would look at the code of other admin mods and see how they did it. Of course you should also make sure that your code is being ran serverside. (Which yeah I know it should already be, but maybe you put the hook in the wrong place or something…)

That’s where I’m greatly confused.
This is the whole initial spawn hook.

[lua]// Load a player.
function SF.MySQL.Player.Load( pl )

// If we're not connected then connect; if we're still not connected then return.
if ( !SF.Connection ) then
	
	// Refresh.
	SF.MySQL.Refresh();
	
	// Recheck connection.
	if ( !SF.Connection ) then
		
		// Return if can't connect.
		return;
		
	end
	
end

// Match the flags to usergroups.
if ( SF.Flags.Has( pl, "Y" ) ) then
	
	// Y = superadmin.
	pl:SetUserGroup( "superadmin" );
	SF.Utility.Debug( "Making " .. pl:SteamID() .. " (" .. pl:Name() .. ") a superadmin!" );
	
elseif ( SF.Flags.Has( pl, "M" ) ) then
	
	// M = admin.
	pl:SetUserGroup( "admin" );
	SF.Utility.Debug( "Making " .. pl:SteamID() .. " (" .. pl:Name() .. ") an admin!" );
	
else
	
	pl:SetUserGroup( "user" );
	
end

// Clear MyData, success, and error.
local MyData;
local Success;
local Error;

// Get the players data.
MyData, Success, Error = mysql.query( SF.Connection, "SELECT * FROM sf_player WHERE steamid = '" .. pl:SteamID() .. "'" );

// Check that it was a success.
if ( !Success ) then
	
	// IF it wasn't display failed and return.
	SF.Utility.Debug( "1: MYSQL ERROR: " .. Error, "1" );
	return;
	
end

// Count the amount of tables in the data.
if ( table.Count( MyData ) > 0 ) then
	
	// Set the date.
	// YYYY:MM:DD HH:MM:SS
	local Date = SF.Utility.Year .. os.date( "-%m-%d %H:%M:%S" );
	
	// If there's already tables.
	NewTime, Success, Error = mysql.query( SF.Connection, "UPDATE sf_player SET lastlogin = '" .. Date .. "' WHERE steamid = '" .. pl:SteamID() .. "'" );
	
	// Check that it was a success.
	if ( !Success ) then
		
		// IF it wasn't display failed and return.
		SF.Utility.Debug( "2: MYSQL ERROR: " .. Error, "1" );
		return;
		
	end
	
	//NewName, Success, Error = mysql.query( SF.Connection, "UPDATE sf_player SET name = '" .. mysql.escape( SF.Connection, pl:Name() ) .. "' WHERE steamid = '" .. pl:SteamID() .. "'" );
	
	// Check that it was a success.
	//if ( !Success ) then
		
		// IF it wasn't display failed and return.
	//	SF.Utility.Debug( "3: MYSQL ERROR: " .. Error, "1" );
	//	return;
		
	//end
	
	NewAddr, Success, Error = mysql.query( SF.Connection, "UPDATE sf_player SET lastip = '" .. pl:IPAddress() .. "' WHERE steamid = '" .. pl:SteamID() .. "'" );
	
	// Check that it was a success.
	if ( !Success ) then
		
		// IF it wasn't display failed and return.
		SF.Utility.Debug( "4: MYSQL ERROR: " .. Error, "1" );
		return;
		
	end
	
	// Check the existing name.
	//LastName, Success, Error = mysql.query( SF.Connection, "SELECT lastname FROM sf_player WHERE steamid = '" .. pl:SteamID() .. "'" );
	
	//if ( !Success ) then
		
		// Display error.
	//	SF.Utility.Debug( "24924: MYQL ERROR: " .. Error, "1" );
	//	return;
		
	//end
	
	// HALLO joins the game.
	// HALLO is registered in Name and Last Name.
	// HALLO has changed his name to FAGGURT.
	// FAGGURT joins the game.
	// FAGGURT is registered in Name, not Last Name.
	// FAGGURT has changed his name to FREDDO.
	// FREDDO joins the game.
	// FREDDO is registered as the name.
	// FAGGURT is registered as his Last Name.
	// Sorry, practical solutions help me figure these things out. (:
	
	// If the player has a new name then update the last name.
	if ( MyData[ 1 ][ 3 ] ~= pl:Name() ) then
		
		// Update the last name.
		UpdateTehLastName, Success, Error = mysql.query( SF.Connection, "UPDATE sf_player SET lastname = '" .. mysql.escape( SF.Connection, MyData[ 1 ][ 3 ] ) .. "' WHERE steamid = '" .. pl:SteamID() .. "'" );
		
		// Check for success.
		if ( !Success ) then
			
			// Error.
			SF.Utility.Debug( "49239: MYSQL ERROR: " .. Error, "1" );
			return;
			
		end
		
		// Update the last name.
		UpdateTehName, Success, Error = mysql.query( SF.Connection, "UPDATE sf_player SET name = '" .. mysql.escape( SF.Connection, pl:Name() ) .. "' WHERE steamid = '" .. pl:SteamID() .. "'" );
		
		// Check for success.
		if ( !Success ) then
			
			// Error.
			SF.Utility.Debug( "49239: MYSQL ERROR: " .. Error, "1" );
			return;
			
		end
		
	end
	
	/*
		
		Check to see if the blasted user is banned!
		Then check to see if his ban has run out.
		Oh god, this is getting complicated.
		
	*/
	
	// Get data fpr the user.
	UserBan, Success, Error = mysql.query( SF.Connection, "SELECT * FROM sf_bans WHERE steamid = '" .. pl:SteamID() .. "'" );
	
	// Search for mysql errors.
	if ( !Success ) then
		
		// Debug.
		SF.Utility.Debug( "49244: MYSQL ERROR: " .. Error, "1" );
		return;
		
	end
	
	// Make sure they actually have a ban section.
	if ( table.Count( UserBan ) > 0 ) then
		
		// Get the ostime they were banned.
		local OSTime 	= UserBan[ 1 ][ 11 ];
		// Time they were banned for.
		local BanTime 	= UserBan[ 1 ][ 10 ];
		
		// See if BanTime is empty.
		if ( !BanTime || BanTime == "" || BanTime == nil ) then
			
			// Set OSTime to 0 to symbolize that the user isn't banned because he has no ban time.
			OSTime = 0;
			
		elseif ( BanTime ~= 0 ) then
		
			// Times it by 60 to convert the minutes to seconds.
			BanTime 	= BanTime * 60;
			
		end
		
		// If it's 0 then it'll do nothing to it.
		
		// Get the current os time.
		local NowTime	= os.time();
		
		// Add the times.
		local Added		= OSTime + BanTime;
		// So if it was 123456 when you were banned and you were banned for 50.. hmm, hang on a minute this needs to be done in seconds.
		// Ok how do you make minutes into seconds, as ban time is minutes.
		// Right.. so 60 seconds in a minute.
		// So if you had 5 * 60 = 300. So 300 seconds. So we want to x the minutes by 60.
		
		// Check that we're now ahead of that time.
		if ( ( NowTime < Added && OSTime ~= 0 ) || ( BanTime == 0 ) ) then
			
			// Get the reason for the ban.
			local Reason = UserBan[ 1 ][ 8 ];
			
			// Debug.
			SF.Utility.Debug( "Prevented " .. pl:SteamID() .. " (" .. pl:Name() .. ") from playing (" .. Reason .. ").", "1" );
			
			// Kick the mingebag.
			RunConsoleCommand( "kickid", pl:UserID(), Reason );
			
			return;
			
		end
		
	end
	
	// I scrapped the below.
	/*
	// Check the ban field.
	MyBanned, Success, Error = mysql.query( SF.Connection, "SELECT * FROM sf_bans WHERE steamid = '" .. pl:SteamID() .. "'" );
	
	// Check that it was a success.
	if ( !Success ) then
		
		// IF it wasn't display failed and return.
		SF.Utility.Debug( "5: MYSQL ERROR: " .. Error, "1" );
		return;
		
	end
	
	//local Date = SF.Utility.Year .. os.date( "-%m-%d %H:%M:%S" );
	
	// Get data from the query.
	local BanDate 		= MyBanned[ 1 ][ 9 ];
	local BanLength 	= MyBanned[ 1 ][ 10 ];
	
	// Get the current date.
	local CurrentDate = SF.Utility.Year .. os.date( "-%m-%d %H:%M:%S" );
	
	// minge 1 is banned on     2010-02-15  13:37:15
	// minge 1 is banned for    1440 minutes
	// to work this out we need to.. do some complicated mathematics ^^
	// ok first things first, let's convert these minutes to hours. 60 minutes in 1 hour > minutes /60 = hours.
	
	local Hours	= BanLength / 60;		// Amount of hours the minge is banned for.
	
	// Let's attempt to add these hours onto the existing hours.
	local BannedHours = string.Explode( BanDate, " " )[ 2 ];		// This should get the HH:MM:SS bit.
	BannedHours = string.Explode( BannedHours[, ":" )[ 1 ];			// This should get the HH bit.
	
	local CalculateHours = BannedHours + Hours;						// The minge will be unbanned in this many hours.
	
	// Idea scrapped, would of been too inaccurate. We haz to do this through minutes.
	// BanLength = minutes.
	
	// BanDate = YYYY-MM-DD HH:MM:SS
	local BannedMinutes = string.Explode( BanDate, " " )[ 2 ];	// HH:MM:SS
	BannedMinutes = string.Explode( BannedMinutes, ":" )[ 2 ];	// MM
	
	// Add the minutes on...
	//local CalculateMinutes = BannedMinutes + BanLength;
	// Wait; no. Let's make it all into seconds, then add those seconds, then from the final seconds work out hh:mm:ss on mm:dd.
	// Gah, I'm confused. Let's go visit FacePunch.
	*/
	
	/*
		
		End the holy ban section.
		Jesus.. that took some work (and FacePunch's help - kudos to all!)
		
	*/
	
	// If we don't need to ban them then we can set up data for the user.
	//SF.Flags.Storage[ pl:SteamID() ] = MyData[ 1 ][ 4 ];
	SF.Flags.Give( pl, MyData[ 1 ][ 4 ] );
	SF.Time.Start( pl );
	SF.Frags[ pl:SteamID() ] = 0;
	SF.Frags.Storage[ pl:SteamID() ] = 0;
	
	// Display the users connection.
	SF.Utility.ChatAll( pl:Name() .. " has connected. Last known name: " .. MyData[ 1 ][ 8 ] .. "." );
	
		// After 2 seconds show the motd.
		timer.Simple( 2, function()
			
			// Run the function client-side.
			pl:SendLua( "SFSendMOTD()" );
			
		end
	
else
	
	// Debug it.
	SF.Utility.Debug( pl:Name() .. " doesn't exist! Writing new data." );
	SF.MySQL.Player.New( pl );
	
	// Return false.
	return false;
	
end

end

// Create a timer to load the player on initial spawn.
hook.Add( “PlayerInitialSpawn”, “SF.MySQL.Player.Load”, SF.MySQL.Player.Load );[/lua]

Sorry for it’s hugeness.
Everything else in there works, or at least seems to as far as I’ve tested (not tested MOTD); and the debug works too.
I also put it in the function for whenever flags are set/changed.

[lua]// Give a player this flag.
function SF.Flags.Give( pl, Flag )

// Check that the connection is active.
if ( SF.Connection ) then
	
	// Update the flags.
	New, Success, Error = mysql.query( SF.Connection, "UPDATE sf_player SET flags = '" .. Flag .. "' WHERE steamid = '" .. pl:SteamID() .. "'" );
	
	// Check the query.
	if ( !Success ) then
		
		// Debug.
		SF.Utility.Debug( "293091083: MYSQL ERROR: " .. Error, "1" );
		
	end
	
	// Update flag variable.
	SF.Flags.Storage[ pl:SteamID() ] = Flag;
	
	// Match the flags to usergroups.
	if ( SF.Flags.Has( pl, "Y" ) ) then
		
		// Y = superadmin.
		pl:SetUserGroup( "superadmin" );
		SF.Utility.Debug( "Making " .. pl:SteamID() .. " (" .. pl:Name() .. ") a superadmin!" );
		
	elseif ( SF.Flags.Has( pl, "M" ) ) then
		
		// M = admin.
		pl:SetUserGroup( "admin" );
		SF.Utility.Debug( "Making " .. pl:SteamID() .. " (" .. pl:Name() .. ") an admin!" );
		
	else
		
		pl:SetUserGroup( "user" );
		
	end
	
end

end[/lua]

Still to no avail (even though the debugging works).
I suppose I’ll have a look at other admin mods, but they all seem to use this method as far as I’ve checked.

I’ll note that I’ve also tried to override them as they won’t work (yeah still wont work):
[lua]// meta.
local meta = FindMetaTable( “Player” );

// Override.
function meta:IsSuperAdmin()

// Check their user group.
if ( self:IsUserGroup( "superadmin" ) ) then
	
	// Return true.
	return true;
	
end

// If we have no connection return false.
if ( !SF.Connection ) then
	
	// Return.
	return false;
	
end

// If we have the Y flag.
if ( SF.Flags.Has( pl, "Y" ) ) then
	
	// Return true.
	return true;
	
end

// This far? Return false.
return false;

end

// Admin override.
function meta:IsAdmin()

// If we're a superadmin then we're an admin.
if ( self:IsUserGroup( "superadmin" ) ) then
	
	// Return trueeeth!
	return true;
	
end

// Check their user group.
if ( self:IsUserGroup( "admin" ) ) then
	
	// Return true.
	return true;
	
end

// If we have no connection return false.
if ( !SF.Connection ) then
	
	// Return.
	return false;
	
end

// If we have the Y flag.
if ( SF.Flags.Has( pl, "M" ) ) then
	
	// Return true.
	return true;
	
end

// This far? Return false.
return false;

end[/lua]

I’m completely stumped. Unless ULX/ULib has dumped some hidden files, then I’m completely clueless.
Thanks for your persistence, however.

Sorry, i misread, and no, I’m not mentally defected.

Hmm just to be sure why do you need to query a SQL server? Is it for use on several servers?

You could have some other things interfering with your usergroup setting, try adding a timer to make like a 0.5 second wait to run your function.

Yes. It’s a mysql admin mod.
http://permiacs.com/data/ for example.

Thanks Helix Alioth, I’ll try that now.

Damn I was going to suggest this :frowning:

When I made a bridge for SourceMod Admins -> Gmod Admins, I had to add a 1 second delay on the SetUserGroup() method, otherwise the method wouldn’t take effect.

Also usergroups are case sensitive it seems.

So would it be “Admin” instead of “admin”?

I’ve tried the check it seems to have no effect, I’ll try it again in a moment though with some different code.