@@ -180,12 +203,13 @@
-
-
-
+
+
+
+
diff --git a/build.gradle b/build.gradle
index 3446485..906d3c5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -96,5 +96,9 @@ allprojects {
repositories {
mavenCentral()
+ maven {
+ name("papermc")
+ url("https://repo.papermc.io/repository/maven-public/")
+ }
}
}
diff --git a/gradle.properties b/gradle.properties
index 135b5d7..8f8b207 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -23,6 +23,12 @@ versioningType=alpha
versioningTyperelease=2
versioningFork=
+# Target minecraft version
+minecraftVersion=1.21
+minecraftApiVersion=1.21
+minecraftJavaVersion=21
+minecraftPaperApiVersion=-R0.1-SNAPSHOT
+
# Shared Dependencies
dependencyLombok=1.18.32
dependencyJetbrainsAnnotations=24.1.0
@@ -33,6 +39,8 @@ dependencyReflections=0.10.2
dependencySlf4j=2.0.13
dependencyLwjgl=3.3.3
dependencyLwjglNatives=
+dependencyAdventure=4.17.0
+dependencyAdventureBukkit=4.3.3
# Test dependencies
dependencyJunit=5.11.0-M2
@@ -40,6 +48,7 @@ dependencyJunit=5.11.0-M2
# Plugins
pluginShadow=8.1.7
pluginLombok=8.6
+pluginRunTask=2.3.0
pluginGitProperties=2.4.2
pluginNativeImage=v1.4.0
diff --git a/minecraft/build.gradle b/minecraft/build.gradle
new file mode 100644
index 0000000..738faf6
--- /dev/null
+++ b/minecraft/build.gradle
@@ -0,0 +1,83 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+// Plugins
+plugins {
+ id("java")
+ id("io.freefair.lombok") version("${pluginLombok}")
+}
+
+// Dependencies
+dependencies {
+ // -> Runtime <-
+ // Lombok
+ compileOnly("org.projectlombok:lombok:${dependencyLombok}")
+ annotationProcessor("org.projectlombok:lombok:${dependencyLombok}")
+
+ // JetBrains Annotations
+ compileOnly("org.jetbrains:annotations:${dependencyJetbrainsAnnotations}")
+
+ // Adventure
+ implementation("net.kyori:adventure-api:${dependencyAdventure}")
+ implementation("net.kyori:examination-api") // for some reason required for compilation
+
+ // Reflections
+ implementation("org.reflections:reflections:${dependencyReflections}")
+
+ // -> Project <-
+ implementation(project(":base"))
+}
+
+// Fix delombok task
+delombok.doFirst {
+ File target = file("${project.projectDir}/src/main/module-info.java")
+ File source = file("${project.projectDir}/src/main/java/module-info.java")
+
+ target.delete()
+ source.renameTo(target)
+}
+delombok.doLast {
+ File target = file("${project.projectDir}/src/main/java/module-info.java")
+ File source = file("${project.projectDir}/src/main/module-info.java")
+
+ target.delete()
+ source.renameTo(target)
+}
+
+// Javadoc configuration
+javadoc {
+ outputs.upToDateWhen { false } // Force task execution
+ dependsOn(delombok) // Make sure the source is delomboked first
+
+ javadoc {
+ setClasspath(files(project.sourceSets.main.compileClasspath)) // Include dependencies
+
+ options {
+ if (new File(projectDir, "src/main/javadoc/theme.css").exists())
+ stylesheetFile = new File(projectDir, "src/main/javadoc/theme.css") // Theming is cool :3
+ setMemberLevel(JavadocMemberLevel.PUBLIC) // Only display public stuff
+ setOverview("src/main/javadoc/overview.html") // We want a custom overview page to greet the visitor
+ setLocale("en_US") // 你好
+
+ setJFlags([
+ "-Duser.language=en_US" // See above
+ ])
+ }
+ }
+}
diff --git a/minecraft/bukkit/build.gradle b/minecraft/bukkit/build.gradle
new file mode 100644
index 0000000..246a5d3
--- /dev/null
+++ b/minecraft/bukkit/build.gradle
@@ -0,0 +1,135 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+import java.nio.file.Files
+
+
+
+// Plugins
+plugins {
+ id("java")
+ id("io.freefair.lombok") version("${pluginLombok}")
+ id("io.github.goooler.shadow") version("${pluginShadow}")
+ id("xyz.jpenilla.run-paper") version("${pluginRunTask}")
+}
+
+// Dependencies
+dependencies {
+ // -> Runtime <-
+ // Lombok
+ compileOnly("org.projectlombok:lombok:${dependencyLombok}")
+ annotationProcessor("org.projectlombok:lombok:${dependencyLombok}")
+
+ // JetBrains Annotations
+ compileOnly("org.jetbrains:annotations:${dependencyJetbrainsAnnotations}")
+
+ // Adventure
+ implementation("net.kyori:adventure-api:${dependencyAdventure}")
+ implementation("net.kyori:adventure-platform-bukkit:${dependencyAdventureBukkit}")
+
+ // PaperMC API
+ compileOnly("io.papermc.paper:paper-api:${minecraftVersion}${minecraftPaperApiVersion}")
+
+ // -> Project <-
+ implementation(project(":base"))
+ implementation(project(":minecraft"))
+}
+
+// Set to Minecraft's Java version
+java {
+ toolchain.languageVersion.set(JavaLanguageVersion.of(project.minecraftJavaVersion))
+}
+
+// Fix delombok task
+delombok.doFirst {
+ File target = file("${project.projectDir}/src/main/module-info.java")
+ File source = file("${project.projectDir}/src/main/java/module-info.java")
+
+ target.delete()
+ source.renameTo(target)
+}
+delombok.doLast {
+ File target = file("${project.projectDir}/src/main/java/module-info.java")
+ File source = file("${project.projectDir}/src/main/module-info.java")
+
+ target.delete()
+ source.renameTo(target)
+}
+
+// Javadoc configuration
+javadoc {
+ outputs.upToDateWhen { false } // Force task execution
+ dependsOn(delombok) // Make sure the source is delomboked first
+
+ javadoc {
+ setClasspath(files(project.sourceSets.main.compileClasspath)) // Include dependencies
+
+ options {
+ if (new File(projectDir, "src/main/javadoc/theme.css").exists())
+ stylesheetFile = new File(projectDir, "src/main/javadoc/theme.css") // Theming is cool :3
+ setMemberLevel(JavadocMemberLevel.PUBLIC) // Only display public stuff
+ setOverview("src/main/javadoc/overview.html") // We want a custom overview page to greet the visitor
+ setLocale("en_US") // 你好
+
+ setJFlags([
+ "-Duser.language=en_US" // See above
+ ])
+ }
+ }
+}
+
+// Configure run-task plugin
+runServer {
+ // Set minecraft version
+ minecraftVersion("${minecraftVersion}")
+
+ // Enforce UTF-8 encoding
+ systemProperty("file.encoding", "UTF-8")
+
+ // Agree to EULA
+ systemProperty("com.mojang.eula.agree", "true")
+
+ // From :testapp
+ systemProperty("sosengine.base.loggerLevel", "diagnostic")
+
+ doFirst {
+ // Disable bStats
+ File config = new File(runDirectory.get().getAsFile().getPath() + "/plugins/bStats/config.yml")
+ if (!config.exists()) {
+ config.getParentFile().mkdirs()
+ config.createNewFile()
+ config.write("enabled: false\n")
+ }
+
+ // Copy test extension to load directory
+ File source = new File(project(":minecraft:bukkit:testextension").projectDir.getPath() + "/build/libs/").listFiles()[0]
+ File target = new File(runDirectory.get().getAsFile().getPath() + "/plugins/testextension.jar")
+
+ target.getParentFile().mkdirs()
+ target.delete();
+ Files.copy(source.toPath(), target.toPath())
+ }
+}
+
+// Update plugin.yml
+processResources {
+ filesMatching("plugin.yml") {
+ expand project.properties
+ }
+}
diff --git a/minecraft/bukkit/gradle b/minecraft/bukkit/gradle
new file mode 120000
index 0000000..1ce6c4c
--- /dev/null
+++ b/minecraft/bukkit/gradle
@@ -0,0 +1 @@
+../../gradle
\ No newline at end of file
diff --git a/minecraft/bukkit/gradlew b/minecraft/bukkit/gradlew
new file mode 120000
index 0000000..343e0d2
--- /dev/null
+++ b/minecraft/bukkit/gradlew
@@ -0,0 +1 @@
+../../gradlew
\ No newline at end of file
diff --git a/minecraft/bukkit/gradlew.bat b/minecraft/bukkit/gradlew.bat
new file mode 120000
index 0000000..cb5a946
--- /dev/null
+++ b/minecraft/bukkit/gradlew.bat
@@ -0,0 +1 @@
+../../gradlew.bat
\ No newline at end of file
diff --git a/minecraft/bukkit/src/main/java/de/staropensource/sosengine/minecraft/bukkit/BukkitSubsystem.java b/minecraft/bukkit/src/main/java/de/staropensource/sosengine/minecraft/bukkit/BukkitSubsystem.java
new file mode 100644
index 0000000..aec3d05
--- /dev/null
+++ b/minecraft/bukkit/src/main/java/de/staropensource/sosengine/minecraft/bukkit/BukkitSubsystem.java
@@ -0,0 +1,89 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft.bukkit;
+
+import de.staropensource.sosengine.base.annotations.EngineSubsystem;
+import de.staropensource.sosengine.base.classes.SubsystemMainClass;
+import de.staropensource.sosengine.base.data.info.EngineInformation;
+import de.staropensource.sosengine.base.data.versioning.StarOpenSourceVersioningSystem;
+import de.staropensource.sosengine.base.logging.LoggerInstance;
+import de.staropensource.sosengine.base.types.CodePart;
+import de.staropensource.sosengine.base.types.DependencyVector;
+import de.staropensource.sosengine.base.types.logging.LogIssuer;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+
+/**
+ * Main object for the Minecraft subsystem.
+ *
+ * @since v1-alpha2
+ */
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+@EngineSubsystem
+public class BukkitSubsystem implements SubsystemMainClass {
+ /**
+ * Contains the class instance.
+ *
+ * @since v1-alpha0
+ *
+ * -- GETTER --
+ * Returns the class instance.
+ *
+ * @return class instance unless the subsystem is uninitialized
+ * @since v1-alpha0
+ */
+ @Getter
+ private static BukkitSubsystem instance = null;
+
+ /** {@inheritDoc} */
+ private final LoggerInstance logger = new LoggerInstance(new LogIssuer(getClass(), CodePart.ENGINE));
+
+ /**
+ * Constructs this subsystem.
+ */
+ public BukkitSubsystem() {
+ // Check if subsystem has already initialized
+ if (instance == null)
+ instance = this;
+ else {
+ instance.logger.crash("The subsystem tried to initialize twice");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @NotNull
+ @Override
+ public String getName() {
+ return "bukkit";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void initializeSubsystem() {}
+
+ /** {@inheritDoc} */
+ @NotNull
+ @Override
+ public DependencyVector getDependencyVector() {
+ return new DependencyVector("bukkit", StarOpenSourceVersioningSystem.class, EngineInformation.getVersioningString(), Arrays.stream(new String[]{ "minecraft" }).toList());
+ }
+}
diff --git a/minecraft/bukkit/src/main/java/de/staropensource/sosengine/minecraft/bukkit/PluginEntrypoint.java b/minecraft/bukkit/src/main/java/de/staropensource/sosengine/minecraft/bukkit/PluginEntrypoint.java
new file mode 100644
index 0000000..c5e99f1
--- /dev/null
+++ b/minecraft/bukkit/src/main/java/de/staropensource/sosengine/minecraft/bukkit/PluginEntrypoint.java
@@ -0,0 +1,132 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft.bukkit;
+
+import de.staropensource.sosengine.base.logging.Logger;
+import de.staropensource.sosengine.base.types.CodePart;
+import de.staropensource.sosengine.base.types.logging.LogIssuer;
+import de.staropensource.sosengine.minecraft.bukkit.engine.ForwardingLoggerImpl;
+import de.staropensource.sosengine.minecraft.bukkit.internal.PluginPhase;
+import de.staropensource.sosengine.minecraft.implementation.ExtensionManager;
+import de.staropensource.sosengine.minecraft.implementation.ImplementationBootstrapper;
+import lombok.Getter;
+import org.bukkit.Bukkit;
+import org.bukkit.plugin.java.JavaPlugin;
+
+/**
+ * Bootstraps the Bukkit API implementation of the sos!engine.
+ *
+ * @since v1-alpha2
+ */
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+public class PluginEntrypoint extends JavaPlugin {
+ /**
+ * Contains the class instance.
+ *
+ * @since v1-alpha0
+ *
+ * -- GETTER --
+ * Returns the class instance.
+ *
+ * @return class instance unless the subsystem is uninitialized
+ * @since v1-alpha0
+ */
+ @Getter
+ private static PluginEntrypoint instance;
+
+ /**
+ * Represents the current phase in which the implementation plugin is in.
+ *
+ * @since v1-alpha2
+ */
+ @Getter
+ private static PluginPhase phase = PluginPhase.UNKNOWN;
+
+ /**
+ * Constructs this class.
+ *
+ * @since v1-alpha2
+ */
+ public PluginEntrypoint() {
+ instance = this;
+ }
+
+ /**
+ * Bootstraps the environment, loads the engine into memory and handles early extension initialization.
+ *
+ * @since v1-alpha2
+ */
+ @Override
+ public void onLoad() {
+ phase = PluginPhase.LOADED;
+
+ // Initialize environment and engine
+ ImplementationBootstrapper.initialize(
+ true,
+ () -> {
+ switch (PluginEntrypoint.getPhase()) {
+ case UNKNOWN, LOADED -> {
+ // Server hasn't loaded any data yet, halt JVM
+ Logger.info(new LogIssuer(getClass(), CodePart.ENGINE), "The server has not yet loaded any data, halting JVM");
+ Runtime.getRuntime().halt(69);
+ }
+ default -> {
+ if (!Bukkit.isStopping())
+ Bukkit.shutdown();
+ }
+ }
+ },
+ new ForwardingLoggerImpl()
+ );
+
+ // Initialize implementation subsystem
+ new BukkitSubsystem().initializeSubsystem();
+ }
+
+ /**
+ * Handles extension (late) initialization.
+ *
+ * @since v1-alpha2
+ */
+ @Override
+ public void onEnable() {
+ phase = PluginPhase.ENABLED;
+
+ // Fire initialization methods
+ ExtensionManager.getInstance().fireEarlyInitialization();
+ ExtensionManager.getInstance().fireInitialization();
+
+ // Schedule late initialization for first server tick
+ Bukkit.getScheduler().runTaskLater(this, () -> ExtensionManager.getInstance().fireLateInitialization(), 0L);
+ }
+
+ /**
+ * Handles extension shutdown.
+ *
+ * @since v1-alpha2
+ */
+ @Override
+ public void onDisable() {
+ phase = PluginPhase.DISABLED;
+
+ // Fire shutdown method
+ ExtensionManager.getInstance().fireShutdown();
+ }
+}
diff --git a/minecraft/bukkit/src/main/java/de/staropensource/sosengine/minecraft/bukkit/engine/ForwardingLoggerImpl.java b/minecraft/bukkit/src/main/java/de/staropensource/sosengine/minecraft/bukkit/engine/ForwardingLoggerImpl.java
new file mode 100644
index 0000000..6698895
--- /dev/null
+++ b/minecraft/bukkit/src/main/java/de/staropensource/sosengine/minecraft/bukkit/engine/ForwardingLoggerImpl.java
@@ -0,0 +1,66 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft.bukkit.engine;
+
+import de.staropensource.sosengine.base.classes.LoggerImpl;
+import de.staropensource.sosengine.base.logging.Logger;
+import de.staropensource.sosengine.base.types.CodePart;
+import de.staropensource.sosengine.base.types.logging.LogIssuer;
+import de.staropensource.sosengine.base.types.logging.LogLevel;
+import de.staropensource.sosengine.minecraft.api.misc.AdventureShortcodeConverter;
+import net.kyori.adventure.text.Component;
+import org.bukkit.Bukkit;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Forwards the engine's log messages to Bukkit's logging system.
+ *
+ * @since v1-alpha2
+ */
+public class ForwardingLoggerImpl implements LoggerImpl {
+ /** {@inheritDoc} */
+ @Override
+ public @NotNull String prePlaceholder(@NotNull LogLevel level, @NotNull LogIssuer logIssuer, @NotNull String message) {
+ // No modifications necessary
+ return message;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public @NotNull String postPlaceholder(@NotNull LogLevel level, @NotNull LogIssuer logIssuer, @NotNull String format) {
+ // No modifications necessary
+ return format;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void print(@NotNull LogLevel level, @NotNull LogIssuer logIssuer, @NotNull String format) {
+ Component component;
+
+ try {
+ component = new AdventureShortcodeConverter(format).getComponent();
+ } catch (Exception exception) {
+ Logger.crash(new LogIssuer(getClass(), CodePart.ENGINE), "AdventureShortcodeConverter threw an exception", exception);
+ return;
+ }
+
+ Bukkit.getConsoleSender().sendMessage(component);
+ }
+}
diff --git a/minecraft/bukkit/src/main/java/de/staropensource/sosengine/minecraft/bukkit/internal/PluginPhase.java b/minecraft/bukkit/src/main/java/de/staropensource/sosengine/minecraft/bukkit/internal/PluginPhase.java
new file mode 100644
index 0000000..04ff4b6
--- /dev/null
+++ b/minecraft/bukkit/src/main/java/de/staropensource/sosengine/minecraft/bukkit/internal/PluginPhase.java
@@ -0,0 +1,55 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft.bukkit.internal;
+
+/**
+ * Represents in which phase the implementation plugin is.
+ *
+ * @since v1-alpha2
+ */
+public enum PluginPhase {
+ /**
+ * The current phase is unknown.
+ *
+ * @since v1-alpha2
+ */
+ UNKNOWN,
+
+ /**
+ * The implementation plugin is currently loaded but not enabled.
+ *
+ * @since v1-alpha2
+ */
+ LOADED,
+
+ /**
+ * The implementation plugin is currently loaded and enabled.
+ *
+ * @since v1-alpha2
+ */
+ ENABLED,
+
+ /**
+ * The implementation plugin is currently disabled.
+ *
+ * @since v1-alpha2
+ */
+ DISABLED
+}
diff --git a/minecraft/bukkit/src/main/java/module-info.java b/minecraft/bukkit/src/main/java/module-info.java
new file mode 100644
index 0000000..62b11a8
--- /dev/null
+++ b/minecraft/bukkit/src/main/java/module-info.java
@@ -0,0 +1,16 @@
+/**
+ * Defines the implementation and support plugin for the
+ * StarOpenSource Engine for Bukkit plugins.
+ *
+ * @since v1-alpha2
+ */
+open module sosengine.minecraft.bukkit {
+ // Dependencies
+ // -> Subsystems
+ requires sosengine.base;
+ requires sosengine.minecraft;
+ // -> Libraries
+ requires static lombok;
+ requires net.kyori.adventure;
+ requires org.bukkit;
+}
diff --git a/minecraft/bukkit/src/main/javadoc/theme.css b/minecraft/bukkit/src/main/javadoc/theme.css
new file mode 120000
index 0000000..bccac6b
--- /dev/null
+++ b/minecraft/bukkit/src/main/javadoc/theme.css
@@ -0,0 +1 @@
+../../../../../src/main/javadoc/theme.css
\ No newline at end of file
diff --git a/minecraft/bukkit/src/main/resources/plugin.yml b/minecraft/bukkit/src/main/resources/plugin.yml
new file mode 100644
index 0000000..e389245
--- /dev/null
+++ b/minecraft/bukkit/src/main/resources/plugin.yml
@@ -0,0 +1,9 @@
+name: "sosengine"
+version: "${version}+${minecraftVersion}"
+main: "de.staropensource.sosengine.minecraft.bukkit.PluginEntrypoint"
+description: "Provides compatibility and support for the StarOpenSource Engine for Bukkit plugins"
+authors: [ "The StarOpenSource Engine Contributors" ]
+website: "https://engine.staropensource.de"
+api-version: "${minecraftApiVersion}"
+load: STARTUP
+prefix: "sos!engine"
diff --git a/minecraft/bukkit/testextension/build.gradle b/minecraft/bukkit/testextension/build.gradle
new file mode 100644
index 0000000..43b3cbf
--- /dev/null
+++ b/minecraft/bukkit/testextension/build.gradle
@@ -0,0 +1,74 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+// Plugins
+plugins {
+ id("java")
+ id("io.freefair.lombok") version("${pluginLombok}")
+ id("io.github.goooler.shadow") version("${pluginShadow}")
+}
+
+// Dependencies
+dependencies {
+ // -> Runtime <-
+ // Lombok
+ compileOnly("org.projectlombok:lombok:${dependencyLombok}")
+ annotationProcessor("org.projectlombok:lombok:${dependencyLombok}")
+
+ // JetBrains Annotations
+ compileOnly("org.jetbrains:annotations:${dependencyJetbrainsAnnotations}")
+
+ // PaperMC API
+ compileOnly("io.papermc.paper:paper-api:${minecraftVersion}${minecraftPaperApiVersion}")
+
+ // -> Project <-
+ implementation(project(":base"))
+ implementation(project(":minecraft"))
+ implementation(project(":minecraft:bukkit"))
+}
+
+// Set to Minecraft's Java version
+java {
+ toolchain.languageVersion.set(JavaLanguageVersion.of(project.minecraftJavaVersion))
+}
+
+// Fix delombok task
+delombok.doFirst {
+ File target = file("${project.projectDir}/src/main/module-info.java")
+ File source = file("${project.projectDir}/src/main/java/module-info.java")
+
+ target.delete()
+ source.renameTo(target)
+}
+delombok.doLast {
+ File target = file("${project.projectDir}/src/main/java/module-info.java")
+ File source = file("${project.projectDir}/src/main/module-info.java")
+
+ target.delete()
+ source.renameTo(target)
+}
+
+// Update plugin.yml
+processResources {
+ filesMatching("plugin.yml") {
+ expand project.properties
+ }
+}
+
+// Make runServer task of project :minecraft:bukkit depend on 'jar' task
+project(":minecraft:bukkit").getTasks().named("runServer").get().dependsOn(jar)
diff --git a/minecraft/bukkit/testextension/gradle b/minecraft/bukkit/testextension/gradle
new file mode 120000
index 0000000..84b694e
--- /dev/null
+++ b/minecraft/bukkit/testextension/gradle
@@ -0,0 +1 @@
+../../../gradle
\ No newline at end of file
diff --git a/minecraft/bukkit/testextension/gradlew b/minecraft/bukkit/testextension/gradlew
new file mode 120000
index 0000000..ab9334b
--- /dev/null
+++ b/minecraft/bukkit/testextension/gradlew
@@ -0,0 +1 @@
+../../../gradlew
\ No newline at end of file
diff --git a/minecraft/bukkit/testextension/gradlew.bat b/minecraft/bukkit/testextension/gradlew.bat
new file mode 120000
index 0000000..b284c30
--- /dev/null
+++ b/minecraft/bukkit/testextension/gradlew.bat
@@ -0,0 +1 @@
+../../../gradlew.bat
\ No newline at end of file
diff --git a/minecraft/bukkit/testextension/src/main/java/de/staropensource/sosengine/minecraft/bukkit/testextension/BukkitEntrypoint.java b/minecraft/bukkit/testextension/src/main/java/de/staropensource/sosengine/minecraft/bukkit/testextension/BukkitEntrypoint.java
new file mode 100644
index 0000000..9940098
--- /dev/null
+++ b/minecraft/bukkit/testextension/src/main/java/de/staropensource/sosengine/minecraft/bukkit/testextension/BukkitEntrypoint.java
@@ -0,0 +1,36 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft.bukkit.testextension;
+
+import de.staropensource.sosengine.minecraft.extension.ExtensionRegistrar;
+import org.bukkit.plugin.java.JavaPlugin;
+
+/**
+ * Registers this extension.
+ *
+ * @since v1-alpha2
+ */
+@SuppressWarnings({ "unused" })
+public class BukkitEntrypoint extends JavaPlugin {
+ @Override
+ public void onLoad() {
+ ExtensionRegistrar.register(new Entrypoint());
+ }
+}
diff --git a/minecraft/bukkit/testextension/src/main/java/de/staropensource/sosengine/minecraft/bukkit/testextension/Entrypoint.java b/minecraft/bukkit/testextension/src/main/java/de/staropensource/sosengine/minecraft/bukkit/testextension/Entrypoint.java
new file mode 100644
index 0000000..9c3a2b1
--- /dev/null
+++ b/minecraft/bukkit/testextension/src/main/java/de/staropensource/sosengine/minecraft/bukkit/testextension/Entrypoint.java
@@ -0,0 +1,79 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft.bukkit.testextension;
+
+import de.staropensource.sosengine.base.logging.LoggerInstance;
+import de.staropensource.sosengine.base.types.logging.LogIssuer;
+import de.staropensource.sosengine.minecraft.extension.ExtensionEntrypoint;
+import de.staropensource.sosengine.minecraft.extension.ExtensionMetadata;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * The development extension entrypoint.
+ *
+ * @since v1-alpha2
+ */
+@SuppressWarnings({ "unused" })
+public class Entrypoint implements ExtensionEntrypoint {
+ /**
+ * Logger instance.
+ *
+ * @since v1-alpha2
+ */
+ private final LoggerInstance logger = new LoggerInstance(new LogIssuer(getClass()));
+
+ /** {@inheritDoc} */
+ @Override
+ public @NotNull ExtensionMetadata getMetadata() {
+ return new ExtensionMetadata.Builder()
+ .setName("testextension")
+ .build();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void performEarlyInitialization() {
+ logger.info("performEarlyInitialization() called");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void performInitialization() {
+ logger.info("performInitialization() called");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void performLateInitialization() {
+ logger.info("performLateInitialization() called");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void performReload() {
+ logger.info("performReload() called");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void performShutdown() {
+ logger.info("performShutdown() called");
+ }
+}
diff --git a/minecraft/bukkit/testextension/src/main/java/module-info.java b/minecraft/bukkit/testextension/src/main/java/module-info.java
new file mode 100644
index 0000000..1293fb4
--- /dev/null
+++ b/minecraft/bukkit/testextension/src/main/java/module-info.java
@@ -0,0 +1,16 @@
+/**
+ * Defines the sos!engine test plugin, used by engine developers to test their changes.
+ * This module is very uninteresting for non-engine developers.
+ *
+ * @since v1-alpha2
+ */
+open module sosengine.minecraft.bukkit.testplugin {
+ // Dependencies
+ // -> Subsystems
+ requires sosengine.base;
+ requires sosengine.minecraft;
+ requires sosengine.minecraft.bukkit;
+ // -> Libraries
+ requires static lombok;
+ requires org.bukkit;
+}
diff --git a/minecraft/bukkit/testextension/src/main/resources/plugin.yml b/minecraft/bukkit/testextension/src/main/resources/plugin.yml
new file mode 100644
index 0000000..20739ba
--- /dev/null
+++ b/minecraft/bukkit/testextension/src/main/resources/plugin.yml
@@ -0,0 +1,11 @@
+name: "testextension"
+version: "${version}+${minecraftVersion}"
+main: "de.staropensource.sosengine.minecraft.bukkit.testextension.BukkitEntrypoint"
+description: "Development plugin for the Bukkit implementation of the sos!engine"
+authors: [ "The StarOpenSource Engine Contributors" ]
+website: "https://engine.staropensource.de"
+api-version: "${minecraftApiVersion}"
+load: STARTUP
+prefix: "testextension"
+depend:
+ - sosengine
diff --git a/minecraft/gradle b/minecraft/gradle
new file mode 120000
index 0000000..3337596
--- /dev/null
+++ b/minecraft/gradle
@@ -0,0 +1 @@
+../gradle
\ No newline at end of file
diff --git a/minecraft/gradlew b/minecraft/gradlew
new file mode 120000
index 0000000..502f5a2
--- /dev/null
+++ b/minecraft/gradlew
@@ -0,0 +1 @@
+../gradlew
\ No newline at end of file
diff --git a/minecraft/gradlew.bat b/minecraft/gradlew.bat
new file mode 120000
index 0000000..2840132
--- /dev/null
+++ b/minecraft/gradlew.bat
@@ -0,0 +1 @@
+../gradlew.bat
\ No newline at end of file
diff --git a/minecraft/src/main/java/de/staropensource/sosengine/minecraft/MinecraftSubsystem.java b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/MinecraftSubsystem.java
new file mode 100644
index 0000000..6732096
--- /dev/null
+++ b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/MinecraftSubsystem.java
@@ -0,0 +1,134 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft;
+
+import de.staropensource.sosengine.base.annotations.EngineSubsystem;
+import de.staropensource.sosengine.base.classes.SubsystemMainClass;
+import de.staropensource.sosengine.base.data.info.EngineInformation;
+import de.staropensource.sosengine.base.data.versioning.StarOpenSourceVersioningSystem;
+import de.staropensource.sosengine.base.logging.LoggerInstance;
+import de.staropensource.sosengine.base.types.CodePart;
+import de.staropensource.sosengine.base.types.DependencyVector;
+import de.staropensource.sosengine.base.types.logging.LogIssuer;
+import de.staropensource.sosengine.minecraft.api.api.ImplementationApi;
+import de.staropensource.sosengine.minecraft.implementation.ExtensionManager;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Main object for the Minecraft subsystem.
+ *
+ * @since v1-alpha2
+ */
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+@EngineSubsystem
+public class MinecraftSubsystem implements SubsystemMainClass {
+ /**
+ * Contains the class instance.
+ *
+ * @since v1-alpha0
+ *
+ * -- GETTER --
+ * Returns the class instance.
+ *
+ * @return class instance unless the subsystem is uninitialized
+ * @since v1-alpha0
+ */
+ @Getter
+ private static MinecraftSubsystem instance = null;
+
+ /** {@inheritDoc} */
+ private final LoggerInstance logger = new LoggerInstance(new LogIssuer(getClass(), CodePart.ENGINE));
+
+ /**
+ * Contains the {@link ImplementationApi} implementation
+ * from the platform implementation.
+ *
+ * @since v1-alpha2
+ *
+ * -- GETTER --
+ * Returns the {@link ImplementationApi} implementaion
+ * from the platform implementation.
+ *
+ * @return {@link ImplementationApi} implementation
+ * @since v1-alpha2
+ */
+ @Getter
+ private ImplementationApi api = null;
+
+ /**
+ * Constructs this subsystem.
+ */
+ public MinecraftSubsystem() {
+ // Check if subsystem has already initialized
+ if (instance == null)
+ instance = this;
+ else {
+ instance.logger.crash("The subsystem tried to initialize twice");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @NotNull
+ @Override
+ public String getName() {
+ return "minecraft";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void initializeSubsystem() {
+ // Initialize configuration
+ new MinecraftSubsystemConfiguration().loadConfiguration();
+
+ // Initialize classes
+ initializeClasses();
+ }
+
+ /**
+ * Initializes all classes.
+ *
+ * @since v1-alpha2
+ */
+ private void initializeClasses() {
+ new ExtensionManager();
+ }
+
+ /** {@inheritDoc} */
+ @NotNull
+ @Override
+ public DependencyVector getDependencyVector() {
+ return new DependencyVector("minecraft", StarOpenSourceVersioningSystem.class, EngineInformation.getVersioningString());
+ }
+
+ /**
+ * Sets the {@link #api} variable. Can set once.
+ *
+ * @param api value to set
+ * @throws IllegalStateException when the variable is already set
+ * @since v1-alpha2
+ */
+ public void setApi(@NotNull ImplementationApi api) throws IllegalStateException {
+ if (this.api != null)
+ throw new IllegalStateException("Variable 'api' is already set");
+
+ this.api = api;
+ }
+}
diff --git a/minecraft/src/main/java/de/staropensource/sosengine/minecraft/MinecraftSubsystemConfiguration.java b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/MinecraftSubsystemConfiguration.java
new file mode 100644
index 0000000..88e3bd1
--- /dev/null
+++ b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/MinecraftSubsystemConfiguration.java
@@ -0,0 +1,160 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft;
+
+import de.staropensource.sosengine.base.classes.SubsystemConfiguration;
+import de.staropensource.sosengine.base.logging.Logger;
+import de.staropensource.sosengine.base.types.CodePart;
+import de.staropensource.sosengine.base.types.logging.LogIssuer;
+import de.staropensource.sosengine.base.utility.parser.PropertyParser;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Properties;
+
+/**
+ * Provides the base engine configuration.
+ *
+ * This class does not only provide engine settings but is also
+ * responsible for loading them into memory from {@link Properties} objects.
+ *
+ * Now you might ask why we didn't go with the string-based approach.
+ * The answer is simple: It's a maintenance and documentation burden.
+ * Having various settings strings scattered across many classes will cause
+ * trouble at some point, which will cause some strings to be undocumented
+ * or have an inconsistent naming scheme. Containing settings as variables in
+ * one centralized place mitigates this.
+ *
+ * @since v1-alpha0
+ */
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+@Getter
+public final class MinecraftSubsystemConfiguration implements SubsystemConfiguration {
+ /**
+ * Contains the class instance.
+ *
+ * @since v1-alpha0
+ *
+ * -- GETTER --
+ * Returns the class instance.
+ *
+ * @return class instance unless {@link MinecraftSubsystem} is uninitialized
+ * @since v1-alpha0
+ */
+ @Getter
+ private static MinecraftSubsystemConfiguration instance;
+
+ /**
+ * Defines the group every property must start with to be recognized as a subsystem configuration setting.
+ *
+ * @since v1-alpha0
+ *
+ * -- GETTER --
+ * Returns the group that every property must start with to be recognized as a subsystem configuration setting.
+ *
+ * @return property group
+ * @since v1-alpha0
+ */
+ @NotNull
+ @Getter
+ private static final String group = "sosengine.minecraft.";
+
+ /**
+ * If enabled, allows for unintentional behaviour and excess logging.
+ * Unless you want to debug or work on a sensitive part of the engine, don't enable this!
+ *
+ * @since v1-alpha0
+ *
+ * -- GETTER --
+ * Gets the value for {@link #debug}.
+ *
+ * @return variable value
+ * @see #debug
+ * @since v1-alpha0
+ */
+ private boolean debug;
+
+ /**
+ * Constructs this class.
+ *
+ * @see MinecraftSubsystem
+ * @since v1-alpha0
+ */
+ public MinecraftSubsystemConfiguration() {
+ // Only allow one instance
+ if (instance == null)
+ instance = this;
+ else
+ Logger.crash(new LogIssuer(getClass(), CodePart.ENGINE), "Tried initializing " + getClass().getName() + " twice");
+
+ // Load default configuration
+ loadDefaultConfiguration();
+ }
+
+ /** {@inheritDoc} */
+ public synchronized void loadConfiguration(@NotNull Properties properties) {
+ // Define variables
+ PropertyParser parser = new PropertyParser(properties);
+
+ // Loop through all properties
+ for (String property : properties.stringPropertyNames()) {
+ // Check if property name starts with group
+ if (!property.startsWith(group)) continue;
+
+ // Skip to important stuff
+ property = property.substring(group.length());
+
+ // Overwrite matching settings
+ try {
+ switch (property) {
+ case "debug" -> debug = parser.getBoolean(group + property);
+ }
+ } catch (NullPointerException ignored) {}
+ }
+
+ // Disable all debugging switches if 'debug' is disabled
+ if (!debug) {}
+ }
+
+ /** {@inheritDoc} */
+ public synchronized void loadConfiguration() {
+ loadConfiguration(System.getProperties());
+ }
+
+ /** {@inheritDoc} */
+ public synchronized void loadDefaultConfiguration() {
+ debug = false;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable
+ public Object getSetting(@NotNull String setting) {
+ switch (setting) {
+ case "debug" -> {
+ return debug;
+ }
+
+ default -> {
+ return null;
+ }
+ }
+ }
+}
diff --git a/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/api/ImplementationApi.java b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/api/ImplementationApi.java
new file mode 100644
index 0000000..8214c25
--- /dev/null
+++ b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/api/ImplementationApi.java
@@ -0,0 +1,57 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft.api.api;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Used for interfacing with Minecraft.
+ *
+ * @since v1-alpha2
+ */
+@SuppressWarnings({ "unused" })
+public interface ImplementationApi {
+ /**
+ * Returns the implementation name.
+ *
+ * @return implementation name
+ * @since v1-alpha2
+ */
+ @NotNull
+ String getName();
+
+ /**
+ * Returns the features the implementation supports.
+ *
+ * @return implementation features
+ * @since v1-alpha2
+ */
+ @NotNull
+ ImplementationFeatures getFeatures();
+
+ /**
+ * Returns the {@link Server}.
+ *
+ * @return {@link Server}
+ * @since v1-alpha2
+ */
+ @NotNull
+ Server getServer();
+}
diff --git a/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/api/ImplementationFeatures.java b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/api/ImplementationFeatures.java
new file mode 100644
index 0000000..9a17bdd
--- /dev/null
+++ b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/api/ImplementationFeatures.java
@@ -0,0 +1,71 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft.api.api;
+
+/**
+ * Allows for a implementation to specify
+ * which features it supports.
+ *
+ * @since v1-alpha2
+ */
+@SuppressWarnings({ "unused" })
+public enum ImplementationFeatures {
+ /**
+ * Specifies that the implementation supports registering custom commands.
+ *
+ * @since v1-alpha2
+ */
+ COMMAND_REGISTRATION,
+
+ /**
+ * Specifies that the implementation supports unregistering custom commands.
+ *
+ * @since v1-alpha2
+ */
+ COMMANDS_UNREGISTRATION,
+
+ /**
+ * Specifies that the implementation supports implementing custom inventories.
+ *
+ * @since v1-alpha2
+ */
+ INVENTORY,
+
+ /**
+ * Specifies that the implementation supports adding custom blocks.
+ *
+ * @since v1-alpha2
+ */
+ BLOCKS,
+
+ /**
+ * Specifies that the implementation supports adding custom items.
+ *
+ * @since v1-alpha2
+ */
+ ITEMS,
+
+ /**
+ * Specifies that the implementation supports adding custom recipes.
+ *
+ * @since v1-alpha2
+ */
+ RECIPES,
+}
diff --git a/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/api/Server.java b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/api/Server.java
new file mode 100644
index 0000000..117f5f3
--- /dev/null
+++ b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/api/Server.java
@@ -0,0 +1,26 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft.api.api;
+
+public interface Server {
+ /**
+ *
+ */
+}
diff --git a/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/entity/Console.java b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/entity/Console.java
new file mode 100644
index 0000000..1f538ef
--- /dev/null
+++ b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/entity/Console.java
@@ -0,0 +1,99 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft.api.entity;
+
+import net.kyori.adventure.text.Component;
+import org.jetbrains.annotations.NotNull;
+
+import java.net.InetSocketAddress;
+import java.util.UUID;
+
+/**
+ * Provides a fake player with fake data.
+ *
+ * This allows code to continue working like normal
+ * even when supplied with a {@link Console} entity.
+ *
+ * @since v1-alpha2
+ */
+@SuppressWarnings({ "unused" })
+public abstract class Console implements Player {
+ /**
+ * Console {@link UUID}, to avoid creating
+ * the same objects multiple times.
+ *
+ * @since v1-alpha2
+ */
+ private static final UUID uuid = UUID.fromString("00000000-0000-0000-0000-000000000000");
+
+ /** {@inheritDoc} */
+ @Override
+ public UUID getIdentifier() {
+ return uuid;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int getHealth() {
+ return 20;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setHealth(int health) {}
+
+ /** {@inheritDoc} */
+ @Override
+ public int getPing() {
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public @NotNull InetSocketAddress getAddress() {
+ return new InetSocketAddress("0.0.0.0", 25565);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public @NotNull String getName() {
+ return "";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public @NotNull String getClientBrand() {
+ return "";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean canFly() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public abstract void sendMessage(@NotNull Component message);
+
+ /** {@inheritDoc} */
+ @Override
+ public abstract void sendMessage(@NotNull String message);
+}
diff --git a/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/entity/Entity.java b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/entity/Entity.java
new file mode 100644
index 0000000..695eef2
--- /dev/null
+++ b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/entity/Entity.java
@@ -0,0 +1,53 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft.api.entity;
+
+import java.util.UUID;
+
+/**
+ * Represents an entity.
+ *
+ * @since v1-alpha2
+ */
+public interface Entity {
+ /**
+ * Returns the {@link UUID} of this entity.
+ *
+ * @return entity {@link UUID}
+ * @since v1-alpha2
+ */
+ UUID getIdentifier();
+
+ /**
+ * Returns the amount of health this entity has.
+ *
+ * @return entity health
+ * @since v1-alpha2
+ */
+ int getHealth();
+
+ /**
+ * Sets the amount of health this entity has.
+ *
+ * @param health entity health
+ * @since v1-alpha2
+ */
+ void setHealth(int health);
+}
diff --git a/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/entity/Player.java b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/entity/Player.java
new file mode 100644
index 0000000..a43c8fa
--- /dev/null
+++ b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/entity/Player.java
@@ -0,0 +1,91 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft.api.entity;
+
+import net.kyori.adventure.text.Component;
+import org.jetbrains.annotations.NotNull;
+
+import java.net.InetSocketAddress;
+
+/**
+ * Represents a player.
+ *
+ * @since v1-alpha2
+ */
+public interface Player extends Entity {
+ /**
+ * Returns the player's ping.
+ *
+ * @return latency in milliseconds
+ * @since v1-alpha2
+ */
+ int getPing();
+
+ /**
+ * Returns the player's ip address.
+ *
+ * @return player ip address
+ * @since v1-alpha2
+ */
+ @NotNull
+ InetSocketAddress getAddress();
+
+ /**
+ * Returns the player's name.
+ *
+ * @return player name
+ * @since v1-alpha2
+ */
+ @NotNull
+ String getName();
+
+ /**
+ * Returns the player's client brand.
+ *
+ * @return player client brand
+ * @since v1-alpha2
+ */
+ @NotNull
+ String getClientBrand();
+
+ /**
+ * Returns if the player can fly.
+ *
+ * @return fly status
+ * @since v1-alpha2
+ */
+ boolean canFly();
+
+ /**
+ * Sends a message to the player.
+ *
+ * @param message message to send
+ * @since v1-alpha2
+ */
+ void sendMessage(@NotNull Component message);
+
+ /**
+ * Sends a message to the player.
+ *
+ * @param message message to send
+ * @since v1-alpha2
+ */
+ void sendMessage(@NotNull String message);
+}
diff --git a/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/misc/AdventureShortcodeConverter.java b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/misc/AdventureShortcodeConverter.java
new file mode 100644
index 0000000..800e07f
--- /dev/null
+++ b/minecraft/src/main/java/de/staropensource/sosengine/minecraft/api/misc/AdventureShortcodeConverter.java
@@ -0,0 +1,112 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.minecraft.api.misc;
+
+import de.staropensource.sosengine.base.classes.ShortcodeParserSkeleton;
+import de.staropensource.sosengine.base.exceptions.ParserException;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.TextColor;
+import net.kyori.adventure.text.format.TextDecoration;
+import net.kyori.adventure.util.HSVLike;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Converts shortcodes such as {@code } or {@code