mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-12 17:07:55 -04:00
Merge branch 'entity-meta' into render
# Conflicts: # src/main/java/de/bixilon/minosoft/data/world/Chunk.java
This commit is contained in:
commit
38cdf8e1bb
@ -19,12 +19,12 @@ import de.bixilon.minosoft.util.OSUtil;
|
||||
import java.io.File;
|
||||
|
||||
public class StaticConfiguration {
|
||||
public static final boolean DEBUG_MODE = false; // if true, additional checks will be made to validate data, ... Decreases performance
|
||||
public static String CONFIG_FILENAME = "config.json"; // Filename of minosoft's base configuration (located in AppData/Minosoft/config)
|
||||
public static boolean SKIP_MOJANG_AUTHENTICATION = false; // disables all connections to mojang
|
||||
public static boolean COLORED_LOG = true; // the log should be colored with ANSI (does not affect base components)
|
||||
public static boolean LOG_RELATIVE_TIME = false; // prefix all log messages with the relative start time in milliseconds instead of the formatted time
|
||||
public static boolean VERBOSE_ENTITY_META_DATA_LOGGING = false; // if true, the entity meta data is getting serial
|
||||
|
||||
public static String HOME_DIRECTORY;
|
||||
|
||||
static {
|
||||
@ -34,7 +34,7 @@ public class StaticConfiguration {
|
||||
if (!homeDir.endsWith(File.separator)) {
|
||||
homeDir += "/";
|
||||
}
|
||||
homeDir += switch (OSUtil.getOS()) {
|
||||
homeDir += switch (OSUtil.OS) {
|
||||
case LINUX -> ".local/share/minosoft/";
|
||||
case WINDOWS -> "AppData/Roaming/Minosoft/";
|
||||
case MAC -> "Library/Application Support/Minosoft/";
|
||||
|
@ -21,6 +21,8 @@ import de.bixilon.minosoft.data.mappings.blocks.Block;
|
||||
import de.bixilon.minosoft.data.mappings.particle.data.ParticleData;
|
||||
import de.bixilon.minosoft.data.text.ChatComponent;
|
||||
import de.bixilon.minosoft.data.world.BlockPosition;
|
||||
import de.bixilon.minosoft.logging.Log;
|
||||
import de.bixilon.minosoft.logging.LogLevels;
|
||||
import de.bixilon.minosoft.protocol.network.Connection;
|
||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||
import de.bixilon.minosoft.util.BitByte;
|
||||
@ -147,47 +149,47 @@ public class EntityMetaData {
|
||||
public class MetaDataHashMap extends HashMap<Integer, Object> {
|
||||
|
||||
public Poses getPose(EntityMetaDataFields field) {
|
||||
return (Poses) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public byte getByte(EntityMetaDataFields field) {
|
||||
return (byte) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public VillagerData getVillagerData(EntityMetaDataFields field) {
|
||||
return (VillagerData) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public ParticleData getParticle(EntityMetaDataFields field) {
|
||||
return (ParticleData) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public CompoundTag getNBT(EntityMetaDataFields field) {
|
||||
return (CompoundTag) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public Block getBlock(EntityMetaDataFields field) {
|
||||
return (Block) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public UUID getUUID(EntityMetaDataFields field) {
|
||||
return (UUID) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public Directions getDirection(EntityMetaDataFields field) {
|
||||
return (Directions) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public BlockPosition getPosition(EntityMetaDataFields field) {
|
||||
return (BlockPosition) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public EntityRotation getRotation(EntityMetaDataFields field) {
|
||||
return (EntityRotation) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public Vector getVector(EntityMetaDataFields field) {
|
||||
return (Vector) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public boolean getBoolean(EntityMetaDataFields field) {
|
||||
@ -202,40 +204,45 @@ public class EntityMetaData {
|
||||
return BitByte.isBitMask(getByte(field), bitMask);
|
||||
}
|
||||
|
||||
public Object get(EntityMetaDataFields field) {
|
||||
public <K> K get(EntityMetaDataFields field) {
|
||||
Integer index = connection.getMapping().getEntityMetaDataIndex(field);
|
||||
if (index == null) {
|
||||
// ups, index not found. Index not available in this version?, mappings broken or mappings not available
|
||||
return field.getDefaultValue();
|
||||
}
|
||||
if (containsKey(index)) {
|
||||
return super.get(index);
|
||||
Object ret = super.get(index);
|
||||
try {
|
||||
return (K) ret;
|
||||
} catch (ClassCastException e) {
|
||||
Log.printException(e, LogLevels.VERBOSE);
|
||||
}
|
||||
}
|
||||
return field.getDefaultValue();
|
||||
}
|
||||
|
||||
public Slot getSlot(EntityMetaDataFields field) {
|
||||
return (Slot) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public ChatComponent getChatComponent(EntityMetaDataFields field) {
|
||||
return (ChatComponent) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public String getString(EntityMetaDataFields field) {
|
||||
return (String) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public float getFloat(EntityMetaDataFields field) {
|
||||
return (float) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public int getInt(EntityMetaDataFields field) {
|
||||
return (int) get(field);
|
||||
return get(field);
|
||||
}
|
||||
|
||||
public Short getShort(EntityMetaDataFields field) {
|
||||
return (Short) get(field);
|
||||
return get(field);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,20 +25,21 @@ import de.bixilon.minosoft.protocol.network.Connection;
|
||||
import de.bixilon.minosoft.util.nbt.tag.CompoundTag;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashSet;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerEntity extends LivingEntity {
|
||||
private final String name;
|
||||
private final PlayerPropertyData[] properties;
|
||||
private final HashSet<PlayerPropertyData> properties;
|
||||
private Item currentItem;
|
||||
|
||||
public PlayerEntity(Connection connection, int entityId, UUID uuid, Location location, EntityRotation rotation) {
|
||||
super(connection, entityId, uuid, location, rotation);
|
||||
this.name = "Ghost Player";
|
||||
this.properties = new PlayerPropertyData[0];
|
||||
this.properties = null;
|
||||
}
|
||||
|
||||
public PlayerEntity(Connection connection, int entityId, UUID uuid, Location location, EntityRotation rotation, String name, PlayerPropertyData[] properties, Item currentItem) {
|
||||
public PlayerEntity(Connection connection, int entityId, UUID uuid, Location location, EntityRotation rotation, String name, @Nullable HashSet<PlayerPropertyData> properties, Item currentItem) {
|
||||
super(connection, entityId, uuid, location, rotation);
|
||||
this.name = name;
|
||||
this.properties = properties;
|
||||
@ -82,7 +83,8 @@ public class PlayerEntity extends LivingEntity {
|
||||
}
|
||||
|
||||
@EntityMetaDataFunction(identifier = "properties")
|
||||
public PlayerPropertyData[] getProperties() {
|
||||
@Nullable
|
||||
public HashSet<PlayerPropertyData> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ package de.bixilon.minosoft.data.mappings.blocks;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import de.bixilon.minosoft.config.StaticConfiguration;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
@ -24,7 +25,7 @@ public class Blocks {
|
||||
|
||||
public static HashBiMap<Integer, Block> load(String mod, JsonObject json, boolean metaData) {
|
||||
HashBiMap<Integer, Block> versionMapping = HashBiMap.create();
|
||||
json.keySet().forEach((identifierName) -> {
|
||||
for (String identifierName : json.keySet()) {
|
||||
JsonObject identifierJSON = json.getAsJsonObject(identifierName);
|
||||
JsonArray statesArray = identifierJSON.getAsJsonArray("states");
|
||||
for (int i = 0; i < statesArray.size(); i++) {
|
||||
@ -50,11 +51,13 @@ public class Blocks {
|
||||
|
||||
HashSet<BlockProperties> properties = new HashSet<>();
|
||||
for (String propertyName : propertiesJSON.keySet()) {
|
||||
if (BlockProperties.PROPERTIES_MAPPING.get(propertyName) == null) {
|
||||
throw new RuntimeException(String.format("Unknown block property: %s (identifier=%s)", propertyName, identifierName));
|
||||
}
|
||||
if (BlockProperties.PROPERTIES_MAPPING.get(propertyName).get(propertiesJSON.get(propertyName).getAsString()) == null) {
|
||||
throw new RuntimeException(String.format("Unknown block property: %s -> %s (identifier=%s)", propertyName, propertiesJSON.get(propertyName).getAsString(), identifierName));
|
||||
if (StaticConfiguration.DEBUG_MODE) {
|
||||
if (BlockProperties.PROPERTIES_MAPPING.get(propertyName) == null) {
|
||||
throw new RuntimeException(String.format("Unknown block property: %s (identifier=%s)", propertyName, identifierName));
|
||||
}
|
||||
if (BlockProperties.PROPERTIES_MAPPING.get(propertyName).get(propertiesJSON.get(propertyName).getAsString()) == null) {
|
||||
throw new RuntimeException(String.format("Unknown block property: %s -> %s (identifier=%s)", propertyName, propertiesJSON.get(propertyName).getAsString(), identifierName));
|
||||
}
|
||||
}
|
||||
properties.add(BlockProperties.PROPERTIES_MAPPING.get(propertyName).get(propertiesJSON.get(propertyName).getAsString()));
|
||||
}
|
||||
@ -65,10 +68,12 @@ public class Blocks {
|
||||
block = new Block(mod, identifierName);
|
||||
}
|
||||
int blockId = getBlockId(statesJSON, metaData);
|
||||
checkAndCrashIfBlockIsIn(blockId, identifierName, versionMapping);
|
||||
if (StaticConfiguration.DEBUG_MODE) {
|
||||
checkAndCrashIfBlockIsIn(blockId, identifierName, versionMapping);
|
||||
}
|
||||
versionMapping.put(blockId, block);
|
||||
}
|
||||
});
|
||||
}
|
||||
return versionMapping;
|
||||
}
|
||||
|
||||
@ -76,10 +81,10 @@ public class Blocks {
|
||||
int blockId = json.get("id").getAsInt();
|
||||
if (metaData) {
|
||||
blockId <<= 4;
|
||||
}
|
||||
if (json.has("meta")) {
|
||||
// old format (with metadata)
|
||||
blockId |= json.get("meta").getAsByte();
|
||||
if (json.has("meta")) {
|
||||
// old format (with metadata)
|
||||
blockId |= json.get("meta").getAsByte();
|
||||
}
|
||||
}
|
||||
return blockId;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ package de.bixilon.minosoft.data.mappings.blocks.actions;
|
||||
|
||||
public class BeaconAction implements BlockAction {
|
||||
|
||||
public BeaconAction(byte status, byte ignored) {
|
||||
public BeaconAction(short status, short ignored) {
|
||||
// only 1 action (id 1)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.data.mappings.blocks.actions;
|
||||
|
||||
import com.sun.javafx.scene.traversal.Direction;
|
||||
|
||||
public class BellAction implements BlockAction {
|
||||
private final Direction direction;
|
||||
|
||||
public BellAction(short unused, short direction) {
|
||||
this.direction = Direction.values()[direction];
|
||||
}
|
||||
|
||||
public Direction getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("BELL_HIT_%s", direction);
|
||||
}
|
||||
}
|
@ -14,9 +14,9 @@
|
||||
package de.bixilon.minosoft.data.mappings.blocks.actions;
|
||||
|
||||
public class ChestAction implements BlockAction {
|
||||
final byte playersLookingInChest;
|
||||
final short playersLookingInChest;
|
||||
|
||||
public ChestAction(byte unused, byte playersLookingInChest) {
|
||||
public ChestAction(short unused, short playersLookingInChest) {
|
||||
this.playersLookingInChest = playersLookingInChest;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ package de.bixilon.minosoft.data.mappings.blocks.actions;
|
||||
|
||||
public class EndGatewayAction implements BlockAction {
|
||||
|
||||
public EndGatewayAction(byte status, byte ignored) {
|
||||
public EndGatewayAction(short status, short ignored) {
|
||||
// only 1 action (id 1)
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ package de.bixilon.minosoft.data.mappings.blocks.actions;
|
||||
|
||||
public class MobSpawnerAction implements BlockAction {
|
||||
|
||||
public MobSpawnerAction(byte status, byte ignored) {
|
||||
public MobSpawnerAction(short status, short ignored) {
|
||||
// only 1 action (id 1)
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,9 @@ package de.bixilon.minosoft.data.mappings.blocks.actions;
|
||||
|
||||
public class NoteBlockAction implements BlockAction {
|
||||
final Instruments instrument;
|
||||
final byte pitch;
|
||||
final short pitch;
|
||||
|
||||
public NoteBlockAction(byte instrument, byte pitch) {
|
||||
public NoteBlockAction(short instrument, short pitch) {
|
||||
this.instrument = Instruments.byId(instrument);
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public class PistonAction implements BlockAction {
|
||||
final PistonStates status;
|
||||
final Directions direction;
|
||||
|
||||
public PistonAction(byte status, byte direction) {
|
||||
public PistonAction(short status, short direction) {
|
||||
this.status = PistonStates.byId(status);
|
||||
this.direction = Directions.byId(direction);
|
||||
}
|
||||
|
@ -41,7 +41,6 @@ import java.util.HashSet;
|
||||
|
||||
public class VersionMapping {
|
||||
private final HashSet<Mappings> loaded = new HashSet<>();
|
||||
HashMap<String, HashBiMap<String, Dimension>> dimensionIdentifierMap = new HashMap<>();
|
||||
private Version version;
|
||||
private VersionMapping parentMapping;
|
||||
private HashBiMap<String, Motive> motiveIdentifierMap;
|
||||
@ -51,6 +50,7 @@ public class VersionMapping {
|
||||
private HashBiMap<Integer, Motive> motiveIdMap;
|
||||
private HashBiMap<Integer, MobEffect> mobEffectMap;
|
||||
private HashBiMap<Integer, Dimension> dimensionMap;
|
||||
private HashMap<String, HashBiMap<String, Dimension>> dimensionIdentifierMap = new HashMap<>();
|
||||
private HashBiMap<Integer, Block> blockMap;
|
||||
private HashBiMap<Integer, BlockId> blockIdMap;
|
||||
private HashBiMap<Integer, Enchantment> enchantmentMap;
|
||||
|
@ -122,7 +122,7 @@ public class Versions {
|
||||
try {
|
||||
files = Util.readJsonTarStream(AssetsManager.readAssetAsStream(String.format("mappings/%s", version.getVersionName())));
|
||||
} catch (Exception e) {
|
||||
// should not happen, but if this version is not flattend, we can fallback to the flatten mappings. Some things might not work...
|
||||
// should not happen, but if this version is not flattened, we can fallback to the flatten mappings. Some things might not work...
|
||||
Log.printException(e, LogLevels.VERBOSE);
|
||||
if (version.isFlattened() || version.getVersionId() == ProtocolDefinition.FLATTING_VERSION_ID) {
|
||||
throw e;
|
||||
|
@ -157,6 +157,10 @@ public class BaseComponent implements ChatComponent {
|
||||
thisTextComponent = new TextComponent(text, color, formattingCodes);
|
||||
}
|
||||
|
||||
if (thisTextComponent != null) {
|
||||
parts.add(thisTextComponent);
|
||||
}
|
||||
|
||||
if (json.has("extra")) {
|
||||
JsonArray extras = json.getAsJsonArray("extra");
|
||||
TextComponent finalThisChatPart = thisTextComponent;
|
||||
@ -166,10 +170,6 @@ public class BaseComponent implements ChatComponent {
|
||||
if (json.has("translate")) {
|
||||
parts.add(new TranslatableComponent(json.get("translate").getAsString(), json.getAsJsonArray("with")));
|
||||
}
|
||||
|
||||
if (thisTextComponent != null) {
|
||||
parts.add(thisTextComponent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -16,25 +16,30 @@ package de.bixilon.minosoft.data.text;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
|
||||
public final class ChatColors {
|
||||
private static final HashBiMap<Integer, RGBColor> colors = HashBiMap.create();
|
||||
public static final RGBColor BLACK = new RGBColor(0, 0, 0);
|
||||
public static final RGBColor DARK_BLUE = new RGBColor(0, 0, 170);
|
||||
public static final RGBColor DARK_GREEN = new RGBColor(0, 170, 0);
|
||||
public static final RGBColor DARK_AQUA = new RGBColor(0, 170, 170);
|
||||
public static final RGBColor DARK_RED = new RGBColor(170, 0, 0);
|
||||
public static final RGBColor DARK_PURPLE = new RGBColor(170, 0, 170);
|
||||
public static final RGBColor GOLD = new RGBColor(255, 170, 0);
|
||||
public static final RGBColor GRAY = new RGBColor(170, 170, 170);
|
||||
public static final RGBColor DARK_GRAY = new RGBColor(85, 85, 85);
|
||||
public static final RGBColor BLUE = new RGBColor(85, 85, 255);
|
||||
public static final RGBColor GREEN = new RGBColor(85, 255, 85);
|
||||
public static final RGBColor AQUA = new RGBColor(85, 255, 255);
|
||||
public static final RGBColor RED = new RGBColor(255, 85, 85);
|
||||
public static final RGBColor LIGHT_PURPLE = new RGBColor(255, 85, 255);
|
||||
public static final RGBColor YELLOW = new RGBColor(255, 255, 85);
|
||||
public static final RGBColor WHITE = new RGBColor(255, 255, 255);
|
||||
|
||||
private static final HashBiMap<RGBColor, Integer> colorIntMap = HashBiMap.create();
|
||||
private static final RGBColor[] colors = {BLACK, DARK_BLUE, DARK_GREEN, DARK_AQUA, DARK_RED, DARK_PURPLE, GOLD, GRAY, DARK_GRAY, BLUE, GREEN, AQUA, RED, LIGHT_PURPLE, YELLOW, WHITE};
|
||||
|
||||
static {
|
||||
colors.put(0, new RGBColor(0, 0, 0));
|
||||
colors.put(1, new RGBColor(0, 0, 170));
|
||||
colors.put(2, new RGBColor(0, 170, 0));
|
||||
colors.put(3, new RGBColor(0, 170, 170));
|
||||
colors.put(4, new RGBColor(170, 0, 0));
|
||||
colors.put(5, new RGBColor(170, 0, 170));
|
||||
colors.put(6, new RGBColor(255, 170, 0));
|
||||
colors.put(7, new RGBColor(170, 170, 170));
|
||||
colors.put(8, new RGBColor(85, 85, 85));
|
||||
colors.put(9, new RGBColor(85, 85, 255));
|
||||
colors.put(10, new RGBColor(85, 255, 85));
|
||||
colors.put(11, new RGBColor(85, 255, 255));
|
||||
colors.put(12, new RGBColor(255, 85, 85));
|
||||
colors.put(13, new RGBColor(255, 85, 255));
|
||||
colors.put(14, new RGBColor(255, 255, 85));
|
||||
colors.put(15, new RGBColor(255, 255, 255));
|
||||
for (int i = 0; i < colors.length; i++) {
|
||||
colorIntMap.put(colors[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getANSIColorByFormattingChar(char c) {
|
||||
@ -46,36 +51,57 @@ public final class ChatColors {
|
||||
}
|
||||
|
||||
public static RGBColor getColorByFormattingChar(char c) {
|
||||
return colors.get(Character.digit(c, 16));
|
||||
return getColorById(Character.digit(c, 16));
|
||||
}
|
||||
|
||||
public static ChatFormattingCode getFormattingById(int id) {
|
||||
if (id <= 15) {
|
||||
return getColorById(id);
|
||||
}
|
||||
return switch (id) {
|
||||
case 16 -> ChatFormattingCodes.OBFUSCATED;
|
||||
case 17 -> ChatFormattingCodes.BOLD;
|
||||
case 18 -> ChatFormattingCodes.STRIKETHROUGH;
|
||||
case 19 -> ChatFormattingCodes.UNDERLINED;
|
||||
case 20 -> ChatFormattingCodes.ITALIC;
|
||||
case 21 -> ChatFormattingCodes.RESET;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
public static RGBColor getColorById(int id) {
|
||||
return colors.get(id);
|
||||
if (id < 0) {
|
||||
return null;
|
||||
}
|
||||
if (id <= 15) {
|
||||
return colors[id];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Integer getColorId(RGBColor color) {
|
||||
return colors.inverse().get(color);
|
||||
return colorIntMap.get(color);
|
||||
}
|
||||
|
||||
public static RGBColor getColorByName(String name) {
|
||||
return colors.get(switch (name.toLowerCase()) {
|
||||
case "black" -> 0;
|
||||
case "dark_blue" -> 1;
|
||||
case "dark_green" -> 2;
|
||||
case "dark_aqua" -> 3;
|
||||
case "dark_red" -> 4;
|
||||
case "dark_purple" -> 5;
|
||||
case "gold" -> 6;
|
||||
case "gray", "grey" -> 7;
|
||||
case "dark_gray", "dark_grey" -> 8;
|
||||
case "blue" -> 9;
|
||||
case "green" -> 10;
|
||||
case "aqua" -> 11;
|
||||
case "red" -> 12;
|
||||
case "light_purple" -> 13;
|
||||
case "yellow" -> 14;
|
||||
case "white" -> 15;
|
||||
return switch (name.toLowerCase()) {
|
||||
case "black" -> BLACK;
|
||||
case "dark_blue" -> DARK_BLUE;
|
||||
case "dark_green" -> DARK_GREEN;
|
||||
case "dark_aqua" -> DARK_AQUA;
|
||||
case "dark_red" -> DARK_RED;
|
||||
case "dark_purple" -> DARK_PURPLE;
|
||||
case "gold" -> GOLD;
|
||||
case "gray", "grey" -> GRAY;
|
||||
case "dark_gray", "dark_grey" -> DARK_GRAY;
|
||||
case "blue" -> BLUE;
|
||||
case "green" -> GREEN;
|
||||
case "aqua" -> AQUA;
|
||||
case "red" -> RED;
|
||||
case "light_purple" -> LIGHT_PURPLE;
|
||||
case "yellow" -> YELLOW;
|
||||
case "white" -> WHITE;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + name);
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* 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.data.text;
|
||||
|
||||
public interface ChatFormattingCode {
|
||||
}
|
@ -17,7 +17,7 @@ import com.google.common.collect.HashBiMap;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public enum ChatFormattingCodes {
|
||||
public enum ChatFormattingCodes implements ChatFormattingCode {
|
||||
OBFUSCATED('k', "\u001b[5m"),
|
||||
BOLD('l', "\u001b[1m"),
|
||||
STRIKETHROUGH('m', "\u001b[9m"),
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.data.text;
|
||||
|
||||
public final class RGBColor {
|
||||
public final class RGBColor implements ChatFormattingCode {
|
||||
private final int color;
|
||||
|
||||
public RGBColor(int color) {
|
||||
|
@ -45,15 +45,6 @@ public class Log {
|
||||
}, "Log").start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs all game related things (mostly visible stuff to the user)
|
||||
*
|
||||
* @param message Raw message to log
|
||||
*/
|
||||
public static void game(String message) {
|
||||
log(LogLevels.GAME, message, ChatColors.getColorByName("green"));
|
||||
}
|
||||
|
||||
public static void log(LogLevels level, String message, RGBColor color) {
|
||||
log(level, "", message, color);
|
||||
}
|
||||
@ -90,13 +81,22 @@ public class Log {
|
||||
queue.add(builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs all game related things (mostly visible stuff to the user)
|
||||
*
|
||||
* @param message Raw message to log
|
||||
*/
|
||||
public static void game(String message) {
|
||||
log(LogLevels.GAME, message, ChatColors.GREEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs all fatal errors (critical exceptions, etc)
|
||||
*
|
||||
* @param message Raw message to log
|
||||
*/
|
||||
public static void fatal(String message) {
|
||||
log(LogLevels.FATAL, message, ChatColors.getColorByName("dark_red"));
|
||||
log(LogLevels.FATAL, message, ChatColors.DARK_RED);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,7 +105,7 @@ public class Log {
|
||||
* @param message Raw message to log
|
||||
*/
|
||||
public static void warn(String message) {
|
||||
log(LogLevels.WARNING, message, ChatColors.getColorByName("red"));
|
||||
log(LogLevels.WARNING, message, ChatColors.RED);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,7 +114,7 @@ public class Log {
|
||||
* @param message Raw message to log
|
||||
*/
|
||||
public static void debug(String message) {
|
||||
log(LogLevels.DEBUG, message, ChatColors.getColorByName("gray"));
|
||||
log(LogLevels.DEBUG, message, ChatColors.GRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,7 +123,7 @@ public class Log {
|
||||
* @param message Raw message to log
|
||||
*/
|
||||
public static void verbose(String message) {
|
||||
log(LogLevels.VERBOSE, message, ChatColors.getColorByName("yellow"));
|
||||
log(LogLevels.VERBOSE, message, ChatColors.YELLOW);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,7 +132,7 @@ public class Log {
|
||||
* @param message Raw message to log
|
||||
*/
|
||||
public static void protocol(String message) {
|
||||
log(LogLevels.PROTOCOL, message, ChatColors.getColorByName("blue"));
|
||||
log(LogLevels.PROTOCOL, message, ChatColors.BLUE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -141,7 +141,7 @@ public class Log {
|
||||
* @param message Raw message to log
|
||||
*/
|
||||
public static void mojang(String message) {
|
||||
log(LogLevels.MOJANG, message, ChatColors.getColorByName("aqua"));
|
||||
log(LogLevels.MOJANG, message, ChatColors.AQUA);
|
||||
}
|
||||
|
||||
public static LogLevels getLevel() {
|
||||
@ -162,7 +162,7 @@ public class Log {
|
||||
* @param message Raw message to log
|
||||
*/
|
||||
public static void info(String message) {
|
||||
log(LogLevels.INFO, message, ChatColors.getColorByName("white"));
|
||||
log(LogLevels.INFO, message, ChatColors.WHITE);
|
||||
}
|
||||
|
||||
public static boolean printException(Exception exception, LogLevels minimumLogLevel) {
|
||||
|
@ -25,31 +25,31 @@ public class Logger {
|
||||
this.modName = modName;
|
||||
}
|
||||
|
||||
public void game(String message) {
|
||||
log(LogLevels.GAME, message, ChatColors.getColorByName("green"));
|
||||
}
|
||||
|
||||
public void log(LogLevels level, String message, RGBColor color) {
|
||||
Log.log(level, String.format("[%s] ", modName), message, color);
|
||||
}
|
||||
|
||||
public void game(String message) {
|
||||
log(LogLevels.GAME, message, ChatColors.GREEN);
|
||||
}
|
||||
|
||||
public void fatal(String message) {
|
||||
log(LogLevels.FATAL, message, ChatColors.getColorByName("dark_red"));
|
||||
log(LogLevels.FATAL, message, ChatColors.DARK_RED);
|
||||
}
|
||||
|
||||
public void info(String message) {
|
||||
log(LogLevels.INFO, message, ChatColors.getColorByName("white"));
|
||||
log(LogLevels.INFO, message, ChatColors.WHITE);
|
||||
}
|
||||
|
||||
public void warn(String message) {
|
||||
log(LogLevels.WARNING, message, ChatColors.getColorByName("red"));
|
||||
log(LogLevels.WARNING, message, ChatColors.RED);
|
||||
}
|
||||
|
||||
public void debug(String message) {
|
||||
log(LogLevels.DEBUG, message, ChatColors.getColorByName("gray"));
|
||||
log(LogLevels.DEBUG, message, ChatColors.GRAY);
|
||||
}
|
||||
|
||||
public void verbose(String message) {
|
||||
log(LogLevels.VERBOSE, message, ChatColors.getColorByName("yellow"));
|
||||
log(LogLevels.VERBOSE, message, ChatColors.YELLOW);
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,6 @@ import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
|
||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class PacketBlockAction implements ClientboundPacket {
|
||||
BlockPosition position;
|
||||
BlockAction data;
|
||||
@ -35,26 +33,19 @@ public class PacketBlockAction implements ClientboundPacket {
|
||||
} else {
|
||||
position = buffer.readPosition();
|
||||
}
|
||||
byte byte1 = buffer.readByte();
|
||||
byte byte2 = buffer.readByte();
|
||||
Class<? extends BlockAction> clazz;
|
||||
short byte1 = buffer.readUnsignedByte();
|
||||
short byte2 = buffer.readUnsignedByte();
|
||||
BlockId blockId = buffer.getConnection().getMapping().getBlockIdById(buffer.readVarInt());
|
||||
// beacon
|
||||
// end gateway
|
||||
clazz = switch (blockId.getIdentifier()) {
|
||||
case "noteblock" -> NoteBlockAction.class; // ToDo: was replaced in 17w47a (346) with the block id
|
||||
case "sticky_piston", "piston" -> PistonAction.class;
|
||||
case "chest", "ender_chest", "trapped_chest", "white_shulker_box", "shulker_box", "orange_shulker_box", "magenta_shulker_box", "light_blue_shulker_box", "yellow_shulker_box", "lime_shulker_box", "pink_shulker_box", "gray_shulker_box", "silver_shulker_box", "cyan_shulker_box", "purple_shulker_box", "blue_shulker_box", "brown_shulker_box", "green_shulker_box", "red_shulker_box", "black_shulker_box" -> ChestAction.class;
|
||||
case "beacon" -> BeaconAction.class;
|
||||
case "mob_spawner" -> MobSpawnerAction.class;
|
||||
case "end_gateway" -> EndGatewayAction.class;
|
||||
default -> throw new IllegalStateException(String.format("Unexpected block action (blockId=%s)", blockId));
|
||||
|
||||
data = switch (blockId.getIdentifier()) {
|
||||
case "noteblock" -> new NoteBlockAction(byte1, byte2); // ToDo: was replaced in 17w47a (346) with the block id
|
||||
case "sticky_piston", "piston" -> new PistonAction(byte1, byte2);
|
||||
case "chest", "ender_chest", "trapped_chest", "white_shulker_box", "shulker_box", "orange_shulker_box", "magenta_shulker_box", "light_blue_shulker_box", "yellow_shulker_box", "lime_shulker_box", "pink_shulker_box", "gray_shulker_box", "silver_shulker_box", "cyan_shulker_box", "purple_shulker_box", "blue_shulker_box", "brown_shulker_box", "green_shulker_box", "red_shulker_box", "black_shulker_box" -> new ChestAction(byte1, byte2);
|
||||
case "beacon" -> new BeaconAction(byte1, byte2);
|
||||
case "mob_spawner" -> new MobSpawnerAction(byte1, byte2);
|
||||
case "end_gateway" -> new EndGatewayAction(byte1, byte2);
|
||||
default -> null;
|
||||
};
|
||||
try {
|
||||
data = clazz.getConstructor(byte.class, byte.class).newInstance(byte1, byte2);
|
||||
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -50,18 +50,18 @@ public class PacketChangeGameState implements ClientboundPacket {
|
||||
}
|
||||
|
||||
public enum Reason {
|
||||
INVALID_BED(new MapSet[]{new MapSet<>(0, 0)}),
|
||||
END_RAIN(new MapSet[]{new MapSet<>(0, 1), new MapSet<>(498, 2), new MapSet<>(578, 1)}), // ToDo: when exactly did these 2 switch?
|
||||
START_RAIN(new MapSet[]{new MapSet<>(0, 2), new MapSet<>(498, 1), new MapSet<>(578, 2)}),
|
||||
NO_RESPAWN_BLOCK_AVAILABLE(new MapSet[]{new MapSet<>(0, 0)}),
|
||||
START_RAINING(new MapSet[]{new MapSet<>(0, 1), new MapSet<>(498, 2), new MapSet<>(578, 1)}), // ToDo: when exactly did these 2 switch?
|
||||
STOP_RAINING(new MapSet[]{new MapSet<>(0, 2), new MapSet<>(498, 1), new MapSet<>(578, 2)}),
|
||||
CHANGE_GAMEMODE(new MapSet[]{new MapSet<>(0, 3)}),
|
||||
ENTER_CREDITS(new MapSet[]{new MapSet<>(0, 4)}),
|
||||
DEMO_MESSAGES(new MapSet[]{new MapSet<>(0, 5)}),
|
||||
ARROW_HITTING_PLAYER(new MapSet[]{new MapSet<>(0, 6)}),
|
||||
FADE_VALUE(new MapSet[]{new MapSet<>(0, 7)}),
|
||||
FADE_TIME(new MapSet[]{new MapSet<>(0, 8)}),
|
||||
PLAY_PUFFERFISH_STING_SOUND(new MapSet[]{new MapSet<>(0, 9)}),
|
||||
PLAY_ELDER_GUARDIAN_MOB_APPEARANCE(new MapSet[]{new MapSet<>(0, 10)}),
|
||||
ENABLE_RESPAWN_SCREEN(new MapSet[]{new MapSet<>(552, 11)});
|
||||
RAIN_LEVEL_CHANGE(new MapSet[]{new MapSet<>(0, 7)}),
|
||||
THUNDER_LEVEL_CHANGE(new MapSet[]{new MapSet<>(0, 8)}),
|
||||
PUFFERFISH_STING(new MapSet[]{new MapSet<>(0, 9)}),
|
||||
GUARDIAN_ELDER_EFFECT(new MapSet[]{new MapSet<>(0, 10)}),
|
||||
IMMEDIATE_RESPAWN(new MapSet[]{new MapSet<>(552, 11)});
|
||||
|
||||
final VersionValueMap<Integer> valueMap;
|
||||
|
||||
|
@ -21,6 +21,7 @@ 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.util.nbt.tag.CompoundTag;
|
||||
|
||||
public class PacketRespawn implements ClientboundPacket {
|
||||
Dimension dimension;
|
||||
@ -40,8 +41,11 @@ public class PacketRespawn implements ClientboundPacket {
|
||||
} else {
|
||||
dimension = buffer.getConnection().getMapping().getDimensionById(buffer.readInt());
|
||||
}
|
||||
} else {
|
||||
} else if (buffer.getVersionId() < 748) {
|
||||
dimension = buffer.getConnection().getMapping().getDimensionByIdentifier(buffer.readString());
|
||||
} else {
|
||||
CompoundTag tag = (CompoundTag) buffer.readNBT();
|
||||
dimension = buffer.getConnection().getMapping().getDimensionByIdentifier(tag.getStringTag("effects").getValue()); //ToDo
|
||||
}
|
||||
if (buffer.getVersionId() < 464) {
|
||||
difficulty = Difficulties.byId(buffer.readByte());
|
||||
|
@ -25,6 +25,7 @@ import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
|
||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PacketSpawnPlayer implements ClientboundPacket {
|
||||
@ -36,13 +37,14 @@ public class PacketSpawnPlayer implements ClientboundPacket {
|
||||
int entityId = buffer.readVarInt();
|
||||
String name = null;
|
||||
UUID uuid;
|
||||
PlayerPropertyData[] properties = null;
|
||||
HashSet<PlayerPropertyData> properties = null;
|
||||
if (buffer.getVersionId() < 19) {
|
||||
name = buffer.readString();
|
||||
uuid = UUID.fromString(buffer.readString());
|
||||
properties = new PlayerPropertyData[buffer.readVarInt()];
|
||||
for (int i = 0; i < properties.length; i++) {
|
||||
properties[i] = new PlayerPropertyData(buffer.readString(), buffer.readString(), buffer.readString());
|
||||
properties = new HashSet<>();
|
||||
int length = buffer.readVarInt();
|
||||
for (int i = 0; i < length; i++) {
|
||||
properties.add(new PlayerPropertyData(buffer.readString(), buffer.readString(), buffer.readString()));
|
||||
}
|
||||
} else {
|
||||
uuid = buffer.readUUID();
|
||||
|
@ -15,7 +15,7 @@ package de.bixilon.minosoft.protocol.packets.clientbound.play;
|
||||
|
||||
import de.bixilon.minosoft.data.text.ChatColors;
|
||||
import de.bixilon.minosoft.data.text.ChatComponent;
|
||||
import de.bixilon.minosoft.data.text.RGBColor;
|
||||
import de.bixilon.minosoft.data.text.ChatFormattingCode;
|
||||
import de.bixilon.minosoft.logging.Log;
|
||||
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
|
||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||
@ -32,7 +32,7 @@ public class PacketTeams implements ClientboundPacket {
|
||||
boolean seeFriendlyInvisibles;
|
||||
TeamCollisionRules collisionRule = TeamCollisionRules.NEVER;
|
||||
TeamNameTagVisibilities nameTagVisibility = TeamNameTagVisibilities.ALWAYS;
|
||||
RGBColor color;
|
||||
ChatFormattingCode formattingCode;
|
||||
String[] playerNames;
|
||||
|
||||
@Override
|
||||
@ -58,9 +58,9 @@ public class PacketTeams implements ClientboundPacket {
|
||||
collisionRule = TeamCollisionRules.byName(buffer.readString());
|
||||
}
|
||||
if (buffer.getVersionId() < 352) {
|
||||
color = ChatColors.getColorById(buffer.readByte());
|
||||
formattingCode = ChatColors.getFormattingById(buffer.readByte());
|
||||
} else {
|
||||
color = ChatColors.getColorById(buffer.readVarInt());
|
||||
formattingCode = ChatColors.getFormattingById(buffer.readVarInt());
|
||||
}
|
||||
}
|
||||
if (buffer.getVersionId() >= 375) {
|
||||
@ -133,8 +133,8 @@ public class PacketTeams implements ClientboundPacket {
|
||||
return seeFriendlyInvisibles;
|
||||
}
|
||||
|
||||
public RGBColor getColor() {
|
||||
return color;
|
||||
public ChatFormattingCode getFormattingCode() {
|
||||
return formattingCode;
|
||||
}
|
||||
|
||||
public TeamCollisionRules getCollisionRule() {
|
||||
|
@ -16,7 +16,6 @@ package de.bixilon.minosoft.protocol.protocol;
|
||||
import de.bixilon.minosoft.Minosoft;
|
||||
import de.bixilon.minosoft.config.ConfigurationPaths;
|
||||
import de.bixilon.minosoft.data.GameModes;
|
||||
import de.bixilon.minosoft.data.PlayerPropertyData;
|
||||
import de.bixilon.minosoft.data.entities.entities.Entity;
|
||||
import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity;
|
||||
import de.bixilon.minosoft.data.mappings.blocks.Blocks;
|
||||
@ -122,7 +121,7 @@ public class PacketHandler {
|
||||
connection.getPlayer().getWorld().setHardcore(pkg.isHardcore());
|
||||
connection.getMapping().setDimensions(pkg.getDimensions());
|
||||
connection.getPlayer().getWorld().setDimension(pkg.getDimension());
|
||||
PlayerEntity entity = new PlayerEntity(connection, pkg.getEntityId(), connection.getPlayer().getPlayerUUID(), null, null, connection.getPlayer().getPlayerName(), new PlayerPropertyData[]{}, null);
|
||||
PlayerEntity entity = new PlayerEntity(connection, pkg.getEntityId(), connection.getPlayer().getPlayerUUID(), null, null, connection.getPlayer().getPlayerName(), null, null);
|
||||
connection.getPlayer().setEntity(entity);
|
||||
connection.getPlayer().getWorld().addEntity(entity);
|
||||
connection.getSender().sendChatMessage("I am alive! ~ Minosoft");
|
||||
@ -279,15 +278,15 @@ public class PacketHandler {
|
||||
}
|
||||
|
||||
Log.game(switch (pkg.getReason()) {
|
||||
case START_RAIN -> "Received weather packet: Starting rain...";
|
||||
case END_RAIN -> "Received weather packet: Stopping rain...";
|
||||
case STOP_RAINING -> "Received weather packet: Starting rain...";
|
||||
case START_RAINING -> "Received weather packet: Stopping rain...";
|
||||
case CHANGE_GAMEMODE -> String.format("Received game mode change: Now in %s", GameModes.byId(pkg.getValue().intValue()));
|
||||
default -> "";
|
||||
});
|
||||
|
||||
switch (pkg.getReason()) {
|
||||
case START_RAIN -> connection.getPlayer().getWorld().setRaining(true);
|
||||
case END_RAIN -> connection.getPlayer().getWorld().setRaining(false);
|
||||
case STOP_RAINING -> connection.getPlayer().getWorld().setRaining(true);
|
||||
case START_RAINING -> connection.getPlayer().getWorld().setRaining(false);
|
||||
case CHANGE_GAMEMODE -> connection.getPlayer().setGameMode(GameModes.byId(pkg.getValue().intValue()));
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,9 @@ import com.google.common.collect.HashBiMap;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public abstract class Protocol {
|
||||
static final HashMap<ConnectionStates, HashBiMap<Packets.Serverbound, Integer>> serverboundPacketMapping = new HashMap<>();
|
||||
static final HashMap<ConnectionStates, HashBiMap<Packets.Clientbound, Integer>> clientboundPacketMapping = new HashMap<>();
|
||||
public final class Protocol {
|
||||
private static final HashMap<ConnectionStates, HashBiMap<Packets.Serverbound, Integer>> serverboundPacketMapping = new HashMap<>();
|
||||
private static final HashMap<ConnectionStates, HashBiMap<Packets.Clientbound, Integer>> clientboundPacketMapping = new HashMap<>();
|
||||
|
||||
static {
|
||||
serverboundPacketMapping.put(ConnectionStates.HANDSHAKING, HashBiMap.create());
|
||||
|
@ -14,26 +14,22 @@
|
||||
package de.bixilon.minosoft.util;
|
||||
|
||||
public final class OSUtil {
|
||||
final static OS os;
|
||||
public static final OSs OS;
|
||||
|
||||
static {
|
||||
String name = System.getProperty("os.name");
|
||||
if (name.startsWith("Windows")) {
|
||||
os = OS.WINDOWS;
|
||||
OS = OSs.WINDOWS;
|
||||
} else if (name.startsWith("Linux")) {
|
||||
os = OS.LINUX;
|
||||
OS = OSs.LINUX;
|
||||
} else if (name.startsWith("Mac")) {
|
||||
os = OS.MAC;
|
||||
OS = OSs.MAC;
|
||||
} else {
|
||||
os = OS.OTHER;
|
||||
OS = OSs.OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
public static OS getOS() {
|
||||
return os;
|
||||
}
|
||||
|
||||
public enum OS {
|
||||
public enum OSs {
|
||||
WINDOWS,
|
||||
LINUX,
|
||||
MAC,
|
||||
|
Loading…
x
Reference in New Issue
Block a user