push some codegen boilerplate
This commit is contained in:
parent
3183a3140d
commit
e22a057bff
20 changed files with 724 additions and 41 deletions
|
@ -9,6 +9,7 @@
|
|||
<set>
|
||||
<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" />
|
||||
|
|
|
@ -5,15 +5,25 @@
|
|||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="9d5d9b6f-43c8-41a4-bb42-a66ffc96c9b0" name="Changes" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/meta/CompatibilityIndex.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/Hologram.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/LegacyHologram.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/ModernHologram.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/code-gen/src/main/java/me/tofaa/entitylib/codegen/Main.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/code-gen/src/main/java/me/tofaa/entitylib/codegen/MetaClass.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/code-gen/src/main/java/me/tofaa/entitylib/codegen/MetaMethod.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/code-gen/src/main/resources/EntityMeta.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/gradle.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/gradle.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/EntityLib.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/EntityLib.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/WorldWrapper.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/WorldWrapper.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/meta/UsedVersion.java" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/meta/VersionCompatCheck.java" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/tick/Tickable.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/tick/Tickable.java" 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/ai/goals/RandomHeadMovementGoal.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/ai/goals/RandomHeadMovementGoal.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/common/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java" beforeDir="false" afterPath="$PROJECT_DIR$/common/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/common/src/main/java/me/tofaa/entitylib/common/AbstractWorldWrapper.java" beforeDir="false" afterPath="$PROJECT_DIR$/common/src/main/java/me/tofaa/entitylib/common/AbstractWorldWrapper.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/settings.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/settings.gradle" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/EntityLib.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/EntityLib.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java" beforeDir="false" afterPath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
|
@ -76,42 +86,56 @@
|
|||
<option name="showExcludedFiles" value="false" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
"Downloaded.Files.Path.Enabled": "false",
|
||||
"Gradle.Build EntityLib.executor": "Run",
|
||||
"Gradle.EntityLib [dependencies].executor": "Run",
|
||||
"Gradle.EntityLib:test-plugin [runServer].executor": "Run",
|
||||
"Repository.Attach.Annotations": "false",
|
||||
"Repository.Attach.JavaDocs": "false",
|
||||
"Repository.Attach.Sources": "false",
|
||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"WebServerToolWindowFactoryState": "false",
|
||||
"git-widget-placeholder": "feat/platform-api",
|
||||
"ignore.virus.scanning.warn.message": "true",
|
||||
"jdk.selected.JAVA_MODULE": "corretto-17",
|
||||
"kotlin-language-version-configured": "true",
|
||||
"last_opened_file_path": "D:/Github/EntityLib/api/src/main/java/me/tofaa/entitylib/meta",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"project.structure.last.edited": "Modules",
|
||||
"project.structure.proportion": "0.15",
|
||||
"project.structure.side.proportion": "0.2",
|
||||
"settings.editor.selected.configurable": "preferences.pluginManager",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"Downloaded.Files.Path.Enabled": "false",
|
||||
"Gradle.Build EntityLib.executor": "Run",
|
||||
"Gradle.EntityLib [dependencies].executor": "Run",
|
||||
"Gradle.EntityLib:code-gen [:code-gen:Main.main()].executor": "Run",
|
||||
"Gradle.EntityLib:test-plugin [runServer].executor": "Run",
|
||||
"Repository.Attach.Annotations": "false",
|
||||
"Repository.Attach.JavaDocs": "false",
|
||||
"Repository.Attach.Sources": "false",
|
||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"WebServerToolWindowFactoryState": "false",
|
||||
"git-widget-placeholder": "feat/platform-api",
|
||||
"ignore.virus.scanning.warn.message": "true",
|
||||
"jdk.selected.JAVA_MODULE": "corretto-17",
|
||||
"kotlin-language-version-configured": "true",
|
||||
"last_opened_file_path": "D:/Github/EntityLib/api/src/main/java/me/tofaa/entitylib/meta",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"project.structure.last.edited": "Project",
|
||||
"project.structure.proportion": "0.15",
|
||||
"project.structure.side.proportion": "0.2",
|
||||
"settings.editor.selected.configurable": "preferences.pluginManager",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}</component>
|
||||
}]]></component>
|
||||
<component name="RecentsManager">
|
||||
<key name="CopyFile.RECENT_KEYS">
|
||||
<recent name="D:\Github\EntityLib\api\src\main\java\me\tofaa\entitylib\meta" />
|
||||
<recent name="D:\Github\EntityLib\test-plugin" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunManager" selected="Gradle.EntityLib [dependencies]">
|
||||
<component name="RunManager" selected="Application.Main">
|
||||
<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" />
|
||||
|
@ -202,6 +226,7 @@
|
|||
</configuration>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Application.Main" />
|
||||
<item itemvalue="Gradle.EntityLib [dependencies]" />
|
||||
<item itemvalue="Gradle.EntityLib:test-plugin [runServer]" />
|
||||
<item itemvalue="Gradle.PE-EntityMeta [compileTestJava]" />
|
||||
|
@ -256,7 +281,11 @@
|
|||
<workItem from="1706284605696" duration="11691000" />
|
||||
<workItem from="1706371324325" duration="1187000" />
|
||||
<workItem from="1706443875388" duration="4827000" />
|
||||
<workItem from="1706513591682" duration="2661000" />
|
||||
<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" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
|
@ -271,6 +300,11 @@
|
|||
<line>6787</line>
|
||||
<option name="timeStamp" value="1" />
|
||||
</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">
|
||||
<url>file://$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/meta/types/DisplayMeta.java</url>
|
||||
<line>153</line>
|
||||
|
|
|
@ -30,7 +30,7 @@ public final class EntityLib {
|
|||
}
|
||||
}
|
||||
|
||||
public static EntityLibAPI<?, ?> getApi() {
|
||||
public static <W, T> EntityLibAPI<W, T> getApi() {
|
||||
return api;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@ public interface WorldWrapper<W> {
|
|||
@Nullable WrapperEntity getEntity(@NotNull UUID uuid);
|
||||
|
||||
|
||||
void removeEntity(WrapperEntity entity);
|
||||
|
||||
/**
|
||||
* Gets the block at the specified coordinates. Depending on the platforms implementation, this method may be slow.
|
||||
* @param x The x coordinate.
|
||||
|
|
|
@ -3,7 +3,6 @@ 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 org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ public class WrapperEntity implements Tickable {
|
|||
this.entityType = entityType;
|
||||
this.entityMeta = entityMeta;
|
||||
this.ticking = true;
|
||||
this.viewers = new HashSet<>();
|
||||
}
|
||||
|
||||
public boolean spawn(WorldWrapper<?> world, Location location) {
|
||||
|
@ -84,15 +85,23 @@ public class WrapperEntity implements Tickable {
|
|||
return true;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
world.removeEntity(this);
|
||||
}
|
||||
|
||||
public void despawn() {
|
||||
if (!spawned) return;
|
||||
spawned = false;
|
||||
sendPacketToViewers(new WrapperPlayServerDestroyEntities(entityId));
|
||||
}
|
||||
|
||||
public void teleport(WorldWrapper<?> world, @NotNull Location location) {
|
||||
public void teleport(WorldWrapper<?> world, @NotNull Location location, boolean onGround) {
|
||||
if (!spawned) {
|
||||
return;
|
||||
}
|
||||
this.location = location;
|
||||
this.world = world;
|
||||
this.onGround = onGround;
|
||||
sendPacketToViewers(
|
||||
new WrapperPlayServerEntityTeleport(
|
||||
entityId,
|
||||
|
@ -104,6 +113,10 @@ public class WrapperEntity implements Tickable {
|
|||
);
|
||||
}
|
||||
|
||||
public void teleport(WorldWrapper<?> world, @NotNull Location location) {
|
||||
teleport(world, location, onGround);
|
||||
}
|
||||
|
||||
public boolean addViewer(UUID uuid) {
|
||||
if (!viewers.add(uuid)) {
|
||||
return false;
|
||||
|
@ -129,6 +142,22 @@ public class WrapperEntity implements Tickable {
|
|||
addViewer(user.getUUID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a viewer silently into the viewers set. The viewer will not receive any packets or be informed of this addition
|
||||
* @param uuid the uuid of the user to add
|
||||
*/
|
||||
public void addViewerSilently(UUID uuid) {
|
||||
viewers.add(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a viewer silently into the viewers set. The viewer will not receive any packets or be informed of this addition
|
||||
* @param user the user to add
|
||||
*/
|
||||
public void addViewerSilently(User user) {
|
||||
addViewerSilently(user.getUUID());
|
||||
}
|
||||
|
||||
public void removeViewer(UUID uuid) {
|
||||
if (!viewers.remove(uuid)) {
|
||||
return;
|
||||
|
@ -136,6 +165,26 @@ public class WrapperEntity implements Tickable {
|
|||
sendPacket(uuid, new WrapperPlayServerDestroyEntities(entityId));
|
||||
}
|
||||
|
||||
public void removeViewer(User user) {
|
||||
removeViewer(user.getUUID());
|
||||
}
|
||||
|
||||
/**
|
||||
* removes a viewer silently into the viewers set. The viewer will not receive any packets or be informed of this removal
|
||||
* @param uuid of the user to remove
|
||||
*/
|
||||
public void removeViewerSilently(UUID uuid) {
|
||||
viewers.remove(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* removes a viewer silently into the viewers set. The viewer will not receive any packets or be informed of this removal
|
||||
* @param user the user to remove
|
||||
*/
|
||||
public void removeViewerSilently(User user) {
|
||||
removeViewerSilently(user.getUUID());
|
||||
}
|
||||
|
||||
public boolean isOnGround() {
|
||||
return onGround;
|
||||
}
|
||||
|
@ -345,7 +394,7 @@ public class WrapperEntity implements Tickable {
|
|||
WrapperEntity e = world.getEntity(passenger);
|
||||
if (e != null) {
|
||||
e.riding = -1;
|
||||
e.teleport(world, e.preRidingLocation);
|
||||
e.teleport(world, e.preRidingLocation, e.onGround);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ public class RandomHeadMovementGoal extends GoalSelector {
|
|||
@Override
|
||||
public void tick(long time) {
|
||||
--lookTime;
|
||||
entity.teleport(entity.getWorld(), CoordinateUtil.withDirection(entity.getLocation(), lookDirection));
|
||||
entity.teleport(entity.getWorld(), CoordinateUtil.withDirection(entity.getLocation(), lookDirection), entity.isOnGround());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
package me.tofaa.entitylib.wrapper.hologram;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.world.Location;
|
||||
import com.github.retrooper.packetevents.util.Vector3f;
|
||||
import me.tofaa.entitylib.WorldWrapper;
|
||||
import me.tofaa.entitylib.meta.display.TextDisplayMeta;
|
||||
import me.tofaa.entitylib.meta.types.DisplayMeta;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface Hologram<W> {
|
||||
|
||||
static <C> Hologram.@NotNull Legacy<C> legacy(@NotNull WorldWrapper<C> world, @NotNull Location location) {
|
||||
return new LegacyHologram<>(world, location);
|
||||
}
|
||||
|
||||
static <C> Hologram.@NotNull Legacy<C> legacy(@NotNull WorldWrapper<C> world, @NotNull Location location, List<Component> lines) {
|
||||
return new LegacyHologram<>(world, location, lines);
|
||||
}
|
||||
|
||||
|
||||
@NotNull Location getLocation();
|
||||
|
||||
@NotNull WorldWrapper<W> getWorld();
|
||||
|
||||
void show();
|
||||
|
||||
void hide();
|
||||
|
||||
void teleport(Location location);
|
||||
|
||||
@Nullable Component getLine(int index);
|
||||
|
||||
int length();
|
||||
|
||||
void setLine(int index, @Nullable Component line);
|
||||
|
||||
void addLine(@Nullable Component line);
|
||||
|
||||
interface Modern<W> extends Hologram<W> {
|
||||
|
||||
// I got too lazy
|
||||
void setModifier(@NotNull Consumer<TextDisplayMeta> consumer);
|
||||
|
||||
}
|
||||
interface Legacy<W> extends Hologram<W> {
|
||||
|
||||
float getLineOffset(boolean marker);
|
||||
|
||||
void setLineOffset(boolean marker, float value);
|
||||
|
||||
default float getLineOffset() {
|
||||
return getLineOffset(false);
|
||||
}
|
||||
|
||||
default void setLineOffset(float value) {
|
||||
setLineOffset(false, value);
|
||||
}
|
||||
|
||||
boolean isMarker();
|
||||
|
||||
void setMarker(boolean marker);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
package me.tofaa.entitylib.wrapper.hologram;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.world.Location;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import me.tofaa.entitylib.EntityLib;
|
||||
import me.tofaa.entitylib.WorldWrapper;
|
||||
import me.tofaa.entitylib.meta.other.ArmorStandMeta;
|
||||
import me.tofaa.entitylib.wrapper.WrapperEntity;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
final class LegacyHologram<W> implements Hologram.Legacy<W> {
|
||||
|
||||
private Location location;
|
||||
private WorldWrapper<W> world;
|
||||
private List<WrapperEntity> lines = new ArrayList<>(3);
|
||||
private float lineOffset = -0.9875f;
|
||||
private float markerOffset = -0.40625f;
|
||||
private boolean marker;
|
||||
|
||||
LegacyHologram(@NotNull WorldWrapper<W> world, @NotNull Location location) {
|
||||
this.world = world;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
LegacyHologram(@NotNull WorldWrapper<W> world, @NotNull Location location, List<Component> lines) {
|
||||
this(world, location);
|
||||
for (Component line : lines) {
|
||||
addLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMarker() {
|
||||
return marker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMarker(boolean marker) {
|
||||
this.marker = true;
|
||||
if (lines.isEmpty()) return;
|
||||
teleport(location); // refresh
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
for (WrapperEntity line : lines) {
|
||||
line.spawn(world, location);
|
||||
}
|
||||
teleport(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {
|
||||
for (WrapperEntity line : lines) {
|
||||
line.despawn();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleport(Location location) {
|
||||
this.location = location;
|
||||
// reversed order
|
||||
for (int i = lines.size() -1; i >= 0; i--) {
|
||||
WrapperEntity line = lines.get(i);
|
||||
double y;
|
||||
if (marker) {
|
||||
y = location.getY() + markerOffset;
|
||||
} else {
|
||||
y = location.getY() + (i * lineOffset);
|
||||
}
|
||||
ArmorStandMeta meta = (ArmorStandMeta) line.getEntityMeta();
|
||||
meta.setMarker(marker);
|
||||
Location l = new Location(location.getX(), y, location.getZ(), location.getYaw(), location.getPitch());
|
||||
line.teleport(world, l, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Component getLine(int index) {
|
||||
if (index < 0 || index >= lines.size()) {
|
||||
return null;
|
||||
}
|
||||
return lines.get(index).getEntityMeta().getCustomName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLine(int index, @Nullable Component line) {
|
||||
WrapperEntity e = world.spawnEntity(EntityTypes.ARMOR_STAND, location);
|
||||
ArmorStandMeta meta = (ArmorStandMeta) e.getEntityMeta();
|
||||
meta.setCustomName(line);
|
||||
meta.setCustomNameVisible(true);
|
||||
meta.setInvisible(true);
|
||||
meta.setHasNoGravity(true);
|
||||
meta.setSmall(true);
|
||||
meta.setMarker(marker);
|
||||
this.lines.set(index, e);
|
||||
e.spawn(world, location);
|
||||
teleport(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLine(@Nullable Component line) {
|
||||
setLine(lines.size(), line);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getLineOffset(boolean marker) {
|
||||
return marker ? markerOffset : lineOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return lines.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLineOffset(boolean marker, float value) {
|
||||
if (marker) {
|
||||
markerOffset = value;
|
||||
} else {
|
||||
lineOffset = value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull WorldWrapper<W> getWorld() {
|
||||
return world;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package me.tofaa.entitylib.wrapper.hologram;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.world.Location;
|
||||
import me.tofaa.entitylib.WorldWrapper;
|
||||
import me.tofaa.entitylib.meta.display.TextDisplayMeta;
|
||||
import me.tofaa.entitylib.meta.other.ArmorStandMeta;
|
||||
import me.tofaa.entitylib.wrapper.WrapperEntity;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
final class ModernHologram<W> implements Hologram.Modern<W> {
|
||||
|
||||
private Location location;
|
||||
private WorldWrapper<W> world;
|
||||
private List<WrapperEntity> lines = new ArrayList<>(3);
|
||||
private Consumer<TextDisplayMeta> modifier;
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
for (WrapperEntity line : lines) {
|
||||
line.spawn(world, location);
|
||||
}
|
||||
teleport(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {
|
||||
for (WrapperEntity line : lines) {
|
||||
line.despawn();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleport(Location location) {
|
||||
this.location = location;
|
||||
if (lines.isEmpty()) return;
|
||||
WrapperEntity first = lines.get(0);
|
||||
first.teleport(world, location);
|
||||
for (WrapperEntity e : lines) {
|
||||
if (e.getUuid().equals(first.getUuid())) continue;
|
||||
first.addPassenger(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Component getLine(int index) {
|
||||
if (index < 0 || index >= lines.size()) {
|
||||
return null;
|
||||
}
|
||||
return lines.get(index).getEntityMeta().getCustomName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLine(int index, @Nullable Component line) {
|
||||
WrapperEntity e = world.spawnEntity(EntityTypes.TEXT_DISPLAY, location);
|
||||
TextDisplayMeta meta = (TextDisplayMeta) e.getEntityMeta();
|
||||
meta.setInvisible(true);
|
||||
meta.setHasNoGravity(true);
|
||||
meta.setText(line);
|
||||
this.modifier.accept(meta);
|
||||
this.lines.set(index, e);
|
||||
e.spawn(world, location);
|
||||
teleport(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLine(@Nullable Component line) {
|
||||
setLine(lines.size(), line);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return lines.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull WorldWrapper<W> getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setModifier(@NotNull Consumer<TextDisplayMeta> consumer) {
|
||||
this.modifier = consumer;
|
||||
}
|
||||
}
|
20
code-gen/build.gradle
Normal file
20
code-gen/build.gradle
Normal file
|
@ -0,0 +1,20 @@
|
|||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
|
||||
// jdk 17
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
implementation 'com.squareup:javapoet:1.13.0'
|
||||
implementation 'com.github.retrooper.packetevents:api:2.2.0'
|
||||
implementation 'org.jetbrains:annotations:24.0.0'
|
||||
}
|
114
code-gen/src/main/java/me/tofaa/entitylib/codegen/Main.java
Normal file
114
code-gen/src/main/java/me/tofaa/entitylib/codegen/Main.java
Normal file
|
@ -0,0 +1,114 @@
|
|||
package me.tofaa.entitylib.codegen;
|
||||
|
||||
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 com.google.gson.reflect.TypeToken;
|
||||
import com.squareup.javapoet.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public final class Main {
|
||||
|
||||
private Main() {}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
createMetadataClass();
|
||||
List<MetaClass> metaClasses = new ArrayList<>();
|
||||
|
||||
// test
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static void writeClass(MetaClass metaClass) {
|
||||
File file = new File("src/main/java");
|
||||
TypeSpec typeSpec = metaClass.create();
|
||||
JavaFile javaFile = JavaFile.builder("me.tofaa.entitylib.meta", typeSpec).build();
|
||||
try {
|
||||
FileWriter fileWriter = new FileWriter(file);
|
||||
javaFile.writeTo(fileWriter);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void createMetadataClass() {
|
||||
|
||||
TypeSpec.Builder builder = builder("me.tofaa.entitylib.meta", "Metadata");
|
||||
builder.addField(int.class, "entityId", Modifier.PRIVATE, Modifier.FINAL);
|
||||
builder.addField(TypeToken.getParameterized(Map.class, Byte.class, EntityDataType.class).getType(), "metadataMap", Modifier.PRIVATE, Modifier.FINAL);
|
||||
|
||||
MethodSpec.Builder constructor = MethodSpec.constructorBuilder()
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addCode("this.entityId = entityId;\n")
|
||||
.addCode("this.metadataMap = new ConcurrentHashMap<>();\n")
|
||||
.addParameter(int.class, "entityId");
|
||||
|
||||
MethodSpec.Builder getIndex = MethodSpec.methodBuilder("getIndex")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addTypeVariable(TypeVariableName.get("T"))
|
||||
.addParameter(byte.class, "index")
|
||||
.addParameter(TypeVariableName.get("T"), "defaultValue")
|
||||
.returns(TypeVariableName.get("T"))
|
||||
.addCode("EntityData entityData = metadataMap.get(index);\n")
|
||||
.addCode("if (entityData == null) return defaultValue;\n")
|
||||
.addCode("if (entityData.getValue() == null) return defaultValue;\n")
|
||||
.addCode("return (T) entityData.getValue();\n");
|
||||
|
||||
MethodSpec.Builder setIndex = MethodSpec.methodBuilder("setIndex")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addTypeVariable(TypeVariableName.get("T"))
|
||||
.addParameter(byte.class, "index")
|
||||
.addParameter(EntityDataType.class, "dataType")
|
||||
.addParameter(TypeVariableName.get("T"), "value")
|
||||
.addCode("EntityData data = new EntityData(index, dataType, value);\n")
|
||||
.addCode("this.metadataMap.put(index, data);\n");
|
||||
|
||||
MethodSpec.Builder getEntries = MethodSpec.methodBuilder("getEntries")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.returns(TypeToken.getParameterized(List.class, EntityData.class).getType())
|
||||
.addCode("return new ArrayList<>(metadataMap.values());\n")
|
||||
.addAnnotation(NotNull.class);
|
||||
|
||||
MethodSpec.Builder createPacket = MethodSpec.methodBuilder("createPacket")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.returns(WrapperPlayServerEntityMetadata.class)
|
||||
.addCode("return new WrapperPlayServerEntityMetadata(entityId, getEntries());\n")
|
||||
.addAnnotation(NotNull.class);
|
||||
|
||||
builder.addMethod(constructor.build());
|
||||
builder.addMethod(getIndex.build());
|
||||
builder.addMethod(setIndex.build());
|
||||
builder.addMethod(getEntries.build());
|
||||
builder.addMethod(createPacket.build());
|
||||
|
||||
File file = new File("src/main/java");
|
||||
JavaFile javaFile = JavaFile.builder("me.tofaa.entitylib.meta", builder.build()).build();
|
||||
try {
|
||||
FileWriter fileWriter = new FileWriter(file);
|
||||
javaFile.writeTo(fileWriter);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Include comment in generated code
|
||||
public static TypeSpec.Builder builder(String packageName, String className) {
|
||||
return TypeSpec.classBuilder(ClassName.get(packageName, className))
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addJavadoc("AUTOGENERATED CODE BY ENTITYLIB CODEGEN\n")
|
||||
.addJavadoc("DO NOT EDIT\n");
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package me.tofaa.entitylib.codegen;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static me.tofaa.entitylib.codegen.Main.builder;
|
||||
|
||||
public record MetaClass(
|
||||
String name,
|
||||
String extendsClass,
|
||||
List<MetaMethod> methods
|
||||
) {
|
||||
|
||||
|
||||
public TypeSpec create() {
|
||||
String split[] = name.split(":");
|
||||
String packageName = split[0];
|
||||
String className = split[1];
|
||||
|
||||
TypeSpec.Builder builder = builder(packageName, className);
|
||||
if (extendsClass != null) {
|
||||
String[] extendsSplit = extendsClass.split(":");
|
||||
builder.superclass(ClassName.get(extendsSplit[0], extendsSplit[1]));
|
||||
}
|
||||
for (MetaMethod method : methods) {
|
||||
builder.addMethods(method.create());
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package me.tofaa.entitylib.codegen;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.MethodSpec;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
import java.util.List;
|
||||
|
||||
public record MetaMethod(
|
||||
String name,
|
||||
String returnType,
|
||||
String defaultReturn,
|
||||
String dataType,
|
||||
List<VersionCheck> versionChecks
|
||||
) {
|
||||
|
||||
public List<MethodSpec> create() {
|
||||
String[] nameSplit = name.split(":");
|
||||
String[] returnSplit = returnType.split(":");
|
||||
String namePackage = nameSplit[0];
|
||||
String nameClass = nameSplit[1];
|
||||
String returnPackage = returnSplit[0];
|
||||
String returnClass = returnSplit[1];
|
||||
|
||||
String methodBasedName = nameClass.substring(0, 1).toUpperCase() + nameClass.substring(1);
|
||||
|
||||
/* offset calculator first */
|
||||
MethodSpec.Builder calculator = MethodSpec.methodBuilder(
|
||||
"calculate" + methodBasedName + "Offset")
|
||||
.addModifiers(Modifier.PRIVATE, Modifier.STATIC)
|
||||
.addParameter(int.class, "version");
|
||||
for (VersionCheck check : versionChecks) {
|
||||
calculator.beginControlFlow("if (version >= $L && version <= $L)", check.from(), check.to());
|
||||
calculator.addStatement("return $L", check.offset());
|
||||
calculator.endControlFlow();
|
||||
}
|
||||
// throw exception if version is not in range
|
||||
calculator.addStatement("throw new IllegalArgumentException(\"Version \" + version + \" is not in range\")");
|
||||
|
||||
String versionVariable = "byte offset = calculate" + methodBasedName + "Offset(EntityLib.getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion())";
|
||||
|
||||
/* getter method spec. No params */
|
||||
MethodSpec.Builder getter = MethodSpec.methodBuilder("get" + methodBasedName)
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.returns(ClassName.get(returnPackage, returnClass))
|
||||
.addStatement(versionVariable)
|
||||
.addStatement("return metadata.getIndex(" + "offset," + defaultReturn);
|
||||
|
||||
MethodSpec.Builder setter = MethodSpec.methodBuilder("set" + methodBasedName)
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.returns(void.class)
|
||||
.addParameter(ClassName.get(returnPackage, returnClass), "value")
|
||||
.addStatement(versionVariable)
|
||||
.addStatement("metadata.setIndex(" + "offset, " + dataType + ", " + "value");
|
||||
|
||||
return List.of(
|
||||
calculator.build(),
|
||||
getter.build(),
|
||||
setter.build()
|
||||
);
|
||||
}
|
||||
|
||||
public record VersionCheck(int from, int to, byte offset) {}
|
||||
|
||||
}
|
15
code-gen/src/main/resources/EntityMeta.json
Normal file
15
code-gen/src/main/resources/EntityMeta.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"class-id": "me.tofaa.entitylib.codegen:User",
|
||||
"methods": [
|
||||
|
||||
{
|
||||
"name": "getUsername",
|
||||
"return-type": "java.lang.String",
|
||||
"parameters": [
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
]
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
package me.tofaa.entitylib.common;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.PacketEventsAPI;
|
||||
import me.tofaa.entitylib.APIConfig;
|
||||
import me.tofaa.entitylib.EntityLib;
|
||||
import me.tofaa.entitylib.EntityLibAPI;
|
||||
import me.tofaa.entitylib.Platform;
|
||||
import me.tofaa.entitylib.tick.TickContainer;
|
||||
|
|
|
@ -43,6 +43,13 @@ public abstract class AbstractWorldWrapper<W> implements WorldWrapper<W> {
|
|||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEntity(WrapperEntity entity) {
|
||||
entity.despawn();
|
||||
this.entities.remove(entity.getUuid());
|
||||
this.entitiesById.remove(entity.getEntityId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends WrapperEntity> @NotNull T spawnEntity(Class<T> wrapperClass, @NotNull EntityType entityType, @NotNull Location location) {
|
||||
UUID uuid = EntityLib.getPlatform().getEntityUuidProvider().provide(entityType);
|
||||
|
|
|
@ -4,4 +4,5 @@ include 'api'
|
|||
include 'platforms:spigot'
|
||||
findProject(':platforms:spigot')?.name = 'spigot'
|
||||
include 'common'
|
||||
include 'code-gen'
|
||||
|
||||
|
|
|
@ -281,7 +281,7 @@ public final class EntityLib {
|
|||
|
||||
/**
|
||||
* Sets the entity id provider to the given one.
|
||||
* @param entityIdProvider the entity id provider. The default implementation can be found at {@link EntityIdProvider#simple()}
|
||||
* @param entityIdProvider the entity id provider. The default implementation can be found at {@link me.tofaa.entitylib.entity.EntityIdProvider#simple()}
|
||||
*/
|
||||
public static void setEntityIdProvider(EntityIdProvider entityIdProvider) {
|
||||
EntityLib.entityIdProvider = entityIdProvider;
|
||||
|
|
|
@ -1,12 +1,29 @@
|
|||
package me.tofaa.testentitylib;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import me.tofaa.entitylib.APIConfig;
|
||||
import me.tofaa.entitylib.EntityLib;
|
||||
import me.tofaa.entitylib.EntityLibAPI;
|
||||
import me.tofaa.entitylib.WorldWrapper;
|
||||
import me.tofaa.entitylib.spigot.SpigotEntityLibPlatform;
|
||||
import me.tofaa.entitylib.wrapper.WrapperEntity;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerToggleSneakEvent;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
public class TestEntityLibPlugin extends JavaPlugin {
|
||||
public class TestEntityLibPlugin extends JavaPlugin implements Listener {
|
||||
|
||||
|
||||
private EntityLibAPI<World, BukkitTask> api;
|
||||
private WrapperEntity e;
|
||||
private WorldWrapper<World> world;
|
||||
|
||||
|
||||
@Override
|
||||
|
@ -19,5 +36,20 @@ public class TestEntityLibPlugin extends JavaPlugin {
|
|||
.usePlatformLogger();
|
||||
|
||||
EntityLib.init(platform, settings);
|
||||
api = EntityLib.getApi();
|
||||
getServer().getPluginManager().registerEvents(this, this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onCrouch(PlayerToggleSneakEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (e != null) {
|
||||
e.remove();
|
||||
e = null;
|
||||
}
|
||||
world = api.wrapWorld(player.getWorld());
|
||||
e = world.spawnEntity(EntityTypes.CHICKEN, SpigotConversionUtil.fromBukkitLocation(player.getLocation()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue