/custom-items-gradle

Knokko's Custom Items: Add custom items to your server, completely free of charge

Primary LanguageJavaMIT LicenseMIT

Knokko's Custom Items

This is the source code for the Knokko's Custom Items minecraft plug-in:

This plug-in makes it possible to add custom items with their own textures, without sacrificing existing minecraft items. (At least, if the (server) resourcepack is used.)

How the custom texture system works

Normally, resourcepacks are used to change the textures of regular minecraft items to something that looks better. However, modern minecraft versions have resourcepack predicates, which make it possible to only assign custom textures to items under the right circumstances. One of these predicates allows the resourcepack to base its decision on whether the item stack to be shown is unbreakable or has lost durability. The resourcepacks generated by the Editor will assign different textures to item stacks that have lost durability, but are unbreakable. Such items clearly can't be obtained legitimately (players can't even obtain unbreakable items, let alone unbreakable items that lost durability). But, the plug-in can construct such items via the Bukkit API, which is how it will spawn such custom items in-game. The system described here is used to achieve the custom textures. The rest of the custom item features is not so special.

Repository structure

This repository is split into several modules:

bit-helper

The bit-helper module is a small library of mine that is used for compact binary (de)serialization. When I started this plug-in, I thought it was a good idea to use this, but I am starting to see its limitations. Nevertheless, it is very stable (has been used in production for more than 4 years without any failures) and its results are still quite good (although they could be improved).

editor

This module is the source code for the Editor. This is a GUI application that users must use to configure the plug-in. The users must download it and run it on their computer. Using this GUI, they can configure their custom items (choose their textures, attack damage, display name, and lots of other stuff...).

ce-event-handler

This module is the (tiny) part of the plug-in that directly depends on CrazyEnchantments. Because CrazyEnchantments is compiled with Java 17 and the plug-in module needs to be compatible with Java 8, I can't just put this inside the plug-in module. Some special built steps are used to ensure that ce-event-handler will be compiled using Java 17.

gui

This module is a small gui library that I made a couple of years ago. When I started this custom items plug-in, I thought it was a good idea to use this library to write the Editor. After using it for a few years, I started seeing the limitations of this library: the scale of everything is based on the size of the window. This has the benefit that the editor will look the same to everyone, regardless of their screen resolution (try resizing your window to see what I mean), but has the drawback that this can cause distortion of text and images. Also, it lacks many interesting features that would have avoided the need of implementing all views myself. Switching to a different GUI library might be a good idea, but I am not so sure the amount of work is worth it.

kci-nms...

This project has many kci-nms modules. These modules take care of features that require a different implementation for each minecraft version. For instance, these modules take care of NMS and some features that were added to the Bukkit API in later minecraft versions. The kci-nms module itself defines the interface that is implemented by all the kci-nmsXX modules. Each kci-nmsXX module implements these interfaces for minecraft 1.XX. The modules kci-nms13plus and kci-nms16plus facilitate code reuse between kci-nms13 and later and kci-nms16 and later, respectively. Unfortunately, not every kci-nmsXX module requires the same Java version, so this system is annoying. To work around this problem, kci-nms17 and later are 'disabled' by default: they are commented out in build.gradle and are not present in settings.gradle. So, unless you 'enable' them manually, development builds of this plug-in will not support minecraft 1.17 and later. However, I did enable them in GitHub Actions, so these versions will be supported by release builds.

plug-in

This module is the source code of the custom items plug-in itself. The plug-in essentially finds the binary configuration file generated by the Editor, deserializes it, and makes sure that everything configured in the Editor actually happens in-game.

shared-code

This module contains the code that is used by both the Editor and the plug-in.

Development

Getting started

BuildTools

Before you can compile this project, you will need to get BuildTools from https://www.spigotmc.org/wiki/buildtools/ and then run the following commands using Java 8:

  • java -jar BuildTools.jar --rev 1.12.2 --compile CRAFTBUKKIT
  • java -jar BuildTools.jar --rev 1.13.2 --compile CRAFTBUKKIT
  • java -jar BuildTools.jar --rev 1.14.4 --compile CRAFTBUKKIT
  • java -jar BuildTools.jar --rev 1.15.2
  • java -jar BuildTools.jar --rev 1.16.5

Due to some juridical conflict, it is illegal to publish the entire craftbukkit jar, but it is legal to build it on your own computer using BuildTools... https://www.spigotmc.org/threads/why-exactly-does-the-buildtool-exist.341013/

IDE

You will probably want to use an IDE to work on this project. Regardless of your IDE, you should first clone, fork, or download this project as a ZIP file. If you downloaded it as a ZIP file, you also need to extract it. Then, you should open it in an IDE. For Eclipse, use File -> Import -> Gradle -> Existing Gradle Project -> Navigate file explorer to wherever you downloaded this project to and click on the root folder (normally custom-items). This might take a while the first time, so have some patience. For Intellij, use File -> Open... -> Navigate file explorer to wherever you downloaded this project and click on the root folder (normally custom-items). Then it should start doing all kinds of Gradle stuff on the background, and you should wait for that to complete. It may happen that Intellij won't recognize imports yet after this step (this happens on my computer). You can fix it by restarting Intellij.

Testing

Run ./gradlew test to execute the unit tests.

Deployment

In development, you can use ./gradlew shadowJar to create a plug-in jar that should work on minecraft 1.12 to minecraft 1.16. You can find it in plug-in/build/libs/plug-in-all.jar. Testing on later minecraft versions can be done by manually modifying build.gradle and settings.gradle. In particular, you need to uncomment the kci-nmsXX project for the corresponding minecraft version in build.gradle and add it to settings.gradle. The Editor can be found in editor/build/libs/editor-all.jar, which you can double-click to run it. However, this is not very interesting since you can also just run the Editor via your IDE.

For production, you should simply push all your changes to GitHub, which will cause a GitHub Actions workflow to produce everything. Unlike the development build, this will work on all minecraft versions supported by this plug-in. Everything will be put in a releases.zip artifact for the commit, which contains the following files:

  • CustomItems.jar: the jar file that should be put in the plugins folder of the server
  • Editor.jar the 'raw' Editor: people with a Java installation can double-click it to run the Editor.
  • editor-linux.zip: Linux users without Java installation can download this, extract the contents, and double-click editor to run the Editor
  • editor-macosx.zip: Mac users without Java installation should be able to run the Editor using this file, but I'm not exactly sure how since I don't have a Mac
  • editor-windows.zip: Windows users without Java installation can download this, extract the contents, and double-click editor.exe to run the Editor

The primary advantage of the 'raw' Editor.jar over the native editors is that it is significantly smaller since it doesn't need to bundle a complete JRE.

Adding CustomItems as dependency to your own project

Without build system

If you don't like build systems, you can simply download CustomItems.jar from Spigot or BukkitDev and add it to your classpath.

Gradle

Add the Jitpack maven repository:

repositories {
    // Your current repositories...
    maven { url 'https://jitpack.io' }
}

And add the modules you want to your dependencies:

dependencies {
    // Your current dependencies...
    
    // You probably want shared-code and plug-in
    compileOnly 'com.github.knokko.custom-items-gradle:shared-code:master-SNAPSHOT'
    compileOnly 'com.github.knokko.custom-items-gradle:plug-in:master-SNAPSHOT'
    
    // You may also want to have e.g. the Editor
    compileOnly 'com.github.knokko.custom-items-gradle:editor:master-SNAPSHOT'
}

Maven

Add the Jitpack maven repository:

<repositories>
    # Your current repositories...
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

And add the modules you want to your dependencies:

# Your current dependencies...
<dependency>
    <groupId>com.github.knokko.custom-items-gradle</groupId>
    <artifactId>shared-code</artifactId>
    <version>master-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>com.github.knokko.custom-items-gradle</groupId>
    <artifactId>plug-in</artifactId>
    <version>master-SNAPSHOT</version>
</dependency>