Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
4b4abc0
feat: add Hytale platform support with bootstrap, platform module, an…
LeeGodSRC Jan 20, 2026
738f0bf
feat: Added hytale test plugin
LeeGodSRC Jan 20, 2026
586a191
feat: add hytale-command module with player command support
LeeGodSRC Jan 20, 2026
c9e1883
feat: redesign RunHytaleServer to support development mode with loose…
LeeGodSRC Jan 20, 2026
ae74be7
feat(hytale-command): support mixed context types allowing console to…
LeeGodSRC Jan 21, 2026
7577af8
chore(modules-bom): add hytale-bom to modules BOM
LeeGodSRC Jan 21, 2026
0e68f3a
feat(hytale-platform): add HytaleILogger integration
LeeGodSRC Jan 21, 2026
dc59e5d
fix(gradle-plugin): add FairyExtension inputs to GenerateHytaleManife…
LeeGodSRC Jan 21, 2026
e2fa7c5
chore: bump version to 0.8.5b1-hytale3-SNAPSHOT
LeeGodSRC Jan 21, 2026
a5cef65
fix: address Codacy code quality issues in Hytale modules
LeeGodSRC Jan 21, 2026
561a6ab
fix: address additional Codacy code quality issues
LeeGodSRC Jan 21, 2026
babb548
fix: extract PLUGIN_NAME constant and reduce function count
LeeGodSRC Jan 21, 2026
2d9bd91
fix: add KDoc to companion object and reduce function count to 10
LeeGodSRC Jan 21, 2026
a11d3b9
feat(hytale-platform): add RegisterAsEntitySystem and RegisterAsChunk…
LeeGodSRC Jan 26, 2026
29f8506
refactor(gradle-plugin): use entries instead of values() and extract …
LeeGodSRC Jan 26, 2026
91b9d3e
chore: bump version to 0.8.5b1-hytale5-SNAPSHOT
LeeGodSRC Jan 26, 2026
ea2d843
feat(test-hytale-plugin): implement ExampleSystem using RegisterAsEnt…
LeeGodSRC Jan 26, 2026
d450e14
feat: add fairy.json support to gradle plugin resource action
LeeGodSRC Jan 26, 2026
b88a4df
chore: update dependencies to latest versions in build.gradle.kts
LeeGodSRC Feb 1, 2026
105a6c7
feat: update project to use Java 25 and upgrade Lombok to version 1.1…
LeeGodSRC Feb 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions build-logic/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ dependencies {
compileOnly(gradleApi())
compileOnly("org.codehaus.groovy:groovy-all:3.0.9")

implementation("org.yaml:snakeyaml:1.29")
implementation("org.yaml:snakeyaml:2.0")

compileOnly("org.projectlombok:lombok:1.18.32")
annotationProcessor("org.projectlombok:lombok:1.18.32")
compileOnly("org.projectlombok:lombok:1.18.40")
annotationProcessor("org.projectlombok:lombok:1.18.40")
compileOnly("org.jetbrains:annotations:23.0.0")
annotationProcessor("org.jetbrains:annotations:23.0.0")

implementation("com.google.code.gson:gson:2.8.9")
implementation("com.google.guava:guava:32.0.0-android")
implementation("org.apache.commons:commons-lang3:3.12.0")
implementation("org.ow2.asm:asm:9.7")
implementation("org.ow2.asm:asm-commons:9.7")
implementation("com.google.guava:guava:32.0.1-android")
implementation("org.apache.commons:commons-lang3:3.18.0")
implementation("org.ow2.asm:asm:9.9.1")
implementation("org.ow2.asm:asm-commons:9.9.1")
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public void apply(Project project) {
}

private void configurePlugin(Project project, String language) {
sourceSets.all(sourceSet -> {
sourceSets.configureEach(sourceSet -> {
project.getTasks().named(sourceSet.getCompileTaskName(language), AbstractCompile.class, compile -> {
ModuleCompilerAction action = project.getObjects().newInstance(ModuleCompilerAction.class);
compile.doLast("extraCompile", action);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ plugins {
id("io.fairyproject.publish")
}

configurations {
compileOnly {
isCanBeResolved = true
}
}

//sourceSets {
// test.get().compileClasspath += configurations.compileOnly.get()
Expand Down
8 changes: 4 additions & 4 deletions build-logic/src/main/kotlin/io.fairyproject.common.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,16 @@ repositories {

dependencies {
compileOnly("org.jetbrains:annotations:24.1.0")
compileOnly("org.projectlombok:lombok:1.18.32")
annotationProcessor("org.projectlombok:lombok:1.18.32")
compileOnly("org.projectlombok:lombok:1.18.40")
annotationProcessor("org.projectlombok:lombok:1.18.40")

testCompileOnly("org.jetbrains:annotations:24.1.0")
testImplementation("org.mockito:mockito-core:4.2.0")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")

testCompileOnly("org.projectlombok:lombok:1.18.32")
testAnnotationProcessor("org.projectlombok:lombok:1.18.32")
testCompileOnly("org.projectlombok:lombok:1.18.40")
testAnnotationProcessor("org.projectlombok:lombok:1.18.40")
}

java {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
plugins {
id("io.fairyproject.module")
}

dependencies {
compileOnly("dev.imanity.hytale:HytaleServer:2026.01.17-2")
}

repositories {
maven ("https://repo.imanity.dev/imanity-libraries/")
}

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(25))
}
}

tasks.withType(JavaCompile::class.java).configureEach {
options.encoding = "UTF-8"
options.release = 25
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public enum PlatformType {
BUNGEE,
VELOCITY,
NUKKIT,
APP
APP,
HYTALE

}
19 changes: 19 additions & 0 deletions framework/bootstraps/hytale-bootstrap/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
plugins {
id("io.fairyproject.bootstrap")
}

dependencies {
api(project(":core-bootstrap"))
compileOnly("io.fairyproject:hytale-platform")
}

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(25))
}
}

tasks.withType(JavaCompile::class.java).configureEach {
options.encoding = "UTF-8"
options.release = 25
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* MIT License
*
* Copyright (c) 2022 Fairy Project
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package io.fairyproject.bootstrap.hytale;

import io.fairyproject.FairyPlatform;
import io.fairyproject.bootstrap.platform.AbstractPlatformBootstrap;
import io.fairyproject.bootstrap.type.PlatformType;
import io.fairyproject.hytale.FairyHytalePlatform;
import lombok.Getter;
import org.jetbrains.annotations.Nullable;

@Getter
class HytalePlatformBootstrap extends AbstractPlatformBootstrap {

@Override
protected void onFailure(@Nullable Throwable throwable) {
if (throwable != null) {
throwable.printStackTrace();
}
if (HytalePlugin.INSTANCE != null && HytalePlugin.INSTANCE.getShutdownAction() != null) {
HytalePlugin.INSTANCE.getShutdownAction().run();
}
}

@Override
protected PlatformType getPlatformType() {
return PlatformType.HYTALE;
}

@Override
protected FairyPlatform createPlatform() {
return new FairyHytalePlatform(
HytalePlugin.INSTANCE,
HytalePlugin.INSTANCE.getShutdownAction(),
HytalePlugin.INSTANCE.getDataDirectory().toFile()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* MIT License
*
* Copyright (c) 2022 Fairy Project
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package io.fairyproject.bootstrap.hytale;

import com.google.gson.JsonObject;
import com.hypixel.hytale.server.core.plugin.JavaPlugin;
import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import io.fairyproject.bootstrap.PluginClassInitializerFinder;
import io.fairyproject.bootstrap.PluginFileReader;
import io.fairyproject.bootstrap.instance.PluginInstance;
import io.fairyproject.bootstrap.internal.FairyInternalIdentityMeta;
import io.fairyproject.bootstrap.platform.PlatformBootstrap;
import lombok.AccessLevel;
import lombok.Setter;
import org.jetbrains.annotations.NotNull;

@FairyInternalIdentityMeta
public final class HytalePlugin extends JavaPlugin {

public static HytalePlugin INSTANCE;

private final PluginInstance instance;
private final PluginFileReader pluginFileReader;
private final PlatformBootstrap bootstrap;
private Runnable shutdownAction;

@Setter(AccessLevel.PACKAGE)
private boolean loaded;

/**
* Constructor with dependency injection for testing purposes.
*
* @param init the Hytale plugin init object
* @param instance the plugin instance
* @param pluginFileReader the plugin file reader
* @param bootstrap the platform bootstrap
* @param shutdownAction the action to run on shutdown (nullable, will use default if null)
*/
public HytalePlugin(@NotNull JavaPluginInit init,
PluginInstance instance,
PluginFileReader pluginFileReader,
PlatformBootstrap bootstrap,
Runnable shutdownAction) {
super(init);
this.instance = instance;
this.pluginFileReader = pluginFileReader;
this.bootstrap = bootstrap;
this.shutdownAction = shutdownAction;
}

/**
* Default constructor for Hytale server.
*
* @param init the Hytale plugin init object
*/
public HytalePlugin(@NotNull JavaPluginInit init) {
this(
init,
new HytalePluginInstance(PluginClassInitializerFinder.find()),
new PluginFileReader(),
new HytalePlatformBootstrap(),
null // will be initialized lazily
);
}

/**
* Get the shutdown action to be used by the platform.
* Lazily initializes to server stop if not set.
*
* @return the shutdown action
*/
public Runnable getShutdownAction() {
if (this.shutdownAction == null) {
// Use reflection to call server stop to avoid compile-time API dependency issues
this.shutdownAction = () -> {
try {
Object server = this.getClass().getMethod("getServer").invoke(this);
if (server != null) {
server.getClass().getMethod("stop").invoke(server);
}
} catch (Exception e) {
System.err.println("[Fairy] Failed to stop server: " + e.getMessage());
}
};
}
return this.shutdownAction;
}

/**
* Called by Hytale during plugin setup phase.
* Maps to Bukkit's onLoad() lifecycle.
* Performs: preload + load + instance.onLoad
*/
@Override
protected void setup() {
if (this.loaded)
return;
INSTANCE = this;

if (!this.bootstrap.preload()) {
System.err.println("[Fairy] Failed to boot fairy! check stacktrace for the reason of failure!");
this.getShutdownAction().run();
return;
}

JsonObject jsonObject = pluginFileReader.read(this.getClass());
this.instance.init(jsonObject);
this.bootstrap.load(this.instance.getPlugin());
this.instance.onLoad();

this.loaded = true;
}

/**
* Called by Hytale during plugin start phase.
* Maps to Bukkit's onEnable() lifecycle.
* Performs: enable + instance.onEnable
*/
@Override
protected void start() {
if (!this.loaded)
throw new IllegalStateException("Plugin not loaded yet!");

this.bootstrap.enable();
this.instance.onEnable();
}

/**
* Called by Hytale during plugin shutdown phase.
* Maps to Bukkit's onDisable() lifecycle.
* Performs: instance.onDisable + disable
*/
@Override
protected void shutdown() {
if (!this.loaded)
return;

this.instance.onDisable();
this.bootstrap.disable();
}
}
Loading
Loading