Import support for multiple Minecraft versions?

Discussion in 'Spigot Plugin Development' started by HydroTekZ, May 26, 2017.

  1. Let's say I want these classes, but also for v1.10.
    Code (Text):
    import net.minecraft.server.v1_11_R1.EntityPlayer;

    import net.minecraft.server.v1_11_R1.IChatBaseComponent;
    import net.minecraft.server.v1_11_R1.IChatBaseComponent.ChatSerializer;
    import net.minecraft.server.v1_11_R1.PacketPlayOutChat;
    import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer;
    import net.minecraft.server.v1_11_R1.MinecraftServer;
    How do I make support for v1.10 and still have support for v1.11 in the same jar?
     
    • Agree Agree x 1
  2. You have to use reflections for this. Getting a package by the current version
     
    • Agree Agree x 1
  3. o/ Fellow norwegian :p </offtopic>

    You can use abstraction with multiple modules/subprojects (depending on Maven/Gradle) and compile all of them into one.
    https://www.spigotmc.org/wiki/nms-on-different-versions-without-reflection/
     
    • Like Like x 1
    • Agree Agree x 1
    • Friendly Friendly x 1
  4. If you think you must use reflection for it, you don't know the JVM and Java very well. It's entirely possible with more imports per class which don't exist, and easier with abstraction, which is something you should've quite quickly thought of.
     
    • Agree Agree x 2
  5. What I do is check the version using getServer().getVersion().contains(Version), then use a net.minecraft.server.[Version].[something]. I do this for every version I want to be included.
     
    • Like Like x 1
    • Agree Agree x 1
  6. Just use reflections but i hate them. Or use the ProtocolLIB Api
     
    #6 roboalex, May 26, 2017
    Last edited: May 26, 2017
  7. Just a thought, but can I just do this?
    Code (Text):
            try {
                Class.forName("net.minecraft.server.v1_11_R1.MinecraftServer");
                return net.minecraft.server.v1_11_R1.MinecraftServer.getServer().recentTps;
            } catch( ClassNotFoundException e ) {}
            try {
                Class.forName("net.minecraft.server.v1_8_R3.MinecraftServer");
                return net.minecraft.server.v1_8_R3.MinecraftServer.getServer().recentTps;
            } catch( ClassNotFoundException e ) {}
     
  8. I think this would, but I'd prefer using ifs and elses. In my opinion, it's much easier to read.
     
  9. I would use reflection, but it is possible doing it with version supportive classes
    example: ChatPacket_1_11_R1.class, ChatPacket_1_10_R1.class, ChatPacket_1_8_R3.class
     
  10. Choco

    Moderator

    Hold on... what are you even trying to do? From what we understand so far and based on the imports you have currently, I'm guessing you're trying to send either an actionbar/title to a Player in order to display the recent TPS of the server. Am I correct? If this is the case, you hardly need any NMS whatsoever and might as well use reflection only to retrieve the tps

    You can send a Player an action bar using the Player.Spigot#sendMessage() method. No NMS involved.
    Code (Java):
    player.spigot().sendMessage(ChatMessageType.ACTION_BAR, "This is an action bar");
     
    #11 Choco, May 26, 2017
    Last edited: May 26, 2017
    • Agree Agree x 1
  11. One generally call it Player.Spigot, even in this case, especially as that is the notation for JavaDocs, and in the JavaDocs, it'd be Player.Spigot and due to the capital S, it's a notation for a new class, enum or pretty much anything "classy". (haaaaa)

    To my fellow viking (OP): Use Choco's suggestion instead.
     
    • Like Like x 1
  12. Choco

    Moderator

    I fixed it just for you, bb <3 (Thanks for letting me know ;))