You are not logged in.

  • Login
Bitte besucht unser neues Forum unter https://forum.nitrado.net | Please visit our new Forum at https://forum.nitrado.net

MrAngel08

User / Kunde

  • "MrAngel08" is male
  • "MrAngel08" started this thread

Posts: 339

Location: Deutschland

Occupation: Schüler

Thanks: 1

  • Send private message

1

Monday, November 7th 2016, 3:38pm

[Tutorial] Eigenes Permission-Plugin - spezielle Rechte

Hey liebe Nitrado-Community,

ihr wollt euer Permission-Plugin mit *-Rechten oder negativen Permissions modifizieren, wisst aber nicht wie das geht? Dann habt ihr Glück, denn ich möchte euch heute zeigen, wie ihr das umsetzen könnt.

Zuerst müssen wir aber wissen, wo wir uns einklinken werden.
In der CraftHumanEntity-Klasse gibt es Feld namens perm. Und genau dieses Feld werden wir uns zu nutze machen.
Dieses Feld ist eine Instanz der Klasse PermissibleBase. Deshalb werden wir nun eine Klasse erstellen, die von PermissibleBase erbt.

Spoiler Spoiler


Java source code

1
2
3
    public class CustomPermissibleBase extends PermissibleBase {

    }




Nun erstellen wir uns einen Konstruktor (falls er nicht automatisch erstellt wird) und geben als ersten Parameter einen ServerOperator an.
In diesem Konstruktor rufen wir nun den Konstruktor der Superklasse auf.

Das ganze sollte nun ungefähr so aussehen:

Spoiler Spoiler


Java source code

1
2
3
4
5
    public class CustomPermissibleBase extends PermissibleBase  {
          public CustomPermissibleBase(ServerOperator op) {
         super(op);
       }
    }



Nun können wir anfangen, die hasPermission-Methode zu überschreiben. Als erstes fange ich mit den 'negativen' Rechten an. Dazu fragen wir einfach ab, ob der ServerOperator (in dem Fall wird es der Spieler sein) die Permission -permission oder -* hat. Wenn er die Permission hat, dann returnen wir einfach false.

Es sollte jetzt ungefähr so aussehen:

Spoiler Spoiler


Java source code

1
2
3
4
5
6
      @Override
      public boolean hasPermission(String inName) {
           if(super.hasPermission("-" + inName) || super.hasPermission("-*")) {
                 return false;
           }
      }



Nun wende ich mich der 'Universalpermission' zu.
Das ist eigentlich fast das selbe wie oben, nur ohne dem Bindestrich und das es true returnt. Ich denke, das schafft ihr alleine ^^
Zum Schluss returnen wir einfach die hasPermission-Methode der Superklasse mit dem Input-String, damit die restlichen Permissions, die der Spieler hat bzw. nicht hat, ebenfalls abgefragt werden.

Das gesamte Bild sollte nun so aussehen:

Spoiler Spoiler


Java source code

1
2
3
4
5
6
7
8
9
10
      @Override
      public boolean hasPermission(String inName) {
           if(super.hasPermission("-" + inName) || super.hasPermission("-*")) {
                 return false;
           }
           if(super.hasPermission("*")) {
                return true;
           } 
           return super.hasPermission(inName);
      }




Nun müssen wir noch die Klasse in die CraftHumanEntity-Klasse einschleusen. Da das Feld aber den Modifier final besitzt, wird es ein bisschen schwieriger als normalerweise. Dazu kommt noch ein unschöner Import der CraftHumanEntity-Klasse. Diese Klasse werden wir aber einfach mit Reflections holen, damit der Import wegfällt.
Wir erstellen uns nun eine statische Methode, mit der wir das Feld perm mit unsere Klasse austauschen können. In dieser Methode werden wir einen Parameter angeben, undzwar den Player. Diese Methode sollte nun ungefähr so aussehen:

Spoiler Spoiler


Java source code

1
2
3
4
5
6
7
8
9
   public static void inject(Player p) throws Exception {
      String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
      Field field = Class.forName("org.bukkit.craftbukkit." + version + ".entity.CraftHumanEntity").getDeclaredField("perm");  
      field.setAccessible(true); 
      Field modifiersField = field.getClass().getDeclaredField("modifiers");  
      modifiersField.setAccessible(true);   
      modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
      field.set(p, new CustomPermissibleBase(p));
}



Diese Methode rufen wir beim PlayerJoinEvent sowie im onEnable-Teil des Plugins auf.
Warum jetzt im onEnable-Teil?
Der Server könnte reloaden und dann wird die Klasse einfach ersetzt. Wir müssen einfach nur im onEnable-Teil jeden Spieler die Klasse setzen und sind auf der sicheren Seite.

Hier nochmal die ganze Klasse im Überblick:

Spoiler Spoiler


Java source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
   public class CustomPermissibleBase extends PermissibleBase { 
      
      public CustomPermissibleBase(ServerOperator op) {
         super(op);
      }

     @Override 
     public boolean hasPermission(String inName) {
         if(super.hasPermission("-" + inName) || super.hasPermission("-*")) {
             return false;
         }
         if(super.hasPermission("*")) {
              return true;
         }
         return super.hasPermission(inName);
     }


   public static void inject(Player p) throws Exception {
      String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
      Field field = Class.forName("org.bukkit.craftbukkit." + version + ".entity.CraftHumanEntity").getDeclaredField("perm");  
      field.setAccessible(true); 
      Field modifiersField = field.getClass().getDeclaredField("modifiers");  
      modifiersField.setAccessible(true);   
      modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
      field.set(p, new CustomPermissibleBase(p));
    }
}



Ich hoffe damit haben sich einige Fragen geklärt.

Wenn ihr einen Fehler findet, dann sagt bitte an wo. Ich bin grad am Handy und weiß deshalb nicht, ob die ein oder andere Klammer fehlt.

MfG MrAngel08

This post has been edited 4 times, last edit by "MrAngel08" (Dec 28th 2017, 12:12pm) with the following reason: Die wundervollen Klammern


BtoBastian

Moderator

  • "BtoBastian" is male

Posts: 3,612

Occupation: Softwareentwickler

  • Send private message

2

Tuesday, November 8th 2016, 7:44pm

Interessant.
Habe bisher immer nur gehört, dass man Reflection nutzen muss, wenn man "advanced" Permissions mit * oder - programmieren will, aber wie genau das funktioniert war mir bis jetzt noch unbekannt.
Danke, auch wenn ich vermutlich nie ein Permissions Plugin programmieren werden. :)
Standard Standart eines Flamingos ist einbeinig.

xtrumb

User / Kunde

  • "xtrumb" is male

Posts: 2,295

Location: hier

Occupation: Fachinformatiker für Systemintegration

Thanks: 16

  • Send private message

3

Wednesday, November 9th 2016, 9:28am

Sehr interessant und gut zu Wissen, danke :)
Mit freundlichen Grüßen
TrueMB

Dienstleistungs Service
Unser Csgo Team

BlueMinerHD

User / Kunde

Posts: 3

  • Send private message

4

Wednesday, December 27th 2017, 10:01pm

Sehr interessant. Ich habe es gleich mal ausprobiert und es funktioniert perfekt. Vielen Dank!
Ich wollte dich aber noch drauf hinweisen das in der Methode hasPermission in Zeile 9 am Ende eine Klammer fehlt. Genau das gleiche auch in Zeile 12.

MrAngel08

User / Kunde

  • "MrAngel08" is male
  • "MrAngel08" started this thread

Posts: 339

Location: Deutschland

Occupation: Schüler

Thanks: 1

  • Send private message

5

Thursday, December 28th 2017, 12:10pm

Sehr interessant. Ich habe es gleich mal ausprobiert und es funktioniert perfekt. Vielen Dank!
Ich wollte dich aber noch drauf hinweisen das in der Methode hasPermission in Zeile 9 am Ende eine Klammer fehlt. Genau das gleiche auch in Zeile 12.


Haha, danke xD
Ich wusste doch, dass da irgendwo Klammern fehlen ^^

xMarzl

User / Kunde

  • "xMarzl" is male

Posts: 121

Location: xMarzl.getLocation();

Occupation: Azubi

  • Send private message

6

Thursday, February 22nd 2018, 9:34am

Sehr hilfreich und einfach.
Danke dir!
Bei Fragen kannst du mich gern privat anschreiben .

Bitte besucht unser neues Forum unter https://forum.nitrado.net| Please visit our new Forum at https://forum.nitrado.net