Repository navigation
Releases
v3.1.1
Requires msk_core 4.1.0
Uses the table forms that msk_core 4.1.0 introduced, so the deprecation warnings in the server console are gone. The notifications are sent as a table, which an older msk_core takes as the title. Update msk_core along with this script.
Added
- The msk_core version is checked on start.
MSK.Check.Dependency('msk_core', '4.1.0', true)logs an error in the server console when msk_core is older, instead of leaving you to wonder why the notifications look wrong. (server/versionchecker.lua)
Changed
-
Config.Notificationpasses a table toMSK.Notification. The form with title, message, type and duration is deprecated since msk_core 4.1.0 and logs a warning once per resource. If you keep your own config, change the twoMSK.Notificationlines the same way. Leaving them works too, the old form is still accepted for now. (config/static.lua) -
The escort hint uses the table form of
MSK.TextUI.Show. (client/main.lua)
Changed files
fxmanifest.lua
config/static.lua
client/main.lua
server/versionchecker.lua
v3.1.0
Requires msk_core 4.0.0
This release reads the player and the job list through the rewritten bridge. On
msk_core 3.x the group lookup returns nothing and the job dropdown stays empty.
Update msk_core along with this script.
Security
msk_core:playerLogoutwas registered as a net event on the server. The
event is server-local, so registering it as a net event let any client fire it
with an arbitrary player id, and here that means clearing somebody else's
handcuff state. It is anAddEventHandlernow.
Fixed
-
The logout handler had never run once. Nothing in msk_core 3.x ever
triggeredmsk_core:playerLogout, so a character switch left the handcuff
state behind. Since msk_core 4.0.0 the event actually fires. A disconnect was
always covered byplayerDroppedand is unaffected. -
On Qbox every player counted as unemployed in the client-side pre-checks.
The job lookup covered ESX and QBCore only. It went through the framework
directly becauseMSK.Bridgeresolved to a function in a consumer resource and
could not be read;MSK.GetPlayerJob()answers in one shape on all three now. -
The job dropdown in the dashboard stayed empty on Qbox, for the same
reason.MSK.GetJobs()covers ESX, QBCore and Qbox. -
The framework group was only ever resolved on ESX. It went through
xPlayer.getGroup(), a method QBCore and Qbox do not have, so an admin without
the matchingadd_principalline was refused there.player.groupis a plain
string on all three frameworks since msk_core 4.0.0. -
The QBCore-only fallback ran on every framework.
GetQbPermissionstarts
with a check that leaves the function unless QBCore is running, and that check
could never pass, because readingMSK.Bridge.Frameworkraised
attempt to index a function value. msk_core 4.0.0 makesMSK.Bridgea real
table.
Changed
- The client restore listens to one event instead of three.
esx:playerLoadedandQBCore:Client:OnPlayerLoadedare gone. They were a
workaround for msk_core 3.x, wheremsk_core:playerLoadednever fired, and
they also triggered the restore up to three times per spawn.
Changed files
fxmanifest.lua
client/main.lua
client/actions.lua
server/main.lua
server/admin/api.lua
server/admin/permissions.lua
v3.0.1
Fixed
-
Your team could not open the admin dashboard, even though the group was set in your
server.cfg. Two things were stacked here. First, FiveM keeps principals and ace objects apart: a line likeadd_principal identifier.license:xxx group.adminonly makes that player a member of the group, it does not create the ace object of the same name that the check was looking for. Unless someone had also writtenadd_ace group.admin group.admin allowby hand, the check came back empty. Second, the frameworks do not even agree on how a group principal is named. ESX usesgroup.admin, QBCore usesqbcore.admin, and that is not something you can configure away, it is what/addpermissionandQBCore.Functions.AddPermissionwrite. QBCore also only ever linksqbcore.godtogroup.admin, so anyone below god level was a member of nogroup.*principal at all. On ESX this often stayed invisible because the group from theuserstable caught it, and that fallback does not exist on QBCore. The script now registers its own ace object per group on start and points both spellings at it, foradmin, for every group inConfig.dashboardGroupsand for every group in the permission matrix. A plainadd_principal ... group.modand a/addpermission 1 modboth get you in now, and groups you add on the Permissions tab are covered right away without a restart. -
Checking a group name on the Permissions tab reported "not found" for brand new groups. The check ran before the group existed as an ace object, so it could never find anyone in it. The group is registered first now.
-
Access denied for command add_acespam on every server start. FiveM checks
add_aceagainst the resource that runs it, and no resource holds that right by
default, so the ace objects were never actually created. Every attempt was refused
and only printed an error. On ESX this went unnoticed because the framework group
caught it. The aces are registered through msk_core now, which is the one resource
your server.cfg already grants that right, and the script checks up front whether it
is allowed instead of spamming the console.
(server/admin/permissions.lua)
Requires msk_core 3.3.0
This release uses MSK.AddRawAce and MSK.CanAddAce, both added in msk_core 3.3.0.
Update msk_core along with this script, and make sure your server.cfg has the msk_core
ace lines. They are the ones the msk_core documentation has always listed and they
cover every MSK script at once:
add_ace resource.msk_core command.add_ace allow
add_ace resource.msk_core command.remove_ace allow
add_ace resource.msk_core command.add_principal allow
add_ace resource.msk_core command.remove_principal allowIf they are missing nothing breaks, the script says so on start and group access falls
back to your framework group.
There is nothing to rebuild and no database change. Replace the resource files and restart it.
Changed files
fxmanifest.lua(version bump)server/admin/permissions.lua(own ace object per group, both principal spellings, QBCore permission fallback)server/admin/boot.lua(registers the ace objects on start)server/admin/api.lua(covers groups added or changed while the server is running)
v3.0.0
This is a big one. Handcuffs was rebuilt from the ground up. It runs on QBCore now as well as ESX, it stores everything in MySQL, it got a real target menu, and it comes with its own in-game admin dashboard. Most of the config moves into the database, so you can manage everything while the server is running.
New
- QBCore support. Next to ESX Legacy the script now runs on QBCore. msk_core detects the framework on its own, you don't set anything.
- Target menu. In v2
Config.Targetonly registered the undrag key, there were no target options at all. You now get a real target integration for ox_target (recommended) and qb-target: cuff, hardcuff, uncuff, ankletracker, headbag, tape, drag, put in car and put out of car, each one switchable inConfig.Target.options.Config.Target.systemis set toautoby default, which picks ox_target when it is running and falls back to qb-target. The entries are translated into the dashboard language and the label follows the current state, so the same option reads "Put on headbag" or "Remove headbag" depending on what is going on. Change the language in the dashboard and the text updates live. - Admin dashboard. Type
/handcuffadminin-game to open it. The Players tab lists everyone online with their current status and lets you cuff, hardcuff and uncuff them and toggle the ankletracker, headbag and tape with one click. On top of that there are tabs for your items, the job restrictions, all the settings and who is allowed in. You can rename the command withConfig.adminCommand. - Permission system. You can give your team access to the dashboard without handing them everything. The rights are split per action, so you can let a moderator cuff and uncuff people without also giving them the settings.
group.admincan always do it all andgroup.usercan never get in. You manage the groups from the Permissions tab, andConfig.dashboardGroupsdecides which groups may open the dashboard at all. - Theme editor. You can recolor the dashboard live from the Settings tab.
- Discord webhook in the dashboard. The webhook is a normal setting now, so you can paste it in from the Settings tab instead of opening a file.
- No item needed to remove (optional). New toggles for the headbag and the tape. By default you no longer need an item to take them off. Turn the toggle on if you want a remove item to be required again.
- Keep the remove items (optional). New toggles so the item you use to remove something is not taken out of the inventory. This covers every remove item now, the ankletracker key, the headbag key, the tape key and the uncuff item (cuff_keys / scissors). Off by default, so keys stay reusable.
- Escort hint. While you drag a cuffed person around, a small TextUI tells you which key lets them go again. It shows the key you actually have bound, so if you rebind the undrag key in the FiveM settings the hint follows along. Translated into every language.
- luxu_admin support. luxu_admin v2 keeps its staff groups to itself instead of registering them as ACE principals, so the dashboard could not see them. It now asks luxu_admin directly. You configure it in
config/static.luaunderConfig.LuxuAdmin: turn it on or leave it on ...