Add work in progress minecraft & bukkit subsystems

This commit is contained in:
JeremyStar™ 2024-07-20 18:09:35 +02:00
parent 0c626cc995
commit 70944eccdf
Signed by: JeremyStarTM
GPG key ID: E366BAEF67E4704D
45 changed files with 2588 additions and 6 deletions

View file

@ -6,7 +6,7 @@
<option name="executionName" /> <option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" /> <option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" /> <option name="scriptParameters" value="-PgraalHome=$USER_HOME$/.sdkman/candidates/java/22.0.1-graalce/" />
<option name="taskDescriptions"> <option name="taskDescriptions">
<list /> <list />
</option> </option>
@ -116,13 +116,14 @@
<option name="executionName" /> <option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" /> <option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" /> <option name="scriptParameters" value="-PgraalHome=$USER_HOME$/.sdkman/candidates/java/22.0.1-graalce/" />
<option name="taskDescriptions"> <option name="taskDescriptions">
<list /> <list />
</option> </option>
<option name="taskNames"> <option name="taskNames">
<list> <list>
<option value="testapp:runNativeimage" /> <option value="testapp:nativeImage" />
<option value="testapp:runNativeImage" />
</list> </list>
</option> </option>
<option name="vmOptions" /> <option name="vmOptions" />
@ -155,6 +156,28 @@
<RunAsTest>false</RunAsTest> <RunAsTest>false</RunAsTest>
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="Run test bukkit plugin" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value=":minecraft:bukkit:runServer" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<RunAsTest>false</RunAsTest>
<method v="2" />
</configuration>
<configuration name="Run tests" type="GradleRunConfiguration" factoryName="Gradle"> <configuration name="Run tests" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings> <ExternalSystemSettings>
<option name="executionName" /> <option name="executionName" />
@ -180,12 +203,13 @@
<list> <list>
<item itemvalue="Gradle.Clean" /> <item itemvalue="Gradle.Clean" />
<item itemvalue="Gradle.Run tests" /> <item itemvalue="Gradle.Run tests" />
<item itemvalue="Gradle.Build test application" />
<item itemvalue="Gradle.Run test application" /> <item itemvalue="Gradle.Run test application" />
<item itemvalue="Gradle.Build test application (native)" />
<item itemvalue="Gradle.Run test application (native)" /> <item itemvalue="Gradle.Run test application (native)" />
<item itemvalue="Gradle.Generate Javadoc (separate)" /> <item itemvalue="Gradle.Build test application" />
<item itemvalue="Gradle.Build test application (native)" />
<item itemvalue="Gradle.Run test bukkit plugin" />
<item itemvalue="Gradle.Generate JavaDoc (combined)" /> <item itemvalue="Gradle.Generate JavaDoc (combined)" />
<item itemvalue="Gradle.Generate Javadoc (separate)" />
</list> </list>
</component> </component>
</project> </project>

View file

@ -96,5 +96,9 @@ allprojects {
repositories { repositories {
mavenCentral() mavenCentral()
maven {
name("papermc")
url("https://repo.papermc.io/repository/maven-public/")
}
} }
} }

View file

@ -23,6 +23,12 @@ versioningType=alpha
versioningTyperelease=2 versioningTyperelease=2
versioningFork= versioningFork=
# Target minecraft version
minecraftVersion=1.21
minecraftApiVersion=1.21
minecraftJavaVersion=21
minecraftPaperApiVersion=-R0.1-SNAPSHOT
# Shared Dependencies # Shared Dependencies
dependencyLombok=1.18.32 dependencyLombok=1.18.32
dependencyJetbrainsAnnotations=24.1.0 dependencyJetbrainsAnnotations=24.1.0
@ -33,6 +39,8 @@ dependencyReflections=0.10.2
dependencySlf4j=2.0.13 dependencySlf4j=2.0.13
dependencyLwjgl=3.3.3 dependencyLwjgl=3.3.3
dependencyLwjglNatives= dependencyLwjglNatives=
dependencyAdventure=4.17.0
dependencyAdventureBukkit=4.3.3
# Test dependencies # Test dependencies
dependencyJunit=5.11.0-M2 dependencyJunit=5.11.0-M2
@ -40,6 +48,7 @@ dependencyJunit=5.11.0-M2
# Plugins # Plugins
pluginShadow=8.1.7 pluginShadow=8.1.7
pluginLombok=8.6 pluginLombok=8.6
pluginRunTask=2.3.0
pluginGitProperties=2.4.2 pluginGitProperties=2.4.2
pluginNativeImage=v1.4.0 pluginNativeImage=v1.4.0

83
minecraft/build.gradle Normal file
View file

@ -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 <https://www.gnu.org/licenses/>.
*/
// 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
])
}
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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
}
}

1
minecraft/bukkit/gradle Symbolic link
View file

@ -0,0 +1 @@
../../gradle

1
minecraft/bukkit/gradlew vendored Symbolic link
View file

@ -0,0 +1 @@
../../gradlew

1
minecraft/bukkit/gradlew.bat vendored Symbolic link
View file

@ -0,0 +1 @@
../../gradlew.bat

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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());
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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();
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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
}

View file

@ -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;
}

View file

@ -0,0 +1 @@
../../../../../src/main/javadoc/theme.css

View file

@ -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"

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
// 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)

View file

@ -0,0 +1 @@
../../../gradle

1
minecraft/bukkit/testextension/gradlew vendored Symbolic link
View file

@ -0,0 +1 @@
../../../gradlew

View file

@ -0,0 +1 @@
../../../gradlew.bat

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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());
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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");
}
}

View file

@ -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;
}

View file

@ -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

1
minecraft/gradle Symbolic link
View file

@ -0,0 +1 @@
../gradle

1
minecraft/gradlew vendored Symbolic link
View file

@ -0,0 +1 @@
../gradlew

1
minecraft/gradlew.bat vendored Symbolic link
View file

@ -0,0 +1 @@
../gradlew.bat

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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.
* <p>
* This class does not only provide engine settings but is also
* responsible for loading them into memory from {@link Properties} objects.
* <p>
* 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.<br/>
* 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;
}
}
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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();
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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,
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
package de.staropensource.sosengine.minecraft.api.api;
public interface Server {
/**
*
*/
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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.
* <p>
* 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);
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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 <bold>} or {@code <blink>} into a {@link Component}.
*
* @see ShortcodeParserSkeleton
* @since v1-alpha2
*/
@SuppressWarnings({ "unused" })
public class AdventureShortcodeConverter extends ShortcodeParserSkeleton {
/**
* Constructs this class.
*
* @param string string to convert
* @since v1-alpha0
*/
public AdventureShortcodeConverter(@NotNull String string) {
super(string);
}
/**
* Returns the parsed string as a {@link Component}.
*
* @return new {@link Component}
* @since v1-alpha0
*/
@NotNull
public Component getComponent() throws ParserException {
Component adventureComponent = Component.empty();
HSVLike color = null;
boolean formattingBold = false;
boolean formattingItalic = false;
boolean formattingStrikethrough = false;
boolean formattingUnderline = false;
for (String component : components)
if (component.equals("RESET")) {
color = null;
formattingBold = false;
formattingItalic = false;
formattingStrikethrough = false;
formattingUnderline = false;
} else if (component.startsWith("TEXT:")) {
Component textComponent = Component.text(component.substring(5));
if (color != null)
textComponent = textComponent.color(TextColor.color(color));
if (formattingBold)
textComponent = textComponent.decorate(TextDecoration.BOLD);
if (formattingItalic)
textComponent = textComponent.decorate(TextDecoration.ITALIC);
if (formattingStrikethrough)
textComponent = textComponent.decorate(TextDecoration.STRIKETHROUGH);
if (formattingUnderline)
textComponent = textComponent.decorate(TextDecoration.UNDERLINED);
adventureComponent = adventureComponent.append(textComponent);
} else if (component.startsWith("COLOR:"))
if (component.startsWith("COLOR:FOREGROUND:")) {
switch (component.substring(17)) {
case "BLACK" -> color = HSVLike.fromRGB(0, 0, 0);
case "WHITE" -> color = HSVLike.fromRGB(62, 62, 62);
case "RED" -> color = HSVLike.fromRGB(62, 21, 21);
case "GREEN" -> color = HSVLike.fromRGB(21, 62 ,21);
case "BLUE" -> color = HSVLike.fromRGB(21, 21, 62);
case "YELLOW" -> color = HSVLike.fromRGB(62, 62, 21);
case "MAGENTA" -> color = HSVLike.fromRGB(62, 21, 62);
case "CYAN" -> color = HSVLike.fromRGB(21, 62, 62);
default -> throw new ParserException("Invalid color " + component.substring(17) + ". Is AdventureShortcodeConverter up to date?");
}
}
else if (component.startsWith("ATTRIBUTE:"))
if (component.startsWith("ATTRIBUTE:BOLD"))
formattingBold = true;
else if (component.startsWith("ATTRIBUTE:ITALIC"))
formattingItalic = true;
else if (component.startsWith("ATTRIBUTE:STRIKETHROUGH"))
formattingStrikethrough = true;
else if (component.startsWith("ATTRIBUTE:UNDERLINE"))
formattingUnderline = true;
return adventureComponent;
}
}

View file

@ -0,0 +1,85 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.staropensource.sosengine.minecraft.extension;
import org.jetbrains.annotations.NotNull;
/**
* Implementation for extension entrypoint classes.
*
* @since v1-alpha2
*/
@SuppressWarnings({ "unused" })
public interface ExtensionEntrypoint {
/**
* Returns metadata about this extension.
*
* @return extension metadata
* @since v1-alpha2
*/
@NotNull
ExtensionMetadata getMetadata();
/**
* Called before the server starts up.
* <p>
* During this time the API will not be available.
* Use this method to load resources and early-init your extension.
*
* @since v1-alpha2
*/
void performEarlyInitialization();
/**
* Called during server startup, before worlds are loaded.
* <p>
* During this time the parts of the API will not be available.
* Use this method to register commands and do other initialization stuff.
*
* @since v1-alpha2
*/
void performInitialization();
/**
* Called after the server has started up and the world is already ticking.
* <p>
* As Minecraft is single-threaded however, please do lightweight or
* asynchronous stuff here or you will cause server-wide lag.
*
* @since v1-alpha2
*/
void performLateInitialization();
/**
* Called when the platform wants all plugins to reload.
* <p>
* Reload your configuration files and data in here.
*/
void performReload();
/**
* Called when the server is about to shutdown.
* <p>
* Run your shutdown logic in here.
*
* @since v1-alpha2
*/
void performShutdown();
}

View file

@ -0,0 +1,426 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.staropensource.sosengine.minecraft.extension;
import de.staropensource.sosengine.base.classes.VersioningSystem;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.Set;
/**
* Provides metadata about an extension.
*
* @since v1-alpha2
*/
@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
@Getter
public class ExtensionMetadata {
/**
* Contains the extension name.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension name.
*
* @return extension name
* @since v1-alpha2
*/
@NotNull
protected String name;
/**
* Contains the extension version.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension version.
*
* @return extension version
* @since v1-alpha2
*/
@NotNull
protected VersioningSystem version;
/**
* Contains the extension authors.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension authors.
*
* @return extension authors
* @since v1-alpha2
*/
@NotNull
protected Set<@NotNull String> authors;
/**
* Contains the extension website.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension website.
*
* @return extension website
* @since v1-alpha2
*/
@Nullable
protected String website;
/**
* Contains the extension documentation.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension documentation.
*
* @return extension documentation
* @since v1-alpha2
*/
@Nullable
protected String documentation;
/**
* Contains the extension bug tracker.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension bug tracker.
*
* @return extension bug tracker
* @since v1-alpha2
*/
@Nullable
protected String bugtracker;
/**
* Contains the extension repository.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension repository.
*
* @return extension repository
* @since v1-alpha2
*/
@Nullable
protected String repository;
/**
* Contains the extension social media links.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension social media links.
*
* @return extension socials
* @since v1-alpha2
*/
@Nullable
protected Map<@NotNull String, @NotNull String> socials;
/**
* Constructs this class.
*
* @param name extension name
* @param version extension version
* @param authors extension authors
* @param website extension website
* @param documentation extension documentation
* @param bugtracker extension bug tracker
* @param repository extension repository
* @param socials extension's social media links
* @see Builder
* @since v1-alpha2
*/
public ExtensionMetadata(@NotNull String name, @NotNull VersioningSystem version, @NotNull Set<@NotNull String> authors, @Nullable String website, @Nullable String documentation, @Nullable String bugtracker, @Nullable String repository, @Nullable Map<@NotNull String, @NotNull String> socials) {
this.name = name;
this.version = version;
this.authors = authors;
this.website = website;
this.documentation = documentation;
this.bugtracker = bugtracker;
this.repository = repository;
this.socials = socials;
}
/**
* Provides an API for building {@link ExtensionMetadata} classes more easily.
*
* @since v1-alpha2
*/
@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
@Getter
public static class Builder {
/**
* Contains the extension name.
* <p>
* Must match this regex: {@code ^[A-Za-z0-9_\.-]+$}.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension name.
*
* @return extension name
* @since v1-alpha2
*/
@Nullable
private String name = null;
/**
* Contains the extension version.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension version.
*
* @return extension version
* @since v1-alpha2
*/
@Nullable
private VersioningSystem version = null;
/**
* Contains the extension authors.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension authors.
*
* @return extension authors
* @since v1-alpha2
*/
@Nullable
private Set<@NotNull String> authors = null;
/**
* Contains the extension website.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension website.
*
* @return extension version
* @since v1-alpha2
*/
@Nullable
private String website = null;
/**
* Contains the extension documentation.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension documentation.
*
* @return extension documentation
* @since v1-alpha2
*/
@Nullable
private String documentation = null;
/**
* Contains the extension bug tracker.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension bug tracker.
*
* @return extension bug tracker
* @since v1-alpha2
*/
@Nullable
private String bugtracker = null;
/**
* Contains the extension repository.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension repository.
*
* @return extension repository
* @since v1-alpha2
*/
@Nullable
private String repository = null;
/**
* Contains the extension's social media links.
* <p>
* Keys represent the website name, the value the profile URL.
*
* @since v1-alpha2
*
* -- GETTER --
* Returns the extension's social media links.
* <p>
* Keys represent the website name, the value the profile URL.
*
* @return extension's socials
* @since v1-alpha2
*/
@Nullable
private Map<@NotNull String, @NotNull String> socials = null;
/**
* Constructs this class.
*
* @since v1-alpha2
*/
public Builder() {}
/**
* Builds a new {@link ExtensionMetadata} class.
*
* @since v1-alpha2
*/
public ExtensionMetadata build() throws IllegalStateException {
if (name == null)
throw new IllegalStateException("The extension name is unset but is required");
if (version == null)
throw new IllegalStateException("The extension version is unset but is required");
if (authors == null)
throw new IllegalStateException("The extension author list is unset but is required");
if (authors.isEmpty())
throw new IllegalStateException("The extension author list is empty but is required to contain at least one item");
return new ExtensionMetadata(name, version, authors, website, documentation, bugtracker, repository, socials);
}
/**
* Updates the extension name.
* <p>
* Must match this regex: {@code ^[A-Za-z0-9_\.-]+$}.
*
* @param name new extension name
* @return builder instance
* @since v1-alpha2
*/
public Builder setName(@NotNull String name) {
this.name = name;
return this;
}
/**
* Updates the extension version.
*
* @param version new extension version
* @return builder instance
* @since v1-alpha2
*/
public Builder setVersion(@NotNull VersioningSystem version) {
this.version = version;
return this;
}
/**
* Updates the extension authors.
*
* @param authors new extension authors
* @return builder instance
* @since v1-alpha2
*/
public Builder setAuthors(@NotNull Set<@NotNull String> authors) {
this.authors = authors;
return this;
}
/**
* Updates the extension website.
*
* @param website new extension website
* @return builder instance
* @since v1-alpha2
*/
public Builder setWebsite(@NotNull String website) {
this.website = website;
return this;
}
/**
* Updates the extension documentation.
*
* @param documentation new extension documentation
* @return builder instance
* @since v1-alpha2
*/
public Builder setDocumentation(@NotNull String documentation) {
this.documentation = documentation;
return this;
}
/**
* Updates the extension bug tracker.
*
* @param bugtracker new extension bug tracker
* @return builder instance
* @since v1-alpha2
*/
public Builder setBugtracker(@NotNull String bugtracker) {
this.bugtracker = bugtracker;
return this;
}
/**
* Updates the extension repository.
*
* @param repository new extension repository
* @return builder instance
* @since v1-alpha2
*/
public Builder setRepository(@NotNull String repository) {
this.repository = repository;
return this;
}
/**
* Updates the extension's social media links.
* <p>
* Keys represent the website name, the value the profile URL.
*
* @param socials new extension's socials
* @return builder instance
* @since v1-alpha2
*/
public Builder setSocials(@NotNull Map<@NotNull String, @NotNull String> socials) {
this.socials = socials;
return this;
}
}
}

View file

@ -0,0 +1,41 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.staropensource.sosengine.minecraft.extension;
import de.staropensource.sosengine.minecraft.implementation.ExtensionManager;
import org.jetbrains.annotations.NotNull;
/**
* Allows for {@link ExtensionEntrypoint} registration.
*
* @since v1-alpha2
*/
@SuppressWarnings({ "unused" })
public class ExtensionRegistrar {
/**
* Registers an {@link ExtensionEntrypoint}.
*
* @param entrypoint entrypoint to register
* @since v1-alpha2
*/
public static void register(@NotNull ExtensionEntrypoint entrypoint) {
ExtensionManager.getInstance().registerEntrypoint(entrypoint);
}
}

View file

@ -0,0 +1,184 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.staropensource.sosengine.minecraft.implementation;
import de.staropensource.sosengine.base.logging.LoggerInstance;
import de.staropensource.sosengine.base.types.CodePart;
import de.staropensource.sosengine.base.types.logging.LogIssuer;
import de.staropensource.sosengine.base.utility.parser.StackTraceParser;
import de.staropensource.sosengine.minecraft.extension.ExtensionEntrypoint;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/**
* Loads extensions and helps managing entrypoints.
*
* @since v1-alpha2
*/
@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
public final class ExtensionManager {
/**
* 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 ExtensionManager instance = null;
/**
* Logger instance.
*
* @see LoggerInstance
* @since v1-alpha2
*/
private final LoggerInstance logger = new LoggerInstance(new LogIssuer(getClass(), CodePart.ENGINE));
/**
* Contains all registered {@link ExtensionEntrypoint} classes.
*
* @see ExtensionEntrypoint
* @since v1-alpha2
*/
@NotNull
private final Set<@NotNull ExtensionEntrypoint> entrypoints = new HashSet<>();
/**
* Constructs this class.
*
* @since v1-alpha2
*/
public ExtensionManager() {
// Check if subsystem has already initialized
if (instance == null)
instance = this;
else {
instance.logger.crash("Tried initializing " + getClass().getName() + " twice");
}
}
/**
* Registers an {@link ExtensionEntrypoint}.
*
* @param entrypoint entrypoint to register
* @since v1-alpha2
*/
public void registerEntrypoint(@NotNull ExtensionEntrypoint entrypoint) {
entrypoints.add(entrypoint);
}
/**
* Executes {@link ExtensionEntrypoint#performEarlyInitialization()} on all extensions.
*
* @since v1-alpha2
*/
public void fireEarlyInitialization() {
logger.diag("Firing ExtensionEntrypoint#performEarlyInitialization on extensions");
for (ExtensionEntrypoint entrypoint : entrypoints) {
try {
entrypoint.performEarlyInitialization();
} catch (Throwable throwable) {
StackTraceParser parser = new StackTraceParser(throwable);
logger.error("Extension " + entrypoint.getMetadata().getName() + " (" + entrypoint.getMetadata().getName() + ") threw an exception during early initialization.\n" + parser.getHeader() + "\n" + parser.getStackTrace());
}
}
}
/**
* Executes {@link ExtensionEntrypoint#performInitialization()} on all extensions.
*
* @since v1-alpha2
*/
public void fireInitialization() {
logger.diag("Firing ExtensionEntrypoint#performInitialization on extensions");
for (ExtensionEntrypoint entrypoint : entrypoints) {
try {
entrypoint.performInitialization();
} catch (Throwable throwable) {
StackTraceParser parser = new StackTraceParser(throwable);
logger.error("Extension " + entrypoint.getMetadata().getName() + " (" + entrypoint.getMetadata().getName() + ") threw an exception during initialization.\n" + parser.getHeader() + "\n" + parser.getStackTrace());
}
}
}
/**
* Executes {@link ExtensionEntrypoint#performLateInitialization()} on all extensions.
*
* @since v1-alpha2
*/
public void fireLateInitialization() {
logger.diag("Firing ExtensionEntrypoint#performLateInitialization on extensions");
for (ExtensionEntrypoint entrypoint : entrypoints) {
try {
entrypoint.performLateInitialization();
} catch (Throwable throwable) {
StackTraceParser parser = new StackTraceParser(throwable);
logger.error("Extension " + entrypoint.getMetadata().getName() + " (" + entrypoint.getMetadata().getName() + ") threw an exception during late initialization.\n" + parser.getHeader() + "\n" + parser.getStackTrace());
}
}
}
/**
* Executes {@link ExtensionEntrypoint#performReload()} ()} on all extensions.
*
* @since v1-alpha2
*/
public void fireReload() {
logger.diag("Firing ExtensionEntrypoint#performReload on extensions");
for (ExtensionEntrypoint entrypoint : entrypoints) {
try {
entrypoint.performReload();
} catch (Throwable throwable) {
StackTraceParser parser = new StackTraceParser(throwable);
logger.error("Extension " + entrypoint.getMetadata().getName() + " (" + entrypoint.getMetadata().getName() + ") threw an exception during a reload.\n" + parser.getHeader() + "\n" + parser.getStackTrace());
}
}
}
/**
* Executes {@link ExtensionEntrypoint#performShutdown()} on all extensions.
*
* @since v1-alpha2
*/
public void fireShutdown() {
logger.diag("Firing ExtensionEntrypoint#performShutdown on extensions");
for (ExtensionEntrypoint entrypoint : entrypoints) {
try {
entrypoint.performShutdown();
} catch (Throwable throwable) {
StackTraceParser parser = new StackTraceParser(throwable);
logger.error("Extension " + entrypoint.getMetadata().getName() + " (" + entrypoint.getMetadata().getName() + ") threw an exception during shutdown.\n" + parser.getHeader() + "\n" + parser.getStackTrace());
}
}
}
}

View file

@ -0,0 +1,104 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.staropensource.sosengine.minecraft.implementation;
import de.staropensource.sosengine.base.Engine;
import de.staropensource.sosengine.base.classes.LoggerImpl;
import de.staropensource.sosengine.base.logging.Logger;
import de.staropensource.sosengine.base.logging.LoggerInstance;
import de.staropensource.sosengine.base.types.CodePart;
import de.staropensource.sosengine.base.types.logging.LogIssuer;
import de.staropensource.sosengine.minecraft.MinecraftSubsystem;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Helps bootstrapping the environment for the sos!engine to work in.
*
* @since v1-alpha2
*/
@SuppressWarnings({ "unused" })
public final class ImplementationBootstrapper {
/**
* Logger instance.
*
* @since v1-alpha2
*/
private static final LoggerInstance logger = new LoggerInstance(new LogIssuer(ImplementationBootstrapper.class, CodePart.ENGINE));
/**
* Initializes the engine and the environment.
*
* @param disallowMultithreading makes the engine single-threaded if {@code true}
* @param shutdownLogic shutdown logic to execute during JVM shutdown. Use this to save world and player data and to shutdown the server safely
* @param loggerImplementation logger implementation to use instead of the engine's built-in one. Set to {@code null} to use the built-in one
* @since v1-alpha2
*/
public static void initialize(boolean disallowMultithreading, @NotNull Runnable shutdownLogic, @Nullable LoggerImpl loggerImplementation) {
overwriteEngineConfiguration(disallowMultithreading); // overwrite engine configuration
installShutdownHook(shutdownLogic); // install the shutdown hook
if (loggerImplementation != null)
Logger.setLoggerImplementation(loggerImplementation); // install the custom logger implementation
initializeSubsystems(); // initialize all subsystems
}
/**
* Overwrites the default settings with system properties.
*
* @param disallowMultithreading makes the engine single-threaded if {@code true}
* @since v1-alpha2
*/
private static void overwriteEngineConfiguration(boolean disallowMultithreading) {
System.setProperty("sosengine.base.optimizeLogging", "true"); // enforce multi-threaded logging to avoid slowing down world ticking
System.setProperty("sosengine.base.loggerImmediateShutdown", "false"); // so worlds are saved properly
System.setProperty("sosengine.base.optimizeSubsystemInitialization", "false"); // disable automatic subsystem initialization it this will not work
if (disallowMultithreading)
System.setProperty("sosengine.base.optimizeEvents", "false");
}
/**
* Installs a shutdown hook to prevent {@link Engine#shutdown(int)} from shutting down the JVM without saving world and player data first.
*
* @param shutdownLogic shutdown logic to execute during JVM shutdown. Use this to save world and player data and to shutdown the server safely
* @since v1-alpha2
*/
private static void installShutdownHook(@NotNull Runnable shutdownLogic) {
Runtime.getRuntime().addShutdownHook(Thread.ofVirtual().unstarted(() -> {
logger.diag("Invoking shutdown logic");
try {
shutdownLogic.run();
} catch (Exception exception) {
logger.crash("Unable to shutdown server! Implementation's shutdown logic threw an exception. Hanging JVM", exception, true);
//noinspection InfiniteLoopStatement,StatementWithEmptyBody // we want an infinite loop
while (true) {}
}
}));
}
/**
* Initializes all subsystems.
*
* @since v1-alpha2
*/
private static void initializeSubsystems() {
new Engine().initializeSubsystem();
new MinecraftSubsystem().initializeSubsystem();
}
}

View file

@ -0,0 +1,40 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.staropensource.sosengine.minecraft.implementation;
import de.staropensource.sosengine.base.classes.SubsystemMainClass;
import org.jetbrains.annotations.NotNull;
/**
* The interface for Minecraft implementations main classes.
*
* @since v1-alpha2
*/
@SuppressWarnings({ "unused" })
public interface ImplementationMainClass extends SubsystemMainClass {
/**
* Returns the name of this implementation.
*
* @return implementation name
* @since v1-alpha2
*/
@NotNull
String getImplementationName();
}

View file

@ -0,0 +1,25 @@
/**
* Defines the Minecraft subsystem, which provides interfaces and
* classes that a platform implementation can use and provide.
* This system allows for easy cross-platform development.
*
* @since v1-alpha2
*/
open module sosengine.minecraft {
// Dependencies
// -> Subsystems
requires sosengine.base;
// -> Libraries
requires static lombok;
requires net.kyori.adventure;
requires net.kyori.examination.api;
requires org.reflections;
// API access
exports de.staropensource.sosengine.minecraft;
exports de.staropensource.sosengine.minecraft.api.api;
exports de.staropensource.sosengine.minecraft.api.entity;
exports de.staropensource.sosengine.minecraft.api.misc;
exports de.staropensource.sosengine.minecraft.extension;
exports de.staropensource.sosengine.minecraft.implementation;
}

View file

@ -0,0 +1,22 @@
<!--
~ 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 <https://www.gnu.org/licenses/>.
-->
<body>
<p>Welcome to the sos!engine API documentation!<br/>
You are currently in the documentation for the <b>minecraft</b> subsystem, providing compatibility and integration with Minecraft.</p>
</body>

View file

@ -0,0 +1 @@
../../../../src/main/javadoc/theme.css

View file

@ -24,4 +24,7 @@ include "slf4j-compat"
include "graphics" include "graphics"
include "graphics:opengl" include "graphics:opengl"
include "graphics:vulkan" include "graphics:vulkan"
include "minecraft"
include "minecraft:bukkit"
include "minecraft:bukkit:testextension"
include "testapp" include "testapp"