Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-19 14:30:17 +01:00
Merge remote-tracking branch 'upstream/master' into feature/blocky
Dieser Commit ist enthalten in:
Commit
7770a8b2e0
@ -66,6 +66,22 @@ tasks {
|
|||||||
relocate("org.yaml", "org.geysermc.relocate.yaml") // https://github.com/CardboardPowered/cardboard/issues/139
|
relocate("org.yaml", "org.geysermc.relocate.yaml") // https://github.com/CardboardPowered/cardboard/issues/139
|
||||||
relocate("com.fasterxml.jackson", "org.geysermc.relocate.jackson")
|
relocate("com.fasterxml.jackson", "org.geysermc.relocate.jackson")
|
||||||
relocate("net.kyori", "org.geysermc.relocate.kyori")
|
relocate("net.kyori", "org.geysermc.relocate.kyori")
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// Exclude everything EXCEPT KQueue and some DNS stuff required for HAProxyc
|
||||||
|
exclude(dependency("io.netty:netty-transport-classes-epoll:.*"))
|
||||||
|
exclude(dependency("io.netty:netty-transport-native-epoll:.*"))
|
||||||
|
exclude(dependency("io.netty:netty-transport-native-unix-common:.*"))
|
||||||
|
exclude(dependency("io.netty:netty-transport-native-kqueue:.*"))
|
||||||
|
exclude(dependency("io.netty:netty-handler:.*"))
|
||||||
|
exclude(dependency("io.netty:netty-common:.*"))
|
||||||
|
exclude(dependency("io.netty:netty-buffer:.*"))
|
||||||
|
exclude(dependency("io.netty:netty-resolver:.*"))
|
||||||
|
exclude(dependency("io.netty:netty-transport:.*"))
|
||||||
|
exclude(dependency("io.netty:netty-codec:.*"))
|
||||||
|
exclude(dependency("io.netty:netty-resolver-dns:.*"))
|
||||||
|
exclude(dependency("io.netty:netty-resolver-dns-native-macos:.*"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remapJar {
|
remapJar {
|
||||||
|
@ -44,6 +44,7 @@ tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar> {
|
|||||||
|
|
||||||
// We cannot shade Netty, or else native libraries will not load
|
// We cannot shade Netty, or else native libraries will not load
|
||||||
// Needed because older Spigot builds do not provide the haproxy module
|
// Needed because older Spigot builds do not provide the haproxy module
|
||||||
|
exclude(dependency("io.netty:netty-transport-classes-epoll:.*"))
|
||||||
exclude(dependency("io.netty:netty-transport-native-epoll:.*"))
|
exclude(dependency("io.netty:netty-transport-native-epoll:.*"))
|
||||||
exclude(dependency("io.netty:netty-transport-native-unix-common:.*"))
|
exclude(dependency("io.netty:netty-transport-native-unix-common:.*"))
|
||||||
exclude(dependency("io.netty:netty-transport-native-kqueue:.*"))
|
exclude(dependency("io.netty:netty-transport-native-kqueue:.*"))
|
||||||
|
@ -24,6 +24,11 @@ tasks {
|
|||||||
exclude(dependency(string))
|
exclude(dependency(string))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sJar.dependencies {
|
||||||
|
exclude(dependency("org.checkerframework:checker-qual:.*"))
|
||||||
|
exclude(dependency("org.jetbrains:annotations:.*"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
named("build") {
|
named("build") {
|
||||||
|
@ -304,6 +304,7 @@ public class ItemRegistryPopulator {
|
|||||||
Set<String> javaOnlyItems = new ObjectOpenHashSet<>();
|
Set<String> javaOnlyItems = new ObjectOpenHashSet<>();
|
||||||
Collections.addAll(javaOnlyItems, "minecraft:spectral_arrow", "minecraft:debug_stick",
|
Collections.addAll(javaOnlyItems, "minecraft:spectral_arrow", "minecraft:debug_stick",
|
||||||
"minecraft:knowledge_book", "minecraft:tipped_arrow", "minecraft:bundle");
|
"minecraft:knowledge_book", "minecraft:tipped_arrow", "minecraft:bundle");
|
||||||
|
javaOnlyItems.add("minecraft:decorated_pot"); // TODO 1.19.80 resolve probs?
|
||||||
if (!customItemsAllowed) {
|
if (!customItemsAllowed) {
|
||||||
javaOnlyItems.add("minecraft:furnace_minecart");
|
javaOnlyItems.add("minecraft:furnace_minecart");
|
||||||
}
|
}
|
||||||
|
@ -738,7 +738,11 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
connectDownstream();
|
try {
|
||||||
|
connectDownstream();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -782,7 +786,11 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
connectDownstream();
|
try {
|
||||||
|
connectDownstream();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -856,7 +864,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
selectedProfile,
|
selectedProfile,
|
||||||
service.getAccessToken()
|
service.getAccessToken()
|
||||||
);
|
);
|
||||||
connectDownstream();
|
try {
|
||||||
|
connectDownstream();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Save our refresh token for later use
|
// Save our refresh token for later use
|
||||||
geyser.saveRefreshToken(bedrockUsername(), service.getRefreshToken());
|
geyser.saveRefreshToken(bedrockUsername(), service.getRefreshToken());
|
||||||
|
@ -25,11 +25,14 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.translator.inventory.item.nbt;
|
package org.geysermc.geyser.translator.inventory.item.nbt;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.Identifier;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.*;
|
import com.github.steveice10.opennbt.tag.builtin.*;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.inventory.item.Enchantment;
|
import org.geysermc.geyser.inventory.item.Enchantment;
|
||||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.text.ChatColor;
|
||||||
|
import org.geysermc.geyser.text.MinecraftLocale;
|
||||||
import org.geysermc.geyser.translator.inventory.item.ItemRemapper;
|
import org.geysermc.geyser.translator.inventory.item.ItemRemapper;
|
||||||
import org.geysermc.geyser.translator.inventory.item.NbtItemStackTranslator;
|
import org.geysermc.geyser.translator.inventory.item.NbtItemStackTranslator;
|
||||||
|
|
||||||
@ -43,28 +46,27 @@ public class EnchantmentTranslator extends NbtItemStackTranslator {
|
|||||||
@Override
|
@Override
|
||||||
public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemMapping mapping) {
|
public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemMapping mapping) {
|
||||||
List<Tag> newTags = new ArrayList<>();
|
List<Tag> newTags = new ArrayList<>();
|
||||||
Tag enchantmentTag = itemTag.get("Enchantments");
|
Tag enchantmentTag = itemTag.remove("Enchantments");
|
||||||
if (enchantmentTag instanceof ListTag listTag) {
|
if (enchantmentTag instanceof ListTag listTag) {
|
||||||
for (Tag tag : listTag.getValue()) {
|
for (Tag tag : listTag.getValue()) {
|
||||||
if (!(tag instanceof CompoundTag)) continue;
|
if (!(tag instanceof CompoundTag)) continue;
|
||||||
|
CompoundTag bedrockTag = remapEnchantment(session, (CompoundTag) tag, itemTag);
|
||||||
CompoundTag bedrockTag = remapEnchantment((CompoundTag) tag);
|
if (bedrockTag != null) {
|
||||||
newTags.add(bedrockTag);
|
newTags.add(bedrockTag);
|
||||||
}
|
}
|
||||||
itemTag.remove("Enchantments");
|
}
|
||||||
}
|
}
|
||||||
enchantmentTag = itemTag.get("StoredEnchantments");
|
|
||||||
if (enchantmentTag instanceof ListTag listTag) {
|
// TODO consolidate this into EnchantedBookTranslator
|
||||||
for (Tag tag : listTag.getValue()) {
|
enchantmentTag = itemTag.remove("StoredEnchantments");
|
||||||
if (!(tag instanceof CompoundTag)) continue;
|
if (enchantmentTag instanceof ListTag listTag) {
|
||||||
|
for (Tag tag : listTag.getValue()) {
|
||||||
CompoundTag bedrockTag = remapEnchantment((CompoundTag) tag);
|
if (!(tag instanceof CompoundTag)) continue;
|
||||||
|
CompoundTag bedrockTag = remapEnchantment(session, (CompoundTag) tag, itemTag);
|
||||||
if (bedrockTag != null) {
|
if (bedrockTag != null) {
|
||||||
bedrockTag.put(new ShortTag("GeyserStoredEnchantment", (short) 0));
|
|
||||||
newTags.add(bedrockTag);
|
newTags.add(bedrockTag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
itemTag.remove("StoredEnchantments");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!newTags.isEmpty()) {
|
if (!newTags.isEmpty()) {
|
||||||
@ -99,7 +101,6 @@ public class EnchantmentTranslator extends NbtItemStackTranslator {
|
|||||||
javaValue.put("lvl", new IntTag("lvl", levelTag != null ? levelTag.getValue() : 1));
|
javaValue.put("lvl", new IntTag("lvl", levelTag != null ? levelTag.getValue() : 1));
|
||||||
javaTag.setValue(javaValue);
|
javaTag.setValue(javaValue);
|
||||||
|
|
||||||
|
|
||||||
if (geyserStoredEnchantmentTag != null) {
|
if (geyserStoredEnchantmentTag != null) {
|
||||||
tagValue.remove("GeyserStoredEnchantment");
|
tagValue.remove("GeyserStoredEnchantment");
|
||||||
storedEnchantments.add(javaTag);
|
storedEnchantments.add(javaTag);
|
||||||
@ -120,13 +121,20 @@ public class EnchantmentTranslator extends NbtItemStackTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private CompoundTag remapEnchantment(CompoundTag tag) {
|
private CompoundTag remapEnchantment(GeyserSession session, CompoundTag tag, CompoundTag rootTag) {
|
||||||
Tag javaEnchId = tag.get("id");
|
Tag javaEnchId = tag.get("id");
|
||||||
if (!(javaEnchId instanceof StringTag))
|
if (!(javaEnchId instanceof StringTag))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
Enchantment enchantment = Enchantment.getByJavaIdentifier(((StringTag) javaEnchId).getValue());
|
Enchantment enchantment = Enchantment.getByJavaIdentifier(((StringTag) javaEnchId).getValue());
|
||||||
if (enchantment == null) {
|
if (enchantment == null) {
|
||||||
|
if (Identifier.formalize((String) javaEnchId.getValue()).equals("minecraft:sweeping")) {
|
||||||
|
Tag javaEnchLvl = tag.get("lvl");
|
||||||
|
int sweepingLvl = javaEnchLvl != null && javaEnchLvl.getValue() instanceof Number lvl ? lvl.intValue() : 0;
|
||||||
|
|
||||||
|
addSweeping(session, rootTag, sweepingLvl);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment while NBT item translating: " + javaEnchId.getValue());
|
GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment while NBT item translating: " + javaEnchId.getValue());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -140,4 +148,21 @@ public class EnchantmentTranslator extends NbtItemStackTranslator {
|
|||||||
return bedrockTag;
|
return bedrockTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
private void addSweeping(GeyserSession session, CompoundTag itemTag, int level) {
|
||||||
|
CompoundTag displayTag = itemTag.get("display");
|
||||||
|
if (displayTag == null) {
|
||||||
|
displayTag = new CompoundTag("display");
|
||||||
|
itemTag.put(displayTag);
|
||||||
|
}
|
||||||
|
ListTag loreTag = displayTag.get("Lore");
|
||||||
|
if (loreTag == null) {
|
||||||
|
loreTag = new ListTag("Lore");
|
||||||
|
displayTag.put(loreTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
String sweepingTranslation = MinecraftLocale.getLocaleString("enchantment.minecraft.sweeping", session.locale());
|
||||||
|
String lvlTranslation = MinecraftLocale.getLocaleString("enchantment.level." + level, session.locale());
|
||||||
|
|
||||||
|
loreTag.add(new StringTag("", ChatColor.RESET + ChatColor.GRAY + sweepingTranslation + " " + lvlTranslation));
|
||||||
|
}
|
||||||
|
}
|
@ -47,21 +47,23 @@ import org.geysermc.geyser.translator.protocol.Translator;
|
|||||||
|
|
||||||
@Translator(packet = ClientboundGameEventPacket.class)
|
@Translator(packet = ClientboundGameEventPacket.class)
|
||||||
public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEventPacket> {
|
public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEventPacket> {
|
||||||
|
// Strength of rainstorms and thunderstorms is a 0-1 float on Java, while on Bedrock it is a 0-65535 int
|
||||||
|
private static final int MAX_STORM_STRENGTH = 65535;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, ClientboundGameEventPacket packet) {
|
public void translate(GeyserSession session, ClientboundGameEventPacket packet) {
|
||||||
PlayerEntity entity = session.getPlayerEntity();
|
PlayerEntity entity = session.getPlayerEntity();
|
||||||
|
|
||||||
switch (packet.getNotification()) {
|
switch (packet.getNotification()) {
|
||||||
|
// Yes, START_RAIN and STOP_RAIN are swapped in terms of what they cause the client to do.
|
||||||
|
// This is how the Mojang mappings name them, so we go with it
|
||||||
|
// It seems Mojang's intent was that START_RAIN would set the rain strength to 0 so that it can then be incremeneted on a gradient by the server
|
||||||
|
// The inverse is true for STOP_RAIN
|
||||||
|
// This is indeed the behavior of the vanilla server
|
||||||
|
// However, it seems most server software (at least Spigot and Paper) did not go along with this
|
||||||
|
// As a result many developers use these packets for the opposite of what their names implies
|
||||||
|
// Behavior last verified with Java 1.19.4 and Bedrock 1.19.71
|
||||||
case START_RAIN:
|
case START_RAIN:
|
||||||
LevelEventPacket startRainPacket = new LevelEventPacket();
|
|
||||||
startRainPacket.setType(LevelEventType.START_RAINING);
|
|
||||||
startRainPacket.setData(Integer.MAX_VALUE);
|
|
||||||
startRainPacket.setPosition(Vector3f.ZERO);
|
|
||||||
session.sendUpstreamPacket(startRainPacket);
|
|
||||||
session.setRaining(true);
|
|
||||||
break;
|
|
||||||
case STOP_RAIN:
|
|
||||||
LevelEventPacket stopRainPacket = new LevelEventPacket();
|
LevelEventPacket stopRainPacket = new LevelEventPacket();
|
||||||
stopRainPacket.setType(LevelEventType.STOP_RAINING);
|
stopRainPacket.setType(LevelEventType.STOP_RAINING);
|
||||||
stopRainPacket.setData(0);
|
stopRainPacket.setData(0);
|
||||||
@ -69,34 +71,35 @@ public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEve
|
|||||||
session.sendUpstreamPacket(stopRainPacket);
|
session.sendUpstreamPacket(stopRainPacket);
|
||||||
session.setRaining(false);
|
session.setRaining(false);
|
||||||
break;
|
break;
|
||||||
|
case STOP_RAIN:
|
||||||
|
LevelEventPacket startRainPacket = new LevelEventPacket();
|
||||||
|
startRainPacket.setType(LevelEventType.START_RAINING);
|
||||||
|
startRainPacket.setData(MAX_STORM_STRENGTH);
|
||||||
|
startRainPacket.setPosition(Vector3f.ZERO);
|
||||||
|
session.sendUpstreamPacket(startRainPacket);
|
||||||
|
session.setRaining(true);
|
||||||
|
break;
|
||||||
case RAIN_STRENGTH:
|
case RAIN_STRENGTH:
|
||||||
// While the above values are used, they CANNOT BE TRUSTED on a vanilla server as they are swapped around
|
float rainStrength = ((RainStrengthValue) packet.getValue()).getStrength();
|
||||||
// Spigot and forks implement it correctly
|
boolean isCurrentlyRaining = rainStrength > 0f;
|
||||||
// Rain strength is your best way for determining if there is any rain
|
LevelEventPacket changeRainPacket = new LevelEventPacket();
|
||||||
RainStrengthValue value = (RainStrengthValue) packet.getValue();
|
changeRainPacket.setType(isCurrentlyRaining ? LevelEventType.START_RAINING : LevelEventType.STOP_RAINING);
|
||||||
boolean isCurrentlyRaining = value.getStrength() > 0f;
|
// This is the rain strength on LevelEventType.START_RAINING, but can be any value on LevelEventType.STOP_RAINING
|
||||||
// Java sends the rain level. Bedrock doesn't care, so we don't care if it's already raining.
|
changeRainPacket.setData((int) (rainStrength * MAX_STORM_STRENGTH));
|
||||||
if (isCurrentlyRaining != session.isRaining()) {
|
changeRainPacket.setPosition(Vector3f.ZERO);
|
||||||
LevelEventPacket changeRainPacket = new LevelEventPacket();
|
session.sendUpstreamPacket(changeRainPacket);
|
||||||
changeRainPacket.setType(isCurrentlyRaining ? LevelEventType.START_RAINING : LevelEventType.STOP_RAINING);
|
session.setRaining(isCurrentlyRaining);
|
||||||
changeRainPacket.setData(Integer.MAX_VALUE); // Dunno what this does; used to be implemented with ThreadLocalRandom
|
|
||||||
changeRainPacket.setPosition(Vector3f.ZERO);
|
|
||||||
session.sendUpstreamPacket(changeRainPacket);
|
|
||||||
session.setRaining(isCurrentlyRaining);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case THUNDER_STRENGTH:
|
case THUNDER_STRENGTH:
|
||||||
// See above, same process
|
// See above, same process
|
||||||
ThunderStrengthValue thunderValue = (ThunderStrengthValue) packet.getValue();
|
float thunderStrength = ((ThunderStrengthValue) packet.getValue()).getStrength();
|
||||||
boolean isCurrentlyThundering = thunderValue.getStrength() > 0f;
|
boolean isCurrentlyThundering = thunderStrength > 0f;
|
||||||
if (isCurrentlyThundering != session.isThunder()) {
|
LevelEventPacket changeThunderPacket = new LevelEventPacket();
|
||||||
LevelEventPacket changeThunderPacket = new LevelEventPacket();
|
changeThunderPacket.setType(isCurrentlyThundering ? LevelEventType.START_THUNDERSTORM : LevelEventType.STOP_THUNDERSTORM);
|
||||||
changeThunderPacket.setType(isCurrentlyThundering ? LevelEventType.START_THUNDERSTORM : LevelEventType.STOP_THUNDERSTORM);
|
changeThunderPacket.setData((int) (thunderStrength * MAX_STORM_STRENGTH));
|
||||||
changeThunderPacket.setData(Integer.MAX_VALUE);
|
changeThunderPacket.setPosition(Vector3f.ZERO);
|
||||||
changeThunderPacket.setPosition(Vector3f.ZERO);
|
session.sendUpstreamPacket(changeThunderPacket);
|
||||||
session.sendUpstreamPacket(changeThunderPacket);
|
session.setThunder(isCurrentlyThundering);
|
||||||
session.setThunder(isCurrentlyThundering);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case CHANGE_GAMEMODE:
|
case CHANGE_GAMEMODE:
|
||||||
GameMode gameMode = (GameMode) packet.getValue();
|
GameMode gameMode = (GameMode) packet.getValue();
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren