Merge pull request #2 from Tofaa2/feat/platform-api

Feat/platform api
This commit is contained in:
Tofaa 2024-02-17 19:14:08 +04:00 committed by GitHub
commit f5e4bc381c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
212 changed files with 3757 additions and 1259 deletions

4
.gitignore vendored
View file

@ -1,5 +1,9 @@
.gradle .gradle
build/ build/
.idea
run
test-plugin/build
test-plugin/run
!gradle/wrapper/gradle-wrapper.jar !gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/ !**/src/main/**/build/
!**/src/test/**/build/ !**/src/test/**/build/

View file

@ -8,6 +8,11 @@
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/api" />
<option value="$PROJECT_DIR$/code-gen" />
<option value="$PROJECT_DIR$/common" />
<option value="$PROJECT_DIR$/platforms" />
<option value="$PROJECT_DIR$/platforms/spigot" />
<option value="$PROJECT_DIR$/test-plugin" /> <option value="$PROJECT_DIR$/test-plugin" />
</set> </set>
</option> </option>

View file

@ -6,6 +6,9 @@
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="9d5d9b6f-43c8-41a4-bb42-a66ffc96c9b0" name="Changes" comment=""> <list default="true" id="9d5d9b6f-43c8-41a4-bb42-a66ffc96c9b0" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/meta/Metadata.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/meta/Metadata.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntityEquipment.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntityEquipment.java" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -36,6 +39,24 @@
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" /> <item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="EntityLib" type="f1a62948:ProjectNode" /> <item name="EntityLib" type="f1a62948:ProjectNode" />
</path> </path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="EntityLib" type="f1a62948:ProjectNode" />
<item name="test-plugin" type="2d1252cf:ModuleNode" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="EntityLib" type="f1a62948:ProjectNode" />
<item name="test-plugin" type="2d1252cf:ModuleNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="EntityLib" type="f1a62948:ProjectNode" />
<item name="test-plugin" type="2d1252cf:ModuleNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" />
<item name="run paper" type="c8890929:TasksNode$1" />
</path>
</expand> </expand>
<select /> <select />
</tree_state> </tree_state>
@ -70,34 +91,78 @@
</component> </component>
<component name="PropertiesComponent">{ <component name="PropertiesComponent">{
&quot;keyToString&quot;: { &quot;keyToString&quot;: {
&quot;Downloaded.Files.Path.Enabled&quot;: &quot;false&quot;,
&quot;Gradle.Build EntityLib.executor&quot;: &quot;Run&quot;, &quot;Gradle.Build EntityLib.executor&quot;: &quot;Run&quot;,
&quot;Gradle.EntityLib [dependencies].executor&quot;: &quot;Run&quot;,
&quot;Gradle.EntityLib:code-gen [:code-gen:Main.main()].executor&quot;: &quot;Run&quot;,
&quot;Gradle.EntityLib:test-plugin [runServer].executor&quot;: &quot;Run&quot;, &quot;Gradle.EntityLib:test-plugin [runServer].executor&quot;: &quot;Run&quot;,
&quot;Gradle.EntityLib:test-plugin [shadowJar].executor&quot;: &quot;Run&quot;,
&quot;Repository.Attach.Annotations&quot;: &quot;false&quot;,
&quot;Repository.Attach.JavaDocs&quot;: &quot;false&quot;,
&quot;Repository.Attach.Sources&quot;: &quot;false&quot;,
&quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;, &quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;, &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;, &quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
&quot;git-widget-placeholder&quot;: &quot;master&quot;, &quot;git-widget-placeholder&quot;: &quot;feat/platform-api&quot;,
&quot;ignore.virus.scanning.warn.message&quot;: &quot;true&quot;, &quot;ignore.virus.scanning.warn.message&quot;: &quot;true&quot;,
&quot;jdk.selected.JAVA_MODULE&quot;: &quot;corretto-17&quot;, &quot;jdk.selected.JAVA_MODULE&quot;: &quot;corretto-17&quot;,
&quot;kotlin-language-version-configured&quot;: &quot;true&quot;, &quot;kotlin-language-version-configured&quot;: &quot;true&quot;,
&quot;last_opened_file_path&quot;: &quot;D:/Github/EntityLib&quot;, &quot;last_opened_file_path&quot;: &quot;D:/Github/EntityLib/api/src/main/java/me/tofaa/entitylib/extras&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;, &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;, &quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;, &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;, &quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;, &quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;project.structure.last.edited&quot;: &quot;Modules&quot;, &quot;project.structure.last.edited&quot;: &quot;Project&quot;,
&quot;project.structure.proportion&quot;: &quot;0.0&quot;, &quot;project.structure.proportion&quot;: &quot;0.15&quot;,
&quot;project.structure.side.proportion&quot;: &quot;0.0&quot;, &quot;project.structure.side.proportion&quot;: &quot;0.2&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.pluginManager&quot;, &quot;settings.editor.selected.configurable&quot;: &quot;preferences.pluginManager&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot; &quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
} }
}</component> }</component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS"> <key name="CopyFile.RECENT_KEYS">
<recent name="D:\Github\EntityLib\api\src\main\java\me\tofaa\entitylib\extras" />
<recent name="D:\Github\EntityLib\api\src\main\java\me\tofaa\entitylib\meta" />
<recent name="D:\Github\EntityLib\test-plugin" /> <recent name="D:\Github\EntityLib\test-plugin" />
</key> </key>
</component> </component>
<component name="RunManager" selected="Gradle.EntityLib:test-plugin [runServer]"> <component name="RunManager" selected="Gradle.EntityLib:test-plugin [runServer]">
<configuration name="Main" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="me.tofaa.entitylib.codegen.Main" />
<module name="EntityLib.code-gen.main" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="me.tofaa.entitylib.codegen.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="EntityLib [dependencies]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="dependencies" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<RunAsTest>false</RunAsTest>
<method v="2" />
</configuration>
<configuration name="EntityLib:test-plugin [runServer]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true"> <configuration name="EntityLib:test-plugin [runServer]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
<ExternalSystemSettings> <ExternalSystemSettings>
<option name="executionName" /> <option name="executionName" />
@ -167,8 +232,10 @@
<recent_temporary> <recent_temporary>
<list> <list>
<item itemvalue="Gradle.EntityLib:test-plugin [runServer]" /> <item itemvalue="Gradle.EntityLib:test-plugin [runServer]" />
<item itemvalue="Gradle.PE-EntityMeta [compileTestJava]" />
<item itemvalue="Gradle.EntityLib:test-plugin [shadowJar]" /> <item itemvalue="Gradle.EntityLib:test-plugin [shadowJar]" />
<item itemvalue="Application.Main" />
<item itemvalue="Gradle.EntityLib [dependencies]" />
<item itemvalue="Gradle.PE-EntityMeta [compileTestJava]" />
</list> </list>
</recent_temporary> </recent_temporary>
</component> </component>
@ -211,8 +278,26 @@
<workItem from="1705534524814" duration="15424000" /> <workItem from="1705534524814" duration="15424000" />
<workItem from="1705578156456" duration="78000" /> <workItem from="1705578156456" duration="78000" />
<workItem from="1705636302508" duration="7111000" /> <workItem from="1705636302508" duration="7111000" />
<workItem from="1705951390204" duration="4325000" /> <workItem from="1705951390204" duration="3936000" />
<workItem from="1707678043163" duration="66000" /> <workItem from="1705984769972" duration="76000" />
<workItem from="1706183895216" duration="664000" />
<workItem from="1706187926445" duration="4339000" />
<workItem from="1706248178234" duration="17096000" />
<workItem from="1706284605696" duration="11691000" />
<workItem from="1706371324325" duration="1187000" />
<workItem from="1706443875388" duration="4827000" />
<workItem from="1706513591682" duration="8659000" />
<workItem from="1706592660140" duration="89000" />
<workItem from="1706601592145" duration="1670000" />
<workItem from="1706614921404" duration="10508000" />
<workItem from="1706696719616" duration="4783000" />
<workItem from="1706784821835" duration="7882000" />
<workItem from="1706858181164" duration="925000" />
<workItem from="1707159905372" duration="3391000" />
<workItem from="1707210065718" duration="4823000" />
<workItem from="1707219870641" duration="5522000" />
<workItem from="1707300688189" duration="1512000" />
<workItem from="1707381529971" duration="921000" />
</task> </task>
<servers /> <servers />
</component> </component>
@ -227,10 +312,15 @@
<line>6787</line> <line>6787</line>
<option name="timeStamp" value="1" /> <option name="timeStamp" value="1" />
</line-breakpoint> </line-breakpoint>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/LegacyHologram.java</url>
<line>37</line>
<option name="timeStamp" value="3" />
</line-breakpoint>
<line-breakpoint enabled="true" type="java-method"> <line-breakpoint enabled="true" type="java-method">
<url>file://$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/meta/types/DisplayMeta.java</url> <url>file://$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/meta/types/DisplayMeta.java</url>
<line>173</line> <line>153</line>
<properties class="me.tofaa.entitylib.meta.types.DisplayMeta" method="setShadowRadius"> <properties class="me.tofaa.entitylib.meta.types.DisplayMeta">
<option name="EMULATED" value="true" /> <option name="EMULATED" value="true" />
<option name="WATCH_EXIT" value="false" /> <option name="WATCH_EXIT" value="false" />
</properties> </properties>

18
api/build.gradle Normal file
View file

@ -0,0 +1,18 @@
plugins {
id 'java'
id 'java-library'
}
group = 'me.tofaa.entitylib'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
api 'org.jetbrains:annotations:24.0.0'
compileOnlyApi(adventureDependencies)
compileOnlyApi 'com.github.retrooper.packetevents:api:2.2.1'
}

View file

@ -0,0 +1,102 @@
package me.tofaa.entitylib;
import com.github.retrooper.packetevents.PacketEventsAPI;
import com.google.gson.JsonArray;
import com.google.gson.JsonParser;
import org.jetbrains.annotations.Blocking;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
public final class APIConfig {
private final PacketEventsAPI<?> packetEvents;
private boolean debugMode = false;
private boolean checkForUpdates = false;
private boolean tickTickables = false;
private boolean platformLogger = false;
private boolean useAsyncEvents = false;
private boolean defaultCommands = false;
public APIConfig(PacketEventsAPI<?> packetEvents) {
this.packetEvents = packetEvents;
}
@Blocking
public boolean requiresUpdate() throws IOException {
if (!checkForUpdates) return false;
String urlString = "https://api.github.com/repos/Tofaa2/EntityLib/releases/latest";
String version = EntityLib.getVersion();
URL url = new URL(urlString);
JsonParser json = new JsonParser();
InputStream stream = url.openStream();
JsonArray array = json.parse(new InputStreamReader(stream)).getAsJsonArray();
String latest = array.get(0).getAsJsonObject().get("tag_name").getAsString();
stream.close();
return !version.equalsIgnoreCase(latest);
}
public @NotNull APIConfig usePlatformLogger() {
this.platformLogger = true;
return this;
}
public @NotNull APIConfig checkForUpdates() {
this.checkForUpdates = true;
return this;
}
public @NotNull APIConfig tickTickables() {
this.tickTickables = true;
return this;
}
public @NotNull APIConfig debugMode() {
this.debugMode = true;
return this;
}
public @NotNull APIConfig registerDefaultCommands() {
this.defaultCommands = true;
return this;
}
public @NotNull APIConfig useAsyncEvents() {
this.useAsyncEvents = true;
return this;
}
public boolean shouldRegisterDefaultCommands() {
return defaultCommands;
}
public boolean isDebugMode() {
return debugMode;
}
public boolean shouldCheckForUpdate() {
return checkForUpdates;
}
public boolean shouldTickTickables() {
return tickTickables;
}
public PacketEventsAPI<?> getPacketEvents() {
return packetEvents;
}
public boolean shouldUsePlatformLogger() {
return platformLogger;
}
public boolean shouldUseAsyncEvents() {
return useAsyncEvents;
}
}

View file

@ -0,0 +1,28 @@
package me.tofaa.entitylib;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Represents a int provider that gives an id for each entity created. When using EntityLib with platform specific entities (Such as bukkit entities), make sure the id's do not
* conflict with the platform's entity id's.
* {@link DefaultEntityIdProvider} is a default implementation of this interface.
*/
public interface EntityIdProvider {
int provide(@NotNull UUID entityUUID, @NotNull EntityType entityType);
class DefaultEntityIdProvider implements EntityIdProvider {
private final AtomicInteger integer = new AtomicInteger(100000);
@Override
public int provide(@NotNull UUID entityUUID, @NotNull EntityType entityType) {
return integer.incrementAndGet();
}
}
}

View file

@ -0,0 +1,44 @@
package me.tofaa.entitylib;
import java.io.IOException;
import java.util.logging.Level;
public final class EntityLib {
private EntityLib() {}
private static Platform platform;
private static EntityLibAPI api;
public static void init(Platform<?> platform, APIConfig settings) {
EntityLib.platform = platform;
platform.setupApi(settings);
api = platform.getAPI();
if (api.getSettings().shouldCheckForUpdate()) {
try {
if (api.getSettings().isDebugMode()) {
platform.getLogger().log(Level.CONFIG, "Checking for updates...");
}
if (api.getSettings().requiresUpdate()) {
platform.getLogger().log(Level.WARNING, "You are using an outdated version of EntityLib. Please take a look at the Github releases page.");
}
}
catch (IOException e) {
platform.getLogger().log(Level.WARNING, e, () -> "EntityLib failed to check for updates.");
}
}
}
public static <T> EntityLibAPI<T> getApi() {
return api;
}
public static Platform<?> getPlatform() {
return platform;
}
public static String getVersion() {
return "1.2.0-SNAPSHOT";
}
}

View file

@ -0,0 +1,66 @@
package me.tofaa.entitylib;
import com.github.retrooper.packetevents.PacketEventsAPI;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import com.github.retrooper.packetevents.protocol.player.UserProfile;
import com.github.retrooper.packetevents.protocol.world.Location;
import me.tofaa.entitylib.tick.TickContainer;
import me.tofaa.entitylib.wrapper.WrapperEntity;
import me.tofaa.entitylib.wrapper.WrapperPlayer;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.UUID;
/**
* Represents the API for EntityLib.
* Handles the loading, enabling, and disabling of the API. And handles platform specific creation of EntityLib content.
* @param <T> The {@link TickContainer}'s param type for the platform specific TickContainer.
*/
public interface EntityLibAPI<T> {
/**
* @return The {@link PacketEventsAPI} that EntityLib uses.
*/
PacketEventsAPI<?> getPacketEvents();
void onLoad();
void onEnable();
@NotNull WrapperPlayer spawnPlayer(UserProfile profile, Location location);
@NotNull <T extends WrapperEntity> T spawnEntity(@NotNull Class<T> wrapperClass, @NotNull EntityType entityType, @NotNull Location location);
@NotNull WrapperEntity spawnEntity(@NotNull EntityType entityType, @NotNull Location location);
@NotNull <T extends WrapperEntity> T spawnEntity(@NotNull T entity, @NotNull Location location);
@NotNull <T extends WrapperEntity> T cloneEntity(@NotNull Object platformEntity, @NotNull Location location);
@Nullable WrapperEntity getEntity(int id);
@Nullable WrapperEntity getEntity(@NotNull UUID uuid);
void removeEntity(WrapperEntity entity);
@NotNull Collection<WrapperEntity> getAllEntities();
/**
* @return The {@link APIConfig} for the API.
*/
@NotNull APIConfig getSettings();
/**
* @return An unmodifiable collection of TickContainers.
*/
@NotNull Collection<TickContainer<?, T>> getTickContainers();
/**
* Adds a TickContainer to the API. Automatically starts ticking it.
* @param tickContainer the TickContainer to add.
*/
void addTickContainer(@NotNull TickContainer<?, T> tickContainer);
}

View file

@ -0,0 +1,22 @@
package me.tofaa.entitylib;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
public interface EntityUuidProvider {
@NotNull UUID provide(EntityType entityType);
class DefaultEntityUuidProvider implements EntityUuidProvider {
@Override
public @NotNull UUID provide(EntityType entityType) {
return UUID.randomUUID();
}
}
}

View file

@ -0,0 +1,69 @@
package me.tofaa.entitylib;
import me.tofaa.entitylib.event.EventBus;
import org.jetbrains.annotations.NotNull;
import java.util.logging.Logger;
/**
* A generic representation of a platform that EntityLib is running on.
* @param <P> The platform handle, for Spigot this would be a JavaPlugin. etc etc.
*/
public interface Platform<P> {
/**
* Gets the entityId integer provider. This can be provided by a platform if needed.
* @return the entityId integer provider.
*/
@NotNull EntityIdProvider getEntityIdProvider();
/**
* Gets the UUID provider for entities. This can be provided by a platform if needed.
* @return the UUID provider for entities.
*/
@NotNull EntityUuidProvider getEntityUuidProvider();
/**
* Sets the entityId integer provider. This can be provided by a platform if needed.
* @param provider the entityId integer provider.
*/
void setEntityIdProvider(@NotNull EntityIdProvider provider);
/**
* Sets the UUID provider for entities. This can be provided by a platform if needed.
* @param provider
*/
void setEntityUuidProvider(@NotNull EntityUuidProvider provider);
/**
* @return the logger EntityLib uses internally.
*/
@NotNull Logger getLogger();
/**
* Gets the event bus for the platform.
* WARNING: If you have {@link APIConfig#shouldUseAsyncEvents()} set to true, cast this to {@link EventBus.Async} when handling cancelled events.
* @return
*/
@NotNull EventBus getEventBus();
/**
* Sets up the API for the platform. This method should be called automatically by the platform. Don't call it yourself.
* @param settings
*/
void setupApi(@NotNull APIConfig settings);
/**
* @return The API instance.
*/
EntityLibAPI<?> getAPI();
/**
* @return the platforms name.
*/
String getName();
@NotNull P getHandle();
}

View file

@ -0,0 +1,8 @@
package me.tofaa.entitylib.event;
public interface EntityLibEvent {
boolean isCancelled();
void setCancelled(boolean cancelled);
}

View file

@ -0,0 +1,61 @@
package me.tofaa.entitylib.event;
import org.jetbrains.annotations.NotNull;
import java.util.function.Consumer;
/**
* A basic EventBus for scheduling and handling {@link EntityLibEvent}
*/
public interface EventBus {
static @NotNull EventBus newBus(boolean async) {
return async ? new EventBusAsync() : new EventBusSync();
}
/**
* Adds a listener to the EventBus.
* @param listener The listener object
* @param <T> The type of {@link EntityLibEvent}
*/
<T extends EntityLibEvent> void addListener(@NotNull EventListener<T> listener);
/**
* Adds a listener to the EventBus.
* @param eventClass The events class
* @param consumer The consumer for the event.
* @param <T> The type of {@link EntityLibEvent}
*/
<T extends EntityLibEvent> void addListener(@NotNull Class<T> eventClass, @NotNull Consumer<T> consumer);
/**
* Removes a listener from the EventBus.
* @param listener the listener object.
* @param <T> The type of {@link EntityLibEvent}
*/
<T extends EntityLibEvent> void removeListener(@NotNull EventListener<T> listener);
/**
* Calls the event and processes all the attached {@link EventListener} for the event.
* If your bus is async, rather than using this, use {@link Async#call(EntityLibEvent, Consumer)} to avoid any race conditions.
* @param event the event object to process handlers for.
* @return the same event object, but already modified.
* @param <T> The type of {@link EntityLibEvent}
*/
<T extends EntityLibEvent> @NotNull T call(@NotNull T event);
interface Async extends EventBus {
/**
* A safer way to handle and process an event. Does exactly what {@link EventBus#call(EntityLibEvent)} does but allows you to attach a callback, rather than working with it yourself,
* the callback is executed on the thread this is called, and not the main thread.
* @param event the event object to process handlers for.
* @param completionCallback the callback handled after the event is consumed async
* @param <T> The type of {@link EntityLibEvent}
*/
<T extends EntityLibEvent> void call(@NotNull T event, @NotNull Consumer<T> completionCallback);
}
}

View file

@ -0,0 +1,60 @@
package me.tofaa.entitylib.event;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
final class EventBusAsync implements EventBus.Async {
private final Map listeners = new ConcurrentHashMap();
private final ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 4, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
@Override
public <T extends EntityLibEvent> void addListener(@NotNull EventListener<T> listener) {
if (listeners.containsKey(listener.getEventClass())) {
listeners.put(listener.getEventClass(), new HashSet<>());
}
((HashSet) listeners.get(listener.getEventClass())).add(listener);
}
@Override
public <T extends EntityLibEvent> void addListener(@NotNull Class<T> eventClass, @NotNull Consumer<T> consumer) {
addListener(EventListener.generateListener(eventClass, consumer));
}
@Override
public <T extends EntityLibEvent> void removeListener(@NotNull EventListener<T> listener) {
if (listeners.containsKey(listener.getEventClass())) {
((HashSet) listeners.get(listener.getEventClass())).remove(listener);
}
}
@Override
public <T extends EntityLibEvent> @NotNull T call(@NotNull T event) {
executor.execute(() -> dispatchEvent(event));
return event;
}
private <T extends EntityLibEvent> void dispatchEvent(T event) {
if (!listeners.containsKey(event.getClass())) return;
HashSet<EventListener<T>> consumers = (HashSet<EventListener<T>>) listeners.get(event.getClass());
consumers.forEach(consumer -> consumer.handle(event));
}
@Override
public <T extends EntityLibEvent> void call(@NotNull T event, @NotNull Consumer<T> completionCallback) {
executor.execute(() -> {
dispatchEvent(event);
completionCallback.accept(event);
});
}
}

View file

@ -0,0 +1,43 @@
package me.tofaa.entitylib.event;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
@SuppressWarnings("unchecked")
class EventBusSync implements EventBus {
private final Map listeners = new ConcurrentHashMap();
@Override
public <T extends EntityLibEvent> void addListener(@NotNull EventListener<T> listener) {
if (listeners.containsKey(listener.getEventClass())) {
listeners.put(listener.getEventClass(), new HashSet<>());
}
((HashSet) listeners.get(listener.getEventClass())).add(listener);
}
@Override
public <T extends EntityLibEvent> void addListener(@NotNull Class<T> eventClass, @NotNull Consumer<T> consumer) {
addListener(EventListener.generateListener(eventClass, consumer));
}
@Override
public <T extends EntityLibEvent> void removeListener(@NotNull EventListener<T> listener) {
if (listeners.containsKey(listener.getEventClass())) {
((HashSet) listeners.get(listener.getEventClass())).remove(listener);
}
}
@Override
public <T extends EntityLibEvent> @NotNull T call(@NotNull T event) {
if (!listeners.containsKey(event.getClass())) return event;
HashSet<EventListener<T>> consumers = (HashSet<EventListener<T>>) listeners.get(event.getClass());
consumers.forEach(consumer -> consumer.handle(event));
return event;
}
}

View file

@ -0,0 +1,27 @@
package me.tofaa.entitylib.event;
import org.jetbrains.annotations.NotNull;
import java.util.function.Consumer;
public interface EventListener<E extends EntityLibEvent> {
@NotNull Class<E> getEventClass();
void handle(@NotNull E event);
static <T extends EntityLibEvent> EventListener<T> generateListener(Class<T> eventClass, Consumer<T> consumer) {
return new EventListener<T>() {
@Override
public @NotNull Class<T> getEventClass() {
return eventClass;
}
@Override
public void handle(@NotNull T event) {
consumer.accept(event);
}
};
}
}

View file

@ -0,0 +1,30 @@
package me.tofaa.entitylib.event.types;
import com.github.retrooper.packetevents.protocol.player.User;
import me.tofaa.entitylib.event.EntityLibEvent;
import me.tofaa.entitylib.meta.EntityMeta;
public final class UserReceiveMetaUpdateEvent implements EntityLibEvent {
private final User user;
private boolean cancelled;
private EntityMeta meta;
public UserReceiveMetaUpdateEvent(User user) {
this.user = user;
}
public User getUser() {
return user;
}
@Override
public boolean isCancelled() {
return false;
}
@Override
public void setCancelled(boolean cancelled) {
}
}

View file

@ -0,0 +1,36 @@
package me.tofaa.entitylib.event.types;
import com.github.retrooper.packetevents.protocol.player.User;
import me.tofaa.entitylib.event.EntityLibEvent;
import me.tofaa.entitylib.wrapper.WrapperEntity;
public class UserRefreshEntityEvent implements EntityLibEvent {
private final User user;
private final WrapperEntity entity;
private boolean cancelled;
public UserRefreshEntityEvent(User user, WrapperEntity entity) {
this.user = user;
this.entity = entity;
}
public User getUser() {
return user;
}
public WrapperEntity getEntity() {
return entity;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
}

View file

@ -1,6 +1,5 @@
package me.tofaa.entitylib.extras; package me.tofaa.entitylib.extras;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerAttachEntity;
import net.kyori.adventure.util.RGBLike; import net.kyori.adventure.util.RGBLike;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Range; import org.jetbrains.annotations.Range;

View file

@ -1,4 +1,4 @@
package me.tofaa.entitylib.exception; package me.tofaa.entitylib.extras;
public class InvalidVersionException extends RuntimeException { public class InvalidVersionException extends RuntimeException {

View file

@ -0,0 +1,17 @@
package me.tofaa.entitylib.extras;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import me.tofaa.entitylib.EntityLib;
public final class VersionChecker {
private VersionChecker() {}
public static void verifyVersion(ServerVersion version, String message) {
if (!version.isNewerThanOrEquals(EntityLib.getApi().getPacketEvents().getServerManager().getVersion())) {
throw new InvalidVersionException(message);
}
}
}

View file

@ -6,17 +6,47 @@ import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
import com.github.retrooper.packetevents.protocol.entity.data.EntityMetadataProvider; import com.github.retrooper.packetevents.protocol.entity.data.EntityMetadataProvider;
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose; import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import com.github.retrooper.packetevents.protocol.player.ClientVersion; import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata;
import me.tofaa.entitylib.EntityLib; import me.tofaa.entitylib.EntityLib;
import me.tofaa.entitylib.exception.InvalidVersionException; import me.tofaa.entitylib.extras.InvalidVersionException;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
import static me.tofaa.entitylib.meta.MetaOffsetConverter.EntityMetaOffsets.*;
public class EntityMeta implements EntityMetadataProvider { public class EntityMeta implements EntityMetadataProvider {
private static final MetaConverterRegistry registry = new MetaConverterRegistry();
private static final Map<Integer, EntityMeta> metaMap = new ConcurrentHashMap<>();
public static @NotNull BiFunction<Integer, Metadata, EntityMeta> getConverter(EntityType entityType) {
return registry.get(entityType);
}
public static @NotNull Class<? extends EntityMeta> getMetaClass(EntityType entityType) {
return registry.getMetaClass(entityType);
}
public static @NotNull EntityMeta createMeta(int entityId, EntityType entityType) {
Metadata metadata = new Metadata(entityId);
BiFunction<Integer, Metadata, EntityMeta> converter = getConverter(entityType);
EntityMeta entityMeta = converter.apply(entityId, metadata);
metaMap.put(entityId, entityMeta);
return entityMeta;
}
public static @Nullable EntityMeta getMeta(int entityId) {
return metaMap.get(entityId);
}
public static final byte OFFSET = 0; public static final byte OFFSET = 0;
public static final byte MAX_OFFSET = OFFSET + 8; public static final byte MAX_OFFSET = OFFSET + 8;
@ -36,6 +66,14 @@ public class EntityMeta implements EntityMetadataProvider {
this.metadata = metadata; this.metadata = metadata;
} }
public void setNotifyAboutChanges(boolean notifyAboutChanges) {
metadata.setNotifyAboutChanges(notifyAboutChanges);
}
public boolean isNotifyingChanges() {
return metadata.isNotifyingChanges();
}
public boolean isOnFire() { public boolean isOnFire() {
return getMaskBit(OFFSET, ON_FIRE_BIT); return getMaskBit(OFFSET, ON_FIRE_BIT);
} }
@ -68,30 +106,6 @@ public class EntityMeta implements EntityMetadataProvider {
setMaskBit(OFFSET, INVISIBLE_BIT, value); setMaskBit(OFFSET, INVISIBLE_BIT, value);
} }
public short getAirTicks() {
return this.metadata.getIndex((byte) 1, (short) 300);
}
public void setAirTicks(short value) {
this.metadata.setIndex((byte) 1, EntityDataTypes.SHORT, value);
}
public Component getCustomName() {
return this.metadata.getIndex(offset(OFFSET, 2), null);
}
public void setCustomName(Component value) {
this.metadata.setIndex(offset(OFFSET, 2), EntityDataTypes.ADV_COMPONENT, value);
}
public boolean isCustomNameVisible() {
return this.metadata.getIndex(offset(OFFSET, 3), false);
}
public void setCustomNameVisible(boolean value) {
this.metadata.setIndex(offset(OFFSET, 3), EntityDataTypes.BOOLEAN, value);
}
public boolean hasGlowingEffect() { public boolean hasGlowingEffect() {
return getMaskBit(OFFSET, HAS_GLOWING_EFFECT_BIT); return getMaskBit(OFFSET, HAS_GLOWING_EFFECT_BIT);
} }
@ -116,60 +130,78 @@ public class EntityMeta implements EntityMetadataProvider {
setMaskBit(OFFSET, FLYING_WITH_ELYTRA_BIT, value); setMaskBit(OFFSET, FLYING_WITH_ELYTRA_BIT, value);
} }
public short getAirTicks() {
return this.metadata.getIndex(airTicksOffset(), (short) 300);
}
public void setAirTicks(short value) {
this.metadata.setIndex(airTicksOffset(), EntityDataTypes.SHORT, value);
}
public Component getCustomName() {
return this.metadata.getIndex(customNameOffset(), null);
}
public void setCustomName(Component value) {
this.metadata.setIndex(customNameOffset(), EntityDataTypes.ADV_COMPONENT, value);
}
public boolean isCustomNameVisible() {
return this.metadata.getIndex(customNameVisibleOffset(), false);
}
public void setCustomNameVisible(boolean value) {
this.metadata.setIndex(customNameVisibleOffset(), EntityDataTypes.BOOLEAN, value);
}
public boolean isSilent() { public boolean isSilent() {
return this.metadata.getIndex((byte) 4, false); return this.metadata.getIndex(silentOffset(), false);
} }
public void setSilent(boolean value) { public void setSilent(boolean value) {
this.metadata.setIndex((byte) 4, EntityDataTypes.BOOLEAN, value); this.metadata.setIndex(silentOffset(), EntityDataTypes.BOOLEAN, value);
} }
public boolean isHasNoGravity() { public boolean hasNoGravity() {
return this.metadata.getIndex(offset(OFFSET, 5), true); return this.metadata.getIndex(hasNoGravityOffset(), true);
} }
public void setHasNoGravity(boolean value) { public void setHasNoGravity(boolean value) {
this.metadata.setIndex(offset(OFFSET, 5), EntityDataTypes.BOOLEAN, value); this.metadata.setIndex(hasNoGravityOffset(), EntityDataTypes.BOOLEAN, value);
} }
public EntityPose getPose() { public EntityPose getPose() {
return this.metadata.getIndex(offset(OFFSET, 6), EntityPose.STANDING); return this.metadata.getIndex(poseOffset(), EntityPose.STANDING);
} }
public void setPose(EntityPose value) { public void setPose(EntityPose value) {
this.metadata.setIndex(offset(OFFSET, 6), EntityDataTypes.ENTITY_POSE, value); this.metadata.setIndex(poseOffset(), EntityDataTypes.ENTITY_POSE, value);
} }
public int getTicksFrozenInPowderedSnow() { public int getTicksFrozenInPowderedSnow() {
return this.metadata.getIndex(offset(OFFSET, 7), 0); return this.metadata.getIndex(ticksFrozenInPowderedSnowOffset(), 0);
} }
public void setTicksFrozenInPowderedSnow(int value) { public void setTicksFrozenInPowderedSnow(int value) {
this.metadata.setIndex(offset(OFFSET, 7), EntityDataTypes.INT, value); this.metadata.setIndex(ticksFrozenInPowderedSnowOffset(), EntityDataTypes.INT, value);
} }
public WrapperPlayServerEntityMetadata createPacket() { public WrapperPlayServerEntityMetadata createPacket() {
return metadata.createPacket(); return metadata.createPacket();
} }
protected static void isVersionOlder(ServerVersion version) {
if (!EntityLib.getPacketEvents().getServerManager().getVersion().is(VersionComparison.OLDER_THAN, version)) {
throw new InvalidVersionException("This method is only available for versions older than " + version.name() + ".");
}
}
protected static void isVersionNewer(ServerVersion version) { protected static void isVersionNewer(ServerVersion version) {
if (!EntityLib.getPacketEvents().getServerManager().getVersion().is(VersionComparison.NEWER_THAN, version)) { if (!EntityLib.getApi().getPacketEvents().getServerManager().getVersion().is(VersionComparison.NEWER_THAN, version)) {
throw new InvalidVersionException("This method is only available for versions newer than " + version.name() + "."); throw new InvalidVersionException("This method is only available for versions newer than " + version.name() + ".");
} }
} }
protected static boolean isVersion(ServerVersion version, VersionComparison comparison) { protected static boolean isVersion(ServerVersion version, VersionComparison comparison) {
return EntityLib.getPacketEvents().getServerManager().getVersion().is(comparison, version); return EntityLib.getApi().getPacketEvents().getServerManager().getVersion().is(comparison, version);
} }
protected static boolean isVersion(ServerVersion version) { protected static boolean isVersion(ServerVersion version) {
return EntityLib.getPacketEvents().getServerManager().getVersion().is(VersionComparison.EQUALS, version); return EntityLib.getApi().getPacketEvents().getServerManager().getVersion().is(VersionComparison.EQUALS, version);
} }
/** /**
@ -182,19 +214,19 @@ public class EntityMeta implements EntityMetadataProvider {
return (byte) (value + amount); return (byte) (value + amount);
} }
protected byte getMask(byte index) { public byte getMask(byte index) {
return this.metadata.getIndex(index, (byte) 0); return this.metadata.getIndex(index, (byte) 0);
} }
protected void setMask(byte index, byte mask) { public void setMask(byte index, byte mask) {
this.metadata.setIndex(index, EntityDataTypes.BYTE, mask); this.metadata.setIndex(index, EntityDataTypes.BYTE, mask);
} }
protected boolean getMaskBit(byte index, byte bit) { public boolean getMaskBit(byte index, byte bit) {
return (getMask(index) & bit) == bit; return (getMask(index) & bit) == bit;
} }
protected void setMaskBit(int index, byte bit, boolean value) { public void setMaskBit(int index, byte bit, boolean value) {
byte mask = getMask((byte)index); byte mask = getMask((byte)index);
boolean currentValue = (mask & bit) == bit; boolean currentValue = (mask & bit) == bit;
if (currentValue == value) { if (currentValue == value) {
@ -217,4 +249,6 @@ public class EntityMeta implements EntityMetadataProvider {
public List<EntityData> entityData() { public List<EntityData> entityData() {
return metadata.getEntries(); return metadata.getEntries();
} }
} }

View file

@ -1,4 +1,4 @@
package me.tofaa.entitylib; package me.tofaa.entitylib.meta;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType; import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import me.tofaa.entitylib.meta.EntityMeta; import me.tofaa.entitylib.meta.EntityMeta;
@ -164,8 +164,8 @@ final class MetaConverterRegistry {
metaClasses.put(entityType, metaClass); metaClasses.put(entityType, metaClass);
} }
public <T extends EntityMeta> Class<T> getMetaClass(EntityType entityType) { public Class<? extends EntityMeta> getMetaClass(EntityType entityType) {
return (Class<T>) metaClasses.get(entityType); return metaClasses.getOrDefault(entityType, EntityMeta.class);
} }
public @NotNull BiFunction<Integer, Metadata, EntityMeta> get(EntityType entityType) { public @NotNull BiFunction<Integer, Metadata, EntityMeta> get(EntityType entityType) {

View file

@ -0,0 +1,435 @@
// This class is generated by code-gen module. Do not edit manually.
//
package me.tofaa.entitylib.meta;
import static me.tofaa.entitylib.EntityLib.getApi;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Internal
@SuppressWarnings("unused")
public final class MetaOffsetConverter {
private MetaOffsetConverter() {
}
public static final class EntityMetaOffsets {
public static byte airTicksOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 47 && protocolVersion <= 765) {
return 1;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte customNameOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 47 && protocolVersion <= 765) {
return 2;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte customNameVisibleOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 47 && protocolVersion <= 765) {
return 3;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte silentOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 47 && protocolVersion <= 765) {
return 4;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte hasNoGravityOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 47 && protocolVersion <= 765) {
return 5;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte poseOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 47 && protocolVersion <= 765) {
return 6;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte ticksFrozenInPowderedSnowOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 47 && protocolVersion <= 765) {
return 7;
}
throw new RuntimeException("Unknown protocol version for this method");
}
}
public static final class AbstractDisplayMetaOffsets {
public static byte interpolationDelayOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 762 && protocolVersion <= 765) {
return 8;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte transformationDurationOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 762 && protocolVersion <= 765) {
return 9;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte positionRotationInterpolationDurationOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 10;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte translationOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 11;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 10;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte scaleOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 12;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 11;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte leftRotationOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 13;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 12;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte rightRotationOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 14;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 13;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte billboardConstraintsOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 15;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 14;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte brightnessOverrideOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 16;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 15;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte viewRangeOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 17;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 16;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte shadowRadiusOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 18;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 17;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte shadowStrengthOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 19;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 18;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte widthOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 20;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 19;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte heightOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 21;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 20;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte glowColorOverrideOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 22;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 21;
}
throw new RuntimeException("Unknown protocol version for this method");
}
}
public static final class BlockDisplayMetaOffsets {
public static byte blockIdOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 23;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 22;
}
throw new RuntimeException("Unknown protocol version for this method");
}
}
public static final class ItemDisplayMetaOffsets {
public static byte itemOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 24;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 23;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte displayTypeOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 25;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 24;
}
throw new RuntimeException("Unknown protocol version for this method");
}
}
public static final class TextDisplayMetaOffsets {
public static byte textOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 26;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 25;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte textColorOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 27;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 26;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte textBackgroundColorOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 28;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 27;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte textBackgroundOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 29;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 28;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte textScaleOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 30;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 29;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte textAlignmentOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 31;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 30;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte lineWidthOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 32;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 31;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte backgroundColorOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 33;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 32;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte textOpacityOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 34;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 33;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte shadowOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 35;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 34;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte seeThroughOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 36;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 35;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte useDefaultBackgroundOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 37;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 36;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte allighnLeftOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 38;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 37;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte allighnRightOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 39;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 38;
}
throw new RuntimeException("Unknown protocol version for this method");
}
public static byte allighnCenterOffset() {
int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
if (protocolVersion >= 764 && protocolVersion <= 765) {
return 40;
}
if (protocolVersion >= 762 && protocolVersion <= 763) {
return 39;
}
throw new RuntimeException("Unknown protocol version for this method");
}
}
}

View file

@ -0,0 +1,92 @@
package me.tofaa.entitylib.meta;
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataType;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata;
import me.tofaa.entitylib.EntityLib;
import me.tofaa.entitylib.wrapper.WrapperEntity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@SuppressWarnings("unchecked")
public class Metadata {
private final int entityId;
private EntityData[] entries = new EntityData[0];
private volatile Map<Integer, EntityData> entryMap = null;
private volatile boolean notifyChanges = true;
private final Map<Byte, EntityData> notNotifiedChanges = new HashMap<>();
public Metadata(int entityId) {
this.entityId = entityId;
}
public <T> T getIndex(byte index, @Nullable T defaultValue) {
final EntityData[] entries = this.entries;
if (index < 0 || index >= entries.length) {
return defaultValue;
}
final EntityData entry = entries[index];
if (entry == null) return defaultValue;
if (entry.getValue() == null) return defaultValue;
return (T) entry.getValue();
}
public <T> void setIndex(byte index, @NotNull EntityDataType<T> dataType, T value) {
EntityData[] entries = this.entries;
if (index >= entries.length) {
final int newLength = Math.max(entries.length * 2, index + 1);
this.entries = entries = Arrays.copyOf(entries, newLength);
}
EntityData data = new EntityData(index, dataType, value);
entries[index] = data;
this.entryMap = null;
final WrapperEntity entity = EntityLib.getApi().getEntity(entityId);
if (entity == null || entity.isSpawned()) return; // Not EntityLib entity then, the user must send the packet manually. OR not spawned.
if (!this.notifyChanges) {
synchronized (this.notNotifiedChanges) {
this.notNotifiedChanges.put(index, data);
}
}
else {
entity.sendPacketToViewers(createPacket());
}
}
public void setNotifyAboutChanges(boolean value) {
if (this.notifyChanges == value) {
return;
}
if (!notifyChanges) {
return; // cache;
}
final WrapperEntity entity = EntityLib.getApi().getEntity(entityId);
if (entity == null || entity.isSpawned()) return;
Map<Byte, EntityData> entries;
synchronized (this.notNotifiedChanges) {
Map<Byte, EntityData> awaitingChanges = this.notNotifiedChanges;
if (awaitingChanges.isEmpty()) return;
entries = Collections.unmodifiableMap(awaitingChanges);
awaitingChanges.clear();
}
entity.sendPacketsToViewers(new WrapperPlayServerEntityMetadata(entityId, new ArrayList<>(entries.values())));
}
public boolean isNotifyingChanges() {
return notifyChanges;
}
@NotNull List<EntityData> getEntries() {
return Collections.unmodifiableList(Arrays.asList(entries));
}
public WrapperPlayServerEntityMetadata createPacket() {
return new WrapperPlayServerEntityMetadata(entityId, getEntries());
}
}

View file

@ -0,0 +1,255 @@
package me.tofaa.entitylib.meta.display;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.manager.server.VersionComparison;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
import com.github.retrooper.packetevents.util.Quaternion4f;
import com.github.retrooper.packetevents.util.Vector3f;
import me.tofaa.entitylib.meta.EntityMeta;
import me.tofaa.entitylib.meta.Metadata;
public abstract class AbstractDisplayMeta extends EntityMeta {
public static final byte OFFSET = EntityMeta.MAX_OFFSET;
public static final byte MAX_OFFSET;
static {
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.NEWER_THAN_OR_EQUALS)) {
MAX_OFFSET = OFFSET + 15;
}
else {
MAX_OFFSET = OFFSET + 14;
}
}
public AbstractDisplayMeta(int entityId, Metadata metadata) {
super(entityId, metadata);
isVersionNewer(ServerVersion.V_1_19_3);
}
public int getInterpolationDelay() {
return super.metadata.getIndex(OFFSET, 0);
}
public void setInterpolationDelay(int value) {
super.metadata.setIndex(OFFSET, EntityDataTypes.INT, value);
}
public int getTransformationInterpolationDuration() {
return super.metadata.getIndex(offset(OFFSET, 1), 0);
}
public void setTransformationInterpolationDuration(int value) {
super.metadata.setIndex(offset(OFFSET, 1), EntityDataTypes.INT, value);
}
public int getPositionRotationInterpolationDuration() {
return super.metadata.getIndex(offset(OFFSET, 2), 0);
}
public void setPositionRotationInterpolationDuration(int value) {
super.metadata.setIndex(offset(OFFSET, 2), EntityDataTypes.INT, value);
}
public Vector3f getTranslation() {
byte offset = offset(OFFSET, 3);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 2);
}
return super.metadata.getIndex(offset, Vector3f.zero());
}
public void setTranslation(Vector3f value) {
byte offset = offset(OFFSET, 3);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 2);
}
super.metadata.setIndex(offset, EntityDataTypes.VECTOR3F, value);
}
public Vector3f getScale() {
byte offset = offset(OFFSET, 4);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 3);
}
return super.metadata.getIndex(offset, new Vector3f(1.0f, 1.0f, 1.0f));
}
public void setScale(Vector3f value) {
byte offset = offset(OFFSET, 4);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 3);
}
super.metadata.setIndex(offset, EntityDataTypes.VECTOR3F, value);
}
public Quaternion4f getLeftRotation() {
byte offset = offset(OFFSET, 5);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 4);
}
return super.metadata.getIndex(offset, new Quaternion4f(0.0f, 0.0f, 0.0f, 1.0f));
}
public void setLeftRotation(Quaternion4f value) {
byte offset = offset(OFFSET, 5);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 4);
}
super.metadata.setIndex(offset, EntityDataTypes.QUATERNION, value);
}
public Quaternion4f getRightRotation() {
byte offset = offset(OFFSET, 6);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 5);
}
return super.metadata.getIndex(offset, new Quaternion4f(0.0f, 0.0f, 0.0f, 1.0f));
}
public void setRightRotation(Quaternion4f value) {
byte offset = offset(OFFSET, 6);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 5);
}
super.metadata.setIndex(offset, EntityDataTypes.QUATERNION, value);
}
public BillboardConstraints getBillboardConstraints() {
byte offset = offset(OFFSET, 7);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 6);
}
return BillboardConstraints.VALUES[super.metadata.getIndex(offset, (byte) 0)];
}
public void setBillboardConstraints(BillboardConstraints value) {
byte offset = offset(OFFSET, 7);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 6);
}
super.metadata.setIndex(offset, EntityDataTypes.BYTE, (byte) value.ordinal());
}
//(blockLight << 4 | skyLight << 20)
public int getBrightnessOverride() {
byte offset = offset(OFFSET, 8);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 7);
}
return super.metadata.getIndex(offset, -1);
}
public void setBrightnessOverride(int value) {
byte offset = offset(OFFSET, 8);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 7);
}
super.metadata.setIndex(offset, EntityDataTypes.INT, value);
}
public float getViewRange() {
byte offset = offset(OFFSET, 9);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 8);
}
return super.metadata.getIndex(offset, 1.0f);
}
public void setViewRange(float value) {
byte offset = offset(OFFSET, 9);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 8);
}
super.metadata.setIndex(offset, EntityDataTypes.FLOAT, value);
}
public float getShadowRadius() {
byte offset = offset(OFFSET, 10);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 9);
}
return super.metadata.getIndex(offset, 0.0f);
}
public void setShadowRadius(float value) {
byte offset = offset(OFFSET, 10);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 9);
}
super.metadata.setIndex(offset, EntityDataTypes.FLOAT, value);
}
public float getShadowStrength() {
byte offset = offset(OFFSET, 11);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 10);
}
return super.metadata.getIndex(offset, 1.0f);
}
public void setShadowStrength(float value) {
byte offset = offset(OFFSET, 11);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 10);
}
super.metadata.setIndex(offset, EntityDataTypes.FLOAT, value);
}
public float getWidth() {
byte offset = offset(OFFSET, 12);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 11);
}
return super.metadata.getIndex(offset, 0.0f);
}
public void setWidth(float value) {
byte offset = offset(OFFSET, 12);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 11);
}
super.metadata.setIndex(offset, EntityDataTypes.FLOAT, value);
}
public float getHeight() {
byte offset = offset(OFFSET, 13);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 12);
}
return super.metadata.getIndex(offset, 0.0f);
}
public void setHeight(float value) {
byte offset = offset(OFFSET, 13);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 12);
}
super.metadata.setIndex(offset, EntityDataTypes.FLOAT, value);
}
public int getGlowColorOverride() {
byte offset = offset(OFFSET, 14);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 13);
}
return super.metadata.getIndex(offset, -1);
}
public void setGlowColorOverride(int value) {
byte offset = offset(OFFSET, 14);
if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
offset = offset(OFFSET, 13);
}
super.metadata.setIndex(offset, EntityDataTypes.INT, value);
}
public enum BillboardConstraints {
FIXED,
VERTICAL,
HORIZONTAL,
CENTER;
private static final BillboardConstraints[] VALUES = values();
}
}

View file

@ -2,11 +2,10 @@ package me.tofaa.entitylib.meta.display;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
import me.tofaa.entitylib.meta.Metadata; import me.tofaa.entitylib.meta.Metadata;
import me.tofaa.entitylib.meta.types.DisplayMeta;
public class BlockDisplayMeta extends DisplayMeta { public class BlockDisplayMeta extends AbstractDisplayMeta {
public static final byte OFFSET = DisplayMeta.MAX_OFFSET; public static final byte OFFSET = AbstractDisplayMeta.MAX_OFFSET;
public static final byte MAX_OFFSET = offset(OFFSET, 1); public static final byte MAX_OFFSET = offset(OFFSET, 1);
public BlockDisplayMeta(int entityId, Metadata metadata) { public BlockDisplayMeta(int entityId, Metadata metadata) {

View file

@ -3,11 +3,10 @@ package me.tofaa.entitylib.meta.display;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
import com.github.retrooper.packetevents.protocol.item.ItemStack; import com.github.retrooper.packetevents.protocol.item.ItemStack;
import me.tofaa.entitylib.meta.Metadata; import me.tofaa.entitylib.meta.Metadata;
import me.tofaa.entitylib.meta.types.DisplayMeta;
public class ItemDisplayMeta extends DisplayMeta { public class ItemDisplayMeta extends AbstractDisplayMeta {
public static final byte OFFSET = DisplayMeta.MAX_OFFSET; public static final byte OFFSET = AbstractDisplayMeta.MAX_OFFSET;
public static final byte MAX_OFFSET = offset(OFFSET, 1); public static final byte MAX_OFFSET = offset(OFFSET, 1);
public ItemDisplayMeta(int entityId, Metadata metadata) { public ItemDisplayMeta(int entityId, Metadata metadata) {
@ -45,3 +44,4 @@ public class ItemDisplayMeta extends DisplayMeta {
} }
} }

View file

@ -2,12 +2,11 @@ package me.tofaa.entitylib.meta.display;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
import me.tofaa.entitylib.meta.Metadata; import me.tofaa.entitylib.meta.Metadata;
import me.tofaa.entitylib.meta.types.DisplayMeta;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
public class TextDisplayMeta extends DisplayMeta { public class TextDisplayMeta extends AbstractDisplayMeta {
public static final byte OFFSET = DisplayMeta.MAX_OFFSET; public static final byte OFFSET = AbstractDisplayMeta.MAX_OFFSET;
public static final byte MAX_OFFSET = offset(OFFSET, 5); public static final byte MAX_OFFSET = offset(OFFSET, 5);
private static final byte SHADOW = 1; private static final byte SHADOW = 1;

Some files were not shown because too many files have changed in this diff Show more