Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-26 16:12:46 +01:00
Some fixes, added playerlist. Entity spawning doesn't work yet
Dieser Commit ist enthalten in:
Ursprung
f2fb042ae7
Commit
1c74a6252a
@ -97,7 +97,7 @@ public class Entity {
|
||||
valid = true;
|
||||
session.getUpstream().sendPacket(addEntityPacket);
|
||||
|
||||
GeyserLogger.DEFAULT.debug("Spawned entity " + entityType + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")");
|
||||
GeyserLogger.DEFAULT.info("Spawned entity " + entityType + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")");
|
||||
}
|
||||
|
||||
public void despawnEntity(GeyserSession session) {
|
||||
@ -125,11 +125,11 @@ public class Entity {
|
||||
}
|
||||
|
||||
public void moveAbsolute(Vector3f position, float pitch, float yaw) {
|
||||
moveAbsolute(position, new Vector3f(pitch, yaw, 0));
|
||||
moveAbsolute(position, new Vector3f(pitch, yaw, yaw));
|
||||
}
|
||||
|
||||
public void moveAbsolute(Vector3f position, Vector3f rotation) {
|
||||
if (position.getX() == 0 && position.getX() == 0 && position.getX() == 0 && rotation.getX() == 0 && rotation.getY() == 0)
|
||||
if (position.getX() == 0 && position.getY() == 0 && position.getZ() == 0 && rotation.getX() == 0 && rotation.getY() == 0)
|
||||
return;
|
||||
|
||||
this.position = position;
|
||||
|
@ -26,9 +26,7 @@
|
||||
package org.geysermc.connector.entity;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.data.game.PlayerListEntry;
|
||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
||||
import com.nukkitx.protocol.bedrock.data.EntityDataDictionary;
|
||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
||||
import com.nukkitx.protocol.bedrock.data.ItemData;
|
||||
import com.nukkitx.protocol.bedrock.packet.AddPlayerPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket;
|
||||
@ -37,14 +35,12 @@ import lombok.Setter;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Getter @Setter
|
||||
public class PlayerEntity extends Entity {
|
||||
|
||||
private UUID uuid;
|
||||
private String username;
|
||||
|
||||
private ItemData hand;
|
||||
|
||||
@ -53,10 +49,11 @@ public class PlayerEntity extends Entity {
|
||||
private ItemData leggings;
|
||||
private ItemData boots;
|
||||
|
||||
public PlayerEntity(UUID uuid, long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
||||
public PlayerEntity(GameProfile gameProfile, long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
||||
|
||||
this.uuid = uuid;
|
||||
uuid = gameProfile.getId();
|
||||
username = gameProfile.getName();
|
||||
}
|
||||
|
||||
// TODO: Break this into an EquippableEntity class
|
||||
@ -77,10 +74,10 @@ public class PlayerEntity extends Entity {
|
||||
@Override
|
||||
public void spawnEntity(GeyserSession session) {
|
||||
AddPlayerPacket addPlayerPacket = new AddPlayerPacket();
|
||||
addPlayerPacket.setUniqueEntityId(geyserId);
|
||||
addPlayerPacket.setRuntimeEntityId(geyserId);
|
||||
addPlayerPacket.setUniqueEntityId(geyserId);
|
||||
addPlayerPacket.setUuid(uuid);
|
||||
addPlayerPacket.setUsername("Player" + new Random().nextInt(1000) + 1); // TODO: Cache player list values and set it here
|
||||
addPlayerPacket.setUsername(username);
|
||||
addPlayerPacket.setPlatformChatId("");
|
||||
addPlayerPacket.setPosition(position);
|
||||
addPlayerPacket.setMotion(motion);
|
||||
@ -92,8 +89,7 @@ public class PlayerEntity extends Entity {
|
||||
addPlayerPacket.setWorldFlags(0);
|
||||
addPlayerPacket.setPlayerPermission(0);
|
||||
addPlayerPacket.setCustomFlags(0);
|
||||
addPlayerPacket.setDeviceId("WIN10"); // TODO: Find this value
|
||||
addPlayerPacket.getMetadata().putAll(getMetadata());
|
||||
addPlayerPacket.setDeviceId("WIN10");
|
||||
|
||||
valid = true;
|
||||
session.getUpstream().sendPacket(addPlayerPacket);
|
||||
|
@ -29,6 +29,7 @@ import com.flowpowered.math.vector.Vector2f;
|
||||
import com.flowpowered.math.vector.Vector2i;
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
||||
import com.github.steveice10.mc.auth.exception.request.RequestException;
|
||||
import com.github.steveice10.mc.protocol.MinecraftProtocol;
|
||||
import com.github.steveice10.packetlib.Client;
|
||||
@ -103,7 +104,7 @@ public class GeyserSession implements Player {
|
||||
this.scoreboardCache = new ScoreboardCache(this);
|
||||
this.windowCache = new WindowCache(this);
|
||||
|
||||
this.playerEntity = new PlayerEntity(UUID.randomUUID(), 1, 1, EntityType.PLAYER, new Vector3f(0, 0, 0), new Vector3f(0, 0, 0), new Vector3f(0, 0, 0));
|
||||
this.playerEntity = new PlayerEntity(new GameProfile(UUID.randomUUID(), "Unknown"), 1, 1, EntityType.PLAYER, new Vector3f(0, 0, 0), new Vector3f(0, 0, 0), new Vector3f(0, 0, 0));
|
||||
this.inventory = new PlayerInventory();
|
||||
|
||||
this.javaPacketCache = new DataCache<Packet>();
|
||||
@ -152,6 +153,7 @@ public class GeyserSession implements Player {
|
||||
loggedIn = true;
|
||||
connector.getLogger().info(authenticationData.getName() + " (logged in as: " + protocol.getProfile().getName() + ")" + " has connected to remote java server on address " + remoteServer.getAddress());
|
||||
playerEntity.setUuid(protocol.getProfile().getId());
|
||||
playerEntity.setUsername(protocol.getProfile().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -27,10 +27,12 @@ package org.geysermc.connector.network.session.cache;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.entity.PlayerEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
@ -38,13 +40,12 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
* for that player (e.g. seeing vanished players from /vanish)
|
||||
*/
|
||||
public class EntityCache {
|
||||
|
||||
private GeyserSession session;
|
||||
|
||||
@Getter
|
||||
private Map<Long, Entity> entities = new HashMap<Long, Entity>();
|
||||
|
||||
private Map<Long, Long> entityIdTranslations = new HashMap<Long, Long>();
|
||||
private Map<Long, Entity> entities = new HashMap<>();
|
||||
private Map<Long, Long> entityIdTranslations = new HashMap<>();
|
||||
public Map<UUID, PlayerEntity> playerEntities = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
private AtomicLong nextEntityId = new AtomicLong(2L);
|
||||
@ -61,10 +62,9 @@ public class EntityCache {
|
||||
}
|
||||
|
||||
public void removeEntity(Entity entity) {
|
||||
if (entity == null)
|
||||
return;
|
||||
if (entity == null) return;
|
||||
|
||||
entityIdTranslations.remove(entity.getGeyserId());
|
||||
entityIdTranslations.remove(entity.getEntityId());
|
||||
entity.despawnEntity(session);
|
||||
}
|
||||
|
||||
|
@ -26,29 +26,12 @@
|
||||
package org.geysermc.connector.network.translators;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.window.WindowType;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerChatPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerTitlePacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityAnimationPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityDestroyPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityHeadLookPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityMetadataPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPositionPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPositionRotationPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPropertiesPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityRotationPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityTeleportPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityVelocityPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.*;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.*;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerHealthPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerPositionRotationPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerSetExperiencePacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnExpOrbPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnGlobalEntityPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnMobPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnObjectPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnPaintingPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnPlayerPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.*;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerDisplayScoreboardPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerScoreboardObjectivePacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerUpdateScorePacket;
|
||||
@ -60,19 +43,9 @@ import com.nukkitx.nbt.CompoundTagBuilder;
|
||||
import com.nukkitx.nbt.NbtUtils;
|
||||
import com.nukkitx.nbt.stream.NBTOutputStream;
|
||||
import com.nukkitx.nbt.tag.CompoundTag;
|
||||
import com.nukkitx.protocol.bedrock.packet.AnimatePacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.MobEquipmentPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.PlayerActionPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.TextPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.*;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.connector.network.translators.bedrock.BedrockActionTranslator;
|
||||
import org.geysermc.connector.network.translators.bedrock.BedrockAnimateTranslator;
|
||||
import org.geysermc.connector.network.translators.bedrock.BedrockCommandRequestTranslator;
|
||||
import org.geysermc.connector.network.translators.bedrock.BedrockMobEquipmentTranslator;
|
||||
import org.geysermc.connector.network.translators.bedrock.BedrockMovePlayerTranslator;
|
||||
import org.geysermc.connector.network.translators.bedrock.BedrockTextTranslator;
|
||||
import org.geysermc.connector.network.translators.bedrock.*;
|
||||
import org.geysermc.connector.network.translators.block.BlockTranslator;
|
||||
import org.geysermc.connector.network.translators.inventory.GenericInventoryTranslator;
|
||||
import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
|
||||
@ -80,33 +53,19 @@ import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||
import org.geysermc.connector.network.translators.java.JavaChatTranslator;
|
||||
import org.geysermc.connector.network.translators.java.JavaJoinGameTranslator;
|
||||
import org.geysermc.connector.network.translators.java.JavaRespawnTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.JavaEntityAnimationTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.JavaEntityDestroyTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.JavaEntityHeadLookTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.JavaEntityMetadataTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.JavaEntityPositionRotationTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.JavaEntityPositionTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.JavaEntityPropertiesTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.JavaEntityRotationTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.JavaEntityTeleportTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.JavaEntityVelocityTranslator;
|
||||
import org.geysermc.connector.network.translators.java.JavaTitleTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.*;
|
||||
import org.geysermc.connector.network.translators.java.entity.player.JavaPlayerHealthTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.player.JavaPlayerPositionRotationTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.player.JavaPlayerSetExperienceTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.spawn.JavaSpawnExpOrbTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.spawn.JavaSpawnGlobalEntityTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.spawn.JavaSpawnMobTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.spawn.JavaSpawnObjectTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.spawn.JavaSpawnPaintingTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.spawn.JavaSpawnPlayerTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.spawn.*;
|
||||
import org.geysermc.connector.network.translators.java.scoreboard.JavaDisplayScoreboardTranslator;
|
||||
import org.geysermc.connector.network.translators.java.scoreboard.JavaScoreboardObjectiveTranslator;
|
||||
import org.geysermc.connector.network.translators.java.scoreboard.JavaUpdateScoreTranslator;
|
||||
import org.geysermc.connector.network.translators.java.world.*;
|
||||
import org.geysermc.connector.network.translators.java.window.JavaOpenWindowTranslator;
|
||||
import org.geysermc.connector.network.translators.java.window.JavaSetSlotTranslator;
|
||||
import org.geysermc.connector.network.translators.java.JavaTitleTranslator;
|
||||
import org.geysermc.connector.network.translators.java.window.JavaWindowItemsTranslator;
|
||||
import org.geysermc.connector.network.translators.java.world.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@ -165,6 +124,7 @@ public class TranslatorsInit {
|
||||
Registry.registerJava(ServerSpawnObjectPacket.class, new JavaSpawnObjectTranslator());
|
||||
Registry.registerJava(ServerSpawnPaintingPacket.class, new JavaSpawnPaintingTranslator());
|
||||
Registry.registerJava(ServerSpawnPlayerPacket.class, new JavaSpawnPlayerTranslator());
|
||||
Registry.registerJava(ServerPlayerListEntryPacket.class, new JavaPlayerListEntryTranslator());
|
||||
|
||||
Registry.registerJava(ServerPlayerPositionRotationPacket.class, new JavaPlayerPositionRotationTranslator());
|
||||
Registry.registerJava(ServerPlayerSetExperiencePacket.class, new JavaPlayerSetExperienceTranslator());
|
||||
|
@ -0,0 +1,59 @@
|
||||
package org.geysermc.connector.network.translators.java.entity.spawn;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.data.game.PlayerListEntry;
|
||||
import com.github.steveice10.mc.protocol.data.game.PlayerListEntryAction;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerPlayerListEntryPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.PlayerListPacket;
|
||||
import org.geysermc.connector.entity.PlayerEntity;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.utils.ProvidedSkin;
|
||||
import org.geysermc.connector.utils.ProvidedSkinData;
|
||||
|
||||
public class JavaPlayerListEntryTranslator extends PacketTranslator<ServerPlayerListEntryPacket> {
|
||||
private static ProvidedSkinData providedSkinData = ProvidedSkinData.getProvidedSkin("bedrock/skin/model_steve.json");
|
||||
private static byte[] providedSkin = new ProvidedSkin("bedrock/skin/skin_steve.png").getSkin();
|
||||
|
||||
@Override
|
||||
public void translate(ServerPlayerListEntryPacket packet, GeyserSession session) {
|
||||
if (packet.getAction() != PlayerListEntryAction.ADD_PLAYER && packet.getAction() != PlayerListEntryAction.REMOVE_PLAYER) return;
|
||||
|
||||
PlayerListPacket translate = new PlayerListPacket();
|
||||
translate.setType(packet.getAction() == PlayerListEntryAction.ADD_PLAYER ? PlayerListPacket.Type.ADD : PlayerListPacket.Type.REMOVE);
|
||||
|
||||
for (PlayerListEntry entry : packet.getEntries()) {
|
||||
PlayerListPacket.Entry entry1 = new PlayerListPacket.Entry(entry.getProfile().getId());
|
||||
|
||||
if (packet.getAction() == PlayerListEntryAction.ADD_PLAYER) {
|
||||
long geyserId = session.getEntityCache().getNextEntityId().incrementAndGet();
|
||||
|
||||
session.getEntityCache().playerEntities.put(entry.getProfile().getId(), new PlayerEntity(
|
||||
entry.getProfile(),
|
||||
-1,
|
||||
geyserId,
|
||||
EntityType.PLAYER,
|
||||
Vector3f.ZERO,
|
||||
Vector3f.ZERO,
|
||||
Vector3f.ZERO
|
||||
));
|
||||
|
||||
entry1.setName(entry.getProfile().getName());
|
||||
entry1.setEntityId(geyserId);
|
||||
entry1.setSkinId(providedSkinData.getSkinId());
|
||||
entry1.setSkinData(providedSkin);
|
||||
entry1.setCapeData(new byte[0]);
|
||||
entry1.setGeometryName(providedSkinData.getGeometryId());
|
||||
entry1.setGeometryData(providedSkinData.getGeometryDataEncoded());
|
||||
entry1.setXuid("");
|
||||
entry1.setPlatformChatId("WIN10");
|
||||
} else {
|
||||
session.getEntityCache().playerEntities.remove(entry.getProfile().getId());
|
||||
}
|
||||
translate.getEntries().add(entry1);
|
||||
}
|
||||
|
||||
session.getUpstream().sendPacket(translate);
|
||||
}
|
||||
}
|
@ -27,9 +27,8 @@ package org.geysermc.connector.network.translators.java.entity.spawn;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnPlayerPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.api.Geyser;
|
||||
import org.geysermc.connector.entity.PlayerEntity;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
|
||||
@ -38,12 +37,17 @@ public class JavaSpawnPlayerTranslator extends PacketTranslator<ServerSpawnPlaye
|
||||
@Override
|
||||
public void translate(ServerSpawnPlayerPacket packet, GeyserSession session) {
|
||||
Vector3f position = new Vector3f(packet.getX(), packet.getY(), packet.getZ());
|
||||
Vector3f rotation = new Vector3f(packet.getPitch(), packet.getYaw(), 0);
|
||||
Entity entity = new PlayerEntity(packet.getUUID(), packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
|
||||
EntityType.PLAYER, position, new Vector3f(0, 0, 0), rotation);
|
||||
Vector3f rotation = new Vector3f(packet.getPitch(), packet.getYaw(), packet.getYaw());
|
||||
|
||||
if (entity == null)
|
||||
PlayerEntity entity = session.getEntityCache().playerEntities.get(packet.getUUID());
|
||||
if (entity == null) {
|
||||
Geyser.getLogger().error("Haven't received PlayerListEntry packet before spawning player! We ignore the player");
|
||||
return;
|
||||
}
|
||||
|
||||
entity.setEntityId(packet.getEntityId());
|
||||
entity.setPosition(position);
|
||||
entity.setRotation(rotation);
|
||||
|
||||
session.getEntityCache().spawnEntity(entity);
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
package org.geysermc.connector.utils;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ProvidedSkin {
|
||||
@Getter private byte[] skin;
|
||||
|
||||
public ProvidedSkin(String internalUrl) {
|
||||
try {
|
||||
BufferedImage image = ImageIO.read(ProvidedSkin.class.getClassLoader().getResource(internalUrl));
|
||||
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(image.getWidth() * 4 + image.getHeight() * 4);
|
||||
try {
|
||||
for (int y = 0; y < image.getHeight(); y++) {
|
||||
for (int x = 0; x < image.getWidth(); x++) {
|
||||
int rgba = image.getRGB(x, y);
|
||||
outputStream.write((rgba >> 16) & 0xFF);
|
||||
outputStream.write((rgba >> 8) & 0xFF);
|
||||
outputStream.write(rgba & 0xFF);
|
||||
outputStream.write((rgba >> 24) & 0xFF);
|
||||
}
|
||||
}
|
||||
image.flush();
|
||||
skin = outputStream.toByteArray();
|
||||
} finally {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package org.geysermc.connector.utils;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.codec.Charsets;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
@Getter
|
||||
public class ProvidedSkinData {
|
||||
private static final Gson gson = new GsonBuilder().create();
|
||||
private String skinId;
|
||||
private String skinName;
|
||||
private String geometryId;
|
||||
private ObjectNode geometryData;
|
||||
|
||||
public static ProvidedSkinData getProvidedSkin(String skinName) {
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper(new JsonFactory());
|
||||
return objectMapper.readValue(ProvidedSkinData.class.getClassLoader().getResource(skinName), ProvidedSkinData.class);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getGeometryDataEncoded() {
|
||||
try {
|
||||
return new String(Base64.getEncoder().encode(geometryData.toString().getBytes(Charsets.UTF_8)));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
383
connector/src/main/resources/bedrock/skin/model_steve.json
Normale Datei
383
connector/src/main/resources/bedrock/skin/model_steve.json
Normale Datei
@ -0,0 +1,383 @@
|
||||
{
|
||||
"skinId" : "c18e65aa-7b21-4637-9b63-8ad63622ef01_Custom",
|
||||
"skinName" : "skin.Standard.Custom",
|
||||
"geometryId" : "geometry.humanoid.custom",
|
||||
"geometryData" :
|
||||
{
|
||||
"geometry.humanoid": {
|
||||
"bones": [
|
||||
{
|
||||
"name": "body",
|
||||
"pivot": [ 0.0, 24.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -4.0, 12.0, -2.0 ],
|
||||
"size": [ 8, 12, 4 ],
|
||||
"uv": [ 16, 16 ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "waist",
|
||||
"neverRender": true,
|
||||
"pivot": [ 0.0, 12.0, 0.0 ]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "head",
|
||||
"pivot": [ 0.0, 24.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -4.0, 24.0, -4.0 ],
|
||||
"size": [ 8, 8, 8 ],
|
||||
"uv": [ 0, 0 ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "hat",
|
||||
"pivot": [ 0.0, 24.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -4.0, 24.0, -4.0 ],
|
||||
"size": [ 8, 8, 8 ],
|
||||
"uv": [ 32, 0 ],
|
||||
"inflate": 0.5
|
||||
}
|
||||
],
|
||||
"neverRender": true
|
||||
},
|
||||
|
||||
{
|
||||
"name": "rightArm",
|
||||
"pivot": [ -5.0, 22.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -8.0, 12.0, -2.0 ],
|
||||
"size": [ 4, 12, 4 ],
|
||||
"uv": [ 40, 16 ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "leftArm",
|
||||
"pivot": [ 5.0, 22.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ 4.0, 12.0, -2.0 ],
|
||||
"size": [ 4, 12, 4 ],
|
||||
"uv": [ 40, 16 ]
|
||||
}
|
||||
],
|
||||
"mirror": true
|
||||
},
|
||||
|
||||
{
|
||||
"name": "rightLeg",
|
||||
"pivot": [ -1.9, 12.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -3.9, 0.0, -2.0 ],
|
||||
"size": [ 4, 12, 4 ],
|
||||
"uv": [ 0, 16 ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "leftLeg",
|
||||
"pivot": [ 1.9, 12.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -0.1, 0.0, -2.0 ],
|
||||
"size": [ 4, 12, 4 ],
|
||||
"uv": [ 0, 16 ]
|
||||
}
|
||||
],
|
||||
"mirror": true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"geometry.cape": {
|
||||
"texturewidth": 64,
|
||||
"textureheight": 32,
|
||||
|
||||
"bones": [
|
||||
{
|
||||
"name": "cape",
|
||||
"pivot": [ 0.0, 24.0, -3.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -5.0, 8.0, -3.0 ],
|
||||
"size": [ 10, 16, 1 ],
|
||||
"uv": [ 0, 0 ]
|
||||
}
|
||||
],
|
||||
"material": "alpha"
|
||||
}
|
||||
]
|
||||
},
|
||||
"geometry.humanoid.custom:geometry.humanoid": {
|
||||
"bones": [
|
||||
{
|
||||
"name": "hat",
|
||||
"neverRender": false,
|
||||
"material": "alpha",
|
||||
"pivot": [ 0.0, 24.0, 0.0 ]
|
||||
},
|
||||
{
|
||||
"name": "leftArm",
|
||||
"reset": true,
|
||||
"mirror": false,
|
||||
"pivot": [ 5.0, 22.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ 4.0, 12.0, -2.0 ],
|
||||
"size": [ 4, 12, 4 ],
|
||||
"uv": [ 32, 48 ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "rightArm",
|
||||
"reset": true,
|
||||
"pivot": [ -5.0, 22.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -8.0, 12.0, -2.0 ],
|
||||
"size": [ 4, 12, 4 ],
|
||||
"uv": [ 40, 16 ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "rightItem",
|
||||
"pivot": [ -6, 15, 1 ],
|
||||
"neverRender": true,
|
||||
"parent": "rightArm"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "leftSleeve",
|
||||
"pivot": [ 5.0, 22.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ 4.0, 12.0, -2.0 ],
|
||||
"size": [ 4, 12, 4 ],
|
||||
"uv": [ 48, 48 ],
|
||||
"inflate": 0.25
|
||||
}
|
||||
],
|
||||
"material": "alpha"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "rightSleeve",
|
||||
"pivot": [ -5.0, 22.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -8.0, 12.0, -2.0 ],
|
||||
"size": [ 4, 12, 4 ],
|
||||
"uv": [ 40, 32 ],
|
||||
"inflate": 0.25
|
||||
}
|
||||
],
|
||||
"material": "alpha"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "leftLeg",
|
||||
"reset": true,
|
||||
"mirror": false,
|
||||
"pivot": [ 1.9, 12.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -0.1, 0.0, -2.0 ],
|
||||
"size": [ 4, 12, 4 ],
|
||||
"uv": [ 16, 48 ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "leftPants",
|
||||
"pivot": [ 1.9, 12.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -0.1, 0.0, -2.0 ],
|
||||
"size": [ 4, 12, 4 ],
|
||||
"uv": [ 0, 48 ],
|
||||
"inflate": 0.25
|
||||
}
|
||||
],
|
||||
"pos": [ 1.9, 12, 0 ],
|
||||
"material": "alpha"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "rightPants",
|
||||
"pivot": [ -1.9, 12.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -3.9, 0.0, -2.0 ],
|
||||
"size": [ 4, 12, 4 ],
|
||||
"uv": [ 0, 32 ],
|
||||
"inflate": 0.25
|
||||
}
|
||||
],
|
||||
"pos": [ -1.9, 12, 0 ],
|
||||
"material": "alpha"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "jacket",
|
||||
"pivot": [ 0.0, 24.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -4.0, 12.0, -2.0 ],
|
||||
"size": [ 8, 12, 4 ],
|
||||
"uv": [ 16, 32 ],
|
||||
"inflate": 0.25
|
||||
}
|
||||
],
|
||||
"material": "alpha"
|
||||
}
|
||||
]
|
||||
},
|
||||
"geometry.humanoid.customSlim:geometry.humanoid": {
|
||||
|
||||
"bones": [
|
||||
{
|
||||
"name": "hat",
|
||||
"neverRender": false,
|
||||
"material": "alpha"
|
||||
},
|
||||
{
|
||||
"name": "leftArm",
|
||||
"reset": true,
|
||||
"mirror": false,
|
||||
"pivot": [ 5.0, 21.5, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ 4.0, 11.5, -2.0 ],
|
||||
"size": [ 3, 12, 4 ],
|
||||
"uv": [ 32, 48 ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "rightArm",
|
||||
"reset": true,
|
||||
"pivot": [ -5.0, 21.5, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -7.0, 11.5, -2.0 ],
|
||||
"size": [ 3, 12, 4 ],
|
||||
"uv": [ 40, 16 ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"pivot": [ -6, 14.5, 1 ],
|
||||
"neverRender": true,
|
||||
"name": "rightItem",
|
||||
"parent": "rightArm"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "leftSleeve",
|
||||
"pivot": [ 5.0, 21.5, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ 4.0, 11.5, -2.0 ],
|
||||
"size": [ 3, 12, 4 ],
|
||||
"uv": [ 48, 48 ],
|
||||
"inflate": 0.25
|
||||
}
|
||||
],
|
||||
"material": "alpha"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "rightSleeve",
|
||||
"pivot": [ -5.0, 21.5, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -7.0, 11.5, -2.0 ],
|
||||
"size": [ 3, 12, 4 ],
|
||||
"uv": [ 40, 32 ],
|
||||
"inflate": 0.25
|
||||
}
|
||||
],
|
||||
"material": "alpha"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "leftLeg",
|
||||
"reset": true,
|
||||
"mirror": false,
|
||||
"pivot": [ 1.9, 12.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -0.1, 0.0, -2.0 ],
|
||||
"size": [ 4, 12, 4 ],
|
||||
"uv": [ 16, 48 ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "leftPants",
|
||||
"pivot": [ 1.9, 12.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -0.1, 0.0, -2.0 ],
|
||||
"size": [ 4, 12, 4 ],
|
||||
"uv": [ 0, 48 ],
|
||||
"inflate": 0.25
|
||||
}
|
||||
],
|
||||
"material": "alpha"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "rightPants",
|
||||
"pivot": [ -1.9, 12.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -3.9, 0.0, -2.0 ],
|
||||
"size": [ 4, 12, 4 ],
|
||||
"uv": [ 0, 32 ],
|
||||
"inflate": 0.25
|
||||
}
|
||||
],
|
||||
"material": "alpha"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "jacket",
|
||||
"pivot": [ 0.0, 24.0, 0.0 ],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [ -4.0, 12.0, -2.0 ],
|
||||
"size": [ 8, 12, 4 ],
|
||||
"uv": [ 16, 32 ],
|
||||
"inflate": 0.25
|
||||
}
|
||||
],
|
||||
"material": "alpha"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
BIN
connector/src/main/resources/bedrock/skin/skin_steve.png
Normale Datei
BIN
connector/src/main/resources/bedrock/skin/skin_steve.png
Normale Datei
Binäre Datei nicht angezeigt.
Nachher Breite: | Höhe: | Größe: 2.1 KiB |
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren