mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-12-28 23:38:32 +01:00
Start on 1.20.5 mod platform support - NeoForge (temporarily) excluded
Also fixes lecterns, and block break speed calculations
This commit is contained in:
parent
c34f0f2c3b
commit
6a5efa3c9d
15 changed files with 110 additions and 179 deletions
2
.github/workflows/build-remote.yml
vendored
2
.github/workflows/build-remote.yml
vendored
|
@ -64,7 +64,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
name: Geyser NeoForge
|
name: Geyser NeoForge
|
||||||
path: geyser/bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar
|
path: geyser/bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar
|
||||||
if-no-files-found: error
|
#if-no-files-found: error // TODO 1.20.5 until neoforge updates
|
||||||
- name: Archive artifacts (Geyser Standalone)
|
- name: Archive artifacts (Geyser Standalone)
|
||||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
|
||||||
if: success()
|
if: success()
|
||||||
|
|
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
@ -68,7 +68,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
name: Geyser NeoForge
|
name: Geyser NeoForge
|
||||||
path: bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar
|
path: bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar
|
||||||
if-no-files-found: error
|
#if-no-files-found: error // TODO 1.20.5 - currently no neoforge artifacts
|
||||||
- name: Archive artifacts (Geyser Standalone)
|
- name: Archive artifacts (Geyser Standalone)
|
||||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
|
||||||
if: success()
|
if: success()
|
||||||
|
|
2
.github/workflows/preview.yml
vendored
2
.github/workflows/preview.yml
vendored
|
@ -53,10 +53,10 @@ jobs:
|
||||||
with:
|
with:
|
||||||
appID: ${{ secrets.RELEASE_APP_ID }}
|
appID: ${{ secrets.RELEASE_APP_ID }}
|
||||||
appPrivateKey: ${{ secrets.RELEASE_APP_PK }}
|
appPrivateKey: ${{ secrets.RELEASE_APP_PK }}
|
||||||
|
# neoforge:Geyser-NeoForge.jar // TODO 1.20.5
|
||||||
files: |
|
files: |
|
||||||
bungeecord:Geyser-BungeeCord.jar
|
bungeecord:Geyser-BungeeCord.jar
|
||||||
fabric:Geyser-Fabric.jar
|
fabric:Geyser-Fabric.jar
|
||||||
neoforge:Geyser-NeoForge.jar
|
|
||||||
spigot:Geyser-Spigot.jar
|
spigot:Geyser-Spigot.jar
|
||||||
standalone:Geyser-Standalone.jar
|
standalone:Geyser-Standalone.jar
|
||||||
velocity:Geyser-Velocity.jar
|
velocity:Geyser-Velocity.jar
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
architectury {
|
architectury {
|
||||||
common("neoforge", "fabric")
|
common("fabric")
|
||||||
|
//common("neoforge", "fabric") // todo 1.20.5
|
||||||
}
|
}
|
||||||
|
|
||||||
loom {
|
loom {
|
||||||
|
|
|
@ -23,9 +23,8 @@
|
||||||
"geyser.mixins.json"
|
"geyser.mixins.json"
|
||||||
],
|
],
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=0.15.2",
|
"fabricloader": ">=0.15.10",
|
||||||
"fabric": "*",
|
"fabric": "*",
|
||||||
"minecraft": ">=1.20.4",
|
"minecraft": ">=1.20.4"
|
||||||
"fabric-permissions-api-v0": "*"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import lombok.AllArgsConstructor;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.network.Connection;
|
import net.minecraft.network.Connection;
|
||||||
import net.minecraft.network.PacketSendListener;
|
import net.minecraft.network.PacketSendListener;
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
|
@ -69,7 +70,7 @@ public class ModPingPassthrough implements IGeyserPingPassthrough {
|
||||||
StatusInterceptor connection = new StatusInterceptor();
|
StatusInterceptor connection = new StatusInterceptor();
|
||||||
ServerStatusPacketListener statusPacketListener = new ServerStatusPacketListenerImpl(status, connection);
|
ServerStatusPacketListener statusPacketListener = new ServerStatusPacketListenerImpl(status, connection);
|
||||||
|
|
||||||
statusPacketListener.handleStatusRequest(new ServerboundStatusRequestPacket());
|
statusPacketListener.handleStatusRequest(ServerboundStatusRequestPacket.INSTANCE);
|
||||||
// mods like MiniMOTD (that inject into the above method) have now processed the response
|
// mods like MiniMOTD (that inject into the above method) have now processed the response
|
||||||
status = Objects.requireNonNull(connection.status, "status response");
|
status = Objects.requireNonNull(connection.status, "status response");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -79,7 +80,7 @@ public class ModPingPassthrough implements IGeyserPingPassthrough {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String jsonDescription = net.minecraft.network.chat.Component.Serializer.toJson(status.description());
|
String jsonDescription = net.minecraft.network.chat.Component.Serializer.toJson(status.description(), RegistryAccess.EMPTY);
|
||||||
String legacyDescription = LEGACY_SERIALIZER.serialize(GSON_SERIALIZER.deserializeOr(jsonDescription, Component.empty()));
|
String legacyDescription = LEGACY_SERIALIZER.serialize(GSON_SERIALIZER.deserializeOr(jsonDescription, Component.empty()));
|
||||||
|
|
||||||
return new GeyserPingInfo(
|
return new GeyserPingInfo(
|
||||||
|
|
|
@ -27,6 +27,7 @@ package org.geysermc.geyser.platform.mod.command;
|
||||||
|
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
@ -63,7 +64,7 @@ public class ModCommandSender implements GeyserCommandSource {
|
||||||
public void sendMessage(net.kyori.adventure.text.Component message) {
|
public void sendMessage(net.kyori.adventure.text.Component message) {
|
||||||
if (source.getEntity() instanceof ServerPlayer player) {
|
if (source.getEntity() instanceof ServerPlayer player) {
|
||||||
String decoded = GsonComponentSerializer.gson().serialize(message);
|
String decoded = GsonComponentSerializer.gson().serialize(message);
|
||||||
player.displayClientMessage(Objects.requireNonNull(Component.Serializer.fromJson(decoded)), false);
|
player.displayClientMessage(Objects.requireNonNull(Component.Serializer.fromJson(decoded, RegistryAccess.EMPTY)), false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GeyserCommandSource.super.sendMessage(message);
|
GeyserCommandSource.super.sendMessage(message);
|
||||||
|
|
|
@ -27,37 +27,28 @@ package org.geysermc.geyser.platform.mod.world;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
|
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
|
||||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo;
|
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo;
|
||||||
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import net.minecraft.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.ByteArrayTag;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.nbt.ByteTag;
|
import net.minecraft.core.component.DataComponents;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.nbt.DoubleTag;
|
|
||||||
import net.minecraft.nbt.EndTag;
|
|
||||||
import net.minecraft.nbt.FloatTag;
|
|
||||||
import net.minecraft.nbt.IntArrayTag;
|
|
||||||
import net.minecraft.nbt.IntTag;
|
|
||||||
import net.minecraft.nbt.ListTag;
|
|
||||||
import net.minecraft.nbt.LongArrayTag;
|
|
||||||
import net.minecraft.nbt.LongTag;
|
|
||||||
import net.minecraft.nbt.ShortTag;
|
|
||||||
import net.minecraft.nbt.StringTag;
|
|
||||||
import net.minecraft.nbt.Tag;
|
|
||||||
import net.minecraft.nbt.TagVisitor;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.server.network.Filterable;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.WritableBookItem;
|
import net.minecraft.world.item.component.WritableBookContent;
|
||||||
import net.minecraft.world.item.WrittenBookItem;
|
import net.minecraft.world.item.component.WrittenBookContent;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.entity.BannerBlockEntity;
|
import net.minecraft.world.level.block.entity.BannerBlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.LecternBlockEntity;
|
import net.minecraft.world.level.block.entity.LecternBlockEntity;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.cloudburstmc.math.vector.Vector3i;
|
import org.cloudburstmc.math.vector.Vector3i;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
|
@ -72,10 +63,12 @@ import org.geysermc.geyser.util.BlockEntityUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class GeyserModWorldManager extends GeyserWorldManager {
|
public class GeyserModWorldManager extends GeyserWorldManager {
|
||||||
|
|
||||||
|
private static final GsonComponentSerializer GSON_SERIALIZER = GsonComponentSerializer.gson();
|
||||||
|
private static final LegacyComponentSerializer LEGACY_SERIALIZER = LegacyComponentSerializer.legacySection();
|
||||||
private final MinecraftServer server;
|
private final MinecraftServer server;
|
||||||
|
|
||||||
public GeyserModWorldManager(MinecraftServer server) {
|
public GeyserModWorldManager(MinecraftServer server) {
|
||||||
|
@ -180,7 +173,7 @@ public class GeyserModWorldManager extends GeyserWorldManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack book = lectern.getBook();
|
ItemStack book = lectern.getBook();
|
||||||
int pageCount = WrittenBookItem.getPageCount(book);
|
int pageCount = getPageCount(book);
|
||||||
boolean hasBookPages = pageCount > 0;
|
boolean hasBookPages = pageCount > 0;
|
||||||
NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(x, y, z, hasBookPages ? pageCount : 1);
|
NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(x, y, z, hasBookPages ? pageCount : 1);
|
||||||
lecternTag.putInt("page", lectern.getPage() / 2);
|
lecternTag.putInt("page", lectern.getPage() / 2);
|
||||||
|
@ -189,11 +182,9 @@ public class GeyserModWorldManager extends GeyserWorldManager {
|
||||||
.putShort("Damage", (short) 0)
|
.putShort("Damage", (short) 0)
|
||||||
.putString("Name", "minecraft:writable_book");
|
.putString("Name", "minecraft:writable_book");
|
||||||
List<NbtMap> pages = new ArrayList<>(hasBookPages ? pageCount : 1);
|
List<NbtMap> pages = new ArrayList<>(hasBookPages ? pageCount : 1);
|
||||||
if (hasBookPages && WritableBookItem.makeSureTagIsValid(book.getTag())) {
|
if (hasBookPages) {
|
||||||
ListTag listTag = book.getTag().getList("pages", 8);
|
List<String> bookPages = getPages(book);
|
||||||
|
for (String page : bookPages) {
|
||||||
for (int i = 0; i < listTag.size(); i++) {
|
|
||||||
String page = listTag.getString(i);
|
|
||||||
NbtMapBuilder pageBuilder = NbtMap.builder()
|
NbtMapBuilder pageBuilder = NbtMap.builder()
|
||||||
.putString("photoname", "")
|
.putString("photoname", "")
|
||||||
.putString("text", page);
|
.putString("text", page);
|
||||||
|
@ -243,9 +234,8 @@ public class GeyserModWorldManager extends GeyserWorldManager {
|
||||||
// Potentially exposes other NBT data? But we need to get the NBT data for the banner patterns *and*
|
// Potentially exposes other NBT data? But we need to get the NBT data for the banner patterns *and*
|
||||||
// the banner might have a custom name, both of which a Java client knows and caches
|
// the banner might have a custom name, both of which a Java client knows and caches
|
||||||
ItemStack itemStack = banner.getItem();
|
ItemStack itemStack = banner.getItem();
|
||||||
var tag = OpenNbtTagVisitor.convert("", itemStack.getOrCreateTag());
|
|
||||||
|
|
||||||
future.complete(tag);
|
future.complete(null); // todo 1.20.5
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
future.complete(null);
|
future.complete(null);
|
||||||
|
@ -257,95 +247,32 @@ public class GeyserModWorldManager extends GeyserWorldManager {
|
||||||
return server.getPlayerList().getPlayer(session.getPlayerEntity().getUuid());
|
return server.getPlayerList().getPlayer(session.getPlayerEntity().getUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Future considerations: option to clone; would affect arrays
|
private static int getPageCount(ItemStack itemStack) {
|
||||||
private static class OpenNbtTagVisitor implements TagVisitor {
|
WrittenBookContent writtenBookContent = itemStack.get(DataComponents.WRITTEN_BOOK_CONTENT);
|
||||||
private String currentKey;
|
if (writtenBookContent != null) {
|
||||||
private final com.github.steveice10.opennbt.tag.builtin.CompoundTag root;
|
return writtenBookContent.pages().size();
|
||||||
private com.github.steveice10.opennbt.tag.builtin.Tag currentTag;
|
} else {
|
||||||
|
WritableBookContent writableBookContent = itemStack.get(DataComponents.WRITABLE_BOOK_CONTENT);
|
||||||
OpenNbtTagVisitor(String key) {
|
return writableBookContent != null ? writableBookContent.pages().size() : 0;
|
||||||
root = new com.github.steveice10.opennbt.tag.builtin.CompoundTag(key);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
private static List<String> getPages(ItemStack itemStack) {
|
||||||
public void visitString(StringTag stringTag) {
|
WrittenBookContent writtenBookContent = itemStack.get(DataComponents.WRITTEN_BOOK_CONTENT);
|
||||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.StringTag(currentKey, stringTag.getAsString());
|
if (writtenBookContent != null) {
|
||||||
}
|
return writtenBookContent.pages().stream()
|
||||||
|
.map(Filterable::raw)
|
||||||
@Override
|
.map((component) -> Component.Serializer.toJson(component, RegistryAccess.EMPTY))
|
||||||
public void visitByte(ByteTag byteTag) {
|
.map((json -> LEGACY_SERIALIZER.serialize(GSON_SERIALIZER.deserializeOr(json, net.kyori.adventure.text.Component.empty()))))
|
||||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.ByteTag(currentKey, byteTag.getAsByte());
|
.toList();
|
||||||
}
|
} else {
|
||||||
|
WritableBookContent writableBookContent = itemStack.get(DataComponents.WRITABLE_BOOK_CONTENT);
|
||||||
@Override
|
if (writableBookContent == null) {
|
||||||
public void visitShort(ShortTag shortTag) {
|
return List.of();
|
||||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.ShortTag(currentKey, shortTag.getAsShort());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitInt(IntTag intTag) {
|
|
||||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.IntTag(currentKey, intTag.getAsInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitLong(LongTag longTag) {
|
|
||||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.LongTag(currentKey, longTag.getAsLong());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitFloat(FloatTag floatTag) {
|
|
||||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.FloatTag(currentKey, floatTag.getAsFloat());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitDouble(DoubleTag doubleTag) {
|
|
||||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.DoubleTag(currentKey, doubleTag.getAsDouble());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitByteArray(ByteArrayTag byteArrayTag) {
|
|
||||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.ByteArrayTag(currentKey, byteArrayTag.getAsByteArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitIntArray(IntArrayTag intArrayTag) {
|
|
||||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.IntArrayTag(currentKey, intArrayTag.getAsIntArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitLongArray(LongArrayTag longArrayTag) {
|
|
||||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.LongArrayTag(currentKey, longArrayTag.getAsLongArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitList(ListTag listTag) {
|
|
||||||
var newList = new com.github.steveice10.opennbt.tag.builtin.ListTag(currentKey);
|
|
||||||
for (Tag tag : listTag) {
|
|
||||||
currentKey = "";
|
|
||||||
tag.accept(this);
|
|
||||||
newList.add(currentTag);
|
|
||||||
}
|
}
|
||||||
currentTag = newList;
|
return writableBookContent.pages().stream()
|
||||||
}
|
.map(Filterable::raw)
|
||||||
|
.toList();
|
||||||
@Override
|
|
||||||
public void visitCompound(@NonNull CompoundTag compoundTag) {
|
|
||||||
currentTag = convert(currentKey, compoundTag);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static com.github.steveice10.opennbt.tag.builtin.CompoundTag convert(String name, CompoundTag compoundTag) {
|
|
||||||
OpenNbtTagVisitor visitor = new OpenNbtTagVisitor(name);
|
|
||||||
for (String key : compoundTag.getAllKeys()) {
|
|
||||||
visitor.currentKey = key;
|
|
||||||
Tag tag = Objects.requireNonNull(compoundTag.get(key));
|
|
||||||
tag.accept(visitor);
|
|
||||||
visitor.root.put(visitor.currentTag);
|
|
||||||
}
|
|
||||||
return visitor.root;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitEnd(@NonNull EndTag endTag) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,12 @@ loom {
|
||||||
silentMojangMappingsLicense()
|
silentMojangMappingsLicense()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
indra {
|
||||||
|
javaVersions {
|
||||||
|
target(21)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
create("includeTransitive").isTransitive = true
|
create("includeTransitive").isTransitive = true
|
||||||
}
|
}
|
||||||
|
@ -104,7 +110,7 @@ afterEvaluate {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft("com.mojang:minecraft:1.20.4")
|
minecraft("com.mojang:minecraft:1.20.5-rc3")
|
||||||
mappings(loom.officialMojangMappings())
|
mappings(loom.officialMojangMappings())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,6 +134,6 @@ modrinth {
|
||||||
syncBodyFrom.set(rootProject.file("README.md").readText())
|
syncBodyFrom.set(rootProject.file("README.md").readText())
|
||||||
|
|
||||||
uploadFile.set(tasks.getByPath("remapModrinthJar"))
|
uploadFile.set(tasks.getByPath("remapModrinthJar"))
|
||||||
gameVersions.addAll("1.20.4")
|
gameVersions.addAll("1.20.5")
|
||||||
failSilently.set(true)
|
failSilently.set(true)
|
||||||
}
|
}
|
|
@ -22,7 +22,7 @@ val basePlatforms = setOf(
|
||||||
|
|
||||||
val moddedPlatforms = setOf(
|
val moddedPlatforms = setOf(
|
||||||
projects.fabric,
|
projects.fabric,
|
||||||
projects.neoforge,
|
//projects.neoforge, // todo 1.20.5
|
||||||
projects.mod
|
projects.mod
|
||||||
).map { it.dependencyProject }
|
).map { it.dependencyProject }
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,11 @@
|
||||||
package org.geysermc.geyser.translator.inventory;
|
package org.geysermc.geyser.translator.inventory;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
|
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.item.component.WritableBookContent;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.item.component.WrittenBookContent;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
|
||||||
import org.cloudburstmc.math.vector.Vector3i;
|
import org.cloudburstmc.math.vector.Vector3i;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
|
@ -152,7 +153,6 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator
|
||||||
session.setDroppingLecternBook(false);
|
session.setDroppingLecternBook(false);
|
||||||
InventoryUtils.closeInventory(session, inventory.getJavaId(), false);
|
InventoryUtils.closeInventory(session, inventory.getJavaId(), false);
|
||||||
} else if (lecternContainer.getBlockEntityTag() == null) {
|
} else if (lecternContainer.getBlockEntityTag() == null) {
|
||||||
CompoundTag tag = book.getNbt();
|
|
||||||
Vector3i position = lecternContainer.isUsingRealBlock() ? session.getLastInteractionBlockPosition() : inventory.getHolderPosition();
|
Vector3i position = lecternContainer.isUsingRealBlock() ? session.getLastInteractionBlockPosition() : inventory.getHolderPosition();
|
||||||
|
|
||||||
// If shouldExpectLecternHandled returns true, this is already handled for us
|
// If shouldExpectLecternHandled returns true, this is already handled for us
|
||||||
|
@ -163,10 +163,20 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator
|
||||||
&& !GameProtocol.is1_20_60orHigher(session.getUpstream().getProtocolVersion());
|
&& !GameProtocol.is1_20_60orHigher(session.getUpstream().getProtocolVersion());
|
||||||
|
|
||||||
NbtMap blockEntityTag;
|
NbtMap blockEntityTag;
|
||||||
if (tag != null) {
|
if (book.getComponents() != null) {
|
||||||
int pagesSize = ((ListTag) tag.get("pages")).size();
|
int pages = 0;
|
||||||
|
WrittenBookContent writtenBookComponents = book.getComponents().get(DataComponentType.WRITTEN_BOOK_CONTENT);
|
||||||
|
if (writtenBookComponents != null) {
|
||||||
|
pages = writtenBookComponents.getPages().size();
|
||||||
|
} else {
|
||||||
|
WritableBookContent writableBookComponents = book.getComponents().get(DataComponentType.WRITABLE_BOOK_CONTENT);
|
||||||
|
if (writableBookComponents != null) {
|
||||||
|
pages = writableBookComponents.getPages().size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ItemData itemData = book.getItemData(session);
|
ItemData itemData = book.getItemData(session);
|
||||||
NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(position.getX(), position.getY(), position.getZ(), pagesSize);
|
NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(position.getX(), position.getY(), position.getZ(), pages);
|
||||||
lecternTag.putCompound("book", NbtMap.builder()
|
lecternTag.putCompound("book", NbtMap.builder()
|
||||||
.putByte("Count", (byte) itemData.getCount())
|
.putByte("Count", (byte) itemData.getCount())
|
||||||
.putShort("Damage", (short) 0)
|
.putShort("Damage", (short) 0)
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
package org.geysermc.geyser.translator.protocol.java.level;
|
package org.geysermc.geyser.translator.protocol.java.level;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockDestructionPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockDestructionPacket;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
|
||||||
import org.geysermc.geyser.registry.BlockRegistries;
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
|
@ -43,7 +42,7 @@ public class JavaBlockDestructionTranslator extends PacketTranslator<Clientbound
|
||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, ClientboundBlockDestructionPacket packet) {
|
public void translate(GeyserSession session, ClientboundBlockDestructionPacket packet) {
|
||||||
int state = session.getGeyser().getWorldManager().getBlockAt(session, packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ());
|
int state = session.getGeyser().getWorldManager().getBlockAt(session, packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ());
|
||||||
int breakTime = (int) (65535 / Math.ceil(BlockUtils.getBreakTime(session, BlockRegistries.JAVA_BLOCKS.getOrDefault(state, BlockMapping.DEFAULT), ItemMapping.AIR, new CompoundTag(""), false) * 20));
|
int breakTime = (int) (65535 / Math.ceil(BlockUtils.getBreakTime(session, BlockRegistries.JAVA_BLOCKS.getOrDefault(state, BlockMapping.DEFAULT), ItemMapping.AIR, null, false) * 20));
|
||||||
LevelEventPacket levelEventPacket = new LevelEventPacket();
|
LevelEventPacket levelEventPacket = new LevelEventPacket();
|
||||||
levelEventPacket.setPosition(packet.getPosition().toFloat());
|
levelEventPacket.setPosition(packet.getPosition().toFloat());
|
||||||
levelEventPacket.setType(LevelEvent.BLOCK_START_BREAK);
|
levelEventPacket.setType(LevelEvent.BLOCK_START_BREAK);
|
||||||
|
|
|
@ -25,11 +25,12 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.util;
|
package org.geysermc.geyser.util;
|
||||||
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.cloudburstmc.math.vector.Vector3i;
|
import org.cloudburstmc.math.vector.Vector3i;
|
||||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||||
import org.geysermc.geyser.inventory.PlayerInventory;
|
import org.geysermc.geyser.inventory.PlayerInventory;
|
||||||
|
import org.geysermc.geyser.inventory.item.Enchantment;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
import org.geysermc.geyser.registry.BlockRegistries;
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
import org.geysermc.geyser.registry.type.BlockMapping;
|
import org.geysermc.geyser.registry.type.BlockMapping;
|
||||||
|
@ -40,28 +41,23 @@ import org.geysermc.geyser.translator.collision.BlockCollision;
|
||||||
public final class BlockUtils {
|
public final class BlockUtils {
|
||||||
|
|
||||||
private static boolean correctTool(GeyserSession session, BlockMapping blockMapping, String itemToolType) {
|
private static boolean correctTool(GeyserSession session, BlockMapping blockMapping, String itemToolType) {
|
||||||
switch (itemToolType) {
|
return switch (itemToolType) {
|
||||||
case "axe":
|
case "axe" -> session.getTagCache().isAxeEffective(blockMapping);
|
||||||
return session.getTagCache().isAxeEffective(blockMapping);
|
case "hoe" -> session.getTagCache().isHoeEffective(blockMapping);
|
||||||
case "hoe":
|
case "pickaxe" -> session.getTagCache().isPickaxeEffective(blockMapping);
|
||||||
return session.getTagCache().isHoeEffective(blockMapping);
|
case "shears" -> session.getTagCache().isShearsEffective(blockMapping);
|
||||||
case "pickaxe":
|
case "shovel" -> session.getTagCache().isShovelEffective(blockMapping);
|
||||||
return session.getTagCache().isPickaxeEffective(blockMapping);
|
case "sword" -> blockMapping.getJavaBlockId() == BlockStateValues.JAVA_COBWEB_ID;
|
||||||
case "shears":
|
default -> {
|
||||||
return session.getTagCache().isShearsEffective(blockMapping);
|
|
||||||
case "shovel":
|
|
||||||
return session.getTagCache().isShovelEffective(blockMapping);
|
|
||||||
case "sword":
|
|
||||||
return blockMapping.getJavaBlockId() == BlockStateValues.JAVA_COBWEB_ID;
|
|
||||||
default:
|
|
||||||
session.getGeyser().getLogger().warning("Unknown tool type: " + itemToolType);
|
session.getGeyser().getLogger().warning("Unknown tool type: " + itemToolType);
|
||||||
return false;
|
yield false;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double toolBreakTimeBonus(String toolType, String toolTier, boolean isShearsEffective) {
|
private static double toolBreakTimeBonus(String toolType, String toolTier, boolean isShearsEffective) {
|
||||||
if (toolType.equals("shears")) return isShearsEffective ? 5.0 : 15.0;
|
if (toolType.equals("shears")) return isShearsEffective ? 5.0 : 15.0;
|
||||||
if (toolType.equals("")) return 1.0;
|
if (toolType.isEmpty()) return 1.0;
|
||||||
return switch (toolTier) {
|
return switch (toolTier) {
|
||||||
// https://minecraft.wiki/w/Breaking#Speed
|
// https://minecraft.wiki/w/Breaking#Speed
|
||||||
case "wooden" -> 2.0;
|
case "wooden" -> 2.0;
|
||||||
|
@ -134,7 +130,7 @@ public final class BlockUtils {
|
||||||
return 1.0 / speed;
|
return 1.0 / speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double getBreakTime(GeyserSession session, BlockMapping blockMapping, ItemMapping item, @Nullable CompoundTag nbtData, boolean isSessionPlayer) {
|
public static double getBreakTime(GeyserSession session, BlockMapping blockMapping, ItemMapping item, @Nullable DataComponents components, boolean isSessionPlayer) {
|
||||||
boolean isShearsEffective = session.getTagCache().isShearsEffective(blockMapping); //TODO called twice
|
boolean isShearsEffective = session.getTagCache().isShearsEffective(blockMapping); //TODO called twice
|
||||||
boolean canHarvestWithHand = blockMapping.isCanBreakWithHand();
|
boolean canHarvestWithHand = blockMapping.isCanBreakWithHand();
|
||||||
String toolType = "";
|
String toolType = "";
|
||||||
|
@ -147,7 +143,8 @@ public final class BlockUtils {
|
||||||
correctTool = correctTool(session, blockMapping, toolType);
|
correctTool = correctTool(session, blockMapping, toolType);
|
||||||
toolCanBreak = canToolTierBreakBlock(session, blockMapping, toolTier);
|
toolCanBreak = canToolTierBreakBlock(session, blockMapping, toolTier);
|
||||||
}
|
}
|
||||||
int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(nbtData, "minecraft:efficiency");
|
|
||||||
|
int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(components, Enchantment.JavaEnchantment.EFFICIENCY.ordinal());
|
||||||
int hasteLevel = 0;
|
int hasteLevel = 0;
|
||||||
int miningFatigueLevel = 0;
|
int miningFatigueLevel = 0;
|
||||||
|
|
||||||
|
@ -162,7 +159,7 @@ public final class BlockUtils {
|
||||||
|
|
||||||
boolean waterInEyes = session.getCollisionManager().isWaterInEyes();
|
boolean waterInEyes = session.getCollisionManager().isWaterInEyes();
|
||||||
boolean insideOfWaterWithoutAquaAffinity = waterInEyes &&
|
boolean insideOfWaterWithoutAquaAffinity = waterInEyes &&
|
||||||
ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getNbt(), "minecraft:aqua_affinity") < 1;
|
ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getComponents(), Enchantment.JavaEnchantment.AQUA_AFFINITY.ordinal()) < 1;
|
||||||
|
|
||||||
return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective,
|
return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective,
|
||||||
toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity, session.getPlayerEntity().isOnGround());
|
toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity, session.getPlayerEntity().isOnGround());
|
||||||
|
@ -172,12 +169,12 @@ public final class BlockUtils {
|
||||||
PlayerInventory inventory = session.getPlayerInventory();
|
PlayerInventory inventory = session.getPlayerInventory();
|
||||||
GeyserItemStack item = inventory.getItemInHand();
|
GeyserItemStack item = inventory.getItemInHand();
|
||||||
ItemMapping mapping = ItemMapping.AIR;
|
ItemMapping mapping = ItemMapping.AIR;
|
||||||
CompoundTag nbtData = null;
|
DataComponents components = null;
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
mapping = item.getMapping(session);
|
mapping = item.getMapping(session);
|
||||||
nbtData = item.getNbt();
|
components = item.getComponents();
|
||||||
}
|
}
|
||||||
return getBreakTime(session, blockMapping, mapping, nbtData, true);
|
return getBreakTime(session, blockMapping, mapping, components, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,10 +27,7 @@ package org.geysermc.geyser.util;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType;
|
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType;
|
||||||
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
|
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.geysermc.geyser.item.Items;
|
import org.geysermc.geyser.item.Items;
|
||||||
|
@ -39,24 +36,17 @@ import org.geysermc.geyser.item.type.Item;
|
||||||
|
|
||||||
public class ItemUtils {
|
public class ItemUtils {
|
||||||
|
|
||||||
public static int getEnchantmentLevel(@Nullable CompoundTag itemNBTData, String enchantmentId) {
|
public static int getEnchantmentLevel(@Nullable DataComponents components, int enchantmentId) {
|
||||||
if (itemNBTData == null) {
|
if (components == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ListTag enchantments = itemNBTData.get("Enchantments");
|
|
||||||
if (enchantments != null) {
|
ItemEnchantments enchantmentData = components.get(DataComponentType.ENCHANTMENTS);
|
||||||
for (Tag tag : enchantments) {
|
if (enchantmentData == null) {
|
||||||
CompoundTag enchantment = (CompoundTag) tag;
|
return 0;
|
||||||
StringTag enchantId = enchantment.get("id");
|
|
||||||
if (enchantId.getValue().equals(enchantmentId)) {
|
|
||||||
Tag lvl = enchantment.get("lvl");
|
|
||||||
if (lvl != null && lvl.getValue() instanceof Number number) {
|
|
||||||
return number.intValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
return enchantmentData.getEnchantments().getOrDefault(enchantmentId, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -66,7 +66,7 @@ include(":ap")
|
||||||
include(":api")
|
include(":api")
|
||||||
include(":bungeecord")
|
include(":bungeecord")
|
||||||
include(":fabric")
|
include(":fabric")
|
||||||
include(":neoforge")
|
//include(":neoforge") // todo 1.20.5
|
||||||
include(":mod")
|
include(":mod")
|
||||||
include(":spigot")
|
include(":spigot")
|
||||||
include(":standalone")
|
include(":standalone")
|
||||||
|
@ -78,7 +78,7 @@ include(":core")
|
||||||
// Specify project dirs
|
// Specify project dirs
|
||||||
project(":bungeecord").projectDir = file("bootstrap/bungeecord")
|
project(":bungeecord").projectDir = file("bootstrap/bungeecord")
|
||||||
project(":fabric").projectDir = file("bootstrap/mod/fabric")
|
project(":fabric").projectDir = file("bootstrap/mod/fabric")
|
||||||
project(":neoforge").projectDir = file("bootstrap/mod/neoforge")
|
//project(":neoforge").projectDir = file("bootstrap/mod/neoforge") // todo 1.20.5
|
||||||
project(":mod").projectDir = file("bootstrap/mod")
|
project(":mod").projectDir = file("bootstrap/mod")
|
||||||
project(":spigot").projectDir = file("bootstrap/spigot")
|
project(":spigot").projectDir = file("bootstrap/spigot")
|
||||||
project(":standalone").projectDir = file("bootstrap/standalone")
|
project(":standalone").projectDir = file("bootstrap/standalone")
|
||||||
|
|
Loading…
Reference in a new issue