Adding client-side and server-side interactions. Also adds purpur/paper support
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
plugins {
|
||||
id 'net.fabricmc.fabric-loom'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
version = rootProject.mod_version
|
||||
group = rootProject.maven_group
|
||||
|
||||
base {
|
||||
archivesName = "${rootProject.archives_base_name}-26.1.2"
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url 'https://maven.shedaniel.me/' }
|
||||
maven { url 'https://maven.terraformersmc.com/releases/' }
|
||||
maven { url 'https://api.modrinth.com/maven/' }
|
||||
}
|
||||
|
||||
loom {
|
||||
splitEnvironmentSourceSets()
|
||||
|
||||
mods {
|
||||
go_minecraft_bridge {
|
||||
sourceSet sourceSets.main
|
||||
sourceSet sourceSets.client
|
||||
}
|
||||
}
|
||||
|
||||
runs {
|
||||
configureEach {
|
||||
vmArg '--enable-native-access=ALL-UNNAMED'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java.srcDirs rootProject.file('src/main/java'), rootProject.file('src/main/generated')
|
||||
resources.srcDirs rootProject.file('src/main/resources')
|
||||
}
|
||||
client {
|
||||
java.srcDirs rootProject.file('src/client/java')
|
||||
}
|
||||
test {
|
||||
java.srcDirs rootProject.file('src/test/java')
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft 'com.mojang:minecraft:26.1.2'
|
||||
implementation 'net.fabricmc:fabric-loader:0.19.3'
|
||||
implementation 'net.fabricmc.fabric-api:fabric-api:0.149.1+26.1.2'
|
||||
|
||||
implementation 'com.google.code.gson:gson:2.13.2'
|
||||
implementation include('com.google.flatbuffers:flatbuffers-java:25.2.10')
|
||||
implementation 'net.java.dev.jna:jna:5.18.1'
|
||||
|
||||
clientImplementation 'me.shedaniel.cloth:cloth-config-fabric:26.1.154'
|
||||
clientImplementation 'maven.modrinth:modmenu:18.0.0'
|
||||
|
||||
testImplementation platform('org.junit:junit-bom:5.13.4')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property 'version', project.version
|
||||
filesMatching('fabric.mod.json') {
|
||||
expand 'version': project.version
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
options.release = 25
|
||||
}
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
useJUnitPlatform()
|
||||
jvmArgs '--enable-native-access=ALL-UNNAMED'
|
||||
}
|
||||
|
||||
java {
|
||||
withSourcesJar()
|
||||
sourceCompatibility = JavaVersion.VERSION_25
|
||||
targetCompatibility = JavaVersion.VERSION_25
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create('mavenJava', MavenPublication) {
|
||||
from components.java
|
||||
}
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package dev.yawaflua.gominecraftbridge.compat;
|
||||
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
/** Minecraft-version-specific names kept behind one small source overlay. */
|
||||
public final class MinecraftVersionAdapter {
|
||||
private MinecraftVersionAdapter() {
|
||||
}
|
||||
|
||||
public static String gameVersion() {
|
||||
return SharedConstants.getCurrentVersion().name();
|
||||
}
|
||||
|
||||
public static String dimension(Level level) {
|
||||
return level.dimension().identifier().toString();
|
||||
}
|
||||
|
||||
public static long dayTime(ServerLevel level) {
|
||||
return level.getDefaultClockTime();
|
||||
}
|
||||
|
||||
public static boolean isOperator(MinecraftServer server, ServerPlayer player) {
|
||||
return server.getPlayerList().isOp(player.nameAndId());
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package dev.yawaflua.gominecraftbridge.network;
|
||||
|
||||
import dev.yawaflua.gominecraftbridge.GoMinecraftBridgeMod;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.Identifier;
|
||||
|
||||
public record AdminRequestPayload(String action, String pluginId) implements CustomPacketPayload {
|
||||
public static final Type<AdminRequestPayload> TYPE = new Type<>(
|
||||
Identifier.fromNamespaceAndPath(GoMinecraftBridgeMod.MOD_ID, "admin_request")
|
||||
);
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, AdminRequestPayload> CODEC =
|
||||
CustomPacketPayload.codec(AdminRequestPayload::write, AdminRequestPayload::new);
|
||||
|
||||
public AdminRequestPayload(RegistryFriendlyByteBuf buffer) {
|
||||
this(buffer.readUtf(32), buffer.readUtf(64));
|
||||
}
|
||||
|
||||
private void write(RegistryFriendlyByteBuf buffer) {
|
||||
buffer.writeUtf(this.action, 32);
|
||||
buffer.writeUtf(this.pluginId == null ? "" : this.pluginId, 64);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package dev.yawaflua.gominecraftbridge.network;
|
||||
|
||||
import dev.yawaflua.gominecraftbridge.GoMinecraftBridgeMod;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.Identifier;
|
||||
|
||||
public record AdminResponsePayload(String json) implements CustomPacketPayload {
|
||||
public static final int MAX_JSON_CHARS = 2 * 1024 * 1024;
|
||||
public static final Type<AdminResponsePayload> TYPE = new Type<>(
|
||||
Identifier.fromNamespaceAndPath(GoMinecraftBridgeMod.MOD_ID, "admin_response")
|
||||
);
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, AdminResponsePayload> CODEC =
|
||||
CustomPacketPayload.codec(AdminResponsePayload::write, AdminResponsePayload::new);
|
||||
|
||||
public AdminResponsePayload(RegistryFriendlyByteBuf buffer) {
|
||||
this(buffer.readUtf(MAX_JSON_CHARS));
|
||||
}
|
||||
|
||||
private void write(RegistryFriendlyByteBuf buffer) {
|
||||
buffer.writeUtf(this.json, MAX_JSON_CHARS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package dev.yawaflua.gominecraftbridge.network;
|
||||
|
||||
import dev.yawaflua.gominecraftbridge.compat.MinecraftVersionAdapter;
|
||||
import dev.yawaflua.gominecraftbridge.host.GoPluginManager;
|
||||
import dev.yawaflua.gominecraftbridge.management.BridgeManagementSnapshot;
|
||||
import dev.yawaflua.gominecraftbridge.management.ReloadResult;
|
||||
import dev.yawaflua.gominecraftbridge.protocol.ProtocolJson;
|
||||
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class BridgeAdminNetworking {
|
||||
private BridgeAdminNetworking() {
|
||||
}
|
||||
|
||||
public static void register(GoPluginManager plugins) {
|
||||
PayloadTypeRegistry.serverboundPlay().register(AdminRequestPayload.TYPE, AdminRequestPayload.CODEC);
|
||||
PayloadTypeRegistry.clientboundPlay().registerLarge(
|
||||
AdminResponsePayload.TYPE,
|
||||
AdminResponsePayload.CODEC,
|
||||
AdminResponsePayload.MAX_JSON_CHARS * 4 + 256
|
||||
);
|
||||
|
||||
ServerPlayNetworking.registerGlobalReceiver(AdminRequestPayload.TYPE, (payload, context) -> {
|
||||
boolean allowed = MinecraftVersionAdapter.isOperator(context.server(), context.player());
|
||||
if (!allowed) {
|
||||
send(context, withoutDetails(plugins.managementSnapshot(
|
||||
false,
|
||||
"Administrator permission is required"
|
||||
)));
|
||||
return;
|
||||
}
|
||||
|
||||
String message = null;
|
||||
if ("reload".equals(payload.action())) {
|
||||
ReloadResult result = plugins.reload(payload.pluginId(), context.server());
|
||||
message = result.message();
|
||||
} else if ("rescan".equals(payload.action())) {
|
||||
ReloadResult result = plugins.rescan(context.server());
|
||||
message = result.message();
|
||||
} else if (!"refresh".equals(payload.action())) {
|
||||
message = "Unknown admin action: " + payload.action();
|
||||
}
|
||||
|
||||
send(context, plugins.managementSnapshot(true, message));
|
||||
});
|
||||
}
|
||||
|
||||
static BridgeManagementSnapshot withoutDetails(BridgeManagementSnapshot snapshot) {
|
||||
return new BridgeManagementSnapshot(
|
||||
snapshot.generatedAtUnixMilli(),
|
||||
snapshot.serverRunning(),
|
||||
false,
|
||||
snapshot.message(),
|
||||
List.of(),
|
||||
List.of()
|
||||
);
|
||||
}
|
||||
|
||||
private static void send(
|
||||
ServerPlayNetworking.Context context,
|
||||
BridgeManagementSnapshot snapshot
|
||||
) {
|
||||
String json = ProtocolJson.GSON.toJson(snapshot);
|
||||
context.responseSender().sendPacket(new AdminResponsePayload(json));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user