Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 13 additions & 15 deletions EXILED/Exiled.API/Features/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,12 @@ public Quaternion Rotation
public PlayerPermissions RemoteAdminPermissions
{
get => (PlayerPermissions)ReferenceHub.serverRoles.Permissions;
set => ReferenceHub.serverRoles.Permissions = (ulong)value;
set
{
ReferenceHub.serverRoles.Permissions = (ulong)value;
Group.Permissions = (ulong)value;
ReferenceHub.serverRoles.FinalizeSetGroup();
}
Comment on lines 567 to 571

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would change the whole group permission not only the permissions for this player

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would change the whole group permission not only the permissions for this player

Yes, this does override the permissions for the entire group. But only if the player was assigned a group via "Player.SetRank." If we assign them a group via the "Player.Group" property, this problem doesn't occur. I spent three hours trying to reproduce this issue using the "Player.Group" property and various other manipulations, but I couldn't. However, the fact is: if you assign any permissions to a player using the current implementation of the "Player.RemoteAdminPermissions" property, they don't actually receive them. Access to the RA panel and other functionality are disabled.

Copy link
Author

@PUDGE133 PUDGE133 Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked my code this way after your review. And I still couldn't figure out what was going on. Why does adding a group via a property work differently than via a method?

private void PlayerVerified(VerifiedEventArgs ev)
{
    //ev.Player.SetRank("free_tag", new UserGroup()
    //{
    //    Name = "free_tag",
    //    BadgeColor = "cyan",
    //    BadgeText = "adasda",
    //    Permissions = 0,
    //    Cover = true,
    //    HiddenByDefault = false,
    //    Shared = false,
    //    KickPower = 255,
    //    RequiredKickPower = 255,
    //});
    var group = new UserGroup()
    {
        Name = "free_tag",
        BadgeColor = "cyan",
        BadgeText = "adasda",
        Permissions = 0,
        Cover = true,
        HiddenByDefault = false,
        Shared = false,
        KickPower = 255,
        RequiredKickPower = 255,
    };
    ev.Player.Group = group;
    Log.Debug("");

    foreach (var e in ServerStatic.PermissionsHandler.Groups)
    {
        Log.Debug($"{e.Key} {e.Value.Name} {e.Value.BadgeColor} {e.Value.BadgeText} {e.Value.Permissions} {e.Value.Cover} {e.Value.HiddenByDefault} {e.Value.Shared} {e.Value.KickPower} {e.Value.RequiredKickPower}");
    }
    Log.Debug("");

    ev.Player.RemoteAdminPermissions = (PlayerPermissions)ulong.MaxValue;
    ev.Player.Group.Permissions = ulong.MaxValue;
    ev.Player.ReferenceHub.serverRoles.FinalizeSetGroup();

    foreach (var e in ServerStatic.PermissionsHandler.Groups)
    {
        Log.Debug($"{e.Key} {e.Value.Name} {e.Value.BadgeColor} {e.Value.BadgeText} {e.Value.Permissions} {e.Value.Cover} {e.Value.HiddenByDefault} {e.Value.Shared} {e.Value.KickPower} {e.Value.RequiredKickPower}");
    }
}
image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe first try not having that event be async, while Exiled does support async events, that doesn’t mean your method will work, if anything in that method does anything with mirror somehow, it’ll probably kill the server or soft-dc the client. Also it can very easily cause other errors

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe first try not having that event be async, while Exiled does support async events, that doesn’t mean your method will work, if anything in that method does anything with mirror somehow, it’ll probably kill the server or soft-dc the client. Also it can very easily cause other errors

I don't really have a deep understanding of how this game works. If no one has any ideas on how to fix this, I might revert it back to its original state in the next commit.

}

/// <summary>
Expand Down Expand Up @@ -1033,12 +1038,11 @@ public float Stamina
public bool IsStaffBypassEnabled => ReferenceHub.authManager.BypassBansFlagSet;

/// <summary>
/// Gets or sets the player's group name.
/// Gets the player's group name.
/// </summary>
public string GroupName
{
get => ServerStatic.PermissionsHandler.Members.TryGetValue(UserId, out string groupName) ? groupName : null;
set => ServerStatic.PermissionsHandler.Members[UserId] = value;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why removing this line ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why removing this line ?

There's no point in assigning anything to this dictionary. No functionality is called.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the setter doesn’t work then the getter won’t work. Is that not obvious? Also it’s a breaking change

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the setter doesn’t work then the getter won’t work. Is that not obvious? Also it’s a breaking change

The setter and getter functions work. This only makes sense if you want to retrieve the player's group name. Setting a value in this dictionary doesn't make sense because functionally nothing will change. The player's group will remain the same. This violates data integrity. You assign a group name to a player, but in fact, they don't have the properties of that group. This is literally the most obvious idea, immediately obvious.

}

/// <summary>
Expand Down Expand Up @@ -1082,18 +1086,18 @@ public UserGroup Group
}

/// <summary>
/// Gets or sets the player's rank color.
/// Gets or sets the player's badge color.
/// </summary>
public string RankColor
public string BadgeColor
{
get => ReferenceHub.serverRoles.Network_myColor;
set => ReferenceHub.serverRoles.SetColor(value);
}

/// <summary>
/// Gets or sets the player's rank name.
/// Gets or sets the player's badge name.
/// </summary>
public string RankName
public string BadgeText
{
get => ReferenceHub.serverRoles.Network_myText;
set => ReferenceHub.serverRoles.SetText(value);
Expand Down Expand Up @@ -1915,25 +1919,19 @@ public bool TryGetItem(ushort serial, out Item item)
}

/// <summary>
/// Sets the player's rank.
/// Receives an existing rank(group) or, if it doesn't exist, creates a new one and assigns it to this player.
/// </summary>
/// <param name="name">The rank name to be set.</param>
/// <param name="group">The group to be set.</param>
public void SetRank(string name, UserGroup group)
public void SetGroup(string name, UserGroup group)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed breaking change

{
if (ServerStatic.PermissionsHandler.Groups.TryGetValue(name, out UserGroup userGroup))
{
userGroup.BadgeColor = group.BadgeColor;
userGroup.BadgeText = name;
userGroup.HiddenByDefault = !group.Cover;
userGroup.Cover = group.Cover;

ReferenceHub.serverRoles.SetGroup(userGroup, false, false);
}
else
{
ServerStatic.PermissionsHandler.Groups.Add(name, group);

ReferenceHub.serverRoles.SetGroup(group, false, false);
}

Expand Down
6 changes: 3 additions & 3 deletions EXILED/Exiled.CreditTags/CreditTags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ internal bool ShowCreditTag(Player player, bool force = false)
void ShowRank(RankType rank)
{
bool canReceiveCreditBadge = force ||
(((string.IsNullOrEmpty(player.RankName) &&
(((string.IsNullOrEmpty(player.BadgeText) &&
string.IsNullOrEmpty(player.ReferenceHub.serverRoles.HiddenBadge)) ||
Config.BadgeOverride) && player.GlobalBadge is null);
bool canReceiveCreditCustomInfo = string.IsNullOrEmpty(player.CustomInfo) || Config.CustomPlayerInfoOverride;
Expand Down Expand Up @@ -111,8 +111,8 @@ void ShowRank(RankType rank)

private void SetCreditBadge(Player player, Rank value)
{
player.RankName = value.Name;
player.RankColor = value.Color;
player.BadgeText = value.Name;
player.BadgeColor = value.Color;
Log.Debug($"Updated {player.Nickname} badge to {value.Name}.");
}

Expand Down
Loading