Create roles and permissions
Use a custom role when several users need the same access. Use a new permission key when you add a server feature with its own access check.
Create a custom role
Section titled “Create a custom role”This example creates an event_host role that can send alerts in rooms the user owns. Run the SQL against your emulator database after taking a backup.
-
Check that the slug is unused and that the permission exists:
SELECT id, slug FROM roles WHERE slug = 'event_host';SELECT `key`, is_orphan FROM acl_permissionsWHERE `key` = 'command.roomalert';Continue only if the first query returns no role and the second returns the key with
is_orphan = 0. On a new database, the emulator has not checked its keys yet, so many keys still showis_orphan = 1. Start the emulator once, then run the query again. -
Create the role and grant the permission in one transaction:
START TRANSACTION;INSERT INTO roles (slug, name, description, weight, security_level, is_staff)VALUES ('event_host', 'Event host', 'Hosts room events.', 10, 1, 0);INSERT INTO role_permissions (role_id, permission_key)SELECT id, 'command.roomalert' FROM roles WHERE slug = 'event_host';COMMIT;If either insert fails, run
ROLLBACKinstead ofCOMMIT. Choose a weight below the staff who will assign this role. -
In room chat, reload the access definitions:
:update permissionsThis requires both
command.updateandcommand.update_rights. A server restart also loads the definitions. -
Assign the role from an account that meets the role management requirements:
:giverole Alice event_host -
Have Alice enter
:commandsin a room. Check that:roomalertappears. -
In a room Alice owns, enter
:roomalert Welcome to the event. Another user in the room should receive the alert.
Sending a room alert in someone else’s room also requires moderation.alert.
Grant an existing permission
Section titled “Grant an existing permission”To add another registered permission to the same role, insert an exact key:
INSERT INTO role_permissions (role_id, permission_key)SELECT id, 'command.roombadge' FROM roles WHERE slug = 'event_host';Use a key from the active registry:
SELECT `key`, descriptionFROM acl_permissionsWHERE is_orphan = 0ORDER BY `key`;Reload with :update permissions after each set of changes. The reload refreshes online users too.
Grant exact keys when possible. A wildcard such as command.* also grants new matching permissions after a future update.
Add a new permission key
Section titled “Add a new permission key”Adding a row to acl_permissions alone does not implement a permission. The running server builds its registry from code and marks unregistered database entries as orphaned.
To add access control for a new server feature:
-
Add a public string constant to
HabboHotel/Permissions/PermissionKeys.cs. For an event schedule feature, an example is:public const string EventsScheduleManage = "events.schedule.manage"; -
Check the permission in the server operation before changing data:
if (!session.GetHabbo().Access.Can(PermissionKeys.EventsScheduleManage)) {return;}This example belongs in an authenticated handler where
session.GetHabbo()is available. A client-side button check alone does not protect the operation. -
Build and deploy the changed emulator. Restart it so the registry includes the new key.
-
Add
events.schedule.manageto the intended role’srole_permissionsrows. -
Reload permissions and verify the feature with both an allowed account and an account without the permission.
For a chat command, use command.<key>, where <key> is the command’s Key value. CommandManager checks this permission automatically. Register the constant as well.
For an incoming packet handler, [RequiresPermission(PermissionKeys.EventsScheduleManage)] applies a server permission check before the handler runs. If the attribute lists several permissions, the user needs all of them.
See Ranks and permissions for how grants, denies, and multiple roles combine.