mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-19 04:15:14 -04:00
1.16 support (network), dimension flattening update
This commit is contained in:
parent
b66212a7b2
commit
a05a9ea8ac
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Codename Minosoft
|
||||
* Copyright (C) 2020 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.game.datatypes;
|
||||
|
||||
public enum Dimension {
|
||||
NETHER(-1),
|
||||
OVERWORLD(0),
|
||||
END(1);
|
||||
|
||||
final int id;
|
||||
|
||||
Dimension(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static Dimension byId(int id) {
|
||||
for (Dimension g : values()) {
|
||||
if (g.getId() == id) {
|
||||
return g;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
@ -20,7 +20,8 @@ public enum LevelType {
|
||||
AMPLIFIED("amplified"),
|
||||
DEFAULT_1_1("default_1_1"),
|
||||
CUSTOMIZED("customized"),
|
||||
BUFFET("buffet");
|
||||
BUFFET("buffet"),
|
||||
UNKNOWN("unknown");
|
||||
|
||||
final String type;
|
||||
|
||||
|
@ -166,15 +166,13 @@ public class TextComponent {
|
||||
if (json.has("extra")) {
|
||||
JsonArray arr = json.getAsJsonArray("extra");
|
||||
for (int i = 0; i < arr.size(); i++) {
|
||||
JsonObject object;
|
||||
try {
|
||||
object = arr.get(i).getAsJsonObject();
|
||||
} catch (Exception e) {
|
||||
// reset text
|
||||
if (arr.get(i).isJsonPrimitive()) {
|
||||
buffer.append(ChatAttributes.RESET);
|
||||
buffer.append(" ");
|
||||
buffer.append(arr.get(i).getAsString());
|
||||
continue;
|
||||
}
|
||||
JsonObject object = arr.get(i).getAsJsonObject();
|
||||
if (object.has("bold") && object.get("bold").getAsBoolean()) {
|
||||
buffer.append(ChatAttributes.BOLD);
|
||||
}
|
||||
@ -196,9 +194,22 @@ public class TextComponent {
|
||||
buffer.append(object.get("text").getAsString());
|
||||
}
|
||||
buffer.append(ChatAttributes.RESET);
|
||||
return buffer.toString();
|
||||
}
|
||||
return "";
|
||||
if (json.has("with")) {
|
||||
JsonArray arr = json.getAsJsonArray("with");
|
||||
for (int i = 0; i < arr.size(); i++) {
|
||||
if (arr.get(i).isJsonPrimitive()) {
|
||||
buffer.append(ChatAttributes.RESET);
|
||||
buffer.append(" ");
|
||||
buffer.append(arr.get(i).getAsString());
|
||||
continue;
|
||||
}
|
||||
JsonObject object = arr.get(i).getAsJsonObject();
|
||||
buffer.append(object.get("text").getAsString());
|
||||
}
|
||||
buffer.append(ChatAttributes.RESET);
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -95,8 +95,8 @@ public abstract class Entity implements EntityInterface {
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
public void setEquipment(InventorySlots.EntityInventory slot, Slot data) {
|
||||
equipment.put(slot, data);
|
||||
public void setEquipment(HashMap<InventorySlots.EntityInventory, Slot> slots) {
|
||||
equipment.putAll(slots);
|
||||
}
|
||||
|
||||
public Slot getEquipment(InventorySlots.EntityInventory slot) {
|
||||
|
@ -19,6 +19,7 @@ import de.bixilon.minosoft.game.datatypes.Mappings;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.blockIds.BlockIds;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Blocks;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.dimensions.Dimensions;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.effects.MobEffects;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.enchantments.Enchantments;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.entities.Entities;
|
||||
@ -60,6 +61,9 @@ public class ObjectLoader {
|
||||
Motives.load(mod, modJSON.getAsJsonObject("motive").getAsJsonObject("entries"), version);
|
||||
Particles.load(mod, modJSON.getAsJsonObject("particle_type").getAsJsonObject("entries"), version);
|
||||
MobEffects.load(mod, modJSON.getAsJsonObject("mob_effect").getAsJsonObject("entries"), version);
|
||||
if (modJSON.has("dimension_type")) {
|
||||
Dimensions.load(mod, modJSON.getAsJsonObject("dimension_type").getAsJsonObject("entries"), version);
|
||||
}
|
||||
break;
|
||||
case BLOCKS:
|
||||
Blocks.load(mod, modJSON, version);
|
||||
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Codename Minosoft
|
||||
* Copyright (C) 2020 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.game.datatypes.objectLoader.dimensions;
|
||||
|
||||
public class Dimension {
|
||||
final String mod;
|
||||
final String identifier;
|
||||
final boolean hasSkyLight;
|
||||
|
||||
public Dimension(String mod, String identifier, boolean hasSkyLight) {
|
||||
this.mod = mod;
|
||||
this.identifier = identifier;
|
||||
this.hasSkyLight = hasSkyLight;
|
||||
}
|
||||
|
||||
public String getMod() {
|
||||
return mod;
|
||||
}
|
||||
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public boolean hasSkyLight() {
|
||||
return hasSkyLight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s:%s", getMod(), getIdentifier());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mod.hashCode() * identifier.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj)) {
|
||||
return true;
|
||||
}
|
||||
if (hashCode() != obj.hashCode()) {
|
||||
return false;
|
||||
}
|
||||
Dimension their = (Dimension) obj;
|
||||
return getIdentifier().equals(their.getIdentifier()) && getMod().equals(their.getMod()) && hasSkyLight() == their.hasSkyLight();
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Codename Minosoft
|
||||
* Copyright (C) 2020 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.game.datatypes.objectLoader.dimensions;
|
||||
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.gson.JsonObject;
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Dimensions {
|
||||
static HashMap<ProtocolVersion, HashBiMap<Integer, Dimension>> dimensionIdMap = new HashMap<>(); // version -> (protocolId > Dimension)
|
||||
static HashBiMap<String, Dimension> dimensionIdentifierMap = HashBiMap.create(); // Identifier, Dimension
|
||||
static HashMap<String, HashMap<String, Dimension>> customDimensionIdentifierMap = new HashMap<>(); // Mod -> (Identifier, Dimension): used > 1.16
|
||||
|
||||
|
||||
public static Dimension byId(int protocolId, ProtocolVersion version) {
|
||||
if (version.getVersionNumber() < ProtocolVersion.VERSION_1_12_2.getVersionNumber()) {
|
||||
version = ProtocolVersion.VERSION_1_12_2;
|
||||
}
|
||||
return dimensionIdMap.get(version).get(protocolId);
|
||||
}
|
||||
|
||||
public static Dimension byIdentifier(String identifier) {
|
||||
String[] splitted = identifier.split(":", 2);
|
||||
return byIdentifier(splitted[0], splitted[1]);
|
||||
}
|
||||
|
||||
public static Dimension byIdentifier(String mod, String identifier) {
|
||||
if (mod == "minecraft") {
|
||||
return dimensionIdentifierMap.get(identifier);
|
||||
}
|
||||
if (customDimensionIdentifierMap.containsKey(mod)) {
|
||||
return customDimensionIdentifierMap.get(mod).get(identifier);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static void load(String mod, JsonObject json, ProtocolVersion version) {
|
||||
HashBiMap<Integer, Dimension> versionIdMapping = HashBiMap.create();
|
||||
for (String identifierName : json.keySet()) {
|
||||
JsonObject identifierJSON = json.getAsJsonObject(identifierName);
|
||||
Dimension dimension = new Dimension(mod, identifierName, identifierJSON.get("has_skylight").getAsBoolean());
|
||||
if (identifierJSON.has("id")) {
|
||||
versionIdMapping.put(identifierJSON.get("id").getAsInt(), dimension);
|
||||
continue;
|
||||
}
|
||||
dimensionIdentifierMap.put(identifierName, dimension);
|
||||
}
|
||||
if (versionIdMapping.size() > 0) {
|
||||
dimensionIdMap.put(version, versionIdMapping);
|
||||
}
|
||||
}
|
||||
}
|
@ -48,6 +48,12 @@ public class Recipe {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public Recipe(RecipeTypes type, Ingredient base, Ingredient addition, Slot result) {
|
||||
this.type = type;
|
||||
this.ingredients = new Ingredient[]{base, addition};
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public Recipe(RecipeTypes type, String group, Ingredient ingredient, Slot result, float experience, int cookingTime) {
|
||||
this.type = type;
|
||||
this.group = group;
|
||||
|
@ -34,7 +34,8 @@ public enum RecipeTypes {
|
||||
BLASTING("blasting"),
|
||||
SMOKING("smoking"),
|
||||
CAMPFIRE("campfire_cooking"),
|
||||
STONE_CUTTING("stonecutting");
|
||||
STONE_CUTTING("stonecutting"),
|
||||
SMITHING("smithing");
|
||||
|
||||
final String name;
|
||||
|
||||
|
@ -13,10 +13,10 @@
|
||||
|
||||
package de.bixilon.minosoft.game.datatypes.world;
|
||||
|
||||
import de.bixilon.minosoft.game.datatypes.Dimension;
|
||||
import de.bixilon.minosoft.game.datatypes.entities.Entity;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Blocks;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.dimensions.Dimension;
|
||||
import de.bixilon.minosoft.nbt.tag.CompoundTag;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -157,8 +157,9 @@ public class Network {
|
||||
}
|
||||
|
||||
InPacketBuffer inPacketBuffer = new InPacketBuffer(data, connection.getVersion());
|
||||
Packets.Clientbound p = null;
|
||||
try {
|
||||
Packets.Clientbound p = connection.getVersion().getProtocol().getPacketByCommand(connection.getConnectionState(), inPacketBuffer.getCommand());
|
||||
p = connection.getVersion().getProtocol().getPacketByCommand(connection.getConnectionState(), inPacketBuffer.getCommand());
|
||||
Class<? extends ClientboundPacket> clazz = Protocol.getPacketByPacket(p);
|
||||
|
||||
if (clazz == null) {
|
||||
@ -195,7 +196,7 @@ public class Network {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.protocol(String.format("An error occurred while parsing an packet: %s", e));
|
||||
Log.protocol(String.format("An error occurred while parsing an packet (%s): %s", p, e));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -35,12 +35,12 @@ public class PacketBlockEntityMetadata implements ClientboundPacket {
|
||||
case VERSION_1_7_10:
|
||||
position = buffer.readBlockPositionShort();
|
||||
action = Actions.byId(buffer.readByte(), buffer.getVersion());
|
||||
nbt = buffer.readNBT(true);
|
||||
nbt = (CompoundTag) buffer.readNBT(true);
|
||||
return true;
|
||||
default:
|
||||
position = buffer.readPosition();
|
||||
action = Actions.byId(buffer.readByte(), buffer.getVersion());
|
||||
nbt = buffer.readNBT();
|
||||
nbt = (CompoundTag) buffer.readNBT();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.protocol.packets.clientbound.play;
|
||||
|
||||
import de.bixilon.minosoft.game.datatypes.Dimension;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.dimensions.Dimension;
|
||||
import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
|
||||
import de.bixilon.minosoft.game.datatypes.world.Chunk;
|
||||
import de.bixilon.minosoft.game.datatypes.world.ChunkLocation;
|
||||
@ -43,7 +43,7 @@ public class PacketChunkData implements ClientboundPacket {
|
||||
}
|
||||
|
||||
public boolean read(InPacketBuffer buffer, Dimension dimension) {
|
||||
boolean containsSkyLight = dimension == Dimension.OVERWORLD;
|
||||
boolean containsSkyLight = dimension.hasSkyLight();
|
||||
if (buffer.getVersion().getVersionNumber() <= ProtocolVersion.VERSION_1_7_10.getVersionNumber()) {
|
||||
this.location = new ChunkLocation(buffer.readInt(), buffer.readInt());
|
||||
boolean groundUpContinuous = buffer.readBoolean();
|
||||
@ -74,7 +74,7 @@ public class PacketChunkData implements ClientboundPacket {
|
||||
}
|
||||
short sectionBitMask = (short) buffer.readVarInt();
|
||||
if (buffer.getVersion().getVersionNumber() >= ProtocolVersion.VERSION_1_14_4.getVersionNumber()) {
|
||||
heightMap = buffer.readNBT();
|
||||
heightMap = (CompoundTag) buffer.readNBT();
|
||||
}
|
||||
if (groundUpContinuous) {
|
||||
if (buffer.getVersion().getVersionNumber() >= ProtocolVersion.VERSION_1_16_2.getVersionNumber()) {
|
||||
@ -93,7 +93,7 @@ public class PacketChunkData implements ClientboundPacket {
|
||||
}
|
||||
int blockEntitiesCount = buffer.readVarInt();
|
||||
for (int i = 0; i < blockEntitiesCount; i++) {
|
||||
CompoundTag tag = buffer.readNBT();
|
||||
CompoundTag tag = (CompoundTag) buffer.readNBT();
|
||||
blockEntities.put(new BlockPosition(tag.getIntTag("x").getValue(), (short) tag.getIntTag("y").getValue(), tag.getIntTag("z").getValue()), tag);
|
||||
}
|
||||
return true;
|
||||
|
@ -79,6 +79,13 @@ public class PacketDeclareRecipes implements ClientboundPacket {
|
||||
recipe = new Recipe(type, group, ingredient, result);
|
||||
break;
|
||||
}
|
||||
case SMITHING: {
|
||||
Ingredient base = buffer.readIngredient();
|
||||
Ingredient addition = buffer.readIngredient();
|
||||
Slot result = buffer.readSlot();
|
||||
recipe = new Recipe(type, base, addition, result);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
recipe = new Recipe(type);
|
||||
break;
|
||||
|
@ -19,41 +19,53 @@ import de.bixilon.minosoft.logging.Log;
|
||||
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
|
||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PacketEntityEquipment implements ClientboundPacket {
|
||||
int entityId;
|
||||
InventorySlots.EntityInventory slot;
|
||||
Slot data;
|
||||
HashMap<InventorySlots.EntityInventory, Slot> slots = new HashMap<>();
|
||||
|
||||
|
||||
@Override
|
||||
public boolean read(InByteBuffer buffer) {
|
||||
switch (buffer.getVersion()) {
|
||||
case VERSION_1_7_10:
|
||||
entityId = buffer.readInt();
|
||||
this.slot = InventorySlots.EntityInventory.byId(buffer.readShort(), buffer.getVersion());
|
||||
this.data = buffer.readSlot();
|
||||
return true;
|
||||
case VERSION_1_8:
|
||||
entityId = buffer.readVarInt();
|
||||
this.slot = InventorySlots.EntityInventory.byId(buffer.readShort(), buffer.getVersion());
|
||||
this.data = buffer.readSlot();
|
||||
return true;
|
||||
default:
|
||||
entityId = buffer.readVarInt();
|
||||
this.slot = InventorySlots.EntityInventory.byId(buffer.readVarInt(), buffer.getVersion());
|
||||
this.data = buffer.readSlot();
|
||||
return true;
|
||||
if (buffer.getVersion() == ProtocolVersion.VERSION_1_7_10) {
|
||||
entityId = buffer.readInt();
|
||||
slots.put(InventorySlots.EntityInventory.byId(buffer.readShort(), buffer.getVersion()), buffer.readSlot());
|
||||
return true;
|
||||
}
|
||||
if (buffer.getVersion() == ProtocolVersion.VERSION_1_8) {
|
||||
entityId = buffer.readVarInt();
|
||||
slots.put(InventorySlots.EntityInventory.byId(buffer.readShort(), buffer.getVersion()), buffer.readSlot());
|
||||
return true;
|
||||
}
|
||||
if (buffer.getVersion().getVersionNumber() < ProtocolVersion.VERSION_1_16_2.getVersionNumber()) {
|
||||
entityId = buffer.readVarInt();
|
||||
slots.put(InventorySlots.EntityInventory.byId(buffer.readVarInt(), buffer.getVersion()), buffer.readSlot());
|
||||
return true;
|
||||
}
|
||||
entityId = buffer.readVarInt();
|
||||
boolean slotAvailable = true;
|
||||
while (slotAvailable) {
|
||||
int slotId = buffer.readByte();
|
||||
if (slotId >= 0) {
|
||||
slotAvailable = false;
|
||||
}
|
||||
slotId &= 0x7F;
|
||||
slots.put(InventorySlots.EntityInventory.byId(slotId, buffer.getVersion()), buffer.readSlot());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log() {
|
||||
if (data != null) {
|
||||
Log.protocol(String.format("Entity equipment changed (entityId=%d, slot=%s): %dx %s", entityId, slot, data.getItemCount(), data.getDisplayName()));
|
||||
if (slots.size() == 1) {
|
||||
Map.Entry<InventorySlots.EntityInventory, Slot> set = slots.entrySet().iterator().next();
|
||||
Log.protocol(String.format("Entity equipment changed (entityId=%d, slot=%s): %dx %s", entityId, set.getKey(), set.getValue().getItemCount(), set.getValue().getDisplayName()));
|
||||
} else {
|
||||
// null means nothing, means air
|
||||
Log.protocol(String.format("Entity equipment changed (entityId=%d, slot=%s): AIR", entityId, slot));
|
||||
Log.protocol(String.format("Entity equipment changed (entityId=%d, slotCount=%d)", entityId, slots.size()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,11 +78,7 @@ public class PacketEntityEquipment implements ClientboundPacket {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public InventorySlots.EntityInventory getSlot() {
|
||||
return slot;
|
||||
}
|
||||
|
||||
public Slot getData() {
|
||||
return data;
|
||||
public HashMap<InventorySlots.EntityInventory, Slot> getSlots() {
|
||||
return slots;
|
||||
}
|
||||
}
|
||||
|
@ -14,16 +14,22 @@
|
||||
package de.bixilon.minosoft.protocol.packets.clientbound.play;
|
||||
|
||||
import de.bixilon.minosoft.game.datatypes.Difficulty;
|
||||
import de.bixilon.minosoft.game.datatypes.Dimension;
|
||||
import de.bixilon.minosoft.game.datatypes.GameMode;
|
||||
import de.bixilon.minosoft.game.datatypes.LevelType;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.dimensions.Dimension;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.dimensions.Dimensions;
|
||||
import de.bixilon.minosoft.logging.Log;
|
||||
import de.bixilon.minosoft.nbt.tag.CompoundTag;
|
||||
import de.bixilon.minosoft.nbt.tag.ListTag;
|
||||
import de.bixilon.minosoft.nbt.tag.NBTTag;
|
||||
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
|
||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
|
||||
import de.bixilon.minosoft.util.BitByte;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class PacketJoinGame implements ClientboundPacket {
|
||||
int entityId;
|
||||
boolean hardcore;
|
||||
@ -35,7 +41,7 @@ public class PacketJoinGame implements ClientboundPacket {
|
||||
LevelType levelType;
|
||||
boolean reducedDebugScreen;
|
||||
boolean enableRespawnScreen = true;
|
||||
|
||||
HashMap<String, HashMap<String, Dimension>> dimensions;
|
||||
|
||||
@Override
|
||||
public boolean read(InByteBuffer buffer) {
|
||||
@ -49,7 +55,7 @@ public class PacketJoinGame implements ClientboundPacket {
|
||||
gameModeRaw &= ~0x8;
|
||||
gameMode = GameMode.byId(gameModeRaw);
|
||||
|
||||
dimension = Dimension.byId(buffer.readByte());
|
||||
dimension = Dimensions.byId(buffer.readInt(), buffer.getVersion());
|
||||
difficulty = Difficulty.byId(buffer.readByte());
|
||||
maxPlayers = buffer.readByte();
|
||||
levelType = LevelType.byType(buffer.readString());
|
||||
@ -72,7 +78,7 @@ public class PacketJoinGame implements ClientboundPacket {
|
||||
gameModeRaw &= ~0x8;
|
||||
gameMode = GameMode.byId(gameModeRaw);
|
||||
|
||||
dimension = Dimension.byId(buffer.readInt());
|
||||
dimension = Dimensions.byId(buffer.readInt(), buffer.getVersion());
|
||||
difficulty = Difficulty.byId(buffer.readByte());
|
||||
maxPlayers = buffer.readByte();
|
||||
levelType = LevelType.byType(buffer.readString());
|
||||
@ -87,7 +93,7 @@ public class PacketJoinGame implements ClientboundPacket {
|
||||
gameModeRaw &= ~0x8;
|
||||
gameMode = GameMode.byId(gameModeRaw);
|
||||
|
||||
dimension = Dimension.byId(buffer.readInt());
|
||||
dimension = Dimensions.byId(buffer.readInt(), buffer.getVersion());
|
||||
maxPlayers = buffer.readByte();
|
||||
levelType = LevelType.byType(buffer.readString());
|
||||
viewDistance = buffer.readVarInt();
|
||||
@ -102,7 +108,7 @@ public class PacketJoinGame implements ClientboundPacket {
|
||||
gameModeRaw &= ~0x8;
|
||||
gameMode = GameMode.byId(gameModeRaw);
|
||||
|
||||
dimension = Dimension.byId(buffer.readInt());
|
||||
dimension = Dimensions.byId(buffer.readInt(), buffer.getVersion());
|
||||
long hashedSeed = buffer.readLong();
|
||||
maxPlayers = buffer.readByte();
|
||||
levelType = LevelType.byType(buffer.readString());
|
||||
@ -111,9 +117,31 @@ public class PacketJoinGame implements ClientboundPacket {
|
||||
enableRespawnScreen = buffer.readBoolean();
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
this.entityId = buffer.readInt();
|
||||
hardcore = buffer.readBoolean();
|
||||
gameMode = GameMode.byId(buffer.readByte());
|
||||
buffer.readByte(); // previous game mode
|
||||
// worlds
|
||||
String[] worlds = buffer.readStringArray(buffer.readVarInt());
|
||||
NBTTag dimensionCodec = buffer.readNBT();
|
||||
dimensions = parseDimensionCodec(dimensionCodec);
|
||||
String[] currentDimensionSplit = buffer.readString().split(":", 2);
|
||||
dimension = dimensions.get(currentDimensionSplit[0]).get(currentDimensionSplit[1]);
|
||||
buffer.readString(); // world name
|
||||
long hashedSeed = buffer.readLong();
|
||||
maxPlayers = buffer.readByte();
|
||||
levelType = LevelType.UNKNOWN;
|
||||
viewDistance = buffer.readVarInt();
|
||||
reducedDebugScreen = buffer.readBoolean();
|
||||
enableRespawnScreen = buffer.readBoolean();
|
||||
boolean isDebug = buffer.readBoolean();
|
||||
if (buffer.readBoolean()) {
|
||||
levelType = LevelType.FLAT;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -126,6 +154,21 @@ public class PacketJoinGame implements ClientboundPacket {
|
||||
h.handle(this);
|
||||
}
|
||||
|
||||
private HashMap<String, HashMap<String, Dimension>> parseDimensionCodec(NBTTag nbt) {
|
||||
HashMap<String, HashMap<String, Dimension>> dimensionMap = new HashMap<>();
|
||||
ListTag listTag = ((CompoundTag) nbt).getCompoundTag("minecraft:dimension_type").getListTag("value");
|
||||
|
||||
for (NBTTag tag : listTag.getValue()) {
|
||||
CompoundTag compoundTag = (CompoundTag) tag;
|
||||
String[] name = compoundTag.getStringTag("name").getValue().split(":", 2);
|
||||
if (!dimensionMap.containsKey(name[0])) {
|
||||
dimensionMap.put(name[0], new HashMap<>());
|
||||
}
|
||||
dimensionMap.get(name[0]).put(name[1], new Dimension(name[0], name[1], compoundTag.getByteTag("has_skylight").getValue() == 0x01));
|
||||
}
|
||||
return dimensionMap;
|
||||
}
|
||||
|
||||
public boolean isHardcore() {
|
||||
return hardcore;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class PacketNBTQueryResponse implements ClientboundPacket {
|
||||
@Override
|
||||
public boolean read(InByteBuffer buffer) {
|
||||
transactionId = buffer.readVarInt();
|
||||
tag = buffer.readNBT();
|
||||
tag = (CompoundTag) buffer.readNBT();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,10 @@
|
||||
package de.bixilon.minosoft.protocol.packets.clientbound.play;
|
||||
|
||||
import de.bixilon.minosoft.game.datatypes.Difficulty;
|
||||
import de.bixilon.minosoft.game.datatypes.Dimension;
|
||||
import de.bixilon.minosoft.game.datatypes.GameMode;
|
||||
import de.bixilon.minosoft.game.datatypes.LevelType;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.dimensions.Dimension;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.dimensions.Dimensions;
|
||||
import de.bixilon.minosoft.logging.Log;
|
||||
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
|
||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||
@ -27,7 +28,10 @@ public class PacketRespawn implements ClientboundPacket {
|
||||
Difficulty difficulty;
|
||||
GameMode gameMode;
|
||||
LevelType levelType;
|
||||
|
||||
long hashedSeed;
|
||||
boolean isDebug = false;
|
||||
boolean isFlat = false;
|
||||
boolean copyMetaData = false;
|
||||
|
||||
@Override
|
||||
public boolean read(InByteBuffer buffer) {
|
||||
@ -39,21 +43,31 @@ public class PacketRespawn implements ClientboundPacket {
|
||||
case VERSION_1_11_2:
|
||||
case VERSION_1_12_2:
|
||||
case VERSION_1_13_2:
|
||||
dimension = Dimension.byId(buffer.readInt());
|
||||
dimension = Dimensions.byId(buffer.readInt(), buffer.getVersion());
|
||||
difficulty = Difficulty.byId(buffer.readByte());
|
||||
gameMode = GameMode.byId(buffer.readByte());
|
||||
levelType = LevelType.byType(buffer.readString());
|
||||
return true;
|
||||
case VERSION_1_14_4:
|
||||
dimension = Dimension.byId(buffer.readInt());
|
||||
dimension = Dimensions.byId(buffer.readInt(), buffer.getVersion());
|
||||
gameMode = GameMode.byId(buffer.readByte());
|
||||
levelType = LevelType.byType(buffer.readString());
|
||||
return true;
|
||||
case VERSION_1_15_2:
|
||||
dimension = Dimensions.byId(buffer.readInt(), buffer.getVersion());
|
||||
hashedSeed = buffer.readLong();
|
||||
gameMode = GameMode.byId(buffer.readByte());
|
||||
levelType = LevelType.byType(buffer.readString());
|
||||
return true;
|
||||
default:
|
||||
dimension = Dimension.byId(buffer.readInt());
|
||||
long hashedSeed = buffer.readLong();
|
||||
dimension = Dimensions.byIdentifier(buffer.readString());
|
||||
buffer.readString(); // world
|
||||
hashedSeed = buffer.readLong();
|
||||
gameMode = GameMode.byId(buffer.readByte());
|
||||
levelType = LevelType.byType(buffer.readString());
|
||||
buffer.readByte(); // previous game mode
|
||||
isDebug = buffer.readBoolean();
|
||||
isFlat = buffer.readBoolean();
|
||||
copyMetaData = buffer.readBoolean();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -19,13 +19,18 @@ import de.bixilon.minosoft.logging.Log;
|
||||
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
|
||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
|
||||
|
||||
public class PacketUnlockRecipes implements ClientboundPacket {
|
||||
UnlockRecipeActions action;
|
||||
boolean isCraftingBookOpen;
|
||||
boolean isSmeltingBookOpen;
|
||||
boolean isSmeltingBookOpen = false;
|
||||
boolean isBlastFurnaceBookOpen = false;
|
||||
boolean isSmokerBookOpen = false;
|
||||
boolean isCraftingFilteringActive;
|
||||
boolean isSmeltingFilteringActive;
|
||||
boolean isSmeltingFilteringActive = false;
|
||||
boolean isBlastFurnaceFilteringActive = false;
|
||||
boolean isSmokerFilteringActive = false;
|
||||
Recipe[] listed;
|
||||
Recipe[] tagged;
|
||||
|
||||
@ -54,6 +59,12 @@ public class PacketUnlockRecipes implements ClientboundPacket {
|
||||
isCraftingFilteringActive = buffer.readBoolean();
|
||||
isSmeltingBookOpen = buffer.readBoolean();
|
||||
isSmeltingFilteringActive = buffer.readBoolean();
|
||||
if (buffer.getVersion().getVersionNumber() >= ProtocolVersion.VERSION_1_16_2.getVersionNumber()) {
|
||||
isBlastFurnaceBookOpen = buffer.readBoolean();
|
||||
isBlastFurnaceFilteringActive = buffer.readBoolean();
|
||||
isSmokerBookOpen = buffer.readBoolean();
|
||||
isSmokerFilteringActive = buffer.readBoolean();
|
||||
}
|
||||
listed = new Recipe[buffer.readVarInt()];
|
||||
for (int i = 0; i < listed.length; i++) {
|
||||
listed[i] = Recipes.getRecipe(buffer.readString());
|
||||
@ -86,6 +97,30 @@ public class PacketUnlockRecipes implements ClientboundPacket {
|
||||
return isCraftingFilteringActive;
|
||||
}
|
||||
|
||||
public boolean isBlastFurnaceBookOpen() {
|
||||
return isBlastFurnaceBookOpen;
|
||||
}
|
||||
|
||||
public boolean isBlastFurnaceFilteringActive() {
|
||||
return isBlastFurnaceFilteringActive;
|
||||
}
|
||||
|
||||
public boolean isSmeltingBookOpen() {
|
||||
return isSmeltingBookOpen;
|
||||
}
|
||||
|
||||
public boolean isSmeltingFilteringActive() {
|
||||
return isSmeltingFilteringActive;
|
||||
}
|
||||
|
||||
public boolean isSmokerBookOpen() {
|
||||
return isSmokerBookOpen;
|
||||
}
|
||||
|
||||
public boolean isSmokerFilteringActive() {
|
||||
return isSmokerFilteringActive;
|
||||
}
|
||||
|
||||
public Recipe[] getListed() {
|
||||
return listed;
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Codename Minosoft
|
||||
* Copyright (C) 2020 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.protocol.packets.serverbound.play;
|
||||
|
||||
import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
|
||||
import de.bixilon.minosoft.logging.Log;
|
||||
import de.bixilon.minosoft.protocol.packets.ServerboundPacket;
|
||||
import de.bixilon.minosoft.protocol.protocol.OutPacketBuffer;
|
||||
import de.bixilon.minosoft.protocol.protocol.Packets;
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
|
||||
|
||||
public class PacketGenerateStructure implements ServerboundPacket {
|
||||
final BlockPosition position;
|
||||
final int levels;
|
||||
final boolean keepJigsaw;
|
||||
|
||||
public PacketGenerateStructure(BlockPosition position, int levels, boolean keepJigsaw) {
|
||||
this.position = position;
|
||||
this.levels = levels;
|
||||
this.keepJigsaw = keepJigsaw;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public OutPacketBuffer write(ProtocolVersion version) {
|
||||
OutPacketBuffer buffer = new OutPacketBuffer(version, version.getPacketCommand(Packets.Serverbound.PLAY_GENERATE_STRUCTURE));
|
||||
buffer.writePosition(position);
|
||||
buffer.writeVarInt(levels);
|
||||
buffer.writeBoolean(keepJigsaw);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log() {
|
||||
Log.protocol(String.format("Sending generate structure packet (position=%s, levels=%d, keepJigsaw=%s)", position, levels, keepJigsaw));
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ public class PacketInteractEntity implements ServerboundPacket {
|
||||
final Location location;
|
||||
|
||||
final Hand hand;
|
||||
boolean sneaking;
|
||||
|
||||
public PacketInteractEntity(Entity entity, Click click) {
|
||||
this.entityId = entity.getEntityId();
|
||||
@ -57,6 +58,14 @@ public class PacketInteractEntity implements ServerboundPacket {
|
||||
this.hand = hand;
|
||||
}
|
||||
|
||||
public PacketInteractEntity(int entityId, Click click, Location location, Hand hand, boolean sneaking) {
|
||||
this.entityId = entityId;
|
||||
this.click = click;
|
||||
this.location = location;
|
||||
this.hand = hand;
|
||||
this.sneaking = sneaking;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public OutPacketBuffer write(ProtocolVersion version) {
|
||||
@ -86,6 +95,9 @@ public class PacketInteractEntity implements ServerboundPacket {
|
||||
buffer.writeFloat((float) location.getZ());
|
||||
buffer.writeVarInt(hand.getId());
|
||||
}
|
||||
if (version.getVersionNumber() >= ProtocolVersion.VERSION_1_16_2.getVersionNumber()) {
|
||||
buffer.writeBoolean(sneaking);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return buffer;
|
||||
|
@ -30,14 +30,16 @@ public class PacketPlayerAbilitiesSending implements ServerboundPacket {
|
||||
@Override
|
||||
public OutPacketBuffer write(ProtocolVersion version) {
|
||||
OutPacketBuffer buffer = new OutPacketBuffer(version, version.getPacketCommand(Packets.Serverbound.PLAY_PLAYER_ABILITIES));
|
||||
// only fly matters, everything else ignored
|
||||
byte flags = 0;
|
||||
if (flying) {
|
||||
flags |= 0b10;
|
||||
}
|
||||
buffer.writeByte(flags);
|
||||
buffer.writeFloat(0.0F);
|
||||
buffer.writeFloat(0.0F);
|
||||
if (version.getVersionNumber() < ProtocolVersion.VERSION_1_16_2.getVersionNumber()) {
|
||||
// only fly matters, everything else ignored
|
||||
buffer.writeFloat(0.0F);
|
||||
buffer.writeFloat(0.0F);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Codename Minosoft
|
||||
* Copyright (C) 2020 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.protocol.packets.serverbound.play;
|
||||
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.recipes.Recipe;
|
||||
import de.bixilon.minosoft.logging.Log;
|
||||
import de.bixilon.minosoft.protocol.packets.ServerboundPacket;
|
||||
import de.bixilon.minosoft.protocol.protocol.OutPacketBuffer;
|
||||
import de.bixilon.minosoft.protocol.protocol.Packets;
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
|
||||
|
||||
public class PacketSetDisplayedRecipe implements ServerboundPacket {
|
||||
final Recipe recipe;
|
||||
|
||||
public PacketSetDisplayedRecipe(Recipe recipe) {
|
||||
this.recipe = recipe;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutPacketBuffer write(ProtocolVersion version) {
|
||||
OutPacketBuffer buffer = new OutPacketBuffer(version, version.getPacketCommand(Packets.Serverbound.PLAY_SET_DISPLAYED_RECIPE));
|
||||
buffer.writeString(recipe.getResult().getItem().getMod() + ":" + recipe.getResult().getItem().getIdentifier());
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log() {
|
||||
Log.protocol(String.format("Sending set displayed recipe packet (identifier=%s:%s)", recipe.getResult().getItem().getMod(), recipe.getResult().getItem().getIdentifier()));
|
||||
}
|
||||
}
|
@ -22,9 +22,12 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
|
||||
|
||||
public class PacketUpdateJigsawBlock implements ServerboundPacket {
|
||||
final BlockPosition position;
|
||||
final String attachmentType;
|
||||
String attachmentType;
|
||||
final String targetPool;
|
||||
final String finalState;
|
||||
String name;
|
||||
String target;
|
||||
String jointType;
|
||||
|
||||
public PacketUpdateJigsawBlock(BlockPosition position, String attachmentType, String targetPool, String finalState) {
|
||||
this.position = position;
|
||||
@ -34,10 +37,31 @@ public class PacketUpdateJigsawBlock implements ServerboundPacket {
|
||||
}
|
||||
|
||||
|
||||
public PacketUpdateJigsawBlock(BlockPosition position, String name, String target, String targetPool, String finalState, String jointType) {
|
||||
this.position = position;
|
||||
this.name = name;
|
||||
this.target = target;
|
||||
this.targetPool = targetPool;
|
||||
this.finalState = finalState;
|
||||
this.jointType = jointType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public OutPacketBuffer write(ProtocolVersion version) {
|
||||
OutPacketBuffer buffer = new OutPacketBuffer(version, version.getPacketCommand(Packets.Serverbound.PLAY_UPDATE_JIGSAW_BLOCK));
|
||||
buffer.writePosition(position);
|
||||
if (version.getVersionNumber() < ProtocolVersion.VERSION_1_16_2.getVersionNumber()) {
|
||||
buffer.writeString(attachmentType);
|
||||
buffer.writeString(targetPool);
|
||||
buffer.writeString(finalState);
|
||||
return buffer;
|
||||
}
|
||||
buffer.writeString(name);
|
||||
buffer.writeString(target);
|
||||
buffer.writeString(targetPool);
|
||||
buffer.writeString(finalState);
|
||||
buffer.writeString(jointType);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -286,7 +286,7 @@ public class InByteBuffer {
|
||||
// shouldn't be a subtag
|
||||
return new CompoundTag(false, this);
|
||||
}
|
||||
return readNBT();
|
||||
return readNBT(type);
|
||||
}
|
||||
|
||||
public NBTTag readNBT(TagTypes tagType) {
|
||||
|
@ -182,6 +182,10 @@ public class PacketHandler {
|
||||
connection.getPlayer().setFood(pkg.getFood());
|
||||
connection.getPlayer().setHealth(pkg.getHealth());
|
||||
connection.getPlayer().setSaturation(pkg.getSaturation());
|
||||
if (pkg.getHealth() <= 0.0F) {
|
||||
// do respawn
|
||||
connection.getSender().respawn();
|
||||
}
|
||||
}
|
||||
|
||||
public void handle(PacketPluginMessageReceiving pkg) {
|
||||
@ -286,7 +290,7 @@ public class PacketHandler {
|
||||
}
|
||||
|
||||
public void handle(PacketEntityEquipment pkg) {
|
||||
connection.getPlayer().getWorld().getEntity(pkg.getEntityId()).setEquipment(pkg.getSlot(), pkg.getData());
|
||||
connection.getPlayer().getWorld().getEntity(pkg.getEntityId()).setEquipment(pkg.getSlots());
|
||||
}
|
||||
|
||||
public void handle(PacketBlockChange pkg) {
|
||||
@ -303,6 +307,8 @@ public class PacketHandler {
|
||||
}
|
||||
|
||||
public void handle(PacketRespawn pkg) {
|
||||
// clear all chunks
|
||||
connection.getPlayer().getWorld().getAllChunks().clear();
|
||||
connection.getPlayer().getWorld().setDimension(pkg.getDimension());
|
||||
connection.getPlayer().setSpawnConfirmed(false);
|
||||
connection.getPlayer().setGameMode(pkg.getGameMode());
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user