[Tutorial] FakePlayer erstellen

Dieses Thema im Forum "Tutorials" wurde erstellt von trikeyyy, 30. Januar 2016.

  1. trikeyyy
    Offline

    trikeyyy

    Registriert seit:
    9. Januar 2016
    Beiträge:
    8
    Minecraft:
    trikeyyy
    Guten Tag

    In diesem Post stelle ich eine Klasse vor, die FakePlayer ohne ProtocolLib erstellt.
    Das war eines meiner Lieblingsthemen, die ich bisher in Spigot bzw. Bukkit behandelt habe und hoffe, dass ihr auch damit
    Spass haben werdet. :D

    Ich zeige euch die Basics und erkläre alles, was man zuerst braucht.

    Das Basis Objekt, das wir erstellen müssen, ist das Paket selbst. Die PacketPlayOutPlayerInfo Klasse hat mehrere "Constructors". Der Constructor, den wir brauchen, ist der folgende.
    Code (Text):
    1. PacketPlayOutPlayerInfo(EnumPlayerInfoAction action, EntityPlayer... players)
    Man kann sehen, dass das Paket mit einer "Aktion" erstellt wird. Diese Aktion sagt dem Client, was sie tun soll;wird das Paket Spieler erstellen, sie entfernen, ihren Ping aktualisieren, Gamemode oder den Anzeigenamen ändern, usw. Als nächstes gibt es eine "players" Variable. Das bedeutetet, dass man einen Spieler, mehrere Spieler mit einem Komma getrennt oder mit einer ArrayList, die Spieler enthält, hinzufügen kann. Das sind die Spieler, deren Informationen aktualisiert oder gesetzt werden.

    Was übrig bleibt ist der EntityPlayer, den wir erstellen müssen, da der Constructor des Paket public ist und die Aktion des Enums auch.

    EntityPlayer hat nur einen Constructor.
    Code (Text):
    1. EntityPlayer(MinecraftServer server, WorldServer world, GameProfile profile, PlayerInteractManager manager)
    Das Spieler Objekt wird mit ein Paar Einstellungen über den Spieler selbst erstellt. Es benötigt den Server, eine Welt, das Profil vom Spieler und den "InteractManager". Das einzige was für uns wichtig ist, ist das Profil. Das ist die Einstellung, in der man UUID, Skin Daten und Ähnliches hinzufügen kann.

    Die Parameter server, world und manager können einfach abgerufen werden, sodass das einzige, was wir erstellen müssen, das GameProfile ist.

    Das ist der Constructor, den wir benutzen werden.
    Code (Text):
    1. GameProfile(UUID id, String name)
    Das GameProfile Objekt wird mit einer UUID und einem Namen erstellt. Man kann eine zufällige UUID benutzen und den Namen so setzen, wie man ihn will. Aber wenn "name" mit einem echten Spieler, der existiert, zutrifft, werden die Scoreboard Attribute zu dem Spieler hinzugefügt.

    Alles was man nun machen muss, ist dass man alles, was wir bisher gemacht haben, zusammenfügt.


    Als erstes müssen wir das GameProfile erstellen.
    Code (Text):
    1. GameProfile profile = new GameProfile(UUID.randomUUID(), "Ben");
    2. // Erstellt ein neues GameProfile mit einer zufälligen UUID und dem Namen "Ben".
    Als nächstes wird das EntityPlayer Objekt erstellt.
    Code (Text):
    1. MinecraftServer server = MinecraftServer.getServer();
    2. // Übergibt das Minecraft Server Objekt, was als Parameter benötigt wird
    3.  
    4. WorldServer world = server.getWorldServer(0);
    5. // Übergibt den WorldServer für die Oberwelt (0). Wird auch benötigt.
    6.  
    7. PlayerInteractManager manager = new PlayerInteractManager(world);
    8. // Erstellt einen neuen PlayerInteractManager für die Oberwelt.  Wird auch benötigt.
    9.  
    10. EntityPlayer player = new EntityPlayer(server, world, profile, manager);
    11. // Schlussendlich wird das EntityPlayer Objekt mit all den vorherigen Teilen erstellt.
    Jetzt muss man nur noch das Paket erstellen:
    Code (Text):
    1. PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, player);
    2. // Erstell ein Paket, das den "player" zu der Tablist hinzufügen wird.
    Und ganz zum Schluss, wird das Paket an alle Spieler geschickt:
    Code (Text):
    1. for(Player online : Bukkit.getOnlinePlayers()) {
    2.    ((CraftPlayer) online).getHandle().playerConnection.sendPacket(packet);
    3. }
    4. // Für jeden Spieler, der online ist, wird zu einem CraftPlayer "gecastet", holt deren Handle, daraus ihre PlayerConnection und sendet das Paket, das wir erstellt haben.
    Um EntityPlayer Objekte einfacher zu machen, habe ich eine FakePlayer Klasse erstellt.
    FakePlayer: http://pastebin.com/T5Atyjsd

    Um diese Klasse zu benutzen, muss man nur das folgende machen:
    Code (Text):
    1. EntityPlayer player = new FakePlayer("Ben").create();
    Das erstellt einen "Ben", den wir auch oben erstellt haben, nur ein bisschen einfacher. :p

    Man kann aber auch mehr mit dieser Klasse erstellen. Man kann den Namen des Spielers, UUID, Gamemode und den Ping setzen.

    Der folgende Code erstellt einen "Ben" mit dem Gamemode Spectator und den Ping 147:
    Code (Text):
    1. EntityPlayer player = new FakePlayer("Ben").withGameMode(EnumGamemode.SPECTATOR).withPing(147).create();
    Das wars, ich hoffe ihr habt bzw. werdet wie ich Spass damit haben und wenn es noch etwas gibt, lasst es mich wissen. Ich mochte es sehr, das zu lernen und wollte diese Erfahrung mit euch teilen. :D

    Freundliche Grüsse
    trikeyyy

     
    #1
    Lapura, zLyrik und Bot_Jan gefällt das.
  2. Paluffelmuffel
    Offline

    Paluffelmuffel

    Registriert seit:
    18. Juli 2015
    Beiträge:
    2
    Minecraft:
    TVSnatchYT
    Gut beschrieben, klasse!
     
    #2
  3. trikeyyy
    Offline

    trikeyyy

    Registriert seit:
    9. Januar 2016
    Beiträge:
    8
    Minecraft:
    trikeyyy
    #3
  4. Nightishaman
    Offline

    Nightishaman

    Registriert seit:
    3. Januar 2015
    Beiträge:
    51
    Einen Nachteil gibt es bei der Klasse wie du sie verwendest. Es ist nicht auf Reflection ausgelegt und daher nicht versionsunabhängig.
     
    #4
  5. trikeyyy
    Offline

    trikeyyy

    Registriert seit:
    9. Januar 2016
    Beiträge:
    8
    Minecraft:
    trikeyyy
    Ich sehe es nicht unbedingt als Nachteil, da es mich nicht stört.
    Wenn ich die Version aktualisiere, werde ich immer den Code bei jeder Klasse überfliegen und wenn nötig überschreiben.
     
    #5
  6. Kroseida
    Offline

    Kroseida

    Registriert seit:
    28. September 2015
    Beiträge:
    55
    Ort:
    /root/
    Minecraft:
    Kroseida
    Reflection benötigt leider auch mehr performance
     
    #6
  7. Microsamp
    Offline

    Microsamp

    Registriert seit:
    30. Mai 2015
    Beiträge:
    20
    Deswegen cache ich Packets und alles, was Leistung zieht. Ich würde zudem auch empfehlen das ganze soweit wie möglich Asynchron zu handeln, da dies den Haupt-Thread entlastet. Ps: Keine Abfragen, oder Veränderungen der Welten in einem Asynchronen Thread, da dies zu einer Exception führt...

    Deine Klasse ist gut für Anfänger, aber bei beispielsweise größeren Servern nicht gern gesehen.

    ~ Meine Meinung
     
    #7