Skip to content

Tutorial: Hello World Plugin

Guía paso a paso para crear tu primer plugin de Hytale.

Objetivo

Crear un plugin que imprima "Hello World" cuando el servidor inicie.

Requisitos

  • JDK 17+
  • Gradle o Maven
  • Editor de código (IntelliJ IDEA, VSCode, etc.)

Paso 1: Crear Proyecto

Con Gradle

mkdir hello-world-plugin
cd hello-world-plugin
gradle init

Seleccionar: - Type: application - Language: Java - Build script: Groovy - Test framework: JUnit Jupiter

Con Maven

mvn archetype:generate \
  -DgroupId=com.ejemplo \
  -DartifactId=hello-world-plugin \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DinteractiveMode=false

Paso 2: Configurar build.gradle

plugins {
    id 'java'
}

group = 'com.ejemplo'
version = '1.0.0'

sourceCompatibility = 17
targetCompatibility = 17

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.ow2.asm:asm:9.5'
    compileOnly files('libs/hytale-server.jar')
}

jar {
    from {
        configurations.runtimeClasspath.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

Paso 3: Crear Estructura de Directorios

src/
└── main/
    ├── java/
    │   └── com/
    │       └── ejemplo/
    │           └── helloworld/
    │               └── HelloWorldTransformer.java
    └── resources/
        └── META-INF/
            └── services/
                └── com.hypixel.hytale.plugin.early.ClassTransformer

Paso 4: Implementar Transformador

src/main/java/com/ejemplo/helloworld/HelloWorldTransformer.java:

package com.ejemplo.helloworld;

import com.hypixel.hytale.plugin.early.ClassTransformer;
import org.objectweb.asm.*;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class HelloWorldTransformer implements ClassTransformer {

    @Override
    public int priority() {
        return 0;
    }

    @Override
    @Nullable
    public byte[] transform(@Nonnull String className,
                           @Nonnull String classPath,
                           @Nonnull byte[] bytecode) {
        if (className.equals("com.hypixel.hytale.server.core.HytaleServer")) {
            return injectHelloWorld(bytecode);
        }
        return null;
    }

    private byte[] injectHelloWorld(byte[] bytecode) {
        ClassReader reader = new ClassReader(bytecode);
        ClassWriter writer = new ClassWriter(reader, 0);

        ClassVisitor visitor = new ClassVisitor(Opcodes.ASM9, writer) {
            @Override
            public MethodVisitor visitMethod(int access, String name,
                                            String descriptor, String signature,
                                            String[] exceptions) {
                MethodVisitor mv = super.visitMethod(
                    access, name, descriptor, signature, exceptions
                );

                if (name.equals("<init>")) {
                    return new MethodVisitor(Opcodes.ASM9, mv) {
                        @Override
                        public void visitCode() {
                            super.visitCode();
                            // System.out.println("Hello World from Plugin!");
                            mv.visitFieldInsn(Opcodes.GETSTATIC,
                                "java/lang/System", "out",
                                "Ljava/io/PrintStream;");
                            mv.visitLdcInsn("Hello World from Plugin!");
                            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                                "java/io/PrintStream", "println",
                                "(Ljava/lang/String;)V", false);
                        }
                    };
                }
                return mv;
            }
        };

        reader.accept(visitor, 0);
        return writer.toByteArray();
    }
}

Paso 5: Registrar Servicio

src/main/resources/META-INF/services/com.hypixel.hytale.plugin.early.ClassTransformer:

com.ejemplo.helloworld.HelloWorldTransformer

Paso 6: Compilar

./gradlew build

El JAR estará en build/libs/hello-world-plugin-1.0.0.jar

Paso 7: Instalar

cp build/libs/hello-world-plugin-1.0.0.jar /path/to/hytale/earlyplugins/

Paso 8: Ejecutar

cd /path/to/hytale
java -jar hytale-server.jar --accept-early-plugins

Salida Esperada

[EarlyPlugin] Found: hello-world-plugin-1.0.0.jar
[EarlyPlugin] Loading transformer: com.ejemplo.helloworld.HelloWorldTransformer (priority=0)
Hello World from Plugin!
[Hytale] Server starting...

Resolución de Problemas

El plugin no se carga

  1. Verificar que el JAR esté en earlyplugins/
  2. Verificar el archivo de servicio en META-INF
  3. Verificar que el nombre de clase sea correcto

Error de ClassNotFoundException

  1. Incluir ASM en el JAR: verificar configuración de gradle/maven
  2. Verificar libs/hytale-server.jar existe

No aparece el mensaje

  1. Verificar que la clase objetivo sea correcta
  2. Agregar System.out.println para debugging
  3. Verificar que el método sea el correcto

Siguiente


¿Problemas? Consulta Troubleshooting