Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-27 00:23:03 +01:00
Merge branch 'master' of https://github.com/GeyserMC/Geyser
Dieser Commit ist enthalten in:
Commit
5ff855bb00
@ -16,7 +16,7 @@ dependencies {
|
|||||||
|
|
||||||
// Within the gradle plugin classpath, there is a version conflict between loom and some other
|
// Within the gradle plugin classpath, there is a version conflict between loom and some other
|
||||||
// plugin for databind. This fixes it: minimum 2.13.2 is required by loom.
|
// plugin for databind. This fixes it: minimum 2.13.2 is required by loom.
|
||||||
implementation("com.fasterxml.jackson.core:jackson-databind:2.13.3")
|
implementation("com.fasterxml.jackson.core:jackson-databind:2.14.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<KotlinCompile> {
|
tasks.withType<KotlinCompile> {
|
||||||
|
@ -111,6 +111,8 @@ public interface GeyserConfiguration {
|
|||||||
|
|
||||||
boolean isNotifyOnNewBedrockUpdate();
|
boolean isNotifyOnNewBedrockUpdate();
|
||||||
|
|
||||||
|
String getUnusableSpaceBlock();
|
||||||
|
|
||||||
IMetricsInfo getMetrics();
|
IMetricsInfo getMetrics();
|
||||||
|
|
||||||
int getPendingAuthenticationTimeout();
|
int getPendingAuthenticationTimeout();
|
||||||
|
@ -154,6 +154,9 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
|
|||||||
@JsonProperty("notify-on-new-bedrock-update")
|
@JsonProperty("notify-on-new-bedrock-update")
|
||||||
private boolean notifyOnNewBedrockUpdate = true;
|
private boolean notifyOnNewBedrockUpdate = true;
|
||||||
|
|
||||||
|
@JsonProperty("unusable-space-block")
|
||||||
|
private String unusableSpaceBlock = "minecraft:barrier";
|
||||||
|
|
||||||
private MetricsInfo metrics = new MetricsInfo();
|
private MetricsInfo metrics = new MetricsInfo();
|
||||||
|
|
||||||
@JsonProperty("pending-authentication-timeout")
|
@JsonProperty("pending-authentication-timeout")
|
||||||
|
@ -46,9 +46,13 @@ import org.geysermc.geyser.util.MathUtils;
|
|||||||
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Deque;
|
||||||
|
|
||||||
public class UpstreamPacketHandler extends LoggingPacketHandler {
|
public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||||
|
|
||||||
|
private Deque<String> packsToSent = new ArrayDeque<>();
|
||||||
|
|
||||||
public UpstreamPacketHandler(GeyserImpl geyser, GeyserSession session) {
|
public UpstreamPacketHandler(GeyserImpl geyser, GeyserSession session) {
|
||||||
super(geyser, session);
|
super(geyser, session);
|
||||||
}
|
}
|
||||||
@ -161,24 +165,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SEND_PACKS:
|
case SEND_PACKS:
|
||||||
for(String id : packet.getPackIds()) {
|
packsToSent.addAll(packet.getPackIds());
|
||||||
ResourcePackDataInfoPacket data = new ResourcePackDataInfoPacket();
|
sendPackDataInfo(packsToSent.pop());
|
||||||
String[] packID = id.split("_");
|
|
||||||
ResourcePack pack = ResourcePack.PACKS.get(packID[0]);
|
|
||||||
ResourcePackManifest.Header header = pack.getManifest().getHeader();
|
|
||||||
|
|
||||||
data.setPackId(header.getUuid());
|
|
||||||
int chunkCount = (int) Math.ceil((int) pack.getFile().length() / (double) ResourcePack.CHUNK_SIZE);
|
|
||||||
data.setChunkCount(chunkCount);
|
|
||||||
data.setCompressedPackSize(pack.getFile().length());
|
|
||||||
data.setMaxChunkSize(ResourcePack.CHUNK_SIZE);
|
|
||||||
data.setHash(pack.getSha256());
|
|
||||||
data.setPackVersion(packID[1]);
|
|
||||||
data.setPremium(false);
|
|
||||||
data.setType(ResourcePackType.RESOURCE);
|
|
||||||
|
|
||||||
session.sendUpstreamPacket(data);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HAVE_ALL_PACKS:
|
case HAVE_ALL_PACKS:
|
||||||
@ -271,7 +259,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
data.setPackId(packet.getPackId());
|
data.setPackId(packet.getPackId());
|
||||||
|
|
||||||
int offset = packet.getChunkIndex() * ResourcePack.CHUNK_SIZE;
|
int offset = packet.getChunkIndex() * ResourcePack.CHUNK_SIZE;
|
||||||
byte[] packData = new byte[(int) MathUtils.constrain(pack.getFile().length() - offset, 0, ResourcePack.CHUNK_SIZE)];
|
long remainingSize = pack.getFile().length() - offset;
|
||||||
|
byte[] packData = new byte[(int) MathUtils.constrain(remainingSize, 0, ResourcePack.CHUNK_SIZE)];
|
||||||
|
|
||||||
try (InputStream inputStream = new FileInputStream(pack.getFile())) {
|
try (InputStream inputStream = new FileInputStream(pack.getFile())) {
|
||||||
inputStream.skip(offset);
|
inputStream.skip(offset);
|
||||||
@ -283,6 +272,31 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
data.setData(packData);
|
data.setData(packData);
|
||||||
|
|
||||||
session.sendUpstreamPacket(data);
|
session.sendUpstreamPacket(data);
|
||||||
|
|
||||||
|
// Check if it is the last chunk and send next pack in queue when available.
|
||||||
|
if (remainingSize <= ResourcePack.CHUNK_SIZE && !packsToSent.isEmpty()) {
|
||||||
|
sendPackDataInfo(packsToSent.pop());
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sendPackDataInfo(String id) {
|
||||||
|
ResourcePackDataInfoPacket data = new ResourcePackDataInfoPacket();
|
||||||
|
String[] packID = id.split("_");
|
||||||
|
ResourcePack pack = ResourcePack.PACKS.get(packID[0]);
|
||||||
|
ResourcePackManifest.Header header = pack.getManifest().getHeader();
|
||||||
|
|
||||||
|
data.setPackId(header.getUuid());
|
||||||
|
int chunkCount = (int) Math.ceil((int) pack.getFile().length() / (double) ResourcePack.CHUNK_SIZE);
|
||||||
|
data.setChunkCount(chunkCount);
|
||||||
|
data.setCompressedPackSize(pack.getFile().length());
|
||||||
|
data.setMaxChunkSize(ResourcePack.CHUNK_SIZE);
|
||||||
|
data.setHash(pack.getSha256());
|
||||||
|
data.setPackVersion(packID[1]);
|
||||||
|
data.setPremium(false);
|
||||||
|
data.setType(ResourcePackType.RESOURCE);
|
||||||
|
|
||||||
|
session.sendUpstreamPacket(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,6 +124,10 @@ public class CustomItemRegistryPopulator {
|
|||||||
computeArmorProperties(mapping.getArmorType(), mapping.getProtectionValue(), componentBuilder);
|
computeArmorProperties(mapping.getArmorType(), mapping.getProtectionValue(), componentBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mapping.getFirstBlockRuntimeId() != null) {
|
||||||
|
computeBlockItemProperties(mapping.getBedrockIdentifier(), componentBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
computeRenderOffsets(false, customItemData, componentBuilder);
|
computeRenderOffsets(false, customItemData, componentBuilder);
|
||||||
|
|
||||||
componentBuilder.putCompound("item_properties", itemProperties.build());
|
componentBuilder.putCompound("item_properties", itemProperties.build());
|
||||||
@ -260,6 +264,15 @@ public class CustomItemRegistryPopulator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void computeBlockItemProperties(String blockItem, NbtMapBuilder componentBuilder) {
|
||||||
|
// carved pumpkin should be able to be worn and for that we would need to add wearable and armor with protection 0 here
|
||||||
|
// however this would have the side effect of preventing carved pumpkins from working as an attachable on the RP side outside the head slot
|
||||||
|
// it also causes the item to glitch when right clicked to "equip" so this should only be added here later if these issues can be overcome
|
||||||
|
|
||||||
|
// all block items registered should be given this component to prevent double placement
|
||||||
|
componentBuilder.putCompound("minecraft:block_placer", NbtMap.builder().putString("block", blockItem).build());
|
||||||
|
}
|
||||||
|
|
||||||
private static void computeRenderOffsets(boolean isHat, CustomItemData customItemData, NbtMapBuilder componentBuilder) {
|
private static void computeRenderOffsets(boolean isHat, CustomItemData customItemData, NbtMapBuilder componentBuilder) {
|
||||||
if (isHat) {
|
if (isHat) {
|
||||||
componentBuilder.remove("minecraft:render_offsets");
|
componentBuilder.remove("minecraft:render_offsets");
|
||||||
|
@ -629,6 +629,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
creativePacket.setContents(this.itemMappings.getCreativeItems());
|
creativePacket.setContents(this.itemMappings.getCreativeItems());
|
||||||
upstream.sendPacket(creativePacket);
|
upstream.sendPacket(creativePacket);
|
||||||
|
|
||||||
|
// Potion mixes are registered by default, as they are needed to be able to put ingredients into the brewing stand.
|
||||||
|
CraftingDataPacket craftingDataPacket = new CraftingDataPacket();
|
||||||
|
craftingDataPacket.setCleanRecipes(true);
|
||||||
|
craftingDataPacket.getPotionMixData().addAll(Registries.POTION_MIXES.get());
|
||||||
|
upstream.sendPacket(craftingDataPacket);
|
||||||
|
|
||||||
PlayStatusPacket playStatusPacket = new PlayStatusPacket();
|
PlayStatusPacket playStatusPacket = new PlayStatusPacket();
|
||||||
playStatusPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
|
playStatusPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
|
||||||
upstream.sendPacket(playStatusPacket);
|
upstream.sendPacket(playStatusPacket);
|
||||||
|
@ -39,6 +39,7 @@ import com.nukkitx.protocol.bedrock.data.inventory.ContainerId;
|
|||||||
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
|
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.PlayerHotbarPacket;
|
import com.nukkitx.protocol.bedrock.packet.PlayerHotbarPacket;
|
||||||
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.inventory.Container;
|
import org.geysermc.geyser.inventory.Container;
|
||||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||||
import org.geysermc.geyser.inventory.Inventory;
|
import org.geysermc.geyser.inventory.Inventory;
|
||||||
@ -196,11 +197,22 @@ public class InventoryUtils {
|
|||||||
|
|
||||||
root.put("display", display.build());
|
root.put("display", display.build());
|
||||||
return protocolVersion -> ItemData.builder()
|
return protocolVersion -> ItemData.builder()
|
||||||
.id(Registries.ITEMS.forVersion(protocolVersion).getStoredItems().barrier().getBedrockId())
|
.id(getUnusableSpaceBlockID(protocolVersion))
|
||||||
.count(1)
|
.count(1)
|
||||||
.tag(root.build()).build();
|
.tag(root.build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int getUnusableSpaceBlockID(int protocolVersion) {
|
||||||
|
String unusableSpaceBlock = GeyserImpl.getInstance().getConfig().getUnusableSpaceBlock();
|
||||||
|
ItemMapping unusableSpaceBlockID = Registries.ITEMS.forVersion(protocolVersion).getMapping(unusableSpaceBlock);
|
||||||
|
if (unusableSpaceBlockID != null) {
|
||||||
|
return unusableSpaceBlockID.getBedrockId();
|
||||||
|
} else {
|
||||||
|
GeyserImpl.getInstance().getLogger().error("Invalid value" + unusableSpaceBlock + ". Resorting to barrier block.");
|
||||||
|
return Registries.ITEMS.forVersion(protocolVersion).getStoredItems().barrier().getBedrockId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link #findOrCreateItem(GeyserSession, String)}. This is for finding a specified {@link ItemStack}.
|
* See {@link #findOrCreateItem(GeyserSession, String)}. This is for finding a specified {@link ItemStack}.
|
||||||
*
|
*
|
||||||
|
@ -183,6 +183,10 @@ log-player-ip-addresses: true
|
|||||||
# auto-update.
|
# auto-update.
|
||||||
notify-on-new-bedrock-update: true
|
notify-on-new-bedrock-update: true
|
||||||
|
|
||||||
|
# Which item to use to mark unavailable slots in a Bedrock player inventory. Examples of this are the 2x2 crafting grid while in creative,
|
||||||
|
# or custom inventory menus with sizes different from the usual 3x9. A barrier block is the default item.
|
||||||
|
unusable-space-block: minecraft:barrier
|
||||||
|
|
||||||
# bStats is a stat tracker that is entirely anonymous and tracks only basic information
|
# bStats is a stat tracker that is entirely anonymous and tracks only basic information
|
||||||
# about Geyser, such as how many people are online, how many servers are using Geyser,
|
# about Geyser, such as how many people are online, how many servers are using Geyser,
|
||||||
# what OS is being used, etc. You can learn more about bStats here: https://bstats.org/.
|
# what OS is being used, etc. You can learn more about bStats here: https://bstats.org/.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[versions]
|
[versions]
|
||||||
jackson = "2.13.4"
|
jackson = "2.14.0"
|
||||||
fastutil = "8.5.2"
|
fastutil = "8.5.2"
|
||||||
netty = "4.1.80.Final"
|
netty = "4.1.80.Final"
|
||||||
guava = "29.0-jre"
|
guava = "29.0-jre"
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren