1+ package space .essem .image2map ;
2+
3+ import me .lucko .fabric .api .permissions .v0 .Permissions ;
4+ import net .fabricmc .loader .api .FabricLoader ;
5+ import net .minecraft .commands .CommandSourceStack ;
6+ import net .minecraft .resources .Identifier ;
7+ import net .minecraft .server .permissions .Permission ;
8+ import net .minecraft .server .permissions .PermissionLevel ;
9+ import net .minecraft .world .entity .player .Player ;
10+
11+ import java .lang .invoke .MethodHandle ;
12+ import java .lang .invoke .MethodHandles ;
13+ import java .util .function .Predicate ;
14+
15+ /**
16+ * Temporary wrapper for permission checks, targets yet to be merged fabric-permission-api-v1, making the mod support it before it's finalized.
17+ * Also contains a fallback when it's not present or it changes and fails to adapt.
18+ */
19+ public class FabricPermissionBridge {
20+ public static final boolean IS_LOADED = FabricLoader .getInstance ().isModLoaded ("fabric-permission-api-v1" );
21+ public static final boolean IS_LOADED_LEGACY = FabricLoader .getInstance ().isModLoaded ("fabric-permissions-api-v0" );
22+
23+ private static MethodHandle permissionCheckCallPlayerLevel ;
24+ private static MethodHandle permissionCheckCallCommandLevel ;
25+ private static MethodHandle permissionCheckCallPlayerBool ;
26+ private static MethodHandle permissionCheckCallCommandBool ;
27+ private static final boolean enabledFabric ;
28+
29+ public static boolean checkPermission (Player player , Identifier permission , PermissionLevel level ) {
30+ if (enabledFabric ) {
31+ try {
32+ return (boolean ) permissionCheckCallPlayerLevel .bindTo (player ).invokeExact (permission , level );
33+ } catch (Throwable e ) {
34+ e .printStackTrace ();
35+ // Should never happen!
36+ }
37+ }
38+
39+ if (IS_LOADED_LEGACY ) {
40+ return Permissions .check (player , permission .toShortLanguageKey ().replace ('/' , '.' ), level );
41+ }
42+
43+ return player .permissions ().hasPermission (new Permission .HasCommandLevel (level ));
44+ }
45+
46+ public static boolean checkPermission (CommandSourceStack player , Identifier permission , PermissionLevel level ) {
47+ if (enabledFabric ) {
48+ try {
49+ return (boolean ) permissionCheckCallCommandLevel .bindTo (player ).invokeExact (permission , level );
50+ } catch (Throwable e ) {
51+ e .printStackTrace ();
52+ // Should never happen!
53+ }
54+ }
55+
56+ if (IS_LOADED_LEGACY ) {
57+ return Permissions .check (player , permission .toShortLanguageKey ().replace ('/' , '.' ), level );
58+ }
59+
60+ return player .permissions ().hasPermission (new Permission .HasCommandLevel (level ));
61+ }
62+
63+ public static boolean checkPermission (Player player , Identifier permission , boolean defaultValue ) {
64+ if (enabledFabric ) {
65+ try {
66+ return (boolean ) permissionCheckCallPlayerBool .bindTo (player ).invokeExact (permission , defaultValue );
67+ } catch (Throwable e ) {
68+ e .printStackTrace ();
69+ // Should never happen!
70+ }
71+ }
72+
73+ if (IS_LOADED_LEGACY ) {
74+ return Permissions .check (player , permission .toShortLanguageKey ().replace ('/' , '.' ), defaultValue );
75+ }
76+
77+ return defaultValue ;
78+ }
79+
80+ public static boolean checkPermission (CommandSourceStack player , Identifier permission , boolean defaultValue ) {
81+ if (enabledFabric ) {
82+ try {
83+ return (boolean ) permissionCheckCallCommandBool .bindTo (player ).invokeExact (permission , defaultValue );
84+ } catch (Throwable e ) {
85+ e .printStackTrace ();
86+ // Should never happen!
87+ }
88+ }
89+
90+ if (IS_LOADED_LEGACY ) {
91+ return Permissions .check (player , permission .toShortLanguageKey ().replace ('/' , '.' ), defaultValue );
92+ }
93+
94+ return defaultValue ;
95+ }
96+
97+ public static Predicate <CommandSourceStack > require (Identifier permission , PermissionLevel level ) {
98+ return ctx -> checkPermission (ctx , permission , level );
99+ }
100+
101+ public static Predicate <CommandSourceStack > require (Identifier permission , boolean def ) {
102+ return ctx -> checkPermission (ctx , permission , def );
103+ }
104+
105+ private static MethodHandle findCheckPermission (Class <?> object , Class <?> fallback ) throws Throwable {
106+ var lookup = MethodHandles .publicLookup ();
107+ var meth = object .getMethod ("checkPermission" , Identifier .class , fallback );
108+ return permissionCheckCallCommandLevel = lookup .unreflect (meth );
109+ }
110+
111+ static {
112+ var e = false ;
113+ if (IS_LOADED ) {
114+ try {
115+ permissionCheckCallPlayerLevel = findCheckPermission (Player .class , PermissionLevel .class );
116+ permissionCheckCallCommandLevel = findCheckPermission (CommandSourceStack .class , PermissionLevel .class );
117+ permissionCheckCallPlayerBool = findCheckPermission (Player .class , boolean .class );
118+ permissionCheckCallCommandBool = findCheckPermission (CommandSourceStack .class , boolean .class );
119+ e = true ;
120+ } catch (Throwable err ) {
121+ err .printStackTrace ();
122+ }
123+ }
124+ enabledFabric = e ;
125+ }
126+ }
0 commit comments