Skip to content

Commit b597c54

Browse files
authored
feat: add fabric implementation (#138)
1 parent 930a8cc commit b597c54

27 files changed

+1827
-14
lines changed

.github/workflows/validate.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
- name: Setup java
2323
uses: actions/setup-java@v4
2424
with:
25-
java-version: 17
25+
java-version: 21
2626
check-latest: true
2727
distribution: 'zulu'
2828

.idea/codeStyles/Project.xml

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
## Features
1616

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

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

33-
| Module artifact name | Module description |
34-
|----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
35-
| npc-lib-api | General NPC-Lib API without platform specific class usage. This module should be used when the underlying implementation does not matter. |
36-
| npc-lib-common | Abstract implementation of the api module. This module should be used when a new platform implementation is made. |
37-
| npc-lib-bukkit | Platform specific implementation for Bukkit. This module implements the complete API (and common) to support Bukkit (and forks). |
38-
| npc-lib-minestom | Platform specific implementation for Minestom. This module implements the complete API (and common) to support Minestom (and forks). |
39-
| 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. |
33+
| Module artifact name | Module description |
34+
|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
35+
| npc-lib-api | General NPC-Lib API without platform specific class usage. This module should be used when the underlying implementation does not matter. |
36+
| npc-lib-common | Abstract implementation of the api module. This module should be used when a new platform implementation is made. |
37+
| npc-lib-bukkit | Platform specific implementation for Bukkit. This module implements the complete API (and common) to support Bukkit (and forks). |
38+
| npc-lib-minestom | Platform specific implementation for Minestom. This module implements the complete API (and common) to support Minestom (and forks). |
39+
| 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. |
40+
| 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. |
4041

4142
### How to include a module
4243

@@ -101,6 +102,12 @@ BukkitPlatform.bukkitNpcPlatformBuilder()
101102
MinestomPlatform.minestomNpcPlatformBuilder()
102103
```
103104

105+
### On Fabric
106+
107+
```java
108+
FabricPlatform.fabricNpcPlatformBuilder()
109+
```
110+
104111
## Configuring the Platform
105112

106113
In all further examples bukkit will be used as a reference, but the api is the same on all other platforms:

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import com.diffplug.gradle.spotless.SpotlessExtension
2727
plugins {
2828
alias(libs.plugins.spotless)
2929
alias(libs.plugins.nexusPublish)
30+
alias(libs.plugins.fabricLoom) apply false
3031
}
3132

3233
defaultTasks("clean", "build")

checkstyle.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"https://checkstyle.org/dtds/configuration_1_3.dtd">
2929
<module name="Checker">
3030
<module name="BeforeExecutionExclusionFileFilter">
31-
<property name="fileNamePattern" value="module\-info\.java$"/>
31+
<property name="fileNamePattern" value="(module\-info\.java$)|(.*[\\|\/]mixins[\\|\/].*$)"/>
3232
</module>
3333
<module name="SuppressionFilter">
3434
<property default="checkstyle-suppressions.xml" name="file"

fabric/build.gradle.kts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* This file is part of npc-lib, licensed under the MIT License (MIT).
3+
*
4+
* Copyright (c) 2022-2025 Julian M., Pasqual K. and contributors
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
plugins {
26+
alias(libs.plugins.fabricLoom)
27+
}
28+
29+
configurations {
30+
// custom configuration for later dependency resolution
31+
create("runtimeImpl") {
32+
configurations.getByName("api").extendsFrom(this)
33+
}
34+
}
35+
36+
dependencies {
37+
minecraft(libs.minecraft)
38+
modImplementation(libs.fabricLoader)
39+
mappings(loom.officialMojangMappings())
40+
41+
modImplementation(platform(libs.fabricApiBom))
42+
modImplementation(libs.fabricApiNetworkingV1)
43+
44+
"runtimeImpl"(projects.npcLibApi)
45+
"runtimeImpl"(projects.npcLibCommon)
46+
47+
implementation(libs.geantyref)
48+
}
49+
50+
tasks.withType<Jar> {
51+
dependsOn(":npc-lib-api:jar")
52+
dependsOn(":npc-lib-common:jar")
53+
from(configurations.getByName("runtimeImpl").map { if (it.isDirectory) it else zipTree(it) })
54+
}
55+
56+
tasks.withType<JavaCompile> {
57+
options.release.set(21)
58+
}
59+
60+
tasks.withType<ProcessResources> {
61+
val props = mapOf("version" to project.version)
62+
inputs.properties(props)
63+
filesMatching("fabric.mod.json") {
64+
expand(props)
65+
}
66+
}
67+
68+
loom {
69+
accessWidenerPath.set(project.file("src/main/resources/npc_lib.accesswidener"))
70+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* This file is part of npc-lib, licensed under the MIT License (MIT).
3+
*
4+
* Copyright (c) 2022-2023 Julian M., Pasqual K. and contributors
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
package com.github.juliarn.npclib.fabric;
26+
27+
import net.fabricmc.api.ModInitializer;
28+
29+
public final class FabricModInitializer implements ModInitializer {
30+
31+
@Override
32+
public void onInitialize() {
33+
34+
}
35+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* This file is part of npc-lib, licensed under the MIT License (MIT).
3+
*
4+
* Copyright (c) 2022-2023 Julian M., Pasqual K. and contributors
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
package com.github.juliarn.npclib.fabric;
26+
27+
import com.github.juliarn.npclib.api.NpcActionController;
28+
import com.github.juliarn.npclib.api.Platform;
29+
import com.github.juliarn.npclib.common.platform.CommonPlatform;
30+
import com.github.juliarn.npclib.common.platform.CommonPlatformBuilder;
31+
import com.github.juliarn.npclib.fabric.controller.FabricActionController;
32+
import com.github.juliarn.npclib.fabric.protocol.FabricProtocolAdapter;
33+
import net.minecraft.server.level.ServerLevel;
34+
import net.minecraft.server.level.ServerPlayer;
35+
import net.minecraft.world.item.ItemStack;
36+
import org.jetbrains.annotations.NotNull;
37+
38+
public final class FabricPlatform extends CommonPlatformBuilder<ServerLevel, ServerPlayer, ItemStack, Object> {
39+
40+
private FabricPlatform() {
41+
}
42+
43+
public static @NotNull Platform.Builder<ServerLevel, ServerPlayer, ItemStack, Object> fabricNpcPlatformBuilder() {
44+
return new FabricPlatform();
45+
}
46+
47+
@Override
48+
protected void prepareBuild() {
49+
// set the default task manager
50+
if (this.taskManager == null) {
51+
this.taskManager = FabricPlatformTaskManager.taskManager();
52+
}
53+
54+
// set the default version accessor
55+
if (this.versionAccessor == null) {
56+
this.versionAccessor = FabricVersionAccessor.versionNameBased();
57+
}
58+
59+
// set the default world accessor
60+
if (this.worldAccessor == null) {
61+
this.worldAccessor = FabricWorldAccessor.keyBased();
62+
}
63+
64+
// set the default packet adapter
65+
if (this.packetAdapter == null) {
66+
this.packetAdapter = FabricProtocolAdapter.fabricProtocolAdapter();
67+
}
68+
69+
// set the default logger if no logger was provided
70+
if (this.logger == null) {
71+
this.logger = FabricPlatformLogger.logger();
72+
}
73+
}
74+
75+
@Override
76+
protected @NotNull Platform<ServerLevel, ServerPlayer, ItemStack, Object> doBuild() {
77+
// check if we need an action controller
78+
NpcActionController actionController = null;
79+
if (this.actionControllerDecorator != null) {
80+
NpcActionController.Builder builder = FabricActionController.actionControllerBuilder(
81+
this.eventManager,
82+
this.npcTracker);
83+
this.actionControllerDecorator.accept(builder);
84+
actionController = builder.build();
85+
}
86+
87+
// build the platform
88+
return new CommonPlatform<>(
89+
this.debug,
90+
this.extension,
91+
this.logger,
92+
this.npcTracker,
93+
this.profileResolver,
94+
this.taskManager,
95+
actionController,
96+
this.versionAccessor,
97+
this.eventManager,
98+
this.worldAccessor,
99+
this.packetAdapter);
100+
}
101+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* This file is part of npc-lib, licensed under the MIT License (MIT).
3+
*
4+
* Copyright (c) 2022-2023 Julian M., Pasqual K. and contributors
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
package com.github.juliarn.npclib.fabric;
26+
27+
import com.github.juliarn.npclib.api.log.PlatformLogger;
28+
import com.mojang.logging.LogUtils;
29+
import org.jetbrains.annotations.NotNull;
30+
import org.jetbrains.annotations.Nullable;
31+
import org.slf4j.Logger;
32+
33+
public final class FabricPlatformLogger implements PlatformLogger {
34+
35+
private static final Logger LOGGER = LogUtils.getLogger();
36+
private static final FabricPlatformLogger INSTANCE = new FabricPlatformLogger();
37+
38+
private FabricPlatformLogger() {
39+
}
40+
41+
public static @NotNull PlatformLogger logger() {
42+
return INSTANCE;
43+
}
44+
45+
@Override
46+
public void info(@NotNull String message) {
47+
LOGGER.info(message);
48+
}
49+
50+
@Override
51+
public void warning(@NotNull String message) {
52+
LOGGER.warn(message);
53+
}
54+
55+
@Override
56+
public void error(@NotNull String message) {
57+
LOGGER.error(message);
58+
}
59+
60+
@Override
61+
public void error(@NotNull String message, @Nullable Throwable exception) {
62+
LOGGER.error(message, exception);
63+
}
64+
}

0 commit comments

Comments
 (0)