mirror of
https://github.com/GeyserExtensionists/GeyserUtils.git
synced 2025-12-19 23:19:17 +00:00
Compare commits
53 Commits
custom-ent
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b35d17b97b | ||
|
|
ff664c41e7 | ||
|
|
2dcb2b81f9 | ||
|
|
51c5998f80 | ||
|
|
ff0f982953 | ||
|
|
6c99efe401 | ||
|
|
6250e69c68 | ||
|
|
54c1637fed | ||
|
|
96232d44b7 | ||
|
|
90baf05f8d | ||
|
|
66773cace0 | ||
|
|
4e1cd6cbf7 | ||
|
|
7340c8b520 | ||
|
|
85e6bce81b | ||
|
|
3a961101e6 | ||
|
|
e7ac6f8d31 | ||
|
|
8b40b9a4c1 | ||
|
|
20b9860d79 | ||
|
|
e1c6ca6d3b | ||
|
|
f9969833b0 | ||
|
|
90ce4e310f | ||
|
|
4cce065bf0 | ||
|
|
5accabda6b | ||
|
|
1643690907 | ||
|
|
0351a19f31 | ||
|
|
0318440600 | ||
|
|
1fe6dc5935 | ||
|
|
9b425628c1 | ||
|
|
4269b8abb4 | ||
|
|
4b1ddc2bb9 | ||
|
|
f5063bf955 | ||
|
|
2973fad195 | ||
|
|
8e2b5cd1fc | ||
|
|
2963aa7057 | ||
|
|
260c858eb8 | ||
|
|
f1d5af45a7 | ||
|
|
91a3f04bd8 | ||
|
|
2bf2e3c954 | ||
|
|
4c45dcc6b8 | ||
|
|
c803daa4b7 | ||
|
|
2fb33bc350 | ||
|
|
dc75e10790 | ||
|
|
856b19ba67 | ||
|
|
1d1093ba1f | ||
|
|
1d16abdacf | ||
|
|
584e43b733 | ||
|
|
7a093d39aa | ||
|
|
427c4c3e89 | ||
|
|
e30a9b5f83 | ||
|
|
58285ffd7f | ||
|
|
e5fa64e950 | ||
|
|
a44cea571e | ||
|
|
f6e762bea8 |
38
.github/workflows/maven.yml
vendored
Normal file
38
.github/workflows/maven.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: Auto Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Setup JDK
|
||||
- name: Setup Java JDK
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 21
|
||||
distribution: 'zulu'
|
||||
|
||||
# Build
|
||||
- name: Build with Maven
|
||||
run: mvn -B package --file pom.xml
|
||||
|
||||
|
||||
- name: Auto release
|
||||
uses: "marvinpinto/action-automatic-releases@latest"
|
||||
with:
|
||||
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
automatic_release_tag: latest
|
||||
prerelease: false
|
||||
files: |
|
||||
spigot/target/geyserutils-*.jar
|
||||
geyser/target/geyserutils-*.jar
|
||||
velocity/target/geyserutils-*.jar
|
||||
bungee/target/geyserutils-*.jar
|
||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -20,7 +20,7 @@
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -66,7 +66,7 @@
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.20-R0.1-SNAPSHOT</version>
|
||||
<version>1.21-R0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -12,17 +12,26 @@
|
||||
<artifactId>geyserutils-common</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.14.0</version>
|
||||
<configuration>
|
||||
<source>21</source>
|
||||
<target>21</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.4.1</version>
|
||||
<version>3.6.0</version>
|
||||
<configuration>
|
||||
<relocations>
|
||||
<relocation>
|
||||
@@ -58,7 +67,7 @@
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.28</version>
|
||||
<version>1.18.32</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -77,12 +86,6 @@
|
||||
<version>24.0.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>24.0.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -11,6 +11,31 @@ import java.util.TreeMap;
|
||||
@Getter
|
||||
public class CameraPreset {
|
||||
private static final Map<String, CameraPreset> PRESETS = new TreeMap<>();
|
||||
public static CameraPreset FIRST_PERSON;
|
||||
public static CameraPreset FREE;
|
||||
public static CameraPreset THIRD_PERSON;
|
||||
public static CameraPreset THIRD_PERSON_FRONT;
|
||||
private String identifier;
|
||||
@Getter
|
||||
private String inheritFrom;
|
||||
@Getter
|
||||
@Nullable
|
||||
private Pos pos;
|
||||
@Getter
|
||||
@Nullable
|
||||
private Rot rot;
|
||||
@Getter
|
||||
private int id;
|
||||
@Builder
|
||||
public CameraPreset(String identifier, String inheritFrom, @Nullable Pos pos, @Nullable Rot rot) {
|
||||
this.identifier = identifier;
|
||||
this.inheritFrom = inheritFrom != null ? inheritFrom : "";
|
||||
this.pos = pos;
|
||||
this.rot = rot;
|
||||
}
|
||||
protected CameraPreset() {
|
||||
|
||||
}
|
||||
|
||||
public static Map<String, CameraPreset> getPresets() {
|
||||
return PRESETS;
|
||||
@@ -34,11 +59,6 @@ public class CameraPreset {
|
||||
}
|
||||
}
|
||||
|
||||
public static CameraPreset FIRST_PERSON;
|
||||
public static CameraPreset FREE;
|
||||
public static CameraPreset THIRD_PERSON;
|
||||
public static CameraPreset THIRD_PERSON_FRONT;
|
||||
|
||||
public static void load() {
|
||||
FIRST_PERSON = CameraPreset.builder()
|
||||
.identifier("minecraft:first_person")
|
||||
@@ -57,29 +77,4 @@ public class CameraPreset {
|
||||
|
||||
registerCameraPresets(FIRST_PERSON, FREE, THIRD_PERSON, THIRD_PERSON_FRONT);
|
||||
}
|
||||
|
||||
private String identifier;
|
||||
@Getter
|
||||
private String inheritFrom;
|
||||
@Getter
|
||||
@Nullable
|
||||
private Pos pos;
|
||||
@Getter
|
||||
@Nullable
|
||||
private Rot rot;
|
||||
|
||||
@Getter
|
||||
private int id;
|
||||
|
||||
@Builder
|
||||
public CameraPreset(String identifier, String inheritFrom, @Nullable Pos pos, @Nullable Rot rot) {
|
||||
this.identifier = identifier;
|
||||
this.inheritFrom = inheritFrom != null ? inheritFrom : "";
|
||||
this.pos = pos;
|
||||
this.rot = rot;
|
||||
}
|
||||
|
||||
protected CameraPreset() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package me.zimzaza4.geyserutils.common.camera.data;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@@ -4,42 +4,43 @@ import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum EaseType {
|
||||
LINEAR("linear",0),
|
||||
SPRING("spring",1),
|
||||
EASE_IN_SINE("in_sine",2),
|
||||
EASE_OUT_SINE("out_sine",3),
|
||||
EASE_IN_OUT_SINE("in_out_sine",4),
|
||||
EASE_IN_QUAD("in_quad",5),
|
||||
EASE_OUT_QUAD("out_quad",6),
|
||||
EASE_IN_OUT_QUAD("in_out_quad",7),
|
||||
EASE_IN_CUBIC("in_cubic",8),
|
||||
EASE_OUT_CUBIC("out_cubic",9),
|
||||
EASE_IN_OUT_CUBIC("in_out_cubic",10),
|
||||
EASE_IN_QUART("in_quart",11),
|
||||
EASE_OUT_QUART("out_quart",12),
|
||||
EASE_IN_OUT_QUART("in_out_quart",13),
|
||||
EASE_IN_QUINT("in_quint",14),
|
||||
EASE_OUT_QUINT("out_quint",15),
|
||||
EASE_IN_OUT_QUINT("in_out_quint",16),
|
||||
EASE_IN_EXPO("in_expo",17),
|
||||
EASE_OUT_EXPO("out_expo",18),
|
||||
EASE_IN_OUT_EXPO("in_out_expo",19),
|
||||
EASE_IN_CIRC("in_circ",20),
|
||||
EASE_OUT_CIRC("out_circ",21),
|
||||
EASE_IN_OUT_CIRC("in_out_circ",22),
|
||||
EASE_IN_BACK("in_back",23),
|
||||
EASE_OUT_BACK("out_back",24),
|
||||
EASE_IN_OUT_BACK("in_out_back",25),
|
||||
EASE_IN_ELASTIC("in_elastic",26),
|
||||
EASE_OUT_ELASTIC("out_elastic",27),
|
||||
EASE_IN_OUT_ELASTIC("in_out_elastic",28),
|
||||
EASE_IN_BOUNCE("in_bounce",29),
|
||||
EASE_OUT_BOUNCE("out_bounce",30),
|
||||
EASE_IN_OUT_BOUNCE("in_out_bounce",31);
|
||||
LINEAR("linear", 0),
|
||||
SPRING("spring", 1),
|
||||
EASE_IN_SINE("in_sine", 2),
|
||||
EASE_OUT_SINE("out_sine", 3),
|
||||
EASE_IN_OUT_SINE("in_out_sine", 4),
|
||||
EASE_IN_QUAD("in_quad", 5),
|
||||
EASE_OUT_QUAD("out_quad", 6),
|
||||
EASE_IN_OUT_QUAD("in_out_quad", 7),
|
||||
EASE_IN_CUBIC("in_cubic", 8),
|
||||
EASE_OUT_CUBIC("out_cubic", 9),
|
||||
EASE_IN_OUT_CUBIC("in_out_cubic", 10),
|
||||
EASE_IN_QUART("in_quart", 11),
|
||||
EASE_OUT_QUART("out_quart", 12),
|
||||
EASE_IN_OUT_QUART("in_out_quart", 13),
|
||||
EASE_IN_QUINT("in_quint", 14),
|
||||
EASE_OUT_QUINT("out_quint", 15),
|
||||
EASE_IN_OUT_QUINT("in_out_quint", 16),
|
||||
EASE_IN_EXPO("in_expo", 17),
|
||||
EASE_OUT_EXPO("out_expo", 18),
|
||||
EASE_IN_OUT_EXPO("in_out_expo", 19),
|
||||
EASE_IN_CIRC("in_circ", 20),
|
||||
EASE_OUT_CIRC("out_circ", 21),
|
||||
EASE_IN_OUT_CIRC("in_out_circ", 22),
|
||||
EASE_IN_BACK("in_back", 23),
|
||||
EASE_OUT_BACK("out_back", 24),
|
||||
EASE_IN_OUT_BACK("in_out_back", 25),
|
||||
EASE_IN_ELASTIC("in_elastic", 26),
|
||||
EASE_OUT_ELASTIC("out_elastic", 27),
|
||||
EASE_IN_OUT_ELASTIC("in_out_elastic", 28),
|
||||
EASE_IN_BOUNCE("in_bounce", 29),
|
||||
EASE_OUT_BOUNCE("out_bounce", 30),
|
||||
EASE_IN_OUT_BOUNCE("in_out_bounce", 31);
|
||||
|
||||
|
||||
private final String type;
|
||||
private final int index;
|
||||
|
||||
EaseType(String type, int index) {
|
||||
this.type = type;
|
||||
this.index = index;
|
||||
|
||||
@@ -7,7 +7,8 @@ public class ClearInstruction implements Instruction {
|
||||
private static final ClearInstruction INSTANCE = new ClearInstruction();
|
||||
private final int clear = 1;
|
||||
|
||||
private ClearInstruction() {}
|
||||
private ClearInstruction() {
|
||||
}
|
||||
|
||||
public static ClearInstruction instance() {
|
||||
return INSTANCE;
|
||||
|
||||
@@ -16,5 +16,6 @@ public class FadeInstruction implements Instruction {
|
||||
@Nullable
|
||||
private Time time;
|
||||
|
||||
protected FadeInstruction() {}
|
||||
protected FadeInstruction() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package me.zimzaza4.geyserutils.common.camera.instruction;
|
||||
|
||||
import lombok.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import me.zimzaza4.geyserutils.common.camera.data.CameraPreset;
|
||||
import me.zimzaza4.geyserutils.common.camera.data.Ease;
|
||||
import me.zimzaza4.geyserutils.common.util.Pos;
|
||||
import me.zimzaza4.geyserutils.common.camera.data.Rot;
|
||||
import me.zimzaza4.geyserutils.common.util.Pos;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@AllArgsConstructor
|
||||
@@ -23,5 +25,7 @@ public class SetInstruction implements Instruction {
|
||||
private CameraPreset preset;
|
||||
@Nullable
|
||||
private FadeInstruction fade;
|
||||
protected SetInstruction() {}
|
||||
|
||||
protected SetInstruction() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,20 +2,19 @@ package me.zimzaza4.geyserutils.common.form.element;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.Value;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Accessors( fluent = true )
|
||||
@Accessors(fluent = true)
|
||||
public class NpcDialogueButton {
|
||||
private String text;
|
||||
private List<String> commands;
|
||||
private ButtonMode mode;
|
||||
private boolean hasNextForm;
|
||||
|
||||
public enum ButtonMode {
|
||||
BUTTON_MODE,
|
||||
ON_ENTER,
|
||||
|
||||
@@ -2,18 +2,13 @@ package me.zimzaza4.geyserutils.common.manager;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
|
||||
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
|
||||
import me.zimzaza4.geyserutils.common.packet.CustomPayloadPacket;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class PacketManager {
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.List;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public class AnimateEntityCustomPayloadPacket extends CustomPayloadPacket{
|
||||
public class AnimateEntityCustomPayloadPacket extends CustomPayloadPacket {
|
||||
private String animation;
|
||||
private String nextState;
|
||||
private String stopExpression;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package me.zimzaza4.geyserutils.common.packet;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
public class BundlePacket extends CustomPayloadPacket {
|
||||
|
||||
private List<CustomPayloadPacket> packets = new ArrayList<>();
|
||||
|
||||
public void addPacket(CustomPayloadPacket packet) {
|
||||
this.packets.add(packet);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,10 +11,10 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public class CustomEntityDataPacket extends CustomPayloadPacket {
|
||||
private int entityId;
|
||||
|
||||
private Float height;
|
||||
private Float width;
|
||||
|
||||
private Float scale;
|
||||
private Integer color;
|
||||
private Integer variant;
|
||||
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
|
||||
@@ -4,12 +4,8 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
import me.zimzaza4.geyserutils.common.animation.Animation;
|
||||
import me.zimzaza4.geyserutils.common.packet.CustomPayloadPacket;
|
||||
import me.zimzaza4.geyserutils.common.particle.CustomParticle;
|
||||
import me.zimzaza4.geyserutils.common.util.Pos;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
package me.zimzaza4.geyserutils.common.packet;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public abstract class CustomPayloadPacket {
|
||||
|
||||
|
||||
|
||||
@@ -5,9 +5,6 @@ import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package me.zimzaza4.geyserutils.common.packet;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class EntityPropertyPacket<T> extends CustomPayloadPacket {
|
||||
private int entityId;
|
||||
|
||||
private String identifier;
|
||||
private T value;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package me.zimzaza4.geyserutils.common.packet;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class EntityPropertyRegisterPacket extends CustomPayloadPacket {
|
||||
private int entityId;
|
||||
|
||||
private String identifier;
|
||||
private Class<?> type;
|
||||
|
||||
}
|
||||
@@ -3,5 +3,4 @@ package me.zimzaza4.geyserutils.common.util;
|
||||
public class CustomPayloadPacketUtils {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -22,7 +22,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.4.1</version>
|
||||
<version>3.6.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
@@ -79,7 +79,7 @@
|
||||
<dependency>
|
||||
<groupId>org.geysermc.geyser</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>2.2.3-SNAPSHOT</version>
|
||||
<version>2.9.0-SNAPSHOT</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/libs/Geyser-Standalone.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
package me.zimzaza4.geyserutils.geyser;
|
||||
|
||||
import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundCustomPayloadPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket;
|
||||
import com.github.steveice10.packetlib.Session;
|
||||
import com.github.steveice10.packetlib.event.session.PacketSendingEvent;
|
||||
import com.github.steveice10.packetlib.event.session.SessionAdapter;
|
||||
import com.github.steveice10.packetlib.packet.Packet;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.*;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import lombok.Getter;
|
||||
import me.zimzaza4.geyserutils.common.camera.data.CameraPreset;
|
||||
import me.zimzaza4.geyserutils.common.camera.instruction.ClearInstruction;
|
||||
@@ -22,81 +16,153 @@ import me.zimzaza4.geyserutils.common.packet.*;
|
||||
import me.zimzaza4.geyserutils.geyser.form.NpcDialogueForm;
|
||||
import me.zimzaza4.geyserutils.geyser.form.NpcDialogueForms;
|
||||
import me.zimzaza4.geyserutils.geyser.form.element.Button;
|
||||
import me.zimzaza4.geyserutils.geyser.replace.JavaAddEntityTranslatorReplace;
|
||||
import me.zimzaza4.geyserutils.geyser.translator.NPCFormResponseTranslator;
|
||||
import me.zimzaza4.geyserutils.geyser.util.Converter;
|
||||
import me.zimzaza4.geyserutils.geyser.util.DeltaUtils;
|
||||
import me.zimzaza4.geyserutils.geyser.util.ReflectionUtils;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.data.skin.ImageData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.skin.SerializedSkin;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.*;
|
||||
import org.geysermc.event.subscribe.Subscribe;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.bedrock.camera.CameraShake;
|
||||
import org.geysermc.geyser.api.command.Command;
|
||||
import org.geysermc.geyser.api.connection.GeyserConnection;
|
||||
import org.geysermc.geyser.api.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.api.entity.EntityIdentifier;
|
||||
import org.geysermc.geyser.api.event.bedrock.SessionDisconnectEvent;
|
||||
import org.geysermc.geyser.api.event.bedrock.SessionLoginEvent;
|
||||
import org.geysermc.geyser.api.event.java.ServerSpawnEntityEvent;
|
||||
import org.geysermc.geyser.api.event.lifecycle.GeyserDefineCommandsEvent;
|
||||
import org.geysermc.geyser.api.event.lifecycle.GeyserDefineEntitiesEvent;
|
||||
import org.geysermc.geyser.api.event.lifecycle.GeyserDefineEntityPropertiesEvent;
|
||||
import org.geysermc.geyser.api.event.lifecycle.GeyserPostInitializeEvent;
|
||||
import org.geysermc.geyser.api.extension.Extension;
|
||||
import org.geysermc.geyser.api.skin.Cape;
|
||||
import org.geysermc.geyser.api.skin.Skin;
|
||||
import org.geysermc.geyser.api.skin.SkinData;
|
||||
import org.geysermc.geyser.api.skin.SkinGeometry;
|
||||
import org.geysermc.geyser.api.util.Identifier;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.properties.GeyserEntityProperties;
|
||||
import org.geysermc.geyser.entity.properties.type.BooleanProperty;
|
||||
import org.geysermc.geyser.entity.properties.type.FloatProperty;
|
||||
import org.geysermc.geyser.entity.properties.type.IntProperty;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.skin.SkinProvider;
|
||||
import org.geysermc.geyser.util.DimensionUtils;
|
||||
import org.geysermc.mcprotocollib.network.Session;
|
||||
import org.geysermc.mcprotocollib.network.event.session.PacketSendingEvent;
|
||||
import org.geysermc.mcprotocollib.network.event.session.SessionAdapter;
|
||||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundCustomPayloadPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundAddEntityPacket;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.io.*;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class GeyserUtils implements Extension {
|
||||
|
||||
|
||||
NbtMap CLEAR_INSTRUCTION_TAG = NbtMap.builder().putByte("clear", Integer.valueOf(1).byteValue()).build();
|
||||
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;
|
||||
|
||||
public static PacketManager packetManager = new PacketManager();
|
||||
public static List<String> REGISTERED_ENTITIES = new ArrayList<>();
|
||||
public static boolean GEYSER_LOADED = false;
|
||||
@Getter
|
||||
public static Map<String, SkinProvider.SkinData> LOADED_SKIN_DATA = new HashMap<>();
|
||||
|
||||
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);
|
||||
private static List<String> ENTITIES_WAIT_FOR_LOAD = new ArrayList<>();
|
||||
@Getter
|
||||
private static GeyserUtils instance;
|
||||
|
||||
static SkinProvider.Cape EMPTY_CAPE = new SkinProvider.Cape("", "no-cape", new byte[0], -1, true);
|
||||
;
|
||||
public static final Integer MAX_VALUE = 1000000;
|
||||
|
||||
public static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
|
||||
public static final Integer MIN_VALUE = -1000000;
|
||||
|
||||
@Subscribe
|
||||
public void onEnable(GeyserPostInitializeEvent event) {
|
||||
public GeyserUtils() {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
packetManager = new PacketManager();
|
||||
Registries.BEDROCK_PACKET_TRANSLATORS.register(NpcRequestPacket.class, new NPCFormResponseTranslator());
|
||||
logger().info("Loading Skins:");
|
||||
loadSkins();
|
||||
// the static here is crazy ;(
|
||||
private static GeyserEntityProperties.Builder getProperties(String id) {
|
||||
if (!properties.containsKey(id)) return null;
|
||||
|
||||
CameraPreset.load();
|
||||
GeyserEntityProperties.Builder builder = new GeyserEntityProperties.Builder(id);
|
||||
List<Map.Entry<String, Class<?>>> pairs = properties.get(id);
|
||||
pairs.forEach(p -> {
|
||||
// only bool, float and int support for now
|
||||
if (p.getValue() == Boolean.class) builder.add(new BooleanProperty(Identifier.of(p.getKey()), false));
|
||||
else if (p.getValue() == Float.class) builder.add(new FloatProperty(Identifier.of(p.getKey()), MAX_VALUE, MIN_VALUE,0f));
|
||||
else if (p.getValue() == Integer.class) builder.add(new IntProperty(Identifier.of(p.getKey()), MAX_VALUE, MIN_VALUE, 0));
|
||||
else instance.logger().info("Found unknown property: " + p.getKey());
|
||||
});
|
||||
|
||||
LOADED_ENTITY_DEFINITIONS
|
||||
.forEach((s, entityDefinition) -> {
|
||||
logger().info("DEF ENTITY:" + s);
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static boolean containsProperty(String entityId, String identifier) {
|
||||
if (!properties.containsKey(entityId)) return false;
|
||||
|
||||
return properties.get(entityId).stream().anyMatch(p -> p.getKey().equalsIgnoreCase(identifier));
|
||||
}
|
||||
|
||||
public static void addProperty(String entityId, String identifier, Class<?> type) {
|
||||
if (containsProperty(entityId, identifier)) return;
|
||||
|
||||
List<Map.Entry<String, Class<?>>> pairs = properties.getOrDefault(entityId, new ArrayList<>());
|
||||
pairs.add(new AbstractMap.SimpleEntry<>(identifier, type));
|
||||
|
||||
if (properties.containsKey(entityId)) properties.replace(entityId, pairs);
|
||||
else properties.put(entityId, pairs);
|
||||
}
|
||||
|
||||
public static void registerProperties(String entityId) {
|
||||
if (GEYSER_LOADED) {
|
||||
registerProperties(entityId);
|
||||
}
|
||||
ENTITIES_WAIT_FOR_LOAD.add(entityId);
|
||||
}
|
||||
|
||||
public static NbtMap registerPropertiesForGeyser(String entityId) {
|
||||
GeyserEntityProperties.Builder builder = getProperties(entityId);
|
||||
if (builder == null) return null;
|
||||
GeyserEntityProperties entityProperties = builder.build();
|
||||
properties.values().stream()
|
||||
.flatMap(List::stream)
|
||||
.map(Map.Entry::getKey)
|
||||
.forEach(id -> {
|
||||
Registries.BEDROCK_ENTITY_PROPERTIES.get().removeIf(i -> i.containsKey(id));
|
||||
});
|
||||
|
||||
EntityDefinition old = LOADED_ENTITY_DEFINITIONS.get(entityId);
|
||||
LOADED_ENTITY_DEFINITIONS.replace(entityId, new EntityDefinition(old.factory(), old.entityType(), old.identifier(),
|
||||
old.width(), old.height(), old.offset(), entityProperties, old.translators()));
|
||||
|
||||
instance.logger().info("Defined entity: " + entityId + " in registry.");
|
||||
return entityProperties.toNbtMap(entityId);
|
||||
}
|
||||
|
||||
public static void addCustomEntity(String id) {
|
||||
/*
|
||||
LOADED_ENTITY_DEFINITIONS.put(id,
|
||||
EntityDefinition.builder()
|
||||
.identifier(EntityIdentifier.builder().identifier(id)
|
||||
@@ -105,57 +171,201 @@ public class GeyserUtils implements Extension {
|
||||
.height(0.6f)
|
||||
.width(0.6f)
|
||||
.build());
|
||||
}
|
||||
public void loadEntities() {
|
||||
|
||||
Gson gson = new Gson();
|
||||
File file = this.dataFolder().resolve("entities.json").toFile();
|
||||
if (!file.exists()) {
|
||||
try {
|
||||
file.createNewFile();
|
||||
gson.toJson(new JsonArray(),new FileWriter(file));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
*/
|
||||
if (GEYSER_LOADED) {
|
||||
registerEntityToGeyser(id);
|
||||
}
|
||||
try {
|
||||
List<String> list = gson.fromJson(new FileReader(file), new TypeToken<List<String>>(){}.getType());
|
||||
REGISTERED_ENTITIES.add(id);
|
||||
}
|
||||
|
||||
for (String s : list) {
|
||||
logger().info("Registered: " + s);
|
||||
addCustomEntity(s);
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
public static void registerEntityToGeyser(String id) {
|
||||
NbtMap registry = Registries.BEDROCK_ENTITY_IDENTIFIERS.get();
|
||||
List<NbtMap> idList = new ArrayList<>(registry.getList("idlist", NbtType.COMPOUND));
|
||||
idList.add(NbtMap.builder()
|
||||
.putString("id", id)
|
||||
.putString("bid", "")
|
||||
.putBoolean("hasspawnegg", false)
|
||||
.putInt("rid", idList.size() + 1)
|
||||
.putBoolean("summonable", false).build()
|
||||
);
|
||||
|
||||
Registries.BEDROCK_ENTITY_IDENTIFIERS.set(NbtMap.builder()
|
||||
.putList("idlist", NbtType.COMPOUND, idList).build()
|
||||
);
|
||||
|
||||
EntityDefinition<Entity> def = EntityDefinition.builder(null)
|
||||
.height(0.1f).width(0.1f).identifier(id).propertiesBuilder(getProperties(id)).build();
|
||||
|
||||
LOADED_ENTITY_DEFINITIONS.put(id, def);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static AnimateEntityPacket getAnimateEntityPacket(AnimateEntityCustomPayloadPacket animateEntityCustomPayloadPacket) {
|
||||
AnimateEntityPacket animateEntityPacket = new AnimateEntityPacket();
|
||||
animateEntityPacket.setAnimation(animateEntityCustomPayloadPacket.getAnimation());
|
||||
animateEntityPacket.setController(animateEntityCustomPayloadPacket.getController());
|
||||
animateEntityPacket.setBlendOutTime(animateEntityCustomPayloadPacket.getBlendOutTime());
|
||||
animateEntityPacket.setNextState(animateEntityCustomPayloadPacket.getNextState());
|
||||
animateEntityPacket.setStopExpressionVersion(animateEntityCustomPayloadPacket.getStopExpressionVersion());
|
||||
animateEntityPacket.setStopExpression(animateEntityCustomPayloadPacket.getStopExpression());
|
||||
return animateEntityPacket;
|
||||
}
|
||||
|
||||
public static void sendSkinPacket(GeyserSession session, PlayerEntity entity, SkinData skinData) {
|
||||
Skin skin = skinData.skin();
|
||||
Cape cape = skinData.cape();
|
||||
SkinGeometry geometry = skinData.geometry();
|
||||
|
||||
if (entity.getUuid().equals(session.getPlayerEntity().getUuid())) {
|
||||
PlayerListPacket.Entry updatedEntry = buildEntryManually(
|
||||
session,
|
||||
entity.getUuid(),
|
||||
entity.getUsername(),
|
||||
entity.getGeyserId(),
|
||||
skin,
|
||||
cape,
|
||||
geometry
|
||||
);
|
||||
|
||||
PlayerListPacket playerAddPacket = new PlayerListPacket();
|
||||
playerAddPacket.setAction(PlayerListPacket.Action.ADD);
|
||||
playerAddPacket.getEntries().add(updatedEntry);
|
||||
session.sendUpstreamPacket(playerAddPacket);
|
||||
} else {
|
||||
PlayerSkinPacket packet = new PlayerSkinPacket();
|
||||
packet.setUuid(entity.getUuid());
|
||||
packet.setOldSkinName("");
|
||||
packet.setNewSkinName(skin.textureUrl());
|
||||
packet.setSkin(getSkin(skin.textureUrl(), skin, cape, geometry));
|
||||
packet.setTrustedSkin(true);
|
||||
session.sendUpstreamPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
public static PlayerListPacket.Entry buildEntryManually(GeyserSession session, UUID uuid, String username, long geyserId,
|
||||
Skin skin,
|
||||
Cape cape,
|
||||
SkinGeometry geometry) {
|
||||
SerializedSkin serializedSkin = getSkin(skin.textureUrl(), skin, cape, geometry);
|
||||
|
||||
String xuid = "";
|
||||
GeyserSession playerSession = GeyserImpl.getInstance().connectionByUuid(uuid);
|
||||
|
||||
if (playerSession != null) {
|
||||
xuid = playerSession.getAuthData().xuid();
|
||||
}
|
||||
|
||||
PlayerListPacket.Entry entry;
|
||||
if (session.getPlayerEntity().getUuid().equals(uuid)) {
|
||||
entry = new PlayerListPacket.Entry(session.getAuthData().uuid());
|
||||
} else {
|
||||
entry = new PlayerListPacket.Entry(uuid);
|
||||
}
|
||||
|
||||
entry.setName(username);
|
||||
entry.setEntityId(geyserId);
|
||||
entry.setSkin(serializedSkin);
|
||||
entry.setXuid(xuid);
|
||||
entry.setPlatformChatId("");
|
||||
entry.setTeacher(false);
|
||||
entry.setTrustedSkin(true);
|
||||
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);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Cape getEmptyCapeData() {
|
||||
return EMPTY_CAPE;
|
||||
}
|
||||
|
||||
private static int getColor(int argb) {
|
||||
int r = (argb >> 16) & 0xFF;
|
||||
int g = (argb >> 8) & 0xFF;
|
||||
int b = argb & 0xFF;
|
||||
|
||||
double[] colorLab = DeltaUtils.rgbToLab(r, g, b);
|
||||
|
||||
List<int[]> colors = Arrays.asList(
|
||||
new int[]{249, 255, 254}, // 0: White
|
||||
new int[]{249, 128, 29}, // 1: Orange
|
||||
new int[]{199, 78, 189}, // 2: Magenta
|
||||
new int[]{58, 179, 218}, // 3: Light Blue
|
||||
new int[]{254, 216, 61}, // 4: Yellow
|
||||
new int[]{128, 199, 31}, // 5: Lime
|
||||
new int[]{243, 139, 170}, // 6: Pink
|
||||
new int[]{71, 79, 82}, // 7: Gray
|
||||
new int[]{159, 157, 151}, // 8: Light Gray
|
||||
new int[]{22, 156, 156}, // 9: Cyan
|
||||
new int[]{137, 50, 184}, // 10: Purple
|
||||
new int[]{60, 68, 170}, // 11: Blue
|
||||
new int[]{131, 84, 50}, // 12: Brown
|
||||
new int[]{94, 124, 22}, // 13: Green
|
||||
new int[]{176, 46, 38}, // 14: Red
|
||||
new int[]{29, 29, 33} // 15: Black
|
||||
);
|
||||
|
||||
int closestColorIndex = -1;
|
||||
double minDeltaE = Double.MAX_VALUE;
|
||||
|
||||
for (int i = 0; i < colors.size(); i++) {
|
||||
int[] rgb = colors.get(i);
|
||||
double[] lab = DeltaUtils.rgbToLab(rgb[0], rgb[1], rgb[2]);
|
||||
double deltaE = DeltaUtils.calculateDeltaE(colorLab, lab);
|
||||
if (deltaE < minDeltaE) {
|
||||
minDeltaE = deltaE;
|
||||
closestColorIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
return closestColorIndex;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEntitiesDefine(GeyserDefineEntitiesEvent event) {
|
||||
loadEntities();
|
||||
for (EntityDefinition value : LOADED_ENTITY_DEFINITIONS.values()) {
|
||||
event.register(value);
|
||||
public void onEnable(GeyserPostInitializeEvent event) {
|
||||
Registries.BEDROCK_PACKET_TRANSLATORS.register(NpcRequestPacket.class, new NPCFormResponseTranslator());
|
||||
loadSkins();
|
||||
ReflectionUtils.init();
|
||||
CameraPreset.load();
|
||||
|
||||
replaceTranslator();
|
||||
GEYSER_LOADED = true;
|
||||
logger().info("Defined " + LOADED_ENTITY_DEFINITIONS.size() + " entities");
|
||||
// MountFix.start();
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onDefineProperties(GeyserDefineEntityPropertiesEvent event) {
|
||||
for (String registeredEntity : REGISTERED_ENTITIES) {
|
||||
registerEntityToGeyser(registeredEntity);
|
||||
}
|
||||
Set<NbtMap> entityProperties = new HashSet<>();
|
||||
for (String id : ENTITIES_WAIT_FOR_LOAD) {
|
||||
NbtMap map = registerPropertiesForGeyser(id);
|
||||
if (map == null) continue;
|
||||
entityProperties.add(map);
|
||||
}
|
||||
// Prevent Error: "Cannot add properties outside the GeyserDefineEntityProperties event!"
|
||||
scheduler.schedule(() -> Registries.BEDROCK_ENTITY_PROPERTIES.get().addAll(entityProperties), 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public void replaceTranslator() {
|
||||
Registries.JAVA_PACKET_TRANSLATORS
|
||||
.register(ClientboundAddEntityPacket.class, new JavaAddEntityTranslatorReplace());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onLoadCommand(GeyserDefineCommandsEvent event) {
|
||||
event.register(Command.builder(this)
|
||||
.name("reloadskin")
|
||||
.source(GeyserConnection.class)
|
||||
.aliases(List.of("grs"))
|
||||
.description("Reload GeyserUtils skin.")
|
||||
.executableOnConsole(true)
|
||||
.bedrockOnly(false)
|
||||
.suggestedOpOnly(true)
|
||||
.permission("geyserutils.skin.reload")
|
||||
.executor((source, command, args) -> {
|
||||
loadSkins();
|
||||
source.sendMessage("Loaded");
|
||||
}).build());
|
||||
|
||||
}
|
||||
|
||||
public void loadSkins() {
|
||||
@@ -188,7 +398,7 @@ public class GeyserUtils implements Extension {
|
||||
|
||||
public void loadSkin(String skinId, File geometryFile, File textureFile) {
|
||||
try {
|
||||
SkinProvider.Skin skin = new SkinProvider.Skin(null, skinId, Files.readAllBytes(textureFile.toPath()), -1, false, false);
|
||||
Skin skin = new Skin(skinId, Files.readAllBytes(textureFile.toPath()), false);
|
||||
|
||||
String geoId = "";
|
||||
JsonElement json = new JsonParser().parse(new FileReader(geometryFile));
|
||||
@@ -199,8 +409,8 @@ public class GeyserUtils implements Extension {
|
||||
}
|
||||
}
|
||||
String geoName = "{\"geometry\" :{\"default\" :\"" + geoId + "\"}}";
|
||||
SkinProvider.SkinGeometry geometry = new SkinProvider.SkinGeometry(geoName, Files.readString(geometryFile.toPath()), false);
|
||||
LOADED_SKIN_DATA.put(skinId, new SkinProvider.SkinData(skin, getEmptyCapeData(), geometry));
|
||||
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();
|
||||
@@ -220,230 +430,190 @@ public class GeyserUtils implements Extension {
|
||||
CUSTOM_ENTITIES.remove(event.connection());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void registerPacketListener(GeyserSession session) {
|
||||
|
||||
scheduler.schedule(() -> {
|
||||
if (session.getDownstream() == null) {
|
||||
registerPacketListener(session);
|
||||
return;
|
||||
}
|
||||
scheduler.schedule(() -> {
|
||||
if (session.getDownstream() == null) {
|
||||
registerPacketListener(session);
|
||||
return;
|
||||
}
|
||||
|
||||
session.getDownstream().getSession().addListener(new SessionAdapter() {
|
||||
session.getDownstream().getSession().addListener(new SessionAdapter() {
|
||||
|
||||
@Override
|
||||
public void packetSending(PacketSendingEvent event) {
|
||||
Packet packet = event.getPacket();
|
||||
if (packet instanceof ServerboundCustomPayloadPacket payloadPacket) {
|
||||
if (payloadPacket.getChannel().equals("minecraft:register")) {
|
||||
String channels = new String(payloadPacket.getData(), StandardCharsets.UTF_8);
|
||||
channels = channels + "\0" + GeyserUtilsChannels.MAIN;
|
||||
event.setPacket(new ServerboundCustomPayloadPacket("minecraft:register", channels.getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@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 (payloadPacket.getChannel().equals(GeyserUtilsChannels.MAIN)) {
|
||||
CustomPayloadPacket customPacket = packetManager.decodePacket(payloadPacket.getData());
|
||||
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(new ServerboundCustomPayloadPacket(GeyserUtilsChannels.MAIN, packetManager.encodePacket(new NpcFormResponseCustomPayloadPacket(formData.formId(), finalI))));
|
||||
}
|
||||
}, button.hasNextForm()));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
form.closeHandler(() -> session.sendDownstreamPacket(new ServerboundCustomPayloadPacket(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 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.getDimension()));
|
||||
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) {
|
||||
SkinProvider.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());
|
||||
entity.updateBedrockMetadata();
|
||||
}
|
||||
} else if (customPacket instanceof CustomEntityPacket customEntityPacket) {
|
||||
logger().info("ID:" + customEntityPacket.getEntityId() + "; CUSTOM:" + customEntityPacket.getIdentifier());
|
||||
if (!LOADED_ENTITY_DEFINITIONS.containsKey(customEntityPacket.getIdentifier())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Cache<Integer, String> cache = CUSTOM_ENTITIES.get(session);
|
||||
cache.put(customEntityPacket.getEntityId(), customEntityPacket.getIdentifier());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}, 80, TimeUnit.MILLISECONDS);
|
||||
@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);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEntitySpawn(ServerSpawnEntityEvent event) {
|
||||
String def = CUSTOM_ENTITIES.get(event.connection()).getIfPresent(event.entityId());
|
||||
if (def == null) return;
|
||||
event.entityDefinition(LOADED_ENTITY_DEFINITIONS.getOrDefault(def, event.entityDefinition()));
|
||||
}
|
||||
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().addProperty(new BooleanProperty(Identifier.of(entityPropertyPacket.getIdentifier()), false), value);
|
||||
} else if (entityPropertyPacket.getValue() instanceof Integer value) {
|
||||
entity.getPropertyManager().addProperty(new IntProperty(Identifier.of(entityPropertyPacket.getIdentifier()), MAX_VALUE, MIN_VALUE, 0), 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();
|
||||
animateEntityPacket.setAnimation(animateEntityCustomPayloadPacket.getAnimation());
|
||||
animateEntityPacket.setController(animateEntityCustomPayloadPacket.getController());
|
||||
animateEntityPacket.setBlendOutTime(animateEntityCustomPayloadPacket.getBlendOutTime());
|
||||
animateEntityPacket.setNextState(animateEntityCustomPayloadPacket.getNextState());
|
||||
animateEntityPacket.setStopExpressionVersion(animateEntityCustomPayloadPacket.getStopExpressionVersion());
|
||||
animateEntityPacket.setStopExpression(animateEntityCustomPayloadPacket.getStopExpression());
|
||||
return animateEntityPacket;
|
||||
}
|
||||
|
||||
public static void sendSkinPacket(GeyserSession session, PlayerEntity entity, SkinProvider.SkinData skinData) {
|
||||
SkinProvider.Skin skin = skinData.skin();
|
||||
SkinProvider.Cape cape = skinData.cape();
|
||||
SkinProvider.SkinGeometry geometry = skinData.geometry();
|
||||
if (entity.getUuid().equals(session.getPlayerEntity().getUuid())) {
|
||||
PlayerListPacket.Entry updatedEntry = buildEntryManually(session, entity.getUuid(), entity.getUsername(), entity.getGeyserId(), skin, cape, geometry);
|
||||
PlayerListPacket playerAddPacket = new PlayerListPacket();
|
||||
playerAddPacket.setAction(PlayerListPacket.Action.ADD);
|
||||
playerAddPacket.getEntries().add(updatedEntry);
|
||||
session.sendUpstreamPacket(playerAddPacket);
|
||||
} else {
|
||||
PlayerSkinPacket packet = new PlayerSkinPacket();
|
||||
packet.setUuid(entity.getUuid());
|
||||
packet.setOldSkinName("");
|
||||
String skinId = skin.getTextureUrl() + UUID.randomUUID().toString().replace("-", "");
|
||||
packet.setNewSkinName(skinId);
|
||||
packet.setSkin(getSkin(skinId, skin, cape, geometry));
|
||||
packet.setTrustedSkin(true);
|
||||
session.sendUpstreamPacket(packet);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static PlayerListPacket.Entry buildEntryManually(GeyserSession session, UUID uuid, String username, long geyserId, SkinProvider.Skin skin, SkinProvider.Cape cape, SkinProvider.SkinGeometry geometry) {
|
||||
SerializedSkin serializedSkin = getSkin(skin.getTextureUrl(), skin, cape, geometry);
|
||||
String xuid = "";
|
||||
GeyserSession playerSession = GeyserImpl.getInstance().connectionByUuid(uuid);
|
||||
if (playerSession != null) {
|
||||
xuid = playerSession.getAuthData().xuid();
|
||||
}
|
||||
|
||||
PlayerListPacket.Entry entry;
|
||||
if (session.getPlayerEntity().getUuid().equals(uuid)) {
|
||||
entry = new PlayerListPacket.Entry(session.getAuthData().uuid());
|
||||
} else {
|
||||
entry = new PlayerListPacket.Entry(uuid);
|
||||
}
|
||||
|
||||
entry.setName(username);
|
||||
entry.setEntityId(geyserId);
|
||||
entry.setSkin(serializedSkin);
|
||||
entry.setXuid(xuid);
|
||||
entry.setPlatformChatId("");
|
||||
entry.setTeacher(false);
|
||||
entry.setTrustedSkin(true);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
private static SerializedSkin getSkin(String skinId, SkinProvider.Skin skin, SkinProvider.Cape cape, SkinProvider.SkinGeometry geometry) {
|
||||
|
||||
try {
|
||||
ImageData image = ImageData.from(ImageIO.read(new ByteArrayInputStream(skin.getSkinData())));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public static SkinProvider.Cape getEmptyCapeData() {
|
||||
return EMPTY_CAPE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
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.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class MountFix {
|
||||
|
||||
public static void start() {
|
||||
// just keep send SetEntityLinkPacket to fix the mount bug
|
||||
// https://github.com/GeyserMC/Geyser/issues/3302
|
||||
// if the vehicle is too fast, the problem appear
|
||||
Executors.newSingleThreadScheduledExecutor()
|
||||
.scheduleAtFixedRate(() -> {
|
||||
try {
|
||||
for (GeyserSession session : GeyserImpl.getInstance().onlineConnections()) {
|
||||
Entity v = session.getPlayerEntity().getVehicle();
|
||||
if (v != null && v.getDefinition() == EntityDefinitions.ARMOR_STAND) {
|
||||
session.setShouldSendSneak(true);
|
||||
long vehicleBedrockId = v.getGeyserId();
|
||||
if (session.getPlayerEntity().getVehicle().getGeyserId() == vehicleBedrockId) {
|
||||
// The Bedrock client, as of 1.19.51, dismounts on its end. The server may not agree with this.
|
||||
// If the server doesn't agree with our dismount (sends a packet saying we dismounted),
|
||||
// then remount the player.
|
||||
SetEntityLinkPacket linkPacket = new SetEntityLinkPacket();
|
||||
linkPacket.setEntityLink(new EntityLinkData(vehicleBedrockId, session.getPlayerEntity().getGeyserId(), EntityLinkData.Type.PASSENGER, true, false, 0f));
|
||||
session.sendUpstreamPacket(linkPacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}, 200, 50, TimeUnit.MILLISECONDS);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package me.zimzaza4.geyserutils.geyser.replace;
|
||||
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.*;
|
||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.skin.SkinManager;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.util.EnvironmentUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.FallingBlockData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.ProjectileData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.WardenData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundAddEntityPacket;
|
||||
|
||||
import static me.zimzaza4.geyserutils.geyser.GeyserUtils.CUSTOM_ENTITIES;
|
||||
import static me.zimzaza4.geyserutils.geyser.GeyserUtils.LOADED_ENTITY_DEFINITIONS;
|
||||
|
||||
|
||||
public class JavaAddEntityTranslatorReplace extends PacketTranslator<ClientboundAddEntityPacket> {
|
||||
private static final boolean SHOW_PLAYER_LIST_LOGS = Boolean.parseBoolean(System.getProperty("Geyser.ShowPlayerListLogs", "true"));
|
||||
|
||||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
|
||||
Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
|
||||
Vector3f motion = packet.getMovement().toFloat();
|
||||
float yaw = packet.getYaw();
|
||||
float pitch = packet.getPitch();
|
||||
float headYaw = packet.getHeadYaw();
|
||||
|
||||
if (packet.getType() == EntityType.PLAYER) {
|
||||
|
||||
PlayerEntity entity;
|
||||
if (packet.getUuid().equals(session.getPlayerEntity().getUuid())) {
|
||||
// Server is sending a fake version of the current player
|
||||
entity = new PlayerEntity(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
|
||||
session.getPlayerEntity().getUuid(), position, motion, yaw, pitch, headYaw, session.getPlayerEntity().getUsername(),
|
||||
session.getPlayerEntity().getTexturesProperty());
|
||||
} else {
|
||||
entity = session.getEntityCache().getPlayerEntity(packet.getUuid());
|
||||
if (entity == null) {
|
||||
if (SHOW_PLAYER_LIST_LOGS) {
|
||||
GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.entity.player.failed_list", packet.getUuid()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
entity.setEntityId(packet.getEntityId());
|
||||
entity.setPosition(position);
|
||||
entity.setYaw(yaw);
|
||||
entity.setPitch(pitch);
|
||||
entity.setHeadYaw(headYaw);
|
||||
entity.setMotion(motion);
|
||||
}
|
||||
|
||||
entity.sendPlayer();
|
||||
// only load skin if we're not in a test environment.
|
||||
// Otherwise, it tries to load various resources
|
||||
if (!EnvironmentUtils.IS_UNIT_TESTING) {
|
||||
SkinManager.requestAndHandleSkinAndCape(entity, session, null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Entity entity;
|
||||
if (packet.getType() == EntityType.FALLING_BLOCK) {
|
||||
entity = new FallingBlockEntity(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), packet.getUuid(),
|
||||
position, motion, yaw, pitch, headYaw, ((FallingBlockData) packet.getData()).getId());
|
||||
} else if (packet.getType() == EntityType.FISHING_BOBBER) {
|
||||
// Fishing bobbers need the owner for the line
|
||||
int ownerEntityId = ((ProjectileData) packet.getData()).getOwnerId();
|
||||
Entity owner = session.getEntityCache().getEntityByJavaId(ownerEntityId);
|
||||
// Java clients only spawn fishing hooks with a player as its owner
|
||||
if (owner instanceof PlayerEntity) {
|
||||
entity = new FishingHookEntity(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), packet.getUuid(),
|
||||
position, motion, yaw, pitch, headYaw, (PlayerEntity) owner);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else if (packet.getType() == EntityType.AREA_EFFECT_CLOUD) {
|
||||
definition = Registries.ENTITY_DEFINITIONS.get(EntityType.INTERACTION);
|
||||
entity = definition.factory().create(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
|
||||
packet.getUuid(), definition, position, motion, yaw, pitch, headYaw);
|
||||
} else {
|
||||
entity = definition.factory().create(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
|
||||
packet.getUuid(), definition, position, motion, yaw, pitch, headYaw);
|
||||
|
||||
// This is done over entity metadata in modern versions, but is still sent over network in the spawn packet
|
||||
if (entity instanceof HangingEntity hanging) {
|
||||
hanging.setDirection((Direction) packet.getData());
|
||||
}
|
||||
}
|
||||
|
||||
if (packet.getType() == EntityType.WARDEN) {
|
||||
WardenData wardenData = (WardenData) packet.getData();
|
||||
if (wardenData.isEmerging()) {
|
||||
entity.setPose(Pose.EMERGING);
|
||||
}
|
||||
}
|
||||
String def = CUSTOM_ENTITIES.get(session).getIfPresent(entity.getEntityId());
|
||||
if (def != null) {
|
||||
EntityDefinition newDef = LOADED_ENTITY_DEFINITIONS.getOrDefault(def, entity.getDefinition());
|
||||
entity.setDefinition(newDef);
|
||||
|
||||
// reinstantiate the entity object to create the propertymanager.
|
||||
entity = new Entity(entity.getSession(), entity.getEntityId(), entity.getGeyserId(), entity.getUuid(),
|
||||
entity.getDefinition(), entity.getPosition(), entity.getMotion(), yaw, pitch, headYaw);
|
||||
}
|
||||
|
||||
session.getEntityCache().spawnEntity(entity);
|
||||
}
|
||||
/*
|
||||
|
||||
*/
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
package me.zimzaza4.geyserutils.geyser.util;
|
||||
|
||||
public class DeltaUtils {
|
||||
public static double calculateDeltaE(double[] lab1, double[] lab2) {
|
||||
// CIEDE2000 algorithm implementation
|
||||
double deltaL = lab2[0] - lab1[0];
|
||||
double lBar = (lab1[0] + lab2[0]) / 2.0;
|
||||
double c1 = Math.sqrt(lab1[1] * lab1[1] + lab1[2] * lab1[2]);
|
||||
double c2 = Math.sqrt(lab2[1] * lab2[1] + lab2[2] * lab2[2]);
|
||||
double cBar = (c1 + c2) / 2.0;
|
||||
double a1Prime = lab1[1] + lab1[1] / 2.0 * (1 - Math.sqrt(Math.pow(cBar, 7) / (Math.pow(cBar, 7) + Math.pow(25, 7))));
|
||||
double a2Prime = lab2[1] + lab2[1] / 2.0 * (1 - Math.sqrt(Math.pow(cBar, 7) / (Math.pow(cBar, 7) + Math.pow(25, 7))));
|
||||
double c1Prime = Math.sqrt(a1Prime * a1Prime + lab1[2] * lab1[2]);
|
||||
double c2Prime = Math.sqrt(a2Prime * a2Prime + lab2[2] * lab2[2]);
|
||||
double cBarPrime = (c1Prime + c2Prime) / 2.0;
|
||||
double deltaCPrime = c2Prime - c1Prime;
|
||||
double h1Prime = Math.atan2(lab1[2], a1Prime);
|
||||
if (h1Prime < 0) h1Prime += 2 * Math.PI;
|
||||
double h2Prime = Math.atan2(lab2[2], a2Prime);
|
||||
if (h2Prime < 0) h2Prime += 2 * Math.PI;
|
||||
double deltahPrime = h2Prime - h1Prime;
|
||||
if (Math.abs(deltahPrime) > Math.PI) deltahPrime -= 2 * Math.PI * Math.signum(deltahPrime);
|
||||
double deltaHPrime = 2 * Math.sqrt(c1Prime * c2Prime) * Math.sin(deltahPrime / 2.0);
|
||||
double lBarPrime = (lab1[0] + lab2[0]) / 2.0;
|
||||
double cBarPrimeDelta = (c1Prime + c2Prime) / 2.0;
|
||||
double hBarPrime = (h1Prime + h2Prime) / 2.0;
|
||||
if (Math.abs(h1Prime - h2Prime) > Math.PI) hBarPrime -= Math.PI;
|
||||
double t = 1 - 0.17 * Math.cos(hBarPrime - Math.PI / 6) + 0.24 * Math.cos(2 * hBarPrime) + 0.32 * Math.cos(3 * hBarPrime + Math.PI / 30) - 0.20 * Math.cos(4 * hBarPrime - 63 * Math.PI / 180);
|
||||
double deltaTheta = 30 * Math.exp(-((hBarPrime - 275 * Math.PI / 180) / 25 * Math.PI / 180) * ((hBarPrime - 275 * Math.PI / 180) / 25 * Math.PI / 180));
|
||||
double rC = 2 * Math.sqrt(Math.pow(cBarPrimeDelta, 7) / (Math.pow(cBarPrimeDelta, 7) + Math.pow(25, 7)));
|
||||
double sL = 1 + (0.015 * (lBarPrime - 50) * (lBarPrime - 50)) / Math.sqrt(20 + (lBarPrime - 50) * (lBarPrime - 50));
|
||||
double sC = 1 + 0.045 * cBarPrimeDelta;
|
||||
double sH = 1 + 0.015 * cBarPrimeDelta * t;
|
||||
double rT = -Math.sin(2 * deltaTheta) * rC;
|
||||
return Math.sqrt((deltaL / sL) * (deltaL / sL) + (deltaCPrime / sC) * (deltaCPrime / sC) + (deltaHPrime / sH) * (deltaHPrime / sH) + rT * (deltaCPrime / sC) * (deltaHPrime / sH));
|
||||
}
|
||||
|
||||
public static double[] rgbToLab(int r, int g, int b) {
|
||||
// Convert RGB to XYZ
|
||||
double[] xyz = rgbToXyz(r, g, b);
|
||||
// Convert XYZ to Lab
|
||||
return xyzToLab(xyz[0], xyz[1], xyz[2]);
|
||||
}
|
||||
|
||||
private static double[] rgbToXyz(int r, int g, int b) {
|
||||
double var_R = (r / 255.0);
|
||||
double var_G = (g / 255.0);
|
||||
double var_B = (b / 255.0);
|
||||
|
||||
if (var_R > 0.04045) var_R = Math.pow((var_R + 0.055) / 1.055, 2.4);
|
||||
else var_R = var_R / 12.92;
|
||||
if (var_G > 0.04045) var_G = Math.pow((var_G + 0.055) / 1.055, 2.4);
|
||||
else var_G = var_G / 12.92;
|
||||
if (var_B > 0.04045) var_B = Math.pow((var_B + 0.055) / 1.055, 2.4);
|
||||
else var_B = var_B / 12.92;
|
||||
|
||||
var_R = var_R * 100.0;
|
||||
var_G = var_G * 100.0;
|
||||
var_B = var_B * 100.0;
|
||||
|
||||
// Observer. = 2°, Illuminant = D65
|
||||
double x = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805;
|
||||
double y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722;
|
||||
double z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505;
|
||||
|
||||
return new double[]{x, y, z};
|
||||
}
|
||||
|
||||
private static double[] xyzToLab(double x, double y, double z) {
|
||||
double ref_X = 95.047;
|
||||
double ref_Y = 100.000;
|
||||
double ref_Z = 108.883;
|
||||
|
||||
double var_X = x / ref_X;
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
else var_Z = (7.787 * var_Z) + (16.0 / 116.0);
|
||||
|
||||
double l = (116.0 * var_Y) - 16.0;
|
||||
double a = 500.0 * (var_X - var_Y);
|
||||
double b = 200.0 * (var_Y - var_Z);
|
||||
|
||||
return new double[]{l, a, b};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package me.zimzaza4.geyserutils.geyser.util;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.util.PlatformType;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundCustomPayloadPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class ReflectionUtils {
|
||||
|
||||
public static String prefix;
|
||||
public static Class<?> KEY_CLASS;
|
||||
|
||||
public static Class<?> CLIENTBOUND_PAYLOAD_PACKET_CLASS;
|
||||
|
||||
public static Class<?> SERVERBOUND_PAYLOAD_PACKET_CLASS;
|
||||
|
||||
public static Constructor<?> SERVERBOUND_PAYLOAD_PACKET_CONSTRUCTOR;
|
||||
public static Method KEY_BUILD_METHOD;
|
||||
|
||||
public static Method SERVERBOUND_GET_CHANNEL_METHOD;
|
||||
|
||||
public static Method CLIENTBOUND_GET_CHANNEL_METHOD;
|
||||
|
||||
public static boolean OLD_VERSION = false;
|
||||
|
||||
@SneakyThrows
|
||||
public static void init() {
|
||||
PlatformType type = GeyserImpl.getInstance().platformType();
|
||||
prefix = type == PlatformType.STANDALONE || type == PlatformType.VELOCITY ? "" : "org.geysermc.geyser.platform." + type.platformName().toLowerCase() + ".shaded.";
|
||||
CLIENTBOUND_PAYLOAD_PACKET_CLASS = ClientboundCustomPayloadPacket.class;
|
||||
SERVERBOUND_PAYLOAD_PACKET_CLASS = ServerboundCustomPayloadPacket.class;
|
||||
KEY_CLASS = Class.forName(prefix + "net.kyori.adventure.key.Key");
|
||||
CLIENTBOUND_GET_CHANNEL_METHOD = CLIENTBOUND_PAYLOAD_PACKET_CLASS.getMethod("getChannel");
|
||||
SERVERBOUND_GET_CHANNEL_METHOD = SERVERBOUND_PAYLOAD_PACKET_CLASS.getMethod("getChannel");
|
||||
|
||||
try {
|
||||
SERVERBOUND_PAYLOAD_PACKET_CONSTRUCTOR = SERVERBOUND_PAYLOAD_PACKET_CLASS.getConstructor(KEY_CLASS, byte[].class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
OLD_VERSION = true;
|
||||
SERVERBOUND_PAYLOAD_PACKET_CONSTRUCTOR = SERVERBOUND_PAYLOAD_PACKET_CLASS.getConstructor(String.class, byte[].class);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
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;
|
||||
return KEY_BUILD_METHOD.invoke(null, key);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
name: GeyserUtils
|
||||
id: geyserutils
|
||||
main: me.zimzaza4.geyserutils.geyser.GeyserUtils
|
||||
api: 1.0.0
|
||||
api: 2.4.1
|
||||
version: 1.0.0
|
||||
authors: [zimzaza4]
|
||||
authors: [ zimzaza4, willem.dev ]
|
||||
@@ -21,7 +21,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<version>3.13.0</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
@@ -61,6 +61,10 @@
|
||||
<id>sonatype</id>
|
||||
<url>https://oss.sonatype.org/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>opencollab-snapshot</id>
|
||||
<url>https://repo.opencollab.dev/main/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -4,15 +4,12 @@ import lombok.Getter;
|
||||
import me.zimzaza4.geyserutils.common.camera.data.CameraPreset;
|
||||
import me.zimzaza4.geyserutils.common.channel.GeyserUtilsChannels;
|
||||
import me.zimzaza4.geyserutils.common.manager.PacketManager;
|
||||
import me.zimzaza4.geyserutils.common.packet.NpcFormResponseCustomPayloadPacket;
|
||||
import me.zimzaza4.geyserutils.common.packet.CustomPayloadPacket;
|
||||
import me.zimzaza4.geyserutils.common.util.CustomPayloadPacketUtils;
|
||||
import me.zimzaza4.geyserutils.common.packet.NpcFormResponseCustomPayloadPacket;
|
||||
import me.zimzaza4.geyserutils.spigot.api.form.NpcDialogueForm;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.plugin.messaging.Messenger;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public final class GeyserUtils extends JavaPlugin {
|
||||
|
||||
@Getter
|
||||
@@ -20,6 +17,7 @@ public final class GeyserUtils extends JavaPlugin {
|
||||
|
||||
@Getter
|
||||
private static PacketManager packetManager;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// Plugin startup logic
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
package me.zimzaza4.geyserutils.spigot.api;
|
||||
|
||||
import me.zimzaza4.geyserutils.common.channel.GeyserUtilsChannels;
|
||||
import me.zimzaza4.geyserutils.common.packet.*;
|
||||
import me.zimzaza4.geyserutils.spigot.GeyserUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Map;
|
||||
|
||||
public class EntityUtils {
|
||||
|
||||
public static void sendCustomHitBox(Player player, int id, float height, float width) {
|
||||
CustomEntityDataPacket packet = new CustomEntityDataPacket();
|
||||
packet.setEntityId(id);
|
||||
packet.setWidth(width);
|
||||
packet.setHeight(height);
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
|
||||
}
|
||||
|
||||
public static void sendCustomScale(Player player, int id, float scale) {
|
||||
CustomEntityDataPacket packet = new CustomEntityDataPacket();
|
||||
packet.setEntityId(id);
|
||||
packet.setScale(scale);
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
|
||||
}
|
||||
|
||||
public static void sendCustomColor(Player player, int id, Color color) {
|
||||
CustomEntityDataPacket packet = new CustomEntityDataPacket();
|
||||
packet.setEntityId(id);
|
||||
packet.setColor(color.getRGB());
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
|
||||
}
|
||||
|
||||
public static void sendVariant(Player player, int id, int variant) {
|
||||
CustomEntityDataPacket packet = new CustomEntityDataPacket();
|
||||
packet.setEntityId(id);
|
||||
packet.setVariant(variant);
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void setCustomEntity(Player player, int entityId, String def) {
|
||||
CustomEntityPacket packet = new CustomEntityPacket(entityId, def);
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
|
||||
}
|
||||
|
||||
// (yes I'm aware it's "horrible" code), also this aint player packets at all lmao
|
||||
// right, so this part needs to be refactored xD
|
||||
// the plugin didn't have this much functionality in its earliest days (it even just have camera shakes),
|
||||
// so I didn't think too much about it
|
||||
|
||||
public static void registerProperty(Player player, int id, String identifier, Class<?> type) {
|
||||
EntityPropertyRegisterPacket packet = new EntityPropertyRegisterPacket();
|
||||
packet.setEntityId(id);
|
||||
packet.setIdentifier(identifier);
|
||||
packet.setType(type);
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
}
|
||||
|
||||
public static void sendBoolProperty(Player player, int id, String identifier, Boolean value) {
|
||||
EntityPropertyPacket<Boolean> packet = new EntityPropertyPacket<>();
|
||||
packet.setEntityId(id);
|
||||
packet.setIdentifier(identifier);
|
||||
packet.setValue(value);
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
}
|
||||
|
||||
public static void sendBoolProperties(Player player, int id, Map<String, Boolean> bundle) {
|
||||
BundlePacket packet = new BundlePacket();
|
||||
bundle.forEach((identifier, value) -> {
|
||||
EntityPropertyPacket<Boolean> propertyPacket = new EntityPropertyPacket<>();
|
||||
propertyPacket.setEntityId(id);
|
||||
propertyPacket.setIdentifier(identifier);
|
||||
propertyPacket.setValue(value);
|
||||
packet.addPacket(propertyPacket);
|
||||
});
|
||||
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
}
|
||||
|
||||
public static void sendFloatProperty(Player player, int id, String identifier, Float value) {
|
||||
EntityPropertyPacket<Float> packet = new EntityPropertyPacket<>();
|
||||
packet.setEntityId(id);
|
||||
packet.setIdentifier(identifier);
|
||||
packet.setValue(value);
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
}
|
||||
|
||||
public static void sendFloatProperties(Player player, int id, Map<String, Float> bundle) {
|
||||
BundlePacket packet = new BundlePacket();
|
||||
bundle.forEach((identifier, value) -> {
|
||||
EntityPropertyPacket<Float> propertyPacket = new EntityPropertyPacket<>();
|
||||
propertyPacket.setEntityId(id);
|
||||
propertyPacket.setIdentifier(identifier);
|
||||
propertyPacket.setValue(value);
|
||||
packet.addPacket(propertyPacket);
|
||||
});
|
||||
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
}
|
||||
|
||||
public static void sendIntProperty(Player player, int id, String identifier, Integer value) {
|
||||
EntityPropertyPacket<Integer> packet = new EntityPropertyPacket<>();
|
||||
packet.setEntityId(id);
|
||||
packet.setIdentifier(identifier);
|
||||
packet.setValue(value);
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
}
|
||||
|
||||
public static void sendIntProperties(Player player, int id, Map<String, Integer> bundle) {
|
||||
BundlePacket packet = new BundlePacket();
|
||||
bundle.forEach((identifier, value) -> {
|
||||
EntityPropertyPacket<Integer> propertyPacket = new EntityPropertyPacket<>();
|
||||
propertyPacket.setEntityId(id);
|
||||
propertyPacket.setIdentifier(identifier);
|
||||
propertyPacket.setValue(value);
|
||||
packet.addPacket(propertyPacket);
|
||||
});
|
||||
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,10 @@ import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PlayerUtils {
|
||||
|
||||
@@ -61,25 +63,51 @@ public class PlayerUtils {
|
||||
}
|
||||
|
||||
public static void sendCustomHitBox(Player player, Entity entity, float height, float width) {
|
||||
CustomEntityDataPacket packet = new CustomEntityDataPacket();
|
||||
packet.setEntityId(entity.getEntityId());
|
||||
packet.setWidth(width);
|
||||
packet.setHeight(height);
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
|
||||
EntityUtils.sendCustomHitBox(player, entity.getEntityId(), height, width);
|
||||
}
|
||||
|
||||
public static void sendCustomScale(Player player, Entity entity, float scale) {
|
||||
CustomEntityDataPacket packet = new CustomEntityDataPacket();
|
||||
packet.setEntityId(entity.getEntityId());
|
||||
packet.setScale(scale);
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
|
||||
EntityUtils.sendCustomScale(player, entity.getEntityId(), scale);
|
||||
}
|
||||
|
||||
public static void setCustomEntity(Player player, int entityId, String def) {
|
||||
CustomEntityPacket packet = new CustomEntityPacket(entityId, def);
|
||||
player.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(packet));
|
||||
public static void sendCustomColor(Player player, Entity entity, Color color) {
|
||||
EntityUtils.sendCustomColor(player, entity.getEntityId(), color);
|
||||
}
|
||||
|
||||
public static void setCustomEntity(Player player, int id, String def) {
|
||||
EntityUtils.setCustomEntity(player, id, def);
|
||||
}
|
||||
|
||||
// (yes I'm aware it's "horrible" code), also this aint player packets at all lmao
|
||||
// right, so this part needs to be refactored xD
|
||||
// the plugin didn't have this much functionality in its earliest days (it even just have camera shakes),
|
||||
// so I didn't think too much about it
|
||||
|
||||
public static void registerProperty(Player player, Entity entity, String identifier, Class<?> type) {
|
||||
EntityUtils.registerProperty(player, entity.getEntityId(), identifier, type);
|
||||
}
|
||||
|
||||
public static void sendBoolProperty(Player player, Entity entity, String identifier, Boolean value) {
|
||||
EntityUtils.sendBoolProperty(player, entity.getEntityId(), identifier, value);
|
||||
}
|
||||
|
||||
public static void sendBoolProperties(Player player, Entity entity, Map<String, Boolean> bundle) {
|
||||
EntityUtils.sendBoolProperties(player, entity.getEntityId(), bundle);
|
||||
}
|
||||
|
||||
public static void sendFloatProperty(Player player, Entity entity, String identifier, Float value) {
|
||||
EntityUtils.sendFloatProperty(player, entity.getEntityId(), identifier, value);
|
||||
}
|
||||
|
||||
public static void sendFloatProperties(Player player, Entity entity, Map<String, Float> bundle) {
|
||||
EntityUtils.sendFloatProperties(player, entity.getEntityId(), bundle);
|
||||
}
|
||||
|
||||
public static void sendIntProperty(Player player, Entity entity, String identifier, Integer value) {
|
||||
EntityUtils.sendIntProperty(player, entity.getEntityId(), identifier, value);
|
||||
}
|
||||
|
||||
public static void sendIntProperties(Player player, Entity entity, Map<String, Integer> bundle) {
|
||||
EntityUtils.sendIntProperties(player, entity.getEntityId(), bundle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import lombok.experimental.Accessors;
|
||||
import me.zimzaza4.geyserutils.common.channel.GeyserUtilsChannels;
|
||||
import me.zimzaza4.geyserutils.common.form.element.NpcDialogueButton;
|
||||
import me.zimzaza4.geyserutils.common.packet.NpcDialogueFormDataCustomPayloadPacket;
|
||||
import me.zimzaza4.geyserutils.common.util.CustomPayloadPacketUtils;
|
||||
import me.zimzaza4.geyserutils.spigot.GeyserUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
@@ -27,7 +26,7 @@ import java.util.function.Consumer;
|
||||
@AllArgsConstructor
|
||||
@Setter
|
||||
@Getter
|
||||
@Accessors( fluent = true )
|
||||
@Accessors(fluent = true)
|
||||
public class NpcDialogueForm {
|
||||
|
||||
public static Map<String, NpcDialogueForm> FORMS = new HashMap<>();
|
||||
@@ -41,31 +40,6 @@ public class NpcDialogueForm {
|
||||
BiConsumer<String, Integer> handler;
|
||||
Consumer<String> closeHandler;
|
||||
|
||||
public void send(FloodgatePlayer floodgatePlayer) {
|
||||
UUID formId = UUID.randomUUID();
|
||||
NpcDialogueFormDataCustomPayloadPacket data = new NpcDialogueFormDataCustomPayloadPacket(formId.toString(), title, dialogue, skinData, bindEntity.getEntityId(), buttons, "OPEN", hasNextForm);
|
||||
Player p = Bukkit.getPlayer(floodgatePlayer.getCorrectUniqueId());
|
||||
if (p!= null) {
|
||||
|
||||
FORMS.put(formId.toString(), this);
|
||||
|
||||
p.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(data));
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!FORMS.containsKey(formId.toString())) {
|
||||
this.cancel();
|
||||
}
|
||||
if (!p.isOnline()) {
|
||||
FORMS.remove(formId.toString());
|
||||
}
|
||||
|
||||
}
|
||||
}.runTaskTimerAsynchronously(GeyserUtils.getInstance(), 10, 10);
|
||||
}
|
||||
}
|
||||
|
||||
public static void closeForm(FloodgatePlayer floodgatePlayer) {
|
||||
NpcDialogueFormDataCustomPayloadPacket data = new NpcDialogueFormDataCustomPayloadPacket(null, null, null, null, -1, null, "CLOSE", false);
|
||||
Player p = Bukkit.getPlayer(floodgatePlayer.getCorrectUniqueId());
|
||||
@@ -73,4 +47,29 @@ public class NpcDialogueForm {
|
||||
p.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(data));
|
||||
}
|
||||
}
|
||||
|
||||
public void send(FloodgatePlayer floodgatePlayer) {
|
||||
UUID formId = UUID.randomUUID();
|
||||
NpcDialogueFormDataCustomPayloadPacket data = new NpcDialogueFormDataCustomPayloadPacket(formId.toString(), title, dialogue, skinData, bindEntity.getEntityId(), buttons, "OPEN", hasNextForm);
|
||||
Player p = Bukkit.getPlayer(floodgatePlayer.getCorrectUniqueId());
|
||||
if (p != null) {
|
||||
|
||||
FORMS.put(formId.toString(), this);
|
||||
|
||||
p.sendPluginMessage(GeyserUtils.getInstance(), GeyserUtilsChannels.MAIN, GeyserUtils.getPacketManager().encodePacket(data));
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!FORMS.containsKey(formId.toString())) {
|
||||
this.cancel();
|
||||
}
|
||||
if (!p.isOnline()) {
|
||||
FORMS.remove(formId.toString());
|
||||
}
|
||||
|
||||
}
|
||||
}.runTaskTimerAsynchronously(GeyserUtils.getInstance(), 10, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
name: GeyserUtils
|
||||
version: '${project.version}'
|
||||
main: me.zimzaza4.geyserutils.spigot.GeyserUtils
|
||||
authors:
|
||||
- zimzaza4
|
||||
- willem.dev
|
||||
@@ -12,7 +12,7 @@
|
||||
<name>geyserutils-velocity</name>
|
||||
|
||||
<properties>
|
||||
<java.version>11</java.version>
|
||||
<java.version>21</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
@@ -47,23 +47,7 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-site-plugin</artifactId>
|
||||
<version>3.9.1</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.trajano.wagon</groupId>
|
||||
<artifactId>wagon-git</artifactId>
|
||||
<version>2.0.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.doxia</groupId>
|
||||
<artifactId>doxia-module-markdown</artifactId>
|
||||
<version>1.9.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.nio.file.Path;
|
||||
public class GeyserUtils {
|
||||
|
||||
private final ProxyServer server;
|
||||
|
||||
@Inject
|
||||
public GeyserUtils(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) {
|
||||
this.server = server;
|
||||
|
||||
Reference in New Issue
Block a user