mirror of
https://github.com/GeyserExtensionists/GeyserUtils.git
synced 2025-12-19 14:59:18 +00:00
General cleanup & black particles fix.
This commit is contained in:
@@ -72,30 +72,20 @@ import java.util.concurrent.TimeUnit;
|
||||
public class GeyserUtils implements Extension {
|
||||
|
||||
|
||||
public static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
|
||||
private static final Map<String, List<Map.Entry<String, Class<?>>>> properties = new HashMap<>();
|
||||
@Getter
|
||||
public static PacketManager packetManager = new PacketManager();
|
||||
|
||||
public static List<String> REGISTERED_ENTITIES = new ArrayList<>();
|
||||
private static List<String> ENTITIES_WAIT_FOR_LOAD = new ArrayList<>();
|
||||
|
||||
|
||||
public static boolean GEYSER_LOADED = false;
|
||||
|
||||
@Getter
|
||||
public static Map<String, SkinData> LOADED_SKIN_DATA = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
public static Map<String, EntityDefinition> LOADED_ENTITY_DEFINITIONS = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
public static Map<GeyserConnection, Cache<Integer, String>> CUSTOM_ENTITIES = new ConcurrentHashMap<>();
|
||||
|
||||
static Cape EMPTY_CAPE = new Cape("", "no-cape", new byte[0], true);
|
||||
|
||||
public static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
|
||||
|
||||
private static final Map<String, List<Map.Entry<String, Class<?>>>> properties = new HashMap<>();
|
||||
|
||||
private static List<String> ENTITIES_WAIT_FOR_LOAD = new ArrayList<>();
|
||||
@Getter
|
||||
private static GeyserUtils instance;
|
||||
|
||||
@@ -103,25 +93,6 @@ public class GeyserUtils implements Extension {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEnable(GeyserPostInitializeEvent event) {
|
||||
Registries.BEDROCK_PACKET_TRANSLATORS.register(NpcRequestPacket.class, new NPCFormResponseTranslator());
|
||||
loadSkins();
|
||||
ReflectionUtils.init();
|
||||
CameraPreset.load();
|
||||
|
||||
replaceTranslator();
|
||||
GEYSER_LOADED = true;
|
||||
for (String registeredEntity : REGISTERED_ENTITIES) {
|
||||
registerEntityToGeyser(registeredEntity);
|
||||
}
|
||||
for (String id : ENTITIES_WAIT_FOR_LOAD) {
|
||||
registerPropertiesForGeyser(id);
|
||||
}
|
||||
logger().info("Defined " + LOADED_ENTITY_DEFINITIONS.size() + " entities");
|
||||
MountFix.start();
|
||||
}
|
||||
|
||||
// the static here is crazy ;(
|
||||
private static GeyserEntityProperties getProperties(String id) {
|
||||
if (!properties.containsKey(id)) return null;
|
||||
@@ -162,7 +133,7 @@ public class GeyserUtils implements Extension {
|
||||
ENTITIES_WAIT_FOR_LOAD.add(entityId);
|
||||
}
|
||||
|
||||
public static void registerPropertiesForGeyser(String entityId) {
|
||||
public static void registerPropertiesForGeyser(String entityId) {
|
||||
|
||||
GeyserEntityProperties entityProperties = getProperties(entityId);
|
||||
if (entityProperties == null) return;
|
||||
@@ -200,6 +171,7 @@ public class GeyserUtils implements Extension {
|
||||
}
|
||||
REGISTERED_ENTITIES.add(id);
|
||||
}
|
||||
|
||||
public static void registerEntityToGeyser(String id) {
|
||||
NbtMap registry = Registries.BEDROCK_ENTITY_IDENTIFIERS.get();
|
||||
List<NbtMap> idList = new ArrayList<>(registry.getList("idlist", NbtType.COMPOUND));
|
||||
@@ -221,266 +193,6 @@ public class GeyserUtils implements Extension {
|
||||
LOADED_ENTITY_DEFINITIONS.put(id, def);
|
||||
}
|
||||
|
||||
|
||||
public void replaceTranslator() {
|
||||
Registries.JAVA_PACKET_TRANSLATORS
|
||||
.register(ClientboundAddEntityPacket.class, new JavaAddEntityTranslatorReplace());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onLoadCommand(GeyserDefineCommandsEvent event) {
|
||||
|
||||
}
|
||||
|
||||
public void loadSkins() {
|
||||
LOADED_SKIN_DATA.clear();
|
||||
File folder = this.dataFolder().resolve("skins").toFile();
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
}
|
||||
for (File file : folder.listFiles()) {
|
||||
if (file.isDirectory()) {
|
||||
File textureFile = null;
|
||||
File geometryFile = null;
|
||||
|
||||
for (File folderFile : file.listFiles()) {
|
||||
if (folderFile.getName().endsWith(".png")) {
|
||||
textureFile = folderFile;
|
||||
}
|
||||
if (folderFile.getName().endsWith(".json")) {
|
||||
geometryFile = folderFile;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
loadSkin(file.getName(), geometryFile, textureFile);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loadSkin(String skinId, File geometryFile, File textureFile) {
|
||||
try {
|
||||
Skin skin = new Skin(skinId, Files.readAllBytes(textureFile.toPath()), false);
|
||||
|
||||
String geoId = "";
|
||||
JsonElement json = new JsonParser().parse(new FileReader(geometryFile));
|
||||
for (JsonElement element : json.getAsJsonObject().get("minecraft:geometry").getAsJsonArray()) {
|
||||
if (element.isJsonObject() && element.getAsJsonObject().has("description")) {
|
||||
geoId = element.getAsJsonObject().get("description").getAsJsonObject().get("identifier").getAsString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
String geoName = "{\"geometry\" :{\"default\" :\"" + geoId + "\"}}";
|
||||
SkinGeometry geometry = new SkinGeometry(geoName, Files.readString(geometryFile.toPath()));
|
||||
LOADED_SKIN_DATA.put(skinId, new SkinData(skin, getEmptyCapeData(), geometry));
|
||||
this.logger().info("Loaded skin: " + skinId + "| geo:" + geoName);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSessionJoin(SessionLoginEvent event) {
|
||||
CUSTOM_ENTITIES.put(event.connection(), CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.SECONDS).build());
|
||||
if (event.connection() instanceof GeyserSession session) {
|
||||
registerPacketListener(session);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSessionQuit(SessionDisconnectEvent event) {
|
||||
CUSTOM_ENTITIES.remove(event.connection());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void registerPacketListener(GeyserSession session) {
|
||||
|
||||
scheduler.schedule(() -> {
|
||||
if (session.getDownstream() == null) {
|
||||
registerPacketListener(session);
|
||||
return;
|
||||
}
|
||||
|
||||
session.getDownstream().getSession().addListener(new SessionAdapter() {
|
||||
|
||||
@Override
|
||||
public void packetSending(PacketSendingEvent event) {
|
||||
Packet packet = event.getPacket();
|
||||
if (packet instanceof ServerboundCustomPayloadPacket payloadPacket) {
|
||||
if (ReflectionUtils.getChannel(payloadPacket).toString().equals("minecraft:register")) {
|
||||
String channels = new String(payloadPacket.getData(), StandardCharsets.UTF_8);
|
||||
channels = channels + "\0" + GeyserUtilsChannels.MAIN;
|
||||
event.setPacket(ReflectionUtils.buildServerboundPayloadPacket("minecraft:register", channels.getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void packetReceived(Session tcpSession, Packet packet) {
|
||||
if (packet instanceof ClientboundCustomPayloadPacket payloadPacket) {
|
||||
if (ReflectionUtils.getChannel(payloadPacket).toString().equals(GeyserUtilsChannels.MAIN)) {
|
||||
CustomPayloadPacket customPacket = packetManager.decodePacket(payloadPacket.getData());
|
||||
handleCustomPacket(session, customPacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 80, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void handleCustomPacket(GeyserSession session, CustomPayloadPacket customPacket) {
|
||||
if (customPacket instanceof BundlePacket bundlePacket) {
|
||||
bundlePacket.getPackets().forEach(p -> handleCustomPacket(session, p));
|
||||
}
|
||||
|
||||
else if (customPacket instanceof CameraShakeCustomPayloadPacket cameraShakePacket) {
|
||||
session.camera().shakeCamera(cameraShakePacket.getIntensity(), cameraShakePacket.getDuration(), CameraShake.values()[cameraShakePacket.getType()]);
|
||||
} else if (customPacket instanceof NpcDialogueFormDataCustomPayloadPacket formData) {
|
||||
|
||||
if (formData.action().equals("CLOSE")) {
|
||||
NpcDialogueForm openForm = NpcDialogueForms.getOpenNpcDialogueForms(session);
|
||||
if (openForm != null) {
|
||||
openForm.close(session);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
NpcDialogueForm form = new NpcDialogueForm();
|
||||
form.title(formData.title())
|
||||
.dialogue(formData.dialogue())
|
||||
.bindEntity(session.getEntityCache().getEntityByJavaId(formData.bindEntity()))
|
||||
.hasNextForm(formData.hasNextForm());
|
||||
|
||||
if (formData.skinData() != null) {
|
||||
form.skinData(formData.skinData());
|
||||
}
|
||||
|
||||
|
||||
List<Button> buttons = new ArrayList<>();
|
||||
|
||||
if (formData.buttons() != null) {
|
||||
|
||||
int i = 0;
|
||||
for (NpcDialogueButton button : formData.buttons()) {
|
||||
|
||||
|
||||
int finalI = i;
|
||||
buttons.add(new Button(button.text(), button.commands(),
|
||||
button.mode(), () -> {
|
||||
if (button.mode() == NpcDialogueButton.ButtonMode.BUTTON_MODE) {
|
||||
session.sendDownstreamPacket(ReflectionUtils.buildServerboundPayloadPacket(GeyserUtilsChannels.MAIN, packetManager.encodePacket(new NpcFormResponseCustomPayloadPacket(formData.formId(), finalI))));
|
||||
}
|
||||
}, button.hasNextForm()));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
form.closeHandler(() -> session.sendDownstreamPacket(ReflectionUtils.buildServerboundPayloadPacket(GeyserUtilsChannels.MAIN, packetManager.encodePacket(new NpcFormResponseCustomPayloadPacket(formData.formId(), -1)))));
|
||||
form.buttons(buttons);
|
||||
|
||||
form.createAndSend(session);
|
||||
|
||||
} else if (customPacket instanceof AnimateEntityCustomPayloadPacket animateEntityCustomPayloadPacket) {
|
||||
AnimateEntityPacket animateEntityPacket = getAnimateEntityPacket(animateEntityCustomPayloadPacket);
|
||||
for (int id : animateEntityCustomPayloadPacket.getEntityJavaIds()) {
|
||||
Entity entity = session.getEntityCache().getEntityByJavaId(id);
|
||||
if (entity != null) {
|
||||
try {
|
||||
// because of shaded jar
|
||||
Object object = AnimateEntityPacket.class.getMethod("getRuntimeEntityIds").invoke(animateEntityPacket);
|
||||
object.getClass().getMethod("add", Long.class).invoke(object, entity.getGeyserId());
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
session.sendUpstreamPacket(animateEntityPacket);
|
||||
} else if (customPacket instanceof CustomEntityPacket customEntityPacket) {
|
||||
if (!LOADED_ENTITY_DEFINITIONS.containsKey(customEntityPacket.getIdentifier())) {
|
||||
// System.out.println("Not a vaild entity:" + customEntityPacket.getEntityId());
|
||||
return;
|
||||
}
|
||||
// System.out.println("custom entity:" + customEntityPacket.getEntityId());
|
||||
|
||||
Cache<Integer, String> cache = CUSTOM_ENTITIES.get(session);
|
||||
cache.put(customEntityPacket.getEntityId(), customEntityPacket.getIdentifier());
|
||||
} else if (customPacket instanceof CameraInstructionCustomPayloadPacket cameraInstructionPacket) {
|
||||
if (cameraInstructionPacket.getInstruction() instanceof SetInstruction instruction) {
|
||||
session.camera().sendCameraPosition(Converter.serializeSetInstruction(instruction));
|
||||
session.getCameraData().forceCameraPerspective(Converter.serializeCameraPerspective(instruction.getPreset()));
|
||||
|
||||
} else if (cameraInstructionPacket.getInstruction() instanceof FadeInstruction instruction) {
|
||||
session.camera().sendCameraFade(Converter.serializeFadeInstruction(instruction));
|
||||
} else if (cameraInstructionPacket.getInstruction() instanceof ClearInstruction) {
|
||||
session.camera().clearCameraInstructions();
|
||||
}
|
||||
|
||||
} else if (customPacket instanceof CustomParticleEffectPayloadPacket customParticleEffectPacket) {
|
||||
SpawnParticleEffectPacket spawnParticleEffectPacket = new SpawnParticleEffectPacket();
|
||||
spawnParticleEffectPacket.setDimensionId(DimensionUtils.javaToBedrock(session));
|
||||
spawnParticleEffectPacket.setPosition(Converter.serializePos(customParticleEffectPacket.getPos()));
|
||||
spawnParticleEffectPacket.setIdentifier(customParticleEffectPacket.getParticle().identifier());
|
||||
spawnParticleEffectPacket.setMolangVariablesJson(Optional.ofNullable(customParticleEffectPacket.getParticle().molangVariablesJson()));
|
||||
session.sendUpstreamPacket(spawnParticleEffectPacket);
|
||||
} else if (customPacket instanceof CustomSkinPayloadPacket customSkinPayloadPacket) {
|
||||
if (session.getEntityCache().getEntityByJavaId(customSkinPayloadPacket.getEntityId()) instanceof PlayerEntity player) {
|
||||
SkinData data = LOADED_SKIN_DATA.get(customSkinPayloadPacket.getSkinId());
|
||||
if (data != null) {
|
||||
sendSkinPacket(session, player, data);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (customPacket instanceof CustomEntityDataPacket customEntityDataPacket) {
|
||||
Entity entity = session.getEntityCache().getEntityByJavaId(customEntityDataPacket.getEntityId());
|
||||
if (entity != null) {
|
||||
if (customEntityDataPacket.getHeight() != null) entity.setBoundingBoxHeight(customEntityDataPacket.getHeight());
|
||||
if (customEntityDataPacket.getWidth() != null) entity.setBoundingBoxWidth(customEntityDataPacket.getWidth());
|
||||
if (customEntityDataPacket.getScale() != null) entity.getDirtyMetadata().put(EntityDataTypes.SCALE, customEntityDataPacket.getScale());
|
||||
if (customEntityDataPacket.getColor() != null)
|
||||
entity.getDirtyMetadata().put(EntityDataTypes.COLOR, Byte.parseByte(String.valueOf(getColor(customEntityDataPacket.getColor()))));
|
||||
if (customEntityDataPacket.getVariant() != null)
|
||||
entity.getDirtyMetadata().put(EntityDataTypes.VARIANT, customEntityDataPacket.getVariant());
|
||||
entity.updateBedrockMetadata();
|
||||
}
|
||||
} else if (customPacket instanceof EntityPropertyPacket entityPropertyPacket) {
|
||||
Entity entity = session.getEntityCache().getEntityByJavaId(entityPropertyPacket.getEntityId());
|
||||
if (entity != null) {
|
||||
if (entityPropertyPacket.getIdentifier() == null
|
||||
|| entityPropertyPacket.getValue() == null) return;
|
||||
|
||||
if (entity.getPropertyManager() == null) return;
|
||||
if (entityPropertyPacket.getValue() instanceof Boolean value) {
|
||||
entity.getPropertyManager().add(entityPropertyPacket.getIdentifier(), value);
|
||||
} else if (entityPropertyPacket.getValue() instanceof Integer value) {
|
||||
entity.getPropertyManager().add(entityPropertyPacket.getIdentifier(), value);
|
||||
}
|
||||
entity.updateBedrockEntityProperties();
|
||||
}
|
||||
} else if (customPacket instanceof EntityPropertyRegisterPacket entityPropertyRegisterPacket) {
|
||||
if (entityPropertyRegisterPacket.getIdentifier() == null
|
||||
|| entityPropertyRegisterPacket.getType() == null) return;
|
||||
|
||||
Entity entity = (session.getEntityCache().getEntityByJavaId(entityPropertyRegisterPacket.getEntityId()));
|
||||
if (entity != null) {
|
||||
String def = CUSTOM_ENTITIES.get(session).getIfPresent(entity.getEntityId());
|
||||
if (def == null) return;
|
||||
|
||||
if (!containsProperty(def, entityPropertyRegisterPacket.getIdentifier())) {
|
||||
addProperty(def, entityPropertyRegisterPacket.getIdentifier(), entityPropertyRegisterPacket.getType());
|
||||
|
||||
registerProperties(def);
|
||||
logger().info("DEF PROPERTIES: " + entityPropertyRegisterPacket.getIdentifier());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static AnimateEntityPacket getAnimateEntityPacket(AnimateEntityCustomPayloadPacket animateEntityCustomPayloadPacket) {
|
||||
AnimateEntityPacket animateEntityPacket = new AnimateEntityPacket();
|
||||
@@ -554,12 +266,11 @@ public class GeyserUtils implements Extension {
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
private static SerializedSkin getSkin(String skinId, Skin skin, Cape cape, SkinGeometry geometry) {
|
||||
|
||||
try {
|
||||
ImageData image = ImageData.from(ImageIO.read(new ByteArrayInputStream(skin.skinData())));
|
||||
return SerializedSkin.of(skinId, "", geometry.geometryName(),image , Collections.emptyList(), ImageData.of(cape.capeData()), geometry.geometryData(), "", true, false, false, cape.capeId(), skinId);
|
||||
return SerializedSkin.of(skinId, "", geometry.geometryName(), image, Collections.emptyList(), ImageData.of(cape.capeData()), geometry.geometryData(), "", true, false, false, cape.capeId(), skinId);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -611,5 +322,282 @@ public class GeyserUtils implements Extension {
|
||||
return closestColorIndex;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEnable(GeyserPostInitializeEvent event) {
|
||||
Registries.BEDROCK_PACKET_TRANSLATORS.register(NpcRequestPacket.class, new NPCFormResponseTranslator());
|
||||
loadSkins();
|
||||
ReflectionUtils.init();
|
||||
CameraPreset.load();
|
||||
|
||||
replaceTranslator();
|
||||
GEYSER_LOADED = true;
|
||||
for (String registeredEntity : REGISTERED_ENTITIES) {
|
||||
registerEntityToGeyser(registeredEntity);
|
||||
}
|
||||
for (String id : ENTITIES_WAIT_FOR_LOAD) {
|
||||
registerPropertiesForGeyser(id);
|
||||
}
|
||||
logger().info("Defined " + LOADED_ENTITY_DEFINITIONS.size() + " entities");
|
||||
MountFix.start();
|
||||
}
|
||||
|
||||
public void replaceTranslator() {
|
||||
Registries.JAVA_PACKET_TRANSLATORS
|
||||
.register(ClientboundAddEntityPacket.class, new JavaAddEntityTranslatorReplace());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onLoadCommand(GeyserDefineCommandsEvent event) {
|
||||
|
||||
}
|
||||
|
||||
public void loadSkins() {
|
||||
LOADED_SKIN_DATA.clear();
|
||||
File folder = this.dataFolder().resolve("skins").toFile();
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
}
|
||||
for (File file : folder.listFiles()) {
|
||||
if (file.isDirectory()) {
|
||||
File textureFile = null;
|
||||
File geometryFile = null;
|
||||
|
||||
for (File folderFile : file.listFiles()) {
|
||||
if (folderFile.getName().endsWith(".png")) {
|
||||
textureFile = folderFile;
|
||||
}
|
||||
if (folderFile.getName().endsWith(".json")) {
|
||||
geometryFile = folderFile;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
loadSkin(file.getName(), geometryFile, textureFile);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loadSkin(String skinId, File geometryFile, File textureFile) {
|
||||
try {
|
||||
Skin skin = new Skin(skinId, Files.readAllBytes(textureFile.toPath()), false);
|
||||
|
||||
String geoId = "";
|
||||
JsonElement json = new JsonParser().parse(new FileReader(geometryFile));
|
||||
for (JsonElement element : json.getAsJsonObject().get("minecraft:geometry").getAsJsonArray()) {
|
||||
if (element.isJsonObject() && element.getAsJsonObject().has("description")) {
|
||||
geoId = element.getAsJsonObject().get("description").getAsJsonObject().get("identifier").getAsString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
String geoName = "{\"geometry\" :{\"default\" :\"" + geoId + "\"}}";
|
||||
SkinGeometry geometry = new SkinGeometry(geoName, Files.readString(geometryFile.toPath()));
|
||||
LOADED_SKIN_DATA.put(skinId, new SkinData(skin, getEmptyCapeData(), geometry));
|
||||
this.logger().info("Loaded skin: " + skinId + "| geo:" + geoName);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSessionJoin(SessionLoginEvent event) {
|
||||
CUSTOM_ENTITIES.put(event.connection(), CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.SECONDS).build());
|
||||
if (event.connection() instanceof GeyserSession session) {
|
||||
registerPacketListener(session);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSessionQuit(SessionDisconnectEvent event) {
|
||||
CUSTOM_ENTITIES.remove(event.connection());
|
||||
}
|
||||
|
||||
public void registerPacketListener(GeyserSession session) {
|
||||
|
||||
scheduler.schedule(() -> {
|
||||
if (session.getDownstream() == null) {
|
||||
registerPacketListener(session);
|
||||
return;
|
||||
}
|
||||
|
||||
session.getDownstream().getSession().addListener(new SessionAdapter() {
|
||||
|
||||
@Override
|
||||
public void packetSending(PacketSendingEvent event) {
|
||||
Packet packet = event.getPacket();
|
||||
if (packet instanceof ServerboundCustomPayloadPacket payloadPacket) {
|
||||
if (ReflectionUtils.getChannel(payloadPacket).toString().equals("minecraft:register")) {
|
||||
String channels = new String(payloadPacket.getData(), StandardCharsets.UTF_8);
|
||||
channels = channels + "\0" + GeyserUtilsChannels.MAIN;
|
||||
event.setPacket(ReflectionUtils.buildServerboundPayloadPacket("minecraft:register", channels.getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void packetReceived(Session tcpSession, Packet packet) {
|
||||
if (packet instanceof ClientboundCustomPayloadPacket payloadPacket) {
|
||||
if (ReflectionUtils.getChannel(payloadPacket).toString().equals(GeyserUtilsChannels.MAIN)) {
|
||||
CustomPayloadPacket customPacket = packetManager.decodePacket(payloadPacket.getData());
|
||||
handleCustomPacket(session, customPacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 80, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void handleCustomPacket(GeyserSession session, CustomPayloadPacket customPacket) {
|
||||
if (customPacket instanceof BundlePacket bundlePacket) {
|
||||
bundlePacket.getPackets().forEach(p -> handleCustomPacket(session, p));
|
||||
} else if (customPacket instanceof CameraShakeCustomPayloadPacket cameraShakePacket) {
|
||||
session.camera().shakeCamera(cameraShakePacket.getIntensity(), cameraShakePacket.getDuration(), CameraShake.values()[cameraShakePacket.getType()]);
|
||||
} else if (customPacket instanceof NpcDialogueFormDataCustomPayloadPacket formData) {
|
||||
|
||||
if (formData.action().equals("CLOSE")) {
|
||||
NpcDialogueForm openForm = NpcDialogueForms.getOpenNpcDialogueForms(session);
|
||||
if (openForm != null) {
|
||||
openForm.close(session);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
NpcDialogueForm form = new NpcDialogueForm();
|
||||
form.title(formData.title())
|
||||
.dialogue(formData.dialogue())
|
||||
.bindEntity(session.getEntityCache().getEntityByJavaId(formData.bindEntity()))
|
||||
.hasNextForm(formData.hasNextForm());
|
||||
|
||||
if (formData.skinData() != null) {
|
||||
form.skinData(formData.skinData());
|
||||
}
|
||||
|
||||
|
||||
List<Button> buttons = new ArrayList<>();
|
||||
|
||||
if (formData.buttons() != null) {
|
||||
|
||||
int i = 0;
|
||||
for (NpcDialogueButton button : formData.buttons()) {
|
||||
|
||||
|
||||
int finalI = i;
|
||||
buttons.add(new Button(button.text(), button.commands(),
|
||||
button.mode(), () -> {
|
||||
if (button.mode() == NpcDialogueButton.ButtonMode.BUTTON_MODE) {
|
||||
session.sendDownstreamPacket(ReflectionUtils.buildServerboundPayloadPacket(GeyserUtilsChannels.MAIN, packetManager.encodePacket(new NpcFormResponseCustomPayloadPacket(formData.formId(), finalI))));
|
||||
}
|
||||
}, button.hasNextForm()));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
form.closeHandler(() -> session.sendDownstreamPacket(ReflectionUtils.buildServerboundPayloadPacket(GeyserUtilsChannels.MAIN, packetManager.encodePacket(new NpcFormResponseCustomPayloadPacket(formData.formId(), -1)))));
|
||||
form.buttons(buttons);
|
||||
|
||||
form.createAndSend(session);
|
||||
|
||||
} else if (customPacket instanceof AnimateEntityCustomPayloadPacket animateEntityCustomPayloadPacket) {
|
||||
AnimateEntityPacket animateEntityPacket = getAnimateEntityPacket(animateEntityCustomPayloadPacket);
|
||||
for (int id : animateEntityCustomPayloadPacket.getEntityJavaIds()) {
|
||||
Entity entity = session.getEntityCache().getEntityByJavaId(id);
|
||||
if (entity != null) {
|
||||
try {
|
||||
// because of shaded jar
|
||||
Object object = AnimateEntityPacket.class.getMethod("getRuntimeEntityIds").invoke(animateEntityPacket);
|
||||
object.getClass().getMethod("add", Long.class).invoke(object, entity.getGeyserId());
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
session.sendUpstreamPacket(animateEntityPacket);
|
||||
} else if (customPacket instanceof CustomEntityPacket customEntityPacket) {
|
||||
if (!LOADED_ENTITY_DEFINITIONS.containsKey(customEntityPacket.getIdentifier())) {
|
||||
// System.out.println("Not a vaild entity:" + customEntityPacket.getEntityId());
|
||||
return;
|
||||
}
|
||||
// System.out.println("custom entity:" + customEntityPacket.getEntityId());
|
||||
|
||||
Cache<Integer, String> cache = CUSTOM_ENTITIES.get(session);
|
||||
cache.put(customEntityPacket.getEntityId(), customEntityPacket.getIdentifier());
|
||||
} else if (customPacket instanceof CameraInstructionCustomPayloadPacket cameraInstructionPacket) {
|
||||
if (cameraInstructionPacket.getInstruction() instanceof SetInstruction instruction) {
|
||||
session.camera().sendCameraPosition(Converter.serializeSetInstruction(instruction));
|
||||
session.getCameraData().forceCameraPerspective(Converter.serializeCameraPerspective(instruction.getPreset()));
|
||||
|
||||
} else if (cameraInstructionPacket.getInstruction() instanceof FadeInstruction instruction) {
|
||||
session.camera().sendCameraFade(Converter.serializeFadeInstruction(instruction));
|
||||
} else if (cameraInstructionPacket.getInstruction() instanceof ClearInstruction) {
|
||||
session.camera().clearCameraInstructions();
|
||||
}
|
||||
|
||||
} else if (customPacket instanceof CustomParticleEffectPayloadPacket customParticleEffectPacket) {
|
||||
SpawnParticleEffectPacket spawnParticleEffectPacket = new SpawnParticleEffectPacket();
|
||||
spawnParticleEffectPacket.setDimensionId(DimensionUtils.javaToBedrock(session));
|
||||
spawnParticleEffectPacket.setPosition(Converter.serializePos(customParticleEffectPacket.getPos()));
|
||||
spawnParticleEffectPacket.setIdentifier(customParticleEffectPacket.getParticle().identifier());
|
||||
spawnParticleEffectPacket.setMolangVariablesJson(Optional.ofNullable(customParticleEffectPacket.getParticle().molangVariablesJson()));
|
||||
session.sendUpstreamPacket(spawnParticleEffectPacket);
|
||||
} else if (customPacket instanceof CustomSkinPayloadPacket customSkinPayloadPacket) {
|
||||
if (session.getEntityCache().getEntityByJavaId(customSkinPayloadPacket.getEntityId()) instanceof PlayerEntity player) {
|
||||
SkinData data = LOADED_SKIN_DATA.get(customSkinPayloadPacket.getSkinId());
|
||||
if (data != null) {
|
||||
sendSkinPacket(session, player, data);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (customPacket instanceof CustomEntityDataPacket customEntityDataPacket) {
|
||||
Entity entity = session.getEntityCache().getEntityByJavaId(customEntityDataPacket.getEntityId());
|
||||
if (entity != null) {
|
||||
if (customEntityDataPacket.getHeight() != null)
|
||||
entity.setBoundingBoxHeight(customEntityDataPacket.getHeight());
|
||||
if (customEntityDataPacket.getWidth() != null)
|
||||
entity.setBoundingBoxWidth(customEntityDataPacket.getWidth());
|
||||
if (customEntityDataPacket.getScale() != null)
|
||||
entity.getDirtyMetadata().put(EntityDataTypes.SCALE, customEntityDataPacket.getScale());
|
||||
if (customEntityDataPacket.getColor() != null)
|
||||
entity.getDirtyMetadata().put(EntityDataTypes.COLOR, Byte.parseByte(String.valueOf(getColor(customEntityDataPacket.getColor()))));
|
||||
if (customEntityDataPacket.getVariant() != null)
|
||||
entity.getDirtyMetadata().put(EntityDataTypes.VARIANT, customEntityDataPacket.getVariant());
|
||||
entity.updateBedrockMetadata();
|
||||
}
|
||||
} else if (customPacket instanceof EntityPropertyPacket entityPropertyPacket) {
|
||||
Entity entity = session.getEntityCache().getEntityByJavaId(entityPropertyPacket.getEntityId());
|
||||
if (entity != null) {
|
||||
if (entityPropertyPacket.getIdentifier() == null
|
||||
|| entityPropertyPacket.getValue() == null) return;
|
||||
|
||||
if (entity.getPropertyManager() == null) return;
|
||||
if (entityPropertyPacket.getValue() instanceof Boolean value) {
|
||||
entity.getPropertyManager().add(entityPropertyPacket.getIdentifier(), value);
|
||||
} else if (entityPropertyPacket.getValue() instanceof Integer value) {
|
||||
entity.getPropertyManager().add(entityPropertyPacket.getIdentifier(), value);
|
||||
}
|
||||
entity.updateBedrockEntityProperties();
|
||||
}
|
||||
} else if (customPacket instanceof EntityPropertyRegisterPacket entityPropertyRegisterPacket) {
|
||||
if (entityPropertyRegisterPacket.getIdentifier() == null
|
||||
|| entityPropertyRegisterPacket.getType() == null) return;
|
||||
|
||||
Entity entity = (session.getEntityCache().getEntityByJavaId(entityPropertyRegisterPacket.getEntityId()));
|
||||
if (entity != null) {
|
||||
String def = CUSTOM_ENTITIES.get(session).getIfPresent(entity.getEntityId());
|
||||
if (def == null) return;
|
||||
|
||||
if (!containsProperty(def, entityPropertyRegisterPacket.getIdentifier())) {
|
||||
addProperty(def, entityPropertyRegisterPacket.getIdentifier(), entityPropertyRegisterPacket.getType());
|
||||
|
||||
registerProperties(def);
|
||||
logger().info("DEF PROPERTIES: " + entityPropertyRegisterPacket.getIdentifier());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package me.zimzaza4.geyserutils.geyser;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
@@ -3,8 +3,6 @@ package me.zimzaza4.geyserutils.geyser.camera;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.cloudburstmc.protocol.common.NamedDefinition;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@AllArgsConstructor
|
||||
public class CameraPresetDefinition implements NamedDefinition {
|
||||
|
||||
@@ -10,7 +10,6 @@ import me.zimzaza4.geyserutils.geyser.form.element.Button;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.NpcDialoguePacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.entity.GeyserDirtyMetadata;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@@ -19,7 +18,6 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Accessors(fluent = true, chain = true)
|
||||
public class NpcDialogueForm {
|
||||
@@ -28,29 +26,25 @@ public class NpcDialogueForm {
|
||||
|
||||
@Getter
|
||||
private final String sceneName = UUID.randomUUID().toString();
|
||||
|
||||
@Getter
|
||||
private final ObjectArrayList<Button> dialogueButtons = new ObjectArrayList<>();
|
||||
@Getter
|
||||
@Setter
|
||||
private String title;
|
||||
@Getter
|
||||
@Setter
|
||||
private String dialogue;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Entity bindEntity;
|
||||
private String actionJson = "";
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String skinData = "{\"picker_offsets\":{\"scale\":[1.70,1.70,1.70],\"translate\":[0,20,0]},\"portrait_offsets\":{\"scale\":[1.750,1.750,1.750],\"translate\":[-7,50,0]},\"skin_list\":[{\"variant\":0},{\"variant\":1},{\"variant\":2},{\"variant\":3},{\"variant\":4},{\"variant\":5},{\"variant\":6},{\"variant\":7},{\"variant\":8},{\"variant\":9},{\"variant\":10},{\"variant\":11},{\"variant\":12},{\"variant\":13},{\"variant\":14},{\"variant\":15},{\"variant\":16},{\"variant\":17},{\"variant\":18},{\"variant\":19},{\"variant\":20},{\"variant\":21},{\"variant\":22},{\"variant\":23},{\"variant\":24},{\"variant\":25},{\"variant\":26},{\"variant\":27},{\"variant\":28},{\"variant\":29},{\"variant\":30},{\"variant\":31},{\"variant\":32},{\"variant\":33},{\"variant\":34}]}";
|
||||
|
||||
@Getter
|
||||
private final ObjectArrayList<Button> dialogueButtons = new ObjectArrayList<>();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Runnable closeHandler = () -> { };
|
||||
private Runnable closeHandler = () -> {
|
||||
};
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package me.zimzaza4.geyserutils.geyser.form;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class NpcDialogueForms {
|
||||
|
||||
@@ -10,7 +10,7 @@ import me.zimzaza4.geyserutils.common.form.element.NpcDialogueButton;
|
||||
import java.util.List;
|
||||
|
||||
@Value
|
||||
@Accessors( fluent = true )
|
||||
@Accessors(fluent = true)
|
||||
public class Button {
|
||||
String text;
|
||||
List<String> commands;
|
||||
@@ -20,22 +20,22 @@ public class Button {
|
||||
|
||||
public JsonObject toJsonObject() {
|
||||
JsonObject button = new JsonObject();
|
||||
button.addProperty( "button_name", this.text );
|
||||
button.addProperty("button_name", this.text);
|
||||
|
||||
JsonArray data = new JsonArray();
|
||||
|
||||
for ( String command : this.commands ) {
|
||||
for (String command : this.commands) {
|
||||
JsonObject cmdLine = new JsonObject();
|
||||
cmdLine.addProperty( "cmd_line", command );
|
||||
cmdLine.addProperty( "cmd_ver", 19 );
|
||||
cmdLine.addProperty("cmd_line", command);
|
||||
cmdLine.addProperty("cmd_ver", 19);
|
||||
|
||||
data.add( cmdLine );
|
||||
data.add(cmdLine);
|
||||
}
|
||||
|
||||
button.add( "data", data );
|
||||
button.addProperty( "mode", this.mode.ordinal() );
|
||||
button.addProperty( "text", "" );
|
||||
button.addProperty( "type", 1 );
|
||||
button.add("data", data);
|
||||
button.addProperty("mode", this.mode.ordinal());
|
||||
button.addProperty("text", "");
|
||||
button.addProperty("type", 1);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,8 @@ import static me.zimzaza4.geyserutils.geyser.GeyserUtils.LOADED_ENTITY_DEFINITIO
|
||||
|
||||
public class JavaAddEntityTranslatorReplace extends PacketTranslator<ClientboundAddEntityPacket> {
|
||||
@Override
|
||||
public void translate(GeyserSession session, ClientboundAddEntityPacket packet) { EntityDefinition<?> definition = Registries.ENTITY_DEFINITIONS.get(packet.getType());
|
||||
public void translate(GeyserSession session, ClientboundAddEntityPacket packet) {
|
||||
EntityDefinition<?> definition = Registries.ENTITY_DEFINITIONS.get(packet.getType());
|
||||
if (definition == null) {
|
||||
session.getGeyser().getLogger().debug("Could not find an entity definition with type " + packet.getType());
|
||||
return;
|
||||
@@ -115,6 +116,8 @@ public class JavaAddEntityTranslatorReplace extends PacketTranslator<Clientbound
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else if (packet.getType() == EntityType.AREA_EFFECT_CLOUD) { /* TODO find a way to only remove the MEG ones */
|
||||
return;
|
||||
} else {
|
||||
entity = definition.factory().create(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
|
||||
packet.getUuid(), definition, position, motion, yaw, pitch, headYaw);
|
||||
|
||||
@@ -8,7 +8,6 @@ import org.cloudburstmc.protocol.bedrock.data.NpcRequestType;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.NpcRequestPacket;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
|
||||
public class NPCFormResponseTranslator extends PacketTranslator<NpcRequestPacket> {
|
||||
|
||||
@@ -31,8 +30,6 @@ public class NPCFormResponseTranslator extends PacketTranslator<NpcRequestPacket
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Button button = form.dialogueButtons().get(packet.getActionType());
|
||||
|
||||
if (button == null) {
|
||||
|
||||
@@ -4,7 +4,6 @@ import me.zimzaza4.geyserutils.common.camera.data.*;
|
||||
import me.zimzaza4.geyserutils.common.camera.instruction.FadeInstruction;
|
||||
import me.zimzaza4.geyserutils.common.camera.instruction.SetInstruction;
|
||||
import me.zimzaza4.geyserutils.common.util.Pos;
|
||||
import me.zimzaza4.geyserutils.geyser.camera.CameraPresetDefinition;
|
||||
import org.cloudburstmc.math.vector.Vector2f;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.camera.CameraAudioListener;
|
||||
@@ -12,7 +11,10 @@ import org.cloudburstmc.protocol.bedrock.data.camera.CameraEase;
|
||||
import org.cloudburstmc.protocol.bedrock.data.camera.CameraFadeInstruction;
|
||||
import org.cloudburstmc.protocol.bedrock.data.camera.CameraSetInstruction;
|
||||
import org.cloudburstmc.protocol.common.util.OptionalBoolean;
|
||||
import org.geysermc.geyser.api.bedrock.camera.*;
|
||||
import org.geysermc.geyser.api.bedrock.camera.CameraEaseType;
|
||||
import org.geysermc.geyser.api.bedrock.camera.CameraFade;
|
||||
import org.geysermc.geyser.api.bedrock.camera.CameraPerspective;
|
||||
import org.geysermc.geyser.api.bedrock.camera.CameraPosition;
|
||||
|
||||
public class Converter {
|
||||
|
||||
@@ -86,6 +88,7 @@ public class Converter {
|
||||
}
|
||||
return CameraPerspective.FREE;
|
||||
}
|
||||
|
||||
public static CameraPosition serializeSetInstruction(SetInstruction instruction) {
|
||||
|
||||
CameraPosition.Builder builder = CameraPosition.builder();
|
||||
|
||||
@@ -67,7 +67,7 @@ public class DeltaUtils {
|
||||
}
|
||||
|
||||
private static double[] xyzToLab(double x, double y, double z) {
|
||||
double ref_X = 95.047;
|
||||
double ref_X = 95.047;
|
||||
double ref_Y = 100.000;
|
||||
double ref_Z = 108.883;
|
||||
|
||||
@@ -75,11 +75,11 @@ public class DeltaUtils {
|
||||
double var_Y = y / ref_Y;
|
||||
double var_Z = z / ref_Z;
|
||||
|
||||
if (var_X > 0.008856) var_X = Math.pow(var_X, 1.0/3.0);
|
||||
if (var_X > 0.008856) var_X = Math.pow(var_X, 1.0 / 3.0);
|
||||
else var_X = (7.787 * var_X) + (16.0 / 116.0);
|
||||
if (var_Y > 0.008856) var_Y = Math.pow(var_Y, 1.0/3.0);
|
||||
if (var_Y > 0.008856) var_Y = Math.pow(var_Y, 1.0 / 3.0);
|
||||
else var_Y = (7.787 * var_Y) + (16.0 / 116.0);
|
||||
if (var_Z > 0.008856) var_Z = Math.pow(var_Z, 1.0/3.0);
|
||||
if (var_Z > 0.008856) var_Z = Math.pow(var_Z, 1.0 / 3.0);
|
||||
else var_Z = (7.787 * var_Z) + (16.0 / 116.0);
|
||||
|
||||
double l = (116.0 * var_Y) - 16.0;
|
||||
|
||||
@@ -45,10 +45,12 @@ public class ReflectionUtils {
|
||||
}
|
||||
KEY_BUILD_METHOD = KEY_CLASS.getMethod("key", String.class);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static Object getChannel(ClientboundCustomPayloadPacket packet) {
|
||||
return CLIENTBOUND_GET_CHANNEL_METHOD.invoke(packet);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static Object getChannel(ServerboundCustomPayloadPacket packet) {
|
||||
return SERVERBOUND_GET_CHANNEL_METHOD.invoke(packet);
|
||||
@@ -58,6 +60,7 @@ public class ReflectionUtils {
|
||||
public static ServerboundCustomPayloadPacket buildServerboundPayloadPacket(String key, byte[] data) {
|
||||
return (ServerboundCustomPayloadPacket) SERVERBOUND_PAYLOAD_PACKET_CONSTRUCTOR.newInstance(buildKey(key), data);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static Object buildKey(String key) {
|
||||
if (OLD_VERSION) return key;
|
||||
|
||||
@@ -3,4 +3,4 @@ id: geyserutils
|
||||
main: me.zimzaza4.geyserutils.geyser.GeyserUtils
|
||||
api: 1.0.0
|
||||
version: 1.0.0
|
||||
authors: [zimzaza4, willem.dev]
|
||||
authors: [ zimzaza4, willem.dev ]
|
||||
Reference in New Issue
Block a user