diff --git a/gradle.properties b/gradle.properties index 5d8c090..44e7c68 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx5G org.gradle.parallel=true # Mod Properties -mod_version=0.4.4 +mod_version=0.4.5 archices_preview_version= maven_group=com.github.zly2006 diff --git a/src/main/java/com/github/zly2006/enclosure/gui/EnclosureScreen.java b/src/main/java/com/github/zly2006/enclosure/gui/EnclosureScreen.java index 6303454..ad06222 100644 --- a/src/main/java/com/github/zly2006/enclosure/gui/EnclosureScreen.java +++ b/src/main/java/com/github/zly2006/enclosure/gui/EnclosureScreen.java @@ -86,16 +86,16 @@ protected void init() { } String owner = UUIDCacheS2CPacket.getName(area.getOwner()); assert client != null; - if (!handler.fatherFullName.isEmpty()) { + if (handler.fatherFullName != null && !handler.fatherFullName.isEmpty()) { textWidgets.add(new ClickableTextWidget(client, this, Text.literal("<<< ") - .styled(style -> style.withColor(Formatting.DARK_GREEN)) - .append(Text.literal(handler.fatherFullName).formatted(Formatting.GOLD)), - Text.translatable("enclosure.widget.father_land.hover"), - button -> { - assert client.player != null; - close(); - client.player.networkHandler.sendChatCommand("enclosure gui " + handler.fatherFullName); - }, 5, 5, width - 10)); + .styled(style -> style.withColor(Formatting.DARK_GREEN)) + .append(Text.literal(handler.fatherFullName).formatted(Formatting.GOLD)), + Text.translatable("enclosure.widget.father_land.hover"), + button -> { + assert client.player != null; + close(); + client.player.networkHandler.sendChatCommand("enclosure gui " + handler.fatherFullName); + }, 5, 5, width - 10)); } textWidgets.add(new ClickableTextWidget(client, this, Text.empty() .append(Text.literal(area.getFullName()).styled(style -> style.withColor(Formatting.GOLD))) diff --git a/src/main/java/com/github/zly2006/enclosure/gui/EnclosureScreenHandler.kt b/src/main/java/com/github/zly2006/enclosure/gui/EnclosureScreenHandler.kt index 2b7deda..2f0bf46 100644 --- a/src/main/java/com/github/zly2006/enclosure/gui/EnclosureScreenHandler.kt +++ b/src/main/java/com/github/zly2006/enclosure/gui/EnclosureScreenHandler.kt @@ -1,131 +1,114 @@ -package com.github.zly2006.enclosure.gui; +package com.github.zly2006.enclosure.gui -import com.github.zly2006.enclosure.Enclosure; -import com.github.zly2006.enclosure.EnclosureArea; -import com.github.zly2006.enclosure.EnclosureView; -import com.github.zly2006.enclosure.utils.Serializable2Text; -import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; -import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerType; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.registry.Registries; -import net.minecraft.registry.Registry; -import net.minecraft.screen.ScreenHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import com.github.zly2006.enclosure.Enclosure +import com.github.zly2006.enclosure.EnclosureArea +import com.github.zly2006.enclosure.EnclosureView +import com.github.zly2006.enclosure.EnclosureView.Companion.readonly +import com.github.zly2006.enclosure.utils.Serializable2Text +import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory +import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerType +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NbtCompound +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.RegistryByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.registry.Registries +import net.minecraft.registry.Registry +import net.minecraft.screen.ScreenHandler +import net.minecraft.server.network.ServerPlayerEntity +import net.minecraft.util.Identifier -import java.util.ArrayList; -import java.util.List; +class EnclosureScreenHandler private constructor( + syncId: Int, + @JvmField val area: EnclosureView.ReadOnly, + @JvmField val fullName: String, + @JvmField val fatherFullName: String?, + @JvmField val worldId: Identifier, + @JvmField val subAreaNames: List +) : ScreenHandler(ENCLOSURE_SCREEN_HANDLER, syncId) { + class Data( + var fullName: String, + var fatherFullName: String?, + var worldId: Identifier, + var compound: NbtCompound, + var subAreaNames: List, + ) -public class EnclosureScreenHandler extends ScreenHandler { - public static final Identifier ENCLOSURE_SCREEN_ID = Identifier.of("enclosure", "screen.enclosure"); - public static class Data { - public String fullName; - public String fatherFullName; - public Identifier worldId; - public NbtCompound compound; - public List subAreaNames; + override fun quickMove(player: PlayerEntity, slot: Int): ItemStack { + return ItemStack.EMPTY } - public static final ExtendedScreenHandlerType ENCLOSURE_SCREEN_HANDLER = - new ExtendedScreenHandlerType<>((syncId, inventory, data) -> { - EnclosureView.ReadOnly area = EnclosureView.ReadOnly.Companion.readonly(data.compound); - return new EnclosureScreenHandler(syncId, area, data.fullName, data.fatherFullName, data.worldId, data.subAreaNames); - }, PacketCodec.of((value, buf) -> { - buf.writeString(value.fullName); - buf.writeString(value.fatherFullName); - buf.writeIdentifier(value.worldId); - buf.writeNbt(value.compound); - buf.writeVarInt(value.subAreaNames.size()); - for (String subAreaName : value.subAreaNames) { - buf.writeString(subAreaName); - } - }, buf -> { - Data data = new Data(); - data.fullName = buf.readString(); - data.fatherFullName = buf.readString(); - data.worldId = buf.readIdentifier(); - data.compound = buf.readNbt(); - int size = buf.readVarInt(); - data.subAreaNames = new ArrayList<>(size); - for (int i = 0; i < size; i++) { - data.subAreaNames.add(buf.readString()); - } - return data; - })); - public final EnclosureView.ReadOnly area; - public final String fullName; - public final String fatherFullName; - public final Identifier worldId; - public final List subAreaNames; - private EnclosureScreenHandler(int syncId, EnclosureView.ReadOnly area, String fullName, String fatherFullName, Identifier worldId, List subAreaNames) { - super(ENCLOSURE_SCREEN_HANDLER, syncId); - this.area = area; - this.fullName = fullName; - this.fatherFullName = fatherFullName; - this.worldId = worldId; - this.subAreaNames = subAreaNames; + override fun canUse(player: PlayerEntity): Boolean { + return true } - public static void register() { - Registry.register(Registries.SCREEN_HANDLER, ENCLOSURE_SCREEN_ID, ENCLOSURE_SCREEN_HANDLER); - } - - @Override - public ItemStack quickMove(PlayerEntity player, int slot) { - return null; - } + companion object { + @JvmField + val ENCLOSURE_SCREEN_ID: Identifier = Identifier.of("enclosure", "screen.enclosure") + val ENCLOSURE_SCREEN_HANDLER = ExtendedScreenHandlerType( + { syncId: Int, _: PlayerInventory?, data: Data -> + val area: EnclosureView.ReadOnly = readonly(data.compound) + EnclosureScreenHandler( + syncId, + area, + data.fullName, + data.fatherFullName, + data.worldId, + data.subAreaNames + ) + }, PacketCodec.of( + { value: Data, buf: RegistryByteBuf -> + buf.writeString(value.fullName) + buf.writeString(value.fatherFullName) + buf.writeIdentifier(value.worldId) + buf.writeNbt(value.compound) + buf.writeVarInt(value.subAreaNames.size) + for (subAreaName in value.subAreaNames) { + buf.writeString(subAreaName) + } + }, { buf: RegistryByteBuf -> + Data( + buf.readString(), + buf.readString(), + buf.readIdentifier(), + buf.readNbt()!!, + buf.readList(PacketByteBuf::readString) + ) + }) + ) - @Override - public boolean canUse(PlayerEntity player) { - return true; - } + fun register() { + Registry.register(Registries.SCREEN_HANDLER, ENCLOSURE_SCREEN_ID, ENCLOSURE_SCREEN_HANDLER) + } - public static void open(@NotNull ServerPlayerEntity player, @NotNull EnclosureArea area) { - player.openHandledScreen(new ExtendedScreenHandlerFactory() { - @Override - public Data getScreenOpeningData(ServerPlayerEntity player) { - Data data = new Data(); - data.fullName = area.getFullName(); - if (area.getFather() instanceof Enclosure) { - data.fatherFullName = area.getFather().getFullName(); - } else if (area.getFather() != null) { - data.fatherFullName = "$" + area.getFather().getFullName(); - } else { - data.fatherFullName = ""; - } - data.worldId = area.getWorld().getRegistryKey().getValue(); - NbtCompound compound = new NbtCompound(); - area.writeNbt(compound, null); - data.compound = compound; - if (area instanceof Enclosure enclosure) { - data.subAreaNames = new ArrayList<>(enclosure.getSubEnclosures().getAreas().size()); - for (EnclosureArea subArea : enclosure.getSubEnclosures().getAreas()) { - data.subAreaNames.add(subArea.getName()); + fun open(player: ServerPlayerEntity, area: EnclosureArea) { + player.openHandledScreen(object : ExtendedScreenHandlerFactory { + override fun getScreenOpeningData(player: ServerPlayerEntity) = Data( + area.fullName, + if (area.father is Enclosure) { + area.father!!.fullName + } else if (area.father != null) { + "$" + area.father!!.fullName + } else { + "" + }, + area.world.registryKey.value, + area.writeNbt(NbtCompound(), area.world.registryManager), + if (area is Enclosure) { + area.subEnclosures.names + } else { + emptyList() } - } else { - data.subAreaNames = new ArrayList<>(0); - } - return data; - } + ) - @Override - public Text getDisplayName() { - return area.serialize(Serializable2Text.SerializationSettings.Name, player); - } + override fun getDisplayName() = + area.serialize(Serializable2Text.SerializationSettings.Name, player) - @Nullable - @Override - public ScreenHandler createMenu(int syncId, PlayerInventory inv, PlayerEntity player) { - return EnclosureScreenHandler.ENCLOSURE_SCREEN_HANDLER - .create(syncId, inv, getScreenOpeningData((ServerPlayerEntity) player)); - } - }); + override fun createMenu(syncId: Int, inv: PlayerInventory, player: PlayerEntity) = + ENCLOSURE_SCREEN_HANDLER.create(syncId, inv, getScreenOpeningData(player as ServerPlayerEntity)) + }) + } } } diff --git a/src/main/java/com/github/zly2006/enclosure/mixin/MixinWorldChunk.java b/src/main/java/com/github/zly2006/enclosure/mixin/MixinWorldChunk.java index c2371de..7050612 100644 --- a/src/main/java/com/github/zly2006/enclosure/mixin/MixinWorldChunk.java +++ b/src/main/java/com/github/zly2006/enclosure/mixin/MixinWorldChunk.java @@ -39,9 +39,10 @@ public MixinWorldChunk(ChunkPos pos, UpgradeData upgradeData, HeightLimitView he public List enclosure$cache() { if (cache == null) { if (getWorld() instanceof ServerWorld serverWorld) { - cache = (List) ServerMain.INSTANCE.getAllEnclosures(serverWorld).getAreas() + cache = ServerMain.INSTANCE.getAllEnclosures(serverWorld).getAreas() .stream() .filter(enclosure -> enclosure.containsChunk(getPos())) + .map(enclosure -> (Enclosure) enclosure) .collect(Collectors.toList()); } else { cache = List.of(); diff --git a/src/main/kotlin/com/github/zly2006/enclosure/Enclosure.kt b/src/main/kotlin/com/github/zly2006/enclosure/Enclosure.kt index 81e030f..3d16ee2 100644 --- a/src/main/kotlin/com/github/zly2006/enclosure/Enclosure.kt +++ b/src/main/kotlin/com/github/zly2006/enclosure/Enclosure.kt @@ -1,118 +1,93 @@ -package com.github.zly2006.enclosure; +package com.github.zly2006.enclosure -import com.github.zly2006.enclosure.command.Session; -import com.github.zly2006.enclosure.utils.Permission; -import com.github.zly2006.enclosure.utils.TrT; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.text.ClickEvent; -import net.minecraft.text.HoverEvent; -import net.minecraft.text.MutableText; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.BlockPos; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import com.github.zly2006.enclosure.command.Session +import com.github.zly2006.enclosure.utils.Serializable2Text.SerializationSettings +import com.github.zly2006.enclosure.utils.TrT +import com.github.zly2006.enclosure.utils.clickRun +import com.github.zly2006.enclosure.utils.hoverText +import net.minecraft.nbt.NbtCompound +import net.minecraft.registry.RegistryWrapper.WrapperLookup +import net.minecraft.server.network.ServerPlayerEntity +import net.minecraft.server.world.ServerWorld +import net.minecraft.text.MutableText +import net.minecraft.util.Formatting +import net.minecraft.util.math.BlockPos -import java.util.UUID; - -import static com.github.zly2006.enclosure.EnclosureListKt.SUB_ENCLOSURES_KEY; - -public class Enclosure extends EnclosureArea { - final EnclosureList subEnclosures; +class Enclosure : EnclosureArea { + @JvmField + val subEnclosures: EnclosureList /** * Create an instance from nbt for a specific world. * @param compound the nbt compound tag */ - public Enclosure(NbtCompound compound, ServerWorld world) { - super(compound, world); + constructor(compound: NbtCompound, world: ServerWorld?) : super(compound, world!!) { // process sub enclosures - NbtCompound sub = compound.getCompound(SUB_ENCLOSURES_KEY); - subEnclosures = new EnclosureList(sub, world, false); - subEnclosures.getAreas().forEach(this::addChild); + val sub = compound.getCompound(SUB_ENCLOSURES_KEY) + subEnclosures = EnclosureList(sub, world, false) + subEnclosures.areas.forEach(this::addChild) } - public Enclosure(Session session, String name) { - super(session, name); - subEnclosures = new EnclosureList(session.getWorld(), false); + constructor(session: Session, name: String?) : super(session, name!!) { + subEnclosures = EnclosureList(session.world, false) } - @NotNull - @Override - public NbtCompound writeNbt(@NotNull NbtCompound nbt, @Nullable RegistryWrapper.WrapperLookup registryLookup) { - NbtCompound compound = super.writeNbt(nbt, registryLookup); - NbtCompound sub = new NbtCompound(); - subEnclosures.writeNbt(sub, registryLookup); - compound.put(SUB_ENCLOSURES_KEY, sub); - return compound; + override fun writeNbt(nbt: NbtCompound, registryLookup: WrapperLookup?): NbtCompound { + val compound = super.writeNbt(nbt, registryLookup) + val sub = NbtCompound() + subEnclosures.writeNbt(sub, registryLookup) + compound.put(SUB_ENCLOSURES_KEY, sub) + return compound } - @Override - public void changeWorld(@NotNull ServerWorld world) { - if (world == this.getWorld()) return; - super.setWorld(world); + override fun changeWorld(world: ServerWorld) { + if (world === this.world) return + super.world = world } - @Override - public @NotNull EnclosureArea areaOf(@NotNull BlockPos pos) { - for (EnclosureArea area : subEnclosures.getAreas()) { + override fun areaOf(pos: BlockPos): EnclosureArea { + for (area in subEnclosures.areas) { if (area.contains(pos)) { - return area.areaOf(pos); + return area.areaOf(pos) } } - return super.areaOf(pos); - } - - public @NotNull EnclosureList getSubEnclosures() { - return this.subEnclosures; + return super.areaOf(pos) } - @Override - public @NotNull MutableText serialize(@NotNull SerializationSettings settings, @Nullable ServerPlayerEntity player) { + override fun serialize(settings: SerializationSettings, player: ServerPlayerEntity?): MutableText { if (settings == SerializationSettings.Full) { - MutableText text = super.serialize(settings, player); - if (subEnclosures.getAreas().size() > 0) { - text.append("\n"); - text.append(TrT.of("enclosure.message.sub_lands")); - for (EnclosureArea area : subEnclosures.getAreas()) { - text.append(area.serialize(SerializationSettings.Name, player).styled( - style -> style.withColor(Formatting.GOLD) - .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, area.serialize(SerializationSettings.Hover, player))) - .withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/enclosure info " + area.getFullName())))); - text.append(" "); + val text = super.serialize(settings, player) + if (subEnclosures.areas.isNotEmpty()) { + text.append("\n") + text.append(TrT.of("enclosure.message.sub_lands")) + for (area in subEnclosures.areas) { + text.append(area.serialize(SerializationSettings.Name, player).styled { + it.withColor(Formatting.GOLD) + .hoverText(area.serialize(SerializationSettings.Hover, player)) + .clickRun("/enclosure info ${area.fullName}") + }) + text.append(" ") } } - return text; + return text + } else { + return super.serialize(settings, player) } - else { - return super.serialize(settings, player); - } - } - - @Override - public boolean hasPerm(@NotNull UUID uuid, @NotNull Permission perm) { - return super.hasPerm(uuid, perm); } - @Override - public void onRemoveChild(@NotNull PermissionHolder child) { - if (child instanceof EnclosureArea) - ((EnclosureArea) child).setFather(null); - subEnclosures.remove(child.getName()); - markDirty(); + override fun onRemoveChild(child: PermissionHolder) { + if (child is EnclosureArea) child.father = null + subEnclosures.remove(child.name) + markDirty() } - @Override - public void addChild(@NotNull PermissionHolder child) { - if (child instanceof EnclosureArea area) { - area.setFather(this); - subEnclosures.addArea(area); - markDirty(); - } - else { - throw new IllegalArgumentException("child must be an instance of EnclosureArea"); + override fun addChild(child: PermissionHolder) { + if (child is EnclosureArea) { + child.father = this + subEnclosures.addArea(child) + markDirty() + } else { + throw IllegalArgumentException("child must be an instance of EnclosureArea") } } } diff --git a/src/main/kotlin/com/github/zly2006/enclosure/EnclosureArea.kt b/src/main/kotlin/com/github/zly2006/enclosure/EnclosureArea.kt index 7013e87..bf484ee 100644 --- a/src/main/kotlin/com/github/zly2006/enclosure/EnclosureArea.kt +++ b/src/main/kotlin/com/github/zly2006/enclosure/EnclosureArea.kt @@ -67,7 +67,7 @@ open class EnclosureArea : PersistentState, EnclosureView { final override var createdOn: Long = 0 protected set override var father: PermissionHolder? = null - protected set + internal set val uuid: UUID override val fullName: String @@ -198,11 +198,10 @@ open class EnclosureArea : PersistentState, EnclosureView { } open fun areaOf(pos: BlockPos): EnclosureArea { - return if (contains(pos)) { - this - } else { - throw RuntimeException("The position $pos is not in the area$name") + if (!contains(pos)) { + throw IllegalStateException("The position $pos is not in the area$name") } + return this } fun includesArea(area: EnclosureArea): Boolean { diff --git a/src/main/kotlin/com/github/zly2006/enclosure/EnclosureList.kt b/src/main/kotlin/com/github/zly2006/enclosure/EnclosureList.kt index 5250e8b..f45f259 100644 --- a/src/main/kotlin/com/github/zly2006/enclosure/EnclosureList.kt +++ b/src/main/kotlin/com/github/zly2006/enclosure/EnclosureList.kt @@ -16,6 +16,7 @@ class EnclosureList(world: ServerWorld, private val isRoot: Boolean) : Persisten private val areaMap: MutableMap = mutableMapOf() private val boundWorld: ServerWorld? val areas = areaMap.values + val names get() = areaMap.keys.toList() constructor(nbt: NbtCompound, world: ServerWorld, isRoot: Boolean) : this(world, isRoot) { (nbt[ENCLOSURE_LIST_KEY] as? NbtList)?.forEach { diff --git a/src/main/kotlin/com/github/zly2006/enclosure/ServerMain.kt b/src/main/kotlin/com/github/zly2006/enclosure/ServerMain.kt index 9fa216c..698d4ba 100644 --- a/src/main/kotlin/com/github/zly2006/enclosure/ServerMain.kt +++ b/src/main/kotlin/com/github/zly2006/enclosure/ServerMain.kt @@ -12,10 +12,7 @@ import com.github.zly2006.enclosure.gui.EnclosureScreenHandler import com.github.zly2006.enclosure.listeners.SessionListener import com.github.zly2006.enclosure.network.config.EnclosureInstalledC2SPacket import com.github.zly2006.enclosure.network.config.UUIDCacheS2CPacket -import com.github.zly2006.enclosure.network.play.ConfirmRequestBiPacket -import com.github.zly2006.enclosure.network.play.RequestOpenScreenC2SPPacket -import com.github.zly2006.enclosure.network.play.SyncPermissionS2CPacket -import com.github.zly2006.enclosure.network.play.SyncSelectionS2CPacket +import com.github.zly2006.enclosure.network.play.* import com.github.zly2006.enclosure.utils.Permission import com.github.zly2006.enclosure.utils.ResourceLoader import com.github.zly2006.enclosure.utils.checkPermission @@ -366,6 +363,7 @@ object ServerMain: ModInitializer { UUIDCacheS2CPacket.register() SyncSelectionS2CPacket.register() SyncPermissionS2CPacket.register() + EnclosureInfoPayload.register() ServerPlayConnectionEvents.JOIN.register(ServerPlayConnectionEvents.Join { handler: ServerPlayNetworkHandler, _, _ -> // warn the server ops that this server is running in development mode and not secure. if (minecraftServer.playerManager.isOperator(handler.player.gameProfile) && commonConfig.developMode) { diff --git a/src/main/kotlin/com/github/zly2006/enclosure/exceptions/PermissionTargetException.kt b/src/main/kotlin/com/github/zly2006/enclosure/exceptions/PermissionTargetException.kt index 5ecaa5e..b47c7e8 100644 --- a/src/main/kotlin/com/github/zly2006/enclosure/exceptions/PermissionTargetException.kt +++ b/src/main/kotlin/com/github/zly2006/enclosure/exceptions/PermissionTargetException.kt @@ -1,16 +1,6 @@ -package com.github.zly2006.enclosure.exceptions; +package com.github.zly2006.enclosure.exceptions -import net.minecraft.text.Text; +import net.minecraft.text.Text -public class PermissionTargetException extends RuntimeException { - final Text text; - - public PermissionTargetException(Text text) { - super("This permission does not support the given target."); - this.text = text; - } - - public Text getText() { - return text; - } -} +class PermissionTargetException(val text: Text) + : RuntimeException("This permission does not support the given target.") diff --git a/src/main/kotlin/com/github/zly2006/enclosure/network/NetworkChannels.kt b/src/main/kotlin/com/github/zly2006/enclosure/network/NetworkChannels.kt index 1a9d1b1..c3f3720 100644 --- a/src/main/kotlin/com/github/zly2006/enclosure/network/NetworkChannels.kt +++ b/src/main/kotlin/com/github/zly2006/enclosure/network/NetworkChannels.kt @@ -9,4 +9,5 @@ object NetworkChannels { val SYNC_UUID: Identifier = Identifier.of("enclosure", "packet.uuid") val CONFIRM: Identifier = Identifier.of("enclosure", "packet.confirm") val SYNC_PERMISSION: Identifier = Identifier.of("enclosure", "packet.sync_permission") + val ENCLOSURE_INFO: Identifier = Identifier.of("enclosure", "packet.enclosure_info") } diff --git a/src/main/kotlin/com/github/zly2006/enclosure/network/config/EnclosureInstalledC2SPacket.kt b/src/main/kotlin/com/github/zly2006/enclosure/network/config/EnclosureInstalledC2SPacket.kt index 83350e8..bc691da 100644 --- a/src/main/kotlin/com/github/zly2006/enclosure/network/config/EnclosureInstalledC2SPacket.kt +++ b/src/main/kotlin/com/github/zly2006/enclosure/network/config/EnclosureInstalledC2SPacket.kt @@ -16,6 +16,7 @@ import net.minecraft.network.packet.CustomPayload import net.minecraft.server.MinecraftServer import net.minecraft.server.network.ServerPlayNetworkHandler import net.minecraft.server.network.ServerPlayerEntity +import net.minecraft.text.Text import java.util.* class EnclosureInstalledC2SPacket(var version: Version?) : CustomPayload { @@ -45,6 +46,8 @@ class EnclosureInstalledC2SPacket(var version: Version?) : CustomPayload { return installedClientMod[connection.uuid] } + private val incompatibleVersions = mutableMapOf Text>() + fun register() { ServerPlayConnectionEvents.DISCONNECT.register(ServerPlayConnectionEvents.Disconnect { handler: ServerPlayNetworkHandler, server: MinecraftServer? -> installedClientMod -= handler.player.uuid @@ -62,9 +65,21 @@ class EnclosureInstalledC2SPacket(var version: Version?) : CustomPayload { context.responseSender().sendPacket(UUIDCacheS2CPacket(minecraftServer.userCache!!)) } else if (version != null) { - + incompatibleVersions[uuid] = { + Text.translatable( + "enclosure.message.outdated", + MOD_VERSION.friendlyString, + version.friendlyString + ) + } } } + ServerPlayConnectionEvents.JOIN.register(ServerPlayConnectionEvents.Join { handler, sender, server -> + val message = incompatibleVersions.remove(handler.player.uuid) + if (message != null) { + handler.player.sendMessage(message()) + } + }) } } } diff --git a/src/main/kotlin/com/github/zly2006/enclosure/network/play/EnclosureInfoPayload.kt b/src/main/kotlin/com/github/zly2006/enclosure/network/play/EnclosureInfoPayload.kt new file mode 100644 index 0000000..e0bc470 --- /dev/null +++ b/src/main/kotlin/com/github/zly2006/enclosure/network/play/EnclosureInfoPayload.kt @@ -0,0 +1,57 @@ +package com.github.zly2006.enclosure.network.play + +import com.github.zly2006.enclosure.network.NetworkChannels +import net.fabricmc.api.EnvType +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry +import net.fabricmc.loader.api.FabricLoader +import net.minecraft.nbt.NbtCompound +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload +import net.minecraft.util.Identifier + +class EnclosureInfoPayload( + val fullName: String, + val compound: NbtCompound, + val worldId: Identifier, + val fatherFullName: String?, + val subAreaNames: List, + val openGui: Boolean = false, +): CustomPayload { + companion object { + fun register() { + PayloadTypeRegistry.playS2C().register(ID, CODEC) + if (FabricLoader.getInstance().environmentType == EnvType.CLIENT) { + ClientPlayNetworking.registerGlobalReceiver(ID) { p, context -> + TODO() + } + } + } + + val ID = CustomPayload.Id(NetworkChannels.ENCLOSURE_INFO) + private val CODEC = PacketCodec.of( + { value, buf -> + buf.writeString(value.fullName) + buf.writeNbt(value.compound) + buf.writeIdentifier(value.worldId) + buf.writeNullable(value.fatherFullName, PacketByteBuf::writeString) + buf.writeCollection(value.subAreaNames, PacketByteBuf::writeString) + buf.writeVarInt(value.subAreaNames.size) + buf.writeBoolean(value.openGui) + }, + { buf -> + EnclosureInfoPayload( + buf.readString(), + buf.readNbt()!!, + buf.readIdentifier(), + buf.readNullable(PacketByteBuf::readString), + buf.readList(PacketByteBuf::readString), + buf.readBoolean() + ) + } + ) + } + + override fun getId() = ID +}