Skip to content

Commit

Permalink
Add FabricMC support (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrMicky-FR authored Jun 7, 2023
1 parent e309759 commit bb99830
Show file tree
Hide file tree
Showing 28 changed files with 494 additions and 33 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:

strategy:
matrix:
java-version: [8, 11, 17]
java-version: [ 17 ]

steps:
- name: Checkout repository
Expand Down Expand Up @@ -44,3 +44,9 @@ jobs:
with:
name: AzLink-Legacy
path: universal-legacy/build/libs/AzLink-Legacy-*.jar

- name: Upload AzLink-Fabric.jar
uses: actions/upload-artifact@v3
with:
name: AzLink-Fabric
path: fabric/build/libs/AzLink-Fabric-*.jar
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This plugin currently supports the following platforms:
* [Sponge](https://www.spongepowered.org/)
* [Velocity](https://velocitypowered.com/)
* [Nukkit](https://cloudburstmc.org/articles/)
* [FabricMC](https://fabricmc.net/)

## Setup

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
allprojects {
group 'com.azuriom'
version '1.2.1'
version '1.3.0'
}

subprojects {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public AuthMeIntegration(AzLinkBukkitPlugin plugin) {

this.plugin.getLoggerAdapter().info("AuthMe integration enabled.");

this.plugin.getServer().getScheduler().runTask(this.plugin, () -> {
this.plugin.getPlugin().getScheduler().executeSync(() -> {
try {
Field field = AuthMeApi.class.getDeclaredField("dataSource");
field.setAccessible(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public Executor asyncExecutor() {
}

@Override
public CancellableTask executeAsyncLater(Runnable runnable, long delay, TimeUnit unit) {
public CancellableTask scheduleAsyncLater(Runnable runnable, long delay, TimeUnit unit) {
ScheduledTask task = this.plugin.getProxy()
.getScheduler()
.schedule(this.plugin, runnable, delay, unit);
Expand All @@ -47,7 +47,7 @@ public CancellableTask executeAsyncLater(Runnable runnable, long delay, TimeUnit
}

@Override
public CancellableTask executeAsyncRepeating(Runnable runnable, long delay, long interval, TimeUnit unit) {
public CancellableTask scheduleAsyncRepeating(Runnable runnable, long delay, long interval, TimeUnit unit) {
ScheduledTask task = this.plugin.getProxy()
.getScheduler()
.schedule(this.plugin, runnable, delay, interval, unit);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public void init() {
long startDelay = Duration.between(LocalDateTime.now(), start).toMillis();
long repeatDelay = TimeUnit.MINUTES.toMillis(1);

getScheduler().executeAsyncRepeating(this.fetcherTask, startDelay, repeatDelay, TimeUnit.MILLISECONDS);
getScheduler().scheduleAsyncRepeating(this.fetcherTask, startDelay, repeatDelay, TimeUnit.MILLISECONDS);

if (!this.config.isValid()) {
getLogger().warn("Invalid configuration, please use '/azlink' to setup the plugin.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class AzLinkCommand {
private static final List<String> COMPLETIONS = Arrays.asList("status", "setup", "fetch", "money", "port");
private static final List<String> MONEY_ACTIONS = Arrays.asList("add", "remove", "set");

private final AzLinkPlugin plugin;
protected final AzLinkPlugin plugin;

public AzLinkCommand(AzLinkPlugin plugin) {
this.plugin = plugin;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public enum PlatformType {
BUNGEE("BungeeCord"),
SPONGE("Sponge"),
VELOCITY("Velocity"),
FABRIC("Fabric"),
NUKKIT("Nukkit");

private final String name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,16 @@ public class JavaSchedulerAdapter implements SchedulerAdapter {
private final Executor syncExecutor;
private final Executor asyncExecutor;

public JavaSchedulerAdapter(Executor syncExecutor) {
this(createScheduler(), syncExecutor);
}

public JavaSchedulerAdapter(Executor syncExecutor, Executor asyncExecutor) {
this(Executors.newSingleThreadScheduledExecutor(new ThreadFactoryBuilder()
.name("azlink-scheduler")
.daemon()), syncExecutor, asyncExecutor);
this(createScheduler(), syncExecutor, asyncExecutor);
}

public JavaSchedulerAdapter(ScheduledExecutorService scheduler, Executor syncExecutor) {
this(scheduler, syncExecutor, scheduler);
}

public JavaSchedulerAdapter(ScheduledExecutorService scheduler, Executor syncExecutor, Executor asyncExecutor) {
Expand All @@ -35,12 +41,12 @@ public Executor asyncExecutor() {
}

@Override
public CancellableTask executeAsyncLater(Runnable runnable, long delay, TimeUnit unit) {
public CancellableTask scheduleAsyncLater(Runnable runnable, long delay, TimeUnit unit) {
return new CancellableFuture(this.scheduler.schedule(runnable, delay, unit));
}

@Override
public CancellableTask executeAsyncRepeating(Runnable runnable, long delay, long interval, TimeUnit unit) {
public CancellableTask scheduleAsyncRepeating(Runnable runnable, long delay, long interval, TimeUnit unit) {
return new CancellableFuture(this.scheduler.scheduleAtFixedRate(runnable, delay, interval, unit));
}

Expand All @@ -51,6 +57,12 @@ public void shutdown() throws Exception {
this.scheduler.awaitTermination(5, TimeUnit.SECONDS);
}

private static ScheduledExecutorService createScheduler() {
return Executors.newSingleThreadScheduledExecutor(new ThreadFactoryBuilder()
.name("azlink-scheduler")
.daemon());
}

private static class CancellableFuture implements CancellableTask {

private final Future<?> future;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ default void executeAsync(Runnable runnable) {

Executor asyncExecutor();

CancellableTask executeAsyncLater(Runnable runnable, long delay, TimeUnit unit);
CancellableTask scheduleAsyncLater(Runnable runnable, long delay, TimeUnit unit);

CancellableTask executeAsyncRepeating(Runnable runnable, long delay, long interval, TimeUnit unit);
CancellableTask scheduleAsyncRepeating(Runnable runnable, long delay, long interval, TimeUnit unit);

default void shutdown() throws Exception {

Expand Down
57 changes: 57 additions & 0 deletions fabric/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
plugins {
id 'fabric-loom' version '1.1-SNAPSHOT'
id 'com.github.johnrengelman.shadow' version '8.1.1'
}

sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17

ext {
minecraft_version = '1.20'
yarn_mappings = '1.20+build.1'
loader_version = '0.14.21'
fabric_version = '0.83.0+1.20'
}

repositories {
maven { url 'https://repo.spongepowered.org/repository/maven-public/' }
}

dependencies {
implementation project(':azlink-common')
implementation 'net.kyori:adventure-api:4.12.0'
implementation 'net.kyori:adventure-text-serializer-gson:4.12.0'
implementation 'net.kyori:adventure-text-serializer-legacy:4.12.0'
minecraft "com.mojang:minecraft:${project.ext.minecraft_version}"
mappings "net.fabricmc:yarn:${project.ext.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.ext.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.ext.fabric_version}"
}

processResources {
filesMatching('**/*.json') {
expand 'version': project.version
}
}

shadowJar {
dependencies {
exclude 'net.fabricmc:.*'
include dependency('com.azuriom:.*')
include dependency('net.kyori:.*')
}

relocate 'net.kyori', 'com.azuriom.azlink.libs'
}

remapJar {
dependsOn tasks.shadowJar
mustRunAfter tasks.shadowJar
inputFile = shadowJar.archiveFile
addNestedDependencies = true
archiveFileName = "AzLink-Fabric-${project.version}-${project.ext.minecraft_version}.jar"
}

artifacts {
archives remapJar
}
152 changes: 152 additions & 0 deletions fabric/src/main/java/com/azuriom/azlink/fabric/AzLinkFabricMod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package com.azuriom.azlink.fabric;

import com.azuriom.azlink.common.AzLinkPlatform;
import com.azuriom.azlink.common.AzLinkPlugin;
import com.azuriom.azlink.common.command.CommandSender;
import com.azuriom.azlink.common.data.WorldData;
import com.azuriom.azlink.common.logger.LoggerAdapter;
import com.azuriom.azlink.common.logger.Slf4jLoggerAdapter;
import com.azuriom.azlink.common.platform.PlatformInfo;
import com.azuriom.azlink.common.platform.PlatformType;
import com.azuriom.azlink.common.scheduler.JavaSchedulerAdapter;
import com.azuriom.azlink.common.scheduler.SchedulerAdapter;
import com.azuriom.azlink.common.tasks.TpsTask;
import com.azuriom.azlink.fabric.command.FabricCommandExecutor;
import com.azuriom.azlink.fabric.command.FabricPlayer;
import com.google.common.collect.Iterables;
import com.google.common.collect.Streams;
import net.fabricmc.api.DedicatedServerModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.ServerCommandSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.file.Path;
import java.util.Optional;
import java.util.stream.Stream;

public final class AzLinkFabricMod implements AzLinkPlatform, DedicatedServerModInitializer {

private static final Logger LOGGER = LoggerFactory.getLogger("azlink");

private final LoggerAdapter logger = new Slf4jLoggerAdapter(LOGGER);
private final TpsTask tpsTask = new TpsTask();

private final ModContainer modContainer;
private final AzLinkPlugin plugin;
private SchedulerAdapter scheduler;

public AzLinkFabricMod() {
this.modContainer = FabricLoader.getInstance()
.getModContainer("azlink")
.orElseThrow(() -> new RuntimeException("Unable to get the mod container."));
this.plugin = new AzLinkPlugin(this);
}

@Override
public void onInitializeServer() {
var command = new FabricCommandExecutor<>(this.plugin);

ServerLifecycleEvents.SERVER_STARTING.register(this::onServerStart);
ServerLifecycleEvents.SERVER_STOPPING.register(this::onServerStop);
ServerTickEvents.START_SERVER_TICK.register(s -> this.tpsTask.run());

CommandRegistrationCallback.EVENT
.register((dispatcher, registry, env) -> command.register(dispatcher));
}

public void onServerStart(MinecraftServer server) {
this.scheduler = this.initScheduler();
this.plugin.init();
}

public void onServerStop(MinecraftServer server) {
if (this.plugin != null) {
this.plugin.shutdown();
}
}

@Override
public AzLinkPlugin getPlugin() {
return this.plugin;
}

@Override
public LoggerAdapter getLoggerAdapter() {
return this.logger;
}

@Override
public SchedulerAdapter getSchedulerAdapter() {
return this.scheduler;
}

@Override
public PlatformType getPlatformType() {
return PlatformType.FABRIC;
}

@Override
public PlatformInfo getPlatformInfo() {
return FabricLoader.getInstance()
.getModContainer("fabric")
.map(ModContainer::getMetadata)
.map(m -> new PlatformInfo(m.getName(), m.getVersion().getFriendlyString()))
.orElse(new PlatformInfo("unknown", "unknown"));
}

@Override
public String getPluginVersion() {
return this.modContainer.getMetadata().getVersion().getFriendlyString();
}

@Override
public Path getDataDirectory() {
return FabricLoader.getInstance().getConfigDir().resolve("AzLink");
}

@Override
public Optional<WorldData> getWorldData() {
int loadedChunks = Streams.stream(getServer().getWorlds())
.mapToInt(w -> w.getChunkManager().getLoadedChunkCount())
.sum();
int entities = Streams.stream(getServer().getWorlds())
.mapToInt(w -> Iterables.size(w.iterateEntities()))
.sum();

return Optional.of(new WorldData(this.tpsTask.getTps(), loadedChunks, entities));
}

@Override
public Stream<CommandSender> getOnlinePlayers() {
return getServer().getPlayerManager()
.getPlayerList()
.stream()
.map(FabricPlayer::new);
}

@Override
public void dispatchConsoleCommand(String command) {
ServerCommandSource source = getServer().getCommandSource();
getServer().getCommandManager().executeWithPrefix(source, command);
}

@Override
public int getMaxPlayers() {
return getServer().getMaxPlayerCount();
}

private SchedulerAdapter initScheduler() {
return new JavaSchedulerAdapter(getServer()::executeSync);
}

@SuppressWarnings("deprecation")
private MinecraftServer getServer() {
return (MinecraftServer) FabricLoader.getInstance().getGameInstance();
}
}
Loading

0 comments on commit bb99830

Please sign in to comment.