Skip to content

Commit

Permalink
feat: add fabric implementation (#138)
Browse files Browse the repository at this point in the history
  • Loading branch information
derklaro authored Feb 3, 2025
1 parent 930a8cc commit b597c54
Show file tree
Hide file tree
Showing 27 changed files with 1,827 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Setup java
uses: actions/setup-java@v4
with:
java-version: 17
java-version: 21
check-latest: true
distribution: 'zulu'

Expand Down
2 changes: 0 additions & 2 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 16 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
## Features

- **Bukkit & Forks** (including Folia) supported via **ProtocolLib** or **PacketEvents**
- **Minestom** supported
- Full **Minestom** & **Fabric** support (latest version only)
- **Skin** (Static and Dynamic loading)
- **Attributes** (Status, Pose, Skin Layers)
- **Equipment** (Main & Off Hand, Armor)
- **Equipment** (Main & Off-Hand, Armor)
- **Interaction** (Interact & Attack)
- **Action Controller** (Automatic Looking at Player, Player Imitation & Spawning etc.)
- **LabyMod Extension** (Sending Emotes & Sprays)
Expand All @@ -30,13 +30,14 @@ There are some **[images](#images)** down below showcasing the use and features

All modules are available in [maven central](https://central.sonatype.com/search?q=io.github.juliarn):

| Module artifact name | Module description |
|----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| npc-lib-api | General NPC-Lib API without platform specific class usage. This module should be used when the underlying implementation does not matter. |
| npc-lib-common | Abstract implementation of the api module. This module should be used when a new platform implementation is made. |
| npc-lib-bukkit | Platform specific implementation for Bukkit. This module implements the complete API (and common) to support Bukkit (and forks). |
| npc-lib-minestom | Platform specific implementation for Minestom. This module implements the complete API (and common) to support Minestom (and forks). |
| npc-lib-labymod | This module contains helper methods for accessing LabyMod NPC features (such as emotes and stickers). See the [LabyMod documentation](https://dev.labymod.net/) for more information. |
| Module artifact name | Module description |
|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| npc-lib-api | General NPC-Lib API without platform specific class usage. This module should be used when the underlying implementation does not matter. |
| npc-lib-common | Abstract implementation of the api module. This module should be used when a new platform implementation is made. |
| npc-lib-bukkit | Platform specific implementation for Bukkit. This module implements the complete API (and common) to support Bukkit (and forks). |
| npc-lib-minestom | Platform specific implementation for Minestom. This module implements the complete API (and common) to support Minestom (and forks). |
| npc-lib-fabric | Platform specific implementation for Fabric. This module implements the complete API (and common) to support Fabric and [must be installed as a mod](https://modrinth.com/mod/npc-lib) on the server. |
| npc-lib-labymod | This module contains helper methods for accessing LabyMod NPC features (such as emotes and stickers). See the [LabyMod documentation](https://dev.labymod.net/) for more information. |

### How to include a module

Expand Down Expand Up @@ -101,6 +102,12 @@ BukkitPlatform.bukkitNpcPlatformBuilder()
MinestomPlatform.minestomNpcPlatformBuilder()
```

### On Fabric

```java
FabricPlatform.fabricNpcPlatformBuilder()
```

## Configuring the Platform

In all further examples bukkit will be used as a reference, but the api is the same on all other platforms:
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.diffplug.gradle.spotless.SpotlessExtension
plugins {
alias(libs.plugins.spotless)
alias(libs.plugins.nexusPublish)
alias(libs.plugins.fabricLoom) apply false
}

defaultTasks("clean", "build")
Expand Down
2 changes: 1 addition & 1 deletion checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="module\-info\.java$"/>
<property name="fileNamePattern" value="(module\-info\.java$)|(.*[\\|\/]mixins[\\|\/].*$)"/>
</module>
<module name="SuppressionFilter">
<property default="checkstyle-suppressions.xml" name="file"
Expand Down
70 changes: 70 additions & 0 deletions fabric/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* This file is part of npc-lib, licensed under the MIT License (MIT).
*
* Copyright (c) 2022-2025 Julian M., Pasqual K. and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

plugins {
alias(libs.plugins.fabricLoom)
}

configurations {
// custom configuration for later dependency resolution
create("runtimeImpl") {
configurations.getByName("api").extendsFrom(this)
}
}

dependencies {
minecraft(libs.minecraft)
modImplementation(libs.fabricLoader)
mappings(loom.officialMojangMappings())

modImplementation(platform(libs.fabricApiBom))
modImplementation(libs.fabricApiNetworkingV1)

"runtimeImpl"(projects.npcLibApi)
"runtimeImpl"(projects.npcLibCommon)

implementation(libs.geantyref)
}

tasks.withType<Jar> {
dependsOn(":npc-lib-api:jar")
dependsOn(":npc-lib-common:jar")
from(configurations.getByName("runtimeImpl").map { if (it.isDirectory) it else zipTree(it) })
}

tasks.withType<JavaCompile> {
options.release.set(21)
}

tasks.withType<ProcessResources> {
val props = mapOf("version" to project.version)
inputs.properties(props)
filesMatching("fabric.mod.json") {
expand(props)
}
}

loom {
accessWidenerPath.set(project.file("src/main/resources/npc_lib.accesswidener"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* This file is part of npc-lib, licensed under the MIT License (MIT).
*
* Copyright (c) 2022-2023 Julian M., Pasqual K. and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.github.juliarn.npclib.fabric;

import net.fabricmc.api.ModInitializer;

public final class FabricModInitializer implements ModInitializer {

@Override
public void onInitialize() {

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

package com.github.juliarn.npclib.fabric;

import com.github.juliarn.npclib.api.NpcActionController;
import com.github.juliarn.npclib.api.Platform;
import com.github.juliarn.npclib.common.platform.CommonPlatform;
import com.github.juliarn.npclib.common.platform.CommonPlatformBuilder;
import com.github.juliarn.npclib.fabric.controller.FabricActionController;
import com.github.juliarn.npclib.fabric.protocol.FabricProtocolAdapter;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;

public final class FabricPlatform extends CommonPlatformBuilder<ServerLevel, ServerPlayer, ItemStack, Object> {

private FabricPlatform() {
}

public static @NotNull Platform.Builder<ServerLevel, ServerPlayer, ItemStack, Object> fabricNpcPlatformBuilder() {
return new FabricPlatform();
}

@Override
protected void prepareBuild() {
// set the default task manager
if (this.taskManager == null) {
this.taskManager = FabricPlatformTaskManager.taskManager();
}

// set the default version accessor
if (this.versionAccessor == null) {
this.versionAccessor = FabricVersionAccessor.versionNameBased();
}

// set the default world accessor
if (this.worldAccessor == null) {
this.worldAccessor = FabricWorldAccessor.keyBased();
}

// set the default packet adapter
if (this.packetAdapter == null) {
this.packetAdapter = FabricProtocolAdapter.fabricProtocolAdapter();
}

// set the default logger if no logger was provided
if (this.logger == null) {
this.logger = FabricPlatformLogger.logger();
}
}

@Override
protected @NotNull Platform<ServerLevel, ServerPlayer, ItemStack, Object> doBuild() {
// check if we need an action controller
NpcActionController actionController = null;
if (this.actionControllerDecorator != null) {
NpcActionController.Builder builder = FabricActionController.actionControllerBuilder(
this.eventManager,
this.npcTracker);
this.actionControllerDecorator.accept(builder);
actionController = builder.build();
}

// build the platform
return new CommonPlatform<>(
this.debug,
this.extension,
this.logger,
this.npcTracker,
this.profileResolver,
this.taskManager,
actionController,
this.versionAccessor,
this.eventManager,
this.worldAccessor,
this.packetAdapter);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* This file is part of npc-lib, licensed under the MIT License (MIT).
*
* Copyright (c) 2022-2023 Julian M., Pasqual K. and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.github.juliarn.npclib.fabric;

import com.github.juliarn.npclib.api.log.PlatformLogger;
import com.mojang.logging.LogUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;

public final class FabricPlatformLogger implements PlatformLogger {

private static final Logger LOGGER = LogUtils.getLogger();
private static final FabricPlatformLogger INSTANCE = new FabricPlatformLogger();

private FabricPlatformLogger() {
}

public static @NotNull PlatformLogger logger() {
return INSTANCE;
}

@Override
public void info(@NotNull String message) {
LOGGER.info(message);
}

@Override
public void warning(@NotNull String message) {
LOGGER.warn(message);
}

@Override
public void error(@NotNull String message) {
LOGGER.error(message);
}

@Override
public void error(@NotNull String message, @Nullable Throwable exception) {
LOGGER.error(message, exception);
}
}
Loading

0 comments on commit b597c54

Please sign in to comment.