major refactor
This commit is contained in:
parent
2a3732fa83
commit
718940178f
33 changed files with 840 additions and 226 deletions
|
@ -14,6 +14,7 @@
|
||||||
<option value="$PROJECT_DIR$/model-engine-addon" />
|
<option value="$PROJECT_DIR$/model-engine-addon" />
|
||||||
<option value="$PROJECT_DIR$/platforms" />
|
<option value="$PROJECT_DIR$/platforms" />
|
||||||
<option value="$PROJECT_DIR$/platforms/spigot" />
|
<option value="$PROJECT_DIR$/platforms/spigot" />
|
||||||
|
<option value="$PROJECT_DIR$/platforms/standalone" />
|
||||||
<option value="$PROJECT_DIR$/platforms/velocity" />
|
<option value="$PROJECT_DIR$/platforms/velocity" />
|
||||||
<option value="$PROJECT_DIR$/test-plugin" />
|
<option value="$PROJECT_DIR$/test-plugin" />
|
||||||
</set>
|
</set>
|
||||||
|
|
|
@ -5,14 +5,39 @@
|
||||||
</component>
|
</component>
|
||||||
<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 afterPath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestHologramsCommand.java" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/container/AbstractEntityContainer.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/container/ContainerImpl.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/container/EntityContainer.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/platforms/standalone/build.gradle" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/platforms/standalone/src/main/java/me/tofaa/entitylib/standalone/StandaloneEntityLibApi.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/platforms/standalone/src/main/java/me/tofaa/entitylib/standalone/StandaloneEntityLibPlatform.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/platforms/standalone/src/main/java/me/tofaa/entitylib/standalone/task/ExecutionType.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/platforms/standalone/src/main/java/me/tofaa/entitylib/standalone/task/Scheduler.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/platforms/standalone/src/main/java/me/tofaa/entitylib/standalone/task/SchedulerImpl.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/platforms/standalone/src/main/java/me/tofaa/entitylib/standalone/task/Task.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/platforms/standalone/src/main/java/me/tofaa/entitylib/standalone/task/TaskImpl.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/platforms/standalone/src/main/java/me/tofaa/entitylib/standalone/task/TaskSchedule.java" 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$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/utils/Check.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/utils/Check.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/Hologram.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/Hologram.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/WrapperEntityAttributes.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntityAttributes.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntityCreature.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntityCreature.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperExperienceOrbEntity.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperExperienceOrbEntity.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperLivingEntity.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperLivingEntity.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/LegacyHologram.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/LegacyHologram.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/LegacyHologram.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/LegacyHologram.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/ModernHologram.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/ModernHologram.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/ModernHologram.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/ModernHologram.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/test-plugin/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/test-plugin/build.gradle" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/build.gradle" 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$/platforms/spigot/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/platforms/spigot/build.gradle" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibAPI.java" beforeDir="false" afterPath="$PROJECT_DIR$/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibAPI.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/platforms/velocity/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/platforms/velocity/build.gradle" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/platforms/velocity/src/main/java/me/tofaa/entitylib/velocity/VelocityEntityLibAPI.java" beforeDir="false" afterPath="$PROJECT_DIR$/platforms/velocity/src/main/java/me/tofaa/entitylib/velocity/VelocityEntityLibAPI.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/settings.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/settings.gradle" 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" />
|
<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" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestMassivePigCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestMassivePigCommand.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestTextDisplayCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestTextDisplayCommand.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" />
|
||||||
|
@ -83,51 +108,51 @@
|
||||||
<option name="showExcludedFiles" value="false" />
|
<option name="showExcludedFiles" value="false" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent"><![CDATA[{
|
<component name="PropertiesComponent">{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"Downloaded.Files.Path.Enabled": "false",
|
"Downloaded.Files.Path.Enabled": "false",
|
||||||
"Gradle.Build EntityLib.executor": "Run",
|
"Gradle.Build EntityLib.executor": "Run",
|
||||||
"Gradle.EntityLib [dependencies].executor": "Run",
|
"Gradle.EntityLib [dependencies].executor": "Run",
|
||||||
"Gradle.EntityLib [publish].executor": "Run",
|
"Gradle.EntityLib [publish].executor": "Run",
|
||||||
"Gradle.EntityLib [runServer] (1).executor": "Run",
|
"Gradle.EntityLib [runServer] (1).executor": "Run",
|
||||||
"Gradle.EntityLib [runServer].executor": "Run",
|
"Gradle.EntityLib [runServer].executor": "Run",
|
||||||
"Gradle.EntityLib:code-gen [:code-gen:Main.main()].executor": "Run",
|
"Gradle.EntityLib:code-gen [:code-gen:Main.main()].executor": "Run",
|
||||||
"Gradle.EntityLib:test-plugin [cleanAllRunTaskCaches].executor": "Run",
|
"Gradle.EntityLib:test-plugin [cleanAllRunTaskCaches].executor": "Run",
|
||||||
"Gradle.EntityLib:test-plugin [cleanCustomServiceCaches].executor": "Run",
|
"Gradle.EntityLib:test-plugin [cleanCustomServiceCaches].executor": "Run",
|
||||||
"Gradle.EntityLib:test-plugin [cleanPaperCache].executor": "Run",
|
"Gradle.EntityLib:test-plugin [cleanPaperCache].executor": "Run",
|
||||||
"Gradle.EntityLib:test-plugin [cleanPaperPluginsCache].executor": "Run",
|
"Gradle.EntityLib:test-plugin [cleanPaperPluginsCache].executor": "Run",
|
||||||
"Gradle.EntityLib:test-plugin [publish].executor": "Run",
|
"Gradle.EntityLib:test-plugin [publish].executor": "Run",
|
||||||
"Gradle.EntityLib:test-plugin [runServer].executor": "Run",
|
"Gradle.EntityLib:test-plugin [runServer].executor": "Run",
|
||||||
"Gradle.EntityLib:test-plugin [shadowJar].executor": "Run",
|
"Gradle.EntityLib:test-plugin [shadowJar].executor": "Run",
|
||||||
"JAR Application.Unnamed.executor": "Run",
|
"JAR Application.Unnamed.executor": "Run",
|
||||||
"Repository.Attach.Annotations": "false",
|
"Repository.Attach.Annotations": "false",
|
||||||
"Repository.Attach.JavaDocs": "false",
|
"Repository.Attach.JavaDocs": "false",
|
||||||
"Repository.Attach.Sources": "false",
|
"Repository.Attach.Sources": "false",
|
||||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"WebServerToolWindowFactoryState": "false",
|
"WebServerToolWindowFactoryState": "false",
|
||||||
"git-widget-placeholder": "master",
|
"git-widget-placeholder": "master",
|
||||||
"ignore.virus.scanning.warn.message": "true",
|
"ignore.virus.scanning.warn.message": "true",
|
||||||
"jdk.selected.JAVA_MODULE": "corretto-17",
|
"jdk.selected.JAVA_MODULE": "corretto-17",
|
||||||
"kotlin-language-version-configured": "true",
|
"kotlin-language-version-configured": "true",
|
||||||
"last_opened_file_path": "D:/Github/EntityLib",
|
"last_opened_file_path": "D:/Github/EntityLib",
|
||||||
"node.js.detected.package.eslint": "true",
|
"node.js.detected.package.eslint": "true",
|
||||||
"node.js.detected.package.tslint": "true",
|
"node.js.detected.package.tslint": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
"nodejs_package_manager_path": "npm",
|
"nodejs_package_manager_path": "npm",
|
||||||
"project.structure.last.edited": "Modules",
|
"project.structure.last.edited": "Modules",
|
||||||
"project.structure.proportion": "0.15",
|
"project.structure.proportion": "0.15",
|
||||||
"project.structure.side.proportion": "0.2",
|
"project.structure.side.proportion": "0.2",
|
||||||
"settings.editor.selected.configurable": "preferences.editor",
|
"settings.editor.selected.configurable": "preferences.editor",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"vue.rearranger.settings.migration": "true"
|
||||||
},
|
},
|
||||||
"keyToStringList": {
|
"keyToStringList": {
|
||||||
"kotlin-gradle-user-dirs": [
|
"kotlin-gradle-user-dirs": [
|
||||||
"/home/tofaa/.gradle"
|
"/home/tofaa/.gradle"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}]]></component>
|
}</component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
<recent name="$PROJECT_DIR$/model-engine-addon" />
|
<recent name="$PROJECT_DIR$/model-engine-addon" />
|
||||||
|
@ -385,7 +410,8 @@
|
||||||
<workItem from="1716488324710" duration="3710000" />
|
<workItem from="1716488324710" duration="3710000" />
|
||||||
<workItem from="1716722129881" duration="965000" />
|
<workItem from="1716722129881" duration="965000" />
|
||||||
<workItem from="1716926795264" duration="1000" />
|
<workItem from="1716926795264" duration="1000" />
|
||||||
<workItem from="1718023888535" duration="1738000" />
|
<workItem from="1718023888535" duration="2457000" />
|
||||||
|
<workItem from="1719160307151" duration="6107000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.PacketEventsAPI;
|
||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||||
import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
||||||
import com.github.retrooper.packetevents.protocol.world.Location;
|
import com.github.retrooper.packetevents.protocol.world.Location;
|
||||||
|
import me.tofaa.entitylib.container.EntityContainer;
|
||||||
import me.tofaa.entitylib.tick.TickContainer;
|
import me.tofaa.entitylib.tick.TickContainer;
|
||||||
import me.tofaa.entitylib.wrapper.WrapperEntity;
|
import me.tofaa.entitylib.wrapper.WrapperEntity;
|
||||||
import me.tofaa.entitylib.wrapper.WrapperPlayer;
|
import me.tofaa.entitylib.wrapper.WrapperPlayer;
|
||||||
|
@ -30,30 +31,12 @@ public interface EntityLibAPI<T> {
|
||||||
|
|
||||||
void onEnable();
|
void onEnable();
|
||||||
|
|
||||||
@NotNull <T extends WrapperEntity> T createEntity(UUID uuid, int entityId, EntityType type);
|
@NotNull <P extends WrapperEntity> P cloneEntity(@NotNull Object platformEntity);
|
||||||
|
|
||||||
@NotNull <T extends WrapperEntity> T createEntity(EntityType type);
|
|
||||||
|
|
||||||
@NotNull WrapperPlayer spawnPlayer(UserProfile profile, Location location);
|
|
||||||
|
|
||||||
@NotNull WrapperPlayer createPlayer(UserProfile profile);
|
|
||||||
|
|
||||||
@NotNull WrapperPlayer createPlayer(UserProfile profile, int entityId);
|
|
||||||
|
|
||||||
@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(int id);
|
||||||
|
|
||||||
@Nullable WrapperEntity getEntity(@NotNull UUID uuid);
|
@Nullable WrapperEntity getEntity(@NotNull UUID uuid);
|
||||||
|
|
||||||
void removeEntity(WrapperEntity entity);
|
|
||||||
|
|
||||||
@NotNull Collection<WrapperEntity> getAllEntities();
|
@NotNull Collection<WrapperEntity> getAllEntities();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,4 +54,13 @@ public interface EntityLibAPI<T> {
|
||||||
* @param tickContainer the TickContainer to add.
|
* @param tickContainer the TickContainer to add.
|
||||||
*/
|
*/
|
||||||
void addTickContainer(@NotNull TickContainer<?, T> tickContainer);
|
void addTickContainer(@NotNull TickContainer<?, T> tickContainer);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
EntityContainer getDefaultContainer();
|
||||||
|
|
||||||
|
void addContainer(EntityContainer container);
|
||||||
|
|
||||||
|
void removeContainer(EntityContainer container);
|
||||||
|
|
||||||
|
@NotNull Collection<EntityContainer> getEntityContainers();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
package me.tofaa.entitylib.container;
|
||||||
|
|
||||||
|
import me.tofaa.entitylib.wrapper.WrapperEntity;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public abstract class AbstractEntityContainer implements EntityContainer {
|
||||||
|
|
||||||
|
private final Map<UUID, WrapperEntity> entities = new ConcurrentHashMap<>();
|
||||||
|
private final Map<Integer, WrapperEntity> entitiesById = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addEntity(WrapperEntity entity) {
|
||||||
|
entities.put(entity.getUuid(), entity);
|
||||||
|
entitiesById.put(entity.getEntityId(), entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeEntity(WrapperEntity entity, boolean despawn) {
|
||||||
|
entities.remove(entity.getUuid());
|
||||||
|
entitiesById.remove(entity.getEntityId());
|
||||||
|
if (despawn) {
|
||||||
|
entity.despawn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeEntity(int entityId, boolean despawn) {
|
||||||
|
WrapperEntity entity = entitiesById.get(entityId);
|
||||||
|
if (entity != null) {
|
||||||
|
removeEntity(entity, despawn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeEntity(UUID uuid, boolean despawn) {
|
||||||
|
WrapperEntity entity = entities.get(uuid);
|
||||||
|
if (entity != null) {
|
||||||
|
removeEntity(entity, despawn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearEntities(boolean despawn) {
|
||||||
|
entities.values().forEach(entity -> removeEntity(entity, despawn));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull Iterator<WrapperEntity> iterator() {
|
||||||
|
return entities.values().iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<WrapperEntity> getEntities() {
|
||||||
|
return Collections.unmodifiableCollection(entities.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WrapperEntity getEntity(UUID uuid) {
|
||||||
|
return entities.get(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WrapperEntity getEntity(int entityId) {
|
||||||
|
return entitiesById.get(entityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsEntity(UUID uuid) {
|
||||||
|
return entities.containsKey(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsEntity(int entityId) {
|
||||||
|
return entitiesById.containsKey(entityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsEntity(WrapperEntity entity) {
|
||||||
|
return entities.containsValue(entity);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
package me.tofaa.entitylib.container;
|
||||||
|
|
||||||
|
class ContainerImpl extends AbstractEntityContainer {
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package me.tofaa.entitylib.container;
|
||||||
|
|
||||||
|
import me.tofaa.entitylib.wrapper.WrapperEntity;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Containers are basic iterable classes that hold entities. These containers can be extended to provide more functionality, and this allows for seperation of logic between certain entities.
|
||||||
|
* <p>
|
||||||
|
* To access a specific {@link WrapperEntity}'s container you can use {@link WrapperEntity#getParentContainer()}.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public interface EntityContainer extends Iterable<WrapperEntity> {
|
||||||
|
|
||||||
|
static EntityContainer basic() {
|
||||||
|
return new ContainerImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addEntity(WrapperEntity entity);
|
||||||
|
|
||||||
|
void removeEntity(WrapperEntity entity, boolean despawn);
|
||||||
|
|
||||||
|
default void removeEntity(WrapperEntity entity) {
|
||||||
|
removeEntity(entity, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeEntity(int entityId, boolean despawn);
|
||||||
|
|
||||||
|
default void removeEntity(int entityId) {
|
||||||
|
removeEntity(entityId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeEntity(UUID uuid, boolean despawn);
|
||||||
|
|
||||||
|
default void removeEntity(UUID entity) {
|
||||||
|
removeEntity(entity, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearEntities(boolean despawn);
|
||||||
|
|
||||||
|
default void clearEntities() {
|
||||||
|
clearEntities(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tick();
|
||||||
|
|
||||||
|
Collection<WrapperEntity> getEntities();
|
||||||
|
|
||||||
|
@Nullable WrapperEntity getEntity(UUID uuid);
|
||||||
|
|
||||||
|
@Nullable WrapperEntity getEntity(int entityId);
|
||||||
|
|
||||||
|
boolean containsEntity(UUID uuid);
|
||||||
|
|
||||||
|
boolean containsEntity(int entityId);
|
||||||
|
|
||||||
|
/** Value based contains, not reference based */
|
||||||
|
boolean containsEntity(WrapperEntity entity);
|
||||||
|
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.*;
|
import com.github.retrooper.packetevents.wrapper.play.server.*;
|
||||||
import me.tofaa.entitylib.EntityLib;
|
import me.tofaa.entitylib.EntityLib;
|
||||||
import me.tofaa.entitylib.TrackedEntity;
|
import me.tofaa.entitylib.TrackedEntity;
|
||||||
|
import me.tofaa.entitylib.container.EntityContainer;
|
||||||
import me.tofaa.entitylib.meta.EntityMeta;
|
import me.tofaa.entitylib.meta.EntityMeta;
|
||||||
import me.tofaa.entitylib.meta.types.ObjectData;
|
import me.tofaa.entitylib.meta.types.ObjectData;
|
||||||
import me.tofaa.entitylib.tick.Tickable;
|
import me.tofaa.entitylib.tick.Tickable;
|
||||||
|
@ -34,6 +35,7 @@ public class WrapperEntity implements Tickable, TrackedEntity {
|
||||||
private Vector3d velocity;
|
private Vector3d velocity;
|
||||||
private int riding = -1;
|
private int riding = -1;
|
||||||
private final Set<Integer> passengers;
|
private final Set<Integer> passengers;
|
||||||
|
private EntityContainer parent;
|
||||||
|
|
||||||
public WrapperEntity(int entityId, UUID uuid, EntityType entityType, EntityMeta entityMeta) {
|
public WrapperEntity(int entityId, UUID uuid, EntityType entityType, EntityMeta entityMeta) {
|
||||||
this.entityId = entityId;
|
this.entityId = entityId;
|
||||||
|
@ -45,7 +47,22 @@ public class WrapperEntity implements Tickable, TrackedEntity {
|
||||||
this.passengers = ConcurrentHashMap.newKeySet();
|
this.passengers = ConcurrentHashMap.newKeySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean spawn(Location location) {
|
public WrapperEntity(int entityId, EntityType entityType) {
|
||||||
|
this(entityId, EntityLib.getPlatform().getEntityUuidProvider().provide(entityType), entityType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperEntity(UUID uuid, EntityType entityType) {
|
||||||
|
this(EntityLib.getPlatform().getEntityIdProvider().provide(uuid, entityType), uuid, entityType);
|
||||||
|
}
|
||||||
|
public WrapperEntity(EntityType entityType) {
|
||||||
|
this(EntityLib.getPlatform().getEntityUuidProvider().provide(entityType), entityType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperEntity(int entityId, UUID uuid, EntityType entityType) {
|
||||||
|
this(entityId, uuid, entityType, EntityMeta.createMeta(entityId, entityType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean spawn(Location location, EntityContainer parent) {
|
||||||
if (spawned) return false;
|
if (spawned) return false;
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.spawned = true;
|
this.spawned = true;
|
||||||
|
@ -63,9 +80,15 @@ public class WrapperEntity implements Tickable, TrackedEntity {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
sendPacketToViewers(entityMeta.createPacket());
|
sendPacketToViewers(entityMeta.createPacket());
|
||||||
|
this.parent = parent;
|
||||||
|
parent.addEntity(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean spawn(Location location) {
|
||||||
|
return spawn(location, EntityLib.getApi().getDefaultContainer());
|
||||||
|
}
|
||||||
|
|
||||||
protected int getObjectData() {
|
protected int getObjectData() {
|
||||||
if (entityMeta instanceof ObjectData) {
|
if (entityMeta instanceof ObjectData) {
|
||||||
return ((ObjectData) entityMeta).getObjectData();
|
return ((ObjectData) entityMeta).getObjectData();
|
||||||
|
@ -98,7 +121,7 @@ public class WrapperEntity implements Tickable, TrackedEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove() {
|
public void remove() {
|
||||||
EntityLib.getApi().removeEntity(this);
|
parent.removeEntity(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void despawn() {
|
public void despawn() {
|
||||||
|
@ -159,6 +182,10 @@ public class WrapperEntity implements Tickable, TrackedEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntityContainer getParentContainer() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
public void sendMessageToViewers(Component message) {
|
public void sendMessageToViewers(Component message) {
|
||||||
sendPacketToViewers(new WrapperPlayServerSystemChatMessage(false, message));
|
sendPacketToViewers(new WrapperPlayServerSystemChatMessage(false, message));
|
||||||
}
|
}
|
||||||
|
@ -381,6 +408,18 @@ public class WrapperEntity implements Tickable, TrackedEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendPacketToViewersIfSpawned(PacketWrapper<?> packet) {
|
||||||
|
if (spawned) {
|
||||||
|
sendPacketToViewers(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendPacketsToViewersIfSpawned(PacketWrapper<?>... wrappers) {
|
||||||
|
if (spawned) {
|
||||||
|
sendPacketsToViewers(wrappers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void sendPacket(UUID user, PacketWrapper<?> wrapper) {
|
private static void sendPacket(UUID user, PacketWrapper<?> wrapper) {
|
||||||
if (wrapper == null) return;
|
if (wrapper == null) return;
|
||||||
Object channel = EntityLib.getApi().getPacketEvents().getProtocolManager().getChannel(user);
|
Object channel = EntityLib.getApi().getPacketEvents().getProtocolManager().getChannel(user);
|
||||||
|
|
|
@ -75,7 +75,7 @@ public final class WrapperEntityAttributes {
|
||||||
|
|
||||||
|
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
entity.sendPacketToViewers(createPacket());
|
if (entity.isSpawned()) entity.sendPacketToViewers(createPacket());
|
||||||
}
|
}
|
||||||
|
|
||||||
public WrapperPlayServerUpdateAttributes createPacket() {
|
public WrapperPlayServerUpdateAttributes createPacket() {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package me.tofaa.entitylib.wrapper;
|
package me.tofaa.entitylib.wrapper;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||||
|
import me.tofaa.entitylib.EntityLib;
|
||||||
import me.tofaa.entitylib.meta.EntityMeta;
|
import me.tofaa.entitylib.meta.EntityMeta;
|
||||||
import me.tofaa.entitylib.wrapper.ai.AIGroup;
|
import me.tofaa.entitylib.wrapper.ai.AIGroup;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -29,6 +30,21 @@ public class WrapperEntityCreature extends WrapperLivingEntity {
|
||||||
this.aiGroups = new HashSet<>();
|
this.aiGroups = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WrapperEntityCreature(int entityId, @NotNull UUID uuid, EntityType entityType) {
|
||||||
|
this(entityId, uuid, entityType, EntityMeta.createMeta(entityId, entityType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperEntityCreature(int entityId, EntityType entityType) {
|
||||||
|
this(entityId, EntityLib.getPlatform().getEntityUuidProvider().provide(entityType), entityType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperEntityCreature(UUID uuid, EntityType entityType) {
|
||||||
|
this(EntityLib.getPlatform().getEntityIdProvider().provide(uuid, entityType), uuid, entityType);
|
||||||
|
}
|
||||||
|
public WrapperEntityCreature(EntityType entityType) {
|
||||||
|
this(EntityLib.getPlatform().getEntityUuidProvider().provide(entityType), entityType);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(long time) {
|
public void tick(long time) {
|
||||||
super.tick(time);
|
super.tick(time);
|
||||||
|
|
|
@ -3,6 +3,7 @@ package me.tofaa.entitylib.wrapper;
|
||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||||
import com.github.retrooper.packetevents.protocol.world.Location;
|
import com.github.retrooper.packetevents.protocol.world.Location;
|
||||||
import com.github.retrooper.packetevents.util.Vector3d;
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
|
import me.tofaa.entitylib.EntityLib;
|
||||||
import me.tofaa.entitylib.meta.EntityMeta;
|
import me.tofaa.entitylib.meta.EntityMeta;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@ -17,6 +18,21 @@ public class WrapperExperienceOrbEntity extends WrapperEntity {
|
||||||
super(entityId, uuid, entityType, meta);
|
super(entityId, uuid, entityType, meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WrapperExperienceOrbEntity(int entityId, @NotNull UUID uuid, EntityType entityType) {
|
||||||
|
this(entityId, uuid, entityType, EntityMeta.createMeta(entityId, entityType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperExperienceOrbEntity(int entityId, EntityType entityType) {
|
||||||
|
this(entityId, EntityLib.getPlatform().getEntityUuidProvider().provide(entityType), entityType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperExperienceOrbEntity(UUID uuid, EntityType entityType) {
|
||||||
|
this(EntityLib.getPlatform().getEntityIdProvider().provide(uuid, entityType), uuid, entityType);
|
||||||
|
}
|
||||||
|
public WrapperExperienceOrbEntity(EntityType entityType) {
|
||||||
|
this(EntityLib.getPlatform().getEntityUuidProvider().provide(entityType), entityType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies a slight slide motion towards the given location.
|
* Applies a slight slide motion towards the given location.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
@ -1,19 +1,14 @@
|
||||||
package me.tofaa.entitylib.wrapper;
|
package me.tofaa.entitylib.wrapper;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.attribute.Attribute;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||||
import com.github.retrooper.packetevents.protocol.player.HumanoidArm;
|
|
||||||
import com.github.retrooper.packetevents.protocol.potion.PotionType;
|
import com.github.retrooper.packetevents.protocol.potion.PotionType;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityAnimation;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityAnimation;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEffect;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEffect;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTeams;
|
import me.tofaa.entitylib.EntityLib;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
|
|
||||||
import me.tofaa.entitylib.meta.EntityMeta;
|
import me.tofaa.entitylib.meta.EntityMeta;
|
||||||
import me.tofaa.entitylib.meta.types.LivingEntityMeta;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class WrapperLivingEntity extends WrapperEntity{
|
public class WrapperLivingEntity extends WrapperEntity{
|
||||||
|
@ -27,6 +22,21 @@ public class WrapperLivingEntity extends WrapperEntity{
|
||||||
this.attributes = new WrapperEntityAttributes(this);
|
this.attributes = new WrapperEntityAttributes(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WrapperLivingEntity(int entityId, UUID uuid, EntityType entityType) {
|
||||||
|
this(entityId, uuid, entityType, EntityMeta.createMeta(entityId, entityType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperLivingEntity(int entityId, EntityType entityType) {
|
||||||
|
this(entityId, EntityLib.getPlatform().getEntityUuidProvider().provide(entityType), entityType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperLivingEntity(UUID uuid, EntityType entityType) {
|
||||||
|
this(EntityLib.getPlatform().getEntityIdProvider().provide(uuid, entityType), uuid, entityType);
|
||||||
|
}
|
||||||
|
public WrapperLivingEntity(EntityType entityType) {
|
||||||
|
this(EntityLib.getPlatform().getEntityUuidProvider().provide(entityType), entityType);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
super.refresh();
|
super.refresh();
|
||||||
|
|
|
@ -46,12 +46,12 @@ public class WrapperPlayer extends WrapperLivingEntity {
|
||||||
|
|
||||||
public void setGameMode(GameMode gameMode) {
|
public void setGameMode(GameMode gameMode) {
|
||||||
this.gameMode = gameMode;
|
this.gameMode = gameMode;
|
||||||
sendPacketsToViewers(new WrapperPlayServerPlayerInfoUpdate(WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_GAME_MODE, createInfo()));
|
sendPacketsToViewersIfSpawned(new WrapperPlayServerPlayerInfoUpdate(WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_GAME_MODE, createInfo()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDisplayName(Component displayName) {
|
public void setDisplayName(Component displayName) {
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
sendPacketsToViewers(new WrapperPlayServerPlayerInfoUpdate(WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_DISPLAY_NAME, createInfo()));
|
sendPacketsToViewersIfSpawned(new WrapperPlayServerPlayerInfoUpdate(WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_DISPLAY_NAME, createInfo()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component getDisplayName() {
|
public Component getDisplayName() {
|
||||||
|
@ -94,9 +94,9 @@ public class WrapperPlayer extends WrapperLivingEntity {
|
||||||
|
|
||||||
public void setInTablist(boolean tablist) {
|
public void setInTablist(boolean tablist) {
|
||||||
this.tablist = tablist;
|
this.tablist = tablist;
|
||||||
sendPacketToViewers(tabListPacket());
|
sendPacketsToViewersIfSpawned(tabListPacket());
|
||||||
if (!tablist) {
|
if (!tablist) {
|
||||||
sendPacketToViewers(tabListRemovePacket());
|
sendPacketsToViewersIfSpawned(tabListRemovePacket());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ public class WrapperPlayer extends WrapperLivingEntity {
|
||||||
|
|
||||||
public void setLatency(int latency) {
|
public void setLatency(int latency) {
|
||||||
this.latency = latency;
|
this.latency = latency;
|
||||||
sendPacketsToViewers(
|
sendPacketsToViewersIfSpawned(
|
||||||
new WrapperPlayServerPlayerInfoUpdate(
|
new WrapperPlayServerPlayerInfoUpdate(
|
||||||
WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LATENCY,
|
WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LATENCY,
|
||||||
createInfo()
|
createInfo()
|
||||||
|
|
|
@ -96,7 +96,8 @@ final class LegacyHologram implements Hologram.Legacy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLine(int index, @Nullable Component line) {
|
public void setLine(int index, @Nullable Component line) {
|
||||||
WrapperEntity e = EntityLib.getApi().spawnEntity(EntityTypes.ARMOR_STAND, location);
|
WrapperEntity e = new WrapperEntity(EntityTypes.ARMOR_STAND);
|
||||||
|
e.spawn(location);
|
||||||
ArmorStandMeta meta = (ArmorStandMeta) e.getEntityMeta();
|
ArmorStandMeta meta = (ArmorStandMeta) e.getEntityMeta();
|
||||||
meta.setCustomName(line);
|
meta.setCustomName(line);
|
||||||
meta.setCustomNameVisible(true);
|
meta.setCustomNameVisible(true);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import net.kyori.adventure.text.Component;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.sql.Wrapper;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -72,7 +73,8 @@ final class ModernHologram implements Hologram.Modern {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLine(int index, @Nullable Component line) {
|
public void setLine(int index, @Nullable Component line) {
|
||||||
WrapperEntity e = EntityLib.getApi().spawnEntity(EntityTypes.TEXT_DISPLAY, location);
|
WrapperEntity e = new WrapperEntity(EntityTypes.TEXT_DISPLAY);
|
||||||
|
e.spawn(location);
|
||||||
TextDisplayMeta meta = (TextDisplayMeta) e.getEntityMeta();
|
TextDisplayMeta meta = (TextDisplayMeta) e.getEntityMeta();
|
||||||
meta.setInvisible(true);
|
meta.setInvisible(true);
|
||||||
meta.setHasNoGravity(true);
|
meta.setHasNoGravity(true);
|
||||||
|
|
|
@ -11,6 +11,8 @@ allprojects {
|
||||||
"net.kyori:adventure-text-serializer-legacy:${adventureVersion}",
|
"net.kyori:adventure-text-serializer-legacy:${adventureVersion}",
|
||||||
"net.kyori:adventure-nbt:${adventureVersion}"]
|
"net.kyori:adventure-nbt:${adventureVersion}"]
|
||||||
|
|
||||||
|
project.ext.peVersion = '2.3.0'
|
||||||
|
|
||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
apply plugin: 'java-library'
|
apply plugin: 'java-library'
|
||||||
apply plugin: 'maven-publish'
|
apply plugin: 'maven-publish'
|
||||||
|
@ -59,6 +61,6 @@ allprojects {
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnlyApi 'com.github.retrooper.packetevents:spigot:2.3.0'
|
compileOnlyApi 'com.github.retrooper.packetevents:spigot:${project.ext.peVersion}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import me.tofaa.entitylib.APIConfig;
|
||||||
import me.tofaa.entitylib.EntityLib;
|
import me.tofaa.entitylib.EntityLib;
|
||||||
import me.tofaa.entitylib.EntityLibAPI;
|
import me.tofaa.entitylib.EntityLibAPI;
|
||||||
import me.tofaa.entitylib.Platform;
|
import me.tofaa.entitylib.Platform;
|
||||||
|
import me.tofaa.entitylib.container.EntityContainer;
|
||||||
import me.tofaa.entitylib.meta.EntityMeta;
|
import me.tofaa.entitylib.meta.EntityMeta;
|
||||||
import me.tofaa.entitylib.meta.projectile.ThrownExpBottleMeta;
|
import me.tofaa.entitylib.meta.projectile.ThrownExpBottleMeta;
|
||||||
import me.tofaa.entitylib.meta.types.LivingEntityMeta;
|
import me.tofaa.entitylib.meta.types.LivingEntityMeta;
|
||||||
|
@ -33,6 +34,9 @@ public abstract class AbstractEntityLibAPI<P, T> implements EntityLibAPI<T> {
|
||||||
protected final Map<Integer, WrapperEntity> entitiesById = new ConcurrentHashMap<>();
|
protected final Map<Integer, WrapperEntity> entitiesById = new ConcurrentHashMap<>();
|
||||||
protected final Map<UUID, WrapperEntity> entities = new ConcurrentHashMap<>();
|
protected final Map<UUID, WrapperEntity> entities = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
protected final Set<EntityContainer> entityContainers = ConcurrentHashMap.newKeySet();
|
||||||
|
protected final EntityContainer defaultEntityContainer = EntityContainer.basic();
|
||||||
|
|
||||||
protected AbstractEntityLibAPI(Platform<P> platform, APIConfig settings) {
|
protected AbstractEntityLibAPI(Platform<P> platform, APIConfig settings) {
|
||||||
this.platform = platform;
|
this.platform = platform;
|
||||||
this.packetEvents = settings.getPacketEvents();
|
this.packetEvents = settings.getPacketEvents();
|
||||||
|
@ -40,125 +44,6 @@ public abstract class AbstractEntityLibAPI<P, T> implements EntityLibAPI<T> {
|
||||||
this.tickContainers = settings.shouldTickTickables() ? new HashSet<>() : Collections.emptyList();
|
this.tickContainers = settings.shouldTickTickables() ? new HashSet<>() : Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T1 extends WrapperEntity> @NotNull T1 createEntity(UUID uuid, int entityId, EntityType type) {
|
|
||||||
if (entities.containsKey(uuid)) {
|
|
||||||
throw new IllegalArgumentException("Entity with UUID " + uuid + " already exists in this world.");
|
|
||||||
}
|
|
||||||
if (entitiesById.containsKey(entityId)) {
|
|
||||||
throw new IllegalArgumentException("Entity with ID " + entityId + " already exists in this world.");
|
|
||||||
}
|
|
||||||
EntityMeta meta = EntityMeta.createMeta(entityId, type);
|
|
||||||
WrapperEntity e;
|
|
||||||
if (meta instanceof LivingEntityMeta) {
|
|
||||||
e = new WrapperLivingEntity(entityId, uuid, type, meta);
|
|
||||||
}
|
|
||||||
else if (meta instanceof ThrownExpBottleMeta) {
|
|
||||||
e = new WrapperExperienceOrbEntity(entityId, uuid, type, meta);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
e = new WrapperEntity(entityId, uuid, type, meta);
|
|
||||||
}
|
|
||||||
entities.put(uuid, e);
|
|
||||||
entitiesById.put(entityId, e);
|
|
||||||
return (T1) e;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T1 extends WrapperEntity> @NotNull T1 createEntity(EntityType type) {
|
|
||||||
UUID uuid = EntityLib.getPlatform().getEntityUuidProvider().provide(type);
|
|
||||||
while (entities.containsKey(uuid)) {
|
|
||||||
uuid = EntityLib.getPlatform().getEntityUuidProvider().provide(type);
|
|
||||||
}
|
|
||||||
int entityId = EntityLib.getPlatform().getEntityIdProvider().provide(uuid, type);
|
|
||||||
while (entitiesById.containsKey(entityId)) {
|
|
||||||
entityId = EntityLib.getPlatform().getEntityIdProvider().provide(uuid, type);
|
|
||||||
}
|
|
||||||
return createEntity(uuid, entityId, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull WrapperPlayer spawnPlayer(UserProfile profile, Location location) {
|
|
||||||
if (getEntity(profile.getUUID()) != null) {
|
|
||||||
throw new IllegalArgumentException("Entity with UUID " + profile.getUUID() + " already exists in this world.");
|
|
||||||
}
|
|
||||||
|
|
||||||
int id = EntityLib.getPlatform().getEntityIdProvider().provide(profile.getUUID(), EntityTypes.PLAYER);
|
|
||||||
while (entitiesById.containsKey(id)) {
|
|
||||||
id = EntityLib.getPlatform().getEntityIdProvider().provide(profile.getUUID(), EntityTypes.PLAYER);
|
|
||||||
}
|
|
||||||
WrapperPlayer player = new WrapperPlayer(profile, id);
|
|
||||||
player.spawn(location);
|
|
||||||
entities.put(player.getUuid(), player);
|
|
||||||
entitiesById.put(player.getEntityId(), player);
|
|
||||||
return player;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull WrapperPlayer createPlayer(UserProfile profile) {
|
|
||||||
int id = EntityLib.getPlatform().getEntityIdProvider().provide(profile.getUUID(), EntityTypes.PLAYER);
|
|
||||||
while (entitiesById.containsKey
|
|
||||||
(id)) {
|
|
||||||
id = EntityLib.getPlatform().getEntityIdProvider().provide(profile.getUUID(), EntityTypes.PLAYER);
|
|
||||||
}
|
|
||||||
return createPlayer(profile, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull WrapperPlayer createPlayer(UserProfile profile, int entityId) {
|
|
||||||
if (getEntity(profile.getUUID()) != null) {
|
|
||||||
throw new IllegalArgumentException("Entity with UUID " + profile.getUUID() + " already exists in this world.");
|
|
||||||
}
|
|
||||||
WrapperPlayer player = new WrapperPlayer(profile, entityId);
|
|
||||||
entities.put(player.getUuid(), player);
|
|
||||||
entitiesById.put(player.getEntityId(), player);
|
|
||||||
return player;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T1 extends WrapperEntity> @NotNull T1 spawnEntity(@NotNull T1 entity, @NotNull Location location) {
|
|
||||||
entity.spawn(location);
|
|
||||||
entities.put(entity.getUuid(), entity);
|
|
||||||
entitiesById.put(entity.getEntityId(), entity);
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeEntity(WrapperEntity entity) {
|
|
||||||
entity.despawn();
|
|
||||||
this.entities.remove(entity.getUuid());
|
|
||||||
this.entitiesById.remove(entity.getEntityId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T1 extends WrapperEntity> @NotNull T1 spawnEntity(@NotNull Class<T1> wrapperClass, @NotNull EntityType entityType, @NotNull Location location) {
|
|
||||||
UUID uuid = EntityLib.getPlatform().getEntityUuidProvider().provide(entityType);
|
|
||||||
while (entities.containsKey(uuid)) {
|
|
||||||
uuid = EntityLib.getPlatform().getEntityUuidProvider().provide(entityType);
|
|
||||||
}
|
|
||||||
int entityId = EntityLib.getPlatform().getEntityIdProvider().provide(uuid, entityType);
|
|
||||||
while (entitiesById.containsKey(entityId)) {
|
|
||||||
entityId = EntityLib.getPlatform().getEntityIdProvider().provide(uuid, entityType);
|
|
||||||
}
|
|
||||||
EntityMeta meta = EntityMeta.createMeta(entityId, entityType);
|
|
||||||
WrapperEntity e;
|
|
||||||
if (meta instanceof LivingEntityMeta) {
|
|
||||||
e = new WrapperLivingEntity(entityId, uuid, entityType, meta);
|
|
||||||
}
|
|
||||||
else if (meta instanceof ThrownExpBottleMeta) {
|
|
||||||
e = new WrapperExperienceOrbEntity(entityId, uuid, entityType, meta);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
e = new WrapperEntity(entityId, uuid, entityType, meta);
|
|
||||||
}
|
|
||||||
return spawnEntity(wrapperClass.cast(e), location);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull WrapperEntity spawnEntity(@NotNull EntityType entityType, @NotNull Location location) {
|
|
||||||
return spawnEntity(WrapperEntity.class, entityType, location);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable WrapperEntity getEntity(int id) {
|
public @Nullable WrapperEntity getEntity(int id) {
|
||||||
return entitiesById.get(id);
|
return entitiesById.get(id);
|
||||||
|
@ -174,6 +59,27 @@ public abstract class AbstractEntityLibAPI<P, T> implements EntityLibAPI<T> {
|
||||||
return Collections.unmodifiableCollection(entities.values());
|
return Collections.unmodifiableCollection(entities.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addContainer(EntityContainer container) {
|
||||||
|
entityContainers.add(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeContainer(EntityContainer container) {
|
||||||
|
entityContainers.remove(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull EntityContainer getDefaultContainer() {
|
||||||
|
return defaultEntityContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Set<EntityContainer> getEntityContainers() {
|
||||||
|
return entityContainers;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public APIConfig getSettings() {
|
public APIConfig getSettings() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":common"))
|
api(project(":common"))
|
||||||
compileOnly('com.github.retrooper.packetevents:spigot:2.3.0')
|
compileOnly('com.github.retrooper.packetevents:spigot:' + peVersion)
|
||||||
compileOnly('org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT')
|
compileOnly('org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT')
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class SpigotEntityLibAPI extends AbstractEntityLibAPI<JavaPlugin, BukkitT
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends WrapperEntity> @NotNull T cloneEntity(@NotNull Object platformEntity, @NotNull Location location) {
|
public <T extends WrapperEntity> @NotNull T cloneEntity(@NotNull Object platformEntity) {
|
||||||
Check.stateCondition(!(platformEntity instanceof Entity), "Entity must be a Bukkit entity");
|
Check.stateCondition(!(platformEntity instanceof Entity), "Entity must be a Bukkit entity");
|
||||||
Entity e = (Entity) platformEntity;
|
Entity e = (Entity) platformEntity;
|
||||||
EntityType type = SpigotConversionUtil.fromBukkitEntityType(e.getType());
|
EntityType type = SpigotConversionUtil.fromBukkitEntityType(e.getType());
|
||||||
|
@ -84,10 +84,7 @@ public class SpigotEntityLibAPI extends AbstractEntityLibAPI<JavaPlugin, BukkitT
|
||||||
else {
|
else {
|
||||||
entity = new WrapperEntity(id, uuid, type, meta);
|
entity = new WrapperEntity(id, uuid, type, meta);
|
||||||
}
|
}
|
||||||
if (entity == null) {
|
return (T) entity;
|
||||||
throw new IllegalArgumentException("Could not clone entity");
|
|
||||||
}
|
|
||||||
return (T) this.spawnEntity(entity, location);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
6
platforms/standalone/build.gradle
Normal file
6
platforms/standalone/build.gradle
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api(project(":common"))
|
||||||
|
compileOnly('com.github.retrooper.packetevents:api:2.3.0')
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package me.tofaa.entitylib.standalone;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.world.Location;
|
||||||
|
import me.tofaa.entitylib.APIConfig;
|
||||||
|
import me.tofaa.entitylib.Platform;
|
||||||
|
import me.tofaa.entitylib.common.AbstractEntityLibAPI;
|
||||||
|
import me.tofaa.entitylib.standalone.task.ExecutionType;
|
||||||
|
import me.tofaa.entitylib.standalone.task.Scheduler;
|
||||||
|
import me.tofaa.entitylib.standalone.task.Task;
|
||||||
|
import me.tofaa.entitylib.standalone.task.TaskSchedule;
|
||||||
|
import me.tofaa.entitylib.tick.TickContainer;
|
||||||
|
import me.tofaa.entitylib.wrapper.WrapperEntity;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
public class StandaloneEntityLibApi extends AbstractEntityLibAPI<Object, Task> {
|
||||||
|
|
||||||
|
private final Scheduler scheduler = Scheduler.newScheduler();
|
||||||
|
|
||||||
|
protected StandaloneEntityLibApi(Platform<Object> platform, APIConfig settings) {
|
||||||
|
super(platform, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <P extends WrapperEntity> @NotNull P cloneEntity(@NotNull Object platformEntity) {
|
||||||
|
throw new UnsupportedOperationException("Not supported in standalone mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTickContainer(@NotNull TickContainer<?, Task> tickContainer) {
|
||||||
|
if (!settings.shouldTickTickables()) {
|
||||||
|
if (settings.isDebugMode()) {
|
||||||
|
platform.getLogger().log(Level.WARNING, "Tried to add a TickContainer when ticking tickables is disabled!");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tickContainers.add(tickContainer);
|
||||||
|
if (settings.isDebugMode()) {
|
||||||
|
platform.getLogger().log(Level.CONFIG, "Registering new tick container...");
|
||||||
|
}
|
||||||
|
getTickContainers().add(tickContainer);
|
||||||
|
Task task = scheduler.scheduleTask(() -> tickContainer.tick(System.currentTimeMillis()), TaskSchedule.duration(50L), TaskSchedule.duration(50L), ExecutionType.ASYNC);
|
||||||
|
tickContainer.setHandle(task);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package me.tofaa.entitylib.standalone;
|
||||||
|
|
||||||
|
import me.tofaa.entitylib.APIConfig;
|
||||||
|
import me.tofaa.entitylib.EntityLibAPI;
|
||||||
|
import me.tofaa.entitylib.common.AbstractPlatform;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class StandaloneEntityLibPlatform extends AbstractPlatform<Object> {
|
||||||
|
|
||||||
|
|
||||||
|
private StandaloneEntityLibApi api;
|
||||||
|
|
||||||
|
private StandaloneEntityLibPlatform() {
|
||||||
|
super(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupApi(@NotNull APIConfig settings) {
|
||||||
|
super.setupApi(settings);
|
||||||
|
api = new StandaloneEntityLibApi(this, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Object getHandle() {
|
||||||
|
throw new UnsupportedOperationException("Standalone platform does not have a handle.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityLibAPI<?> getAPI() {
|
||||||
|
return api;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Standalone";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package me.tofaa.entitylib.standalone.task;
|
||||||
|
|
||||||
|
public enum ExecutionType {
|
||||||
|
|
||||||
|
BLOCKING,
|
||||||
|
ASYNC,
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package me.tofaa.entitylib.standalone.task;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public interface Scheduler {
|
||||||
|
|
||||||
|
static Scheduler newScheduler() {
|
||||||
|
return new SchedulerImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
void process();
|
||||||
|
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
Task submitTask(Supplier<TaskSchedule> supplier, ExecutionType type);
|
||||||
|
|
||||||
|
default Task scheduleTask(Runnable task, TaskSchedule delay, TaskSchedule repeat, ExecutionType type) {
|
||||||
|
return buildTask(task)
|
||||||
|
.delay(delay)
|
||||||
|
.repeat(repeat)
|
||||||
|
.executionType(type)
|
||||||
|
.schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
default Task.Builder buildTask(Runnable task) {
|
||||||
|
return new Task.Builder(task, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package me.tofaa.entitylib.standalone.task;
|
||||||
|
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
class SchedulerImpl implements Scheduler {
|
||||||
|
|
||||||
|
private static final AtomicInteger TASK_COUNTER = new AtomicInteger(0);
|
||||||
|
private static final ScheduledExecutorService SCHEDULED_EXECUTOR = Executors.newSingleThreadScheduledExecutor((e) -> {
|
||||||
|
Thread thread = new Thread(e);
|
||||||
|
thread.setDaemon(true);
|
||||||
|
return thread;
|
||||||
|
});
|
||||||
|
private static final ForkJoinPool FORK_JOIN_POOL = new ForkJoinPool();
|
||||||
|
private static final Queue<TaskImpl> TASKS = new ConcurrentLinkedDeque<>();
|
||||||
|
|
||||||
|
private Thread thread;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process() {
|
||||||
|
thread = new Thread(() -> {
|
||||||
|
while (true) {
|
||||||
|
process();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown() {
|
||||||
|
thread.interrupt();
|
||||||
|
thread = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Task submitTask(Supplier<TaskSchedule> supplier, ExecutionType type) {
|
||||||
|
TaskImpl task = new TaskImpl(TASK_COUNTER.getAndIncrement(), supplier, type, this);
|
||||||
|
handleTask(task);
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleTask(TaskImpl task) {
|
||||||
|
TaskSchedule schedule = task.task.get();
|
||||||
|
if (schedule instanceof TaskSchedule.DurationSchedule) {
|
||||||
|
TaskSchedule.DurationSchedule d = (TaskSchedule.DurationSchedule) schedule;
|
||||||
|
SCHEDULED_EXECUTOR.schedule(() -> {
|
||||||
|
safeExecute(task);
|
||||||
|
}, d.duration.toMillis(), TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
else if (schedule instanceof TaskSchedule.FutureSchedule) {
|
||||||
|
TaskSchedule.FutureSchedule f = (TaskSchedule.FutureSchedule) schedule;
|
||||||
|
f.future.thenRun(() -> {
|
||||||
|
safeExecute(task);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (schedule instanceof TaskSchedule.ParkSchedule) {
|
||||||
|
task.parked = 1;
|
||||||
|
}
|
||||||
|
else if (schedule instanceof TaskSchedule.StopSchedule) {
|
||||||
|
task.cancel();
|
||||||
|
}
|
||||||
|
else if (schedule instanceof TaskSchedule.ImmediateSchedule) {
|
||||||
|
TASKS.offer(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void unparkTask(TaskImpl task) {
|
||||||
|
task.tryUnpark();
|
||||||
|
TASKS.offer(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void safeExecute(TaskImpl task) {
|
||||||
|
if (task.executionType() == ExecutionType.BLOCKING) {
|
||||||
|
TASKS.offer(task);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FORK_JOIN_POOL.submit(() -> {
|
||||||
|
if (task.alive) {
|
||||||
|
handleTask(task);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package me.tofaa.entitylib.standalone.task;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
public interface Task {
|
||||||
|
|
||||||
|
|
||||||
|
int id();
|
||||||
|
|
||||||
|
ExecutionType executionType();
|
||||||
|
|
||||||
|
void unpark();
|
||||||
|
boolean isParked();
|
||||||
|
|
||||||
|
void cancel();
|
||||||
|
|
||||||
|
|
||||||
|
class Builder {
|
||||||
|
|
||||||
|
private final Runnable runnable;
|
||||||
|
private final Scheduler scheduler;
|
||||||
|
|
||||||
|
private ExecutionType executionType = ExecutionType.SYNC;//default
|
||||||
|
private TaskSchedule delay = TaskSchedule.immediate();
|
||||||
|
private TaskSchedule repeat = TaskSchedule.stop();
|
||||||
|
|
||||||
|
Builder(Runnable runnable, Scheduler scheduler) {
|
||||||
|
this.runnable = runnable;
|
||||||
|
this.scheduler = scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder executionType(ExecutionType executionType) {
|
||||||
|
this.executionType = executionType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder delay(TaskSchedule delay) {
|
||||||
|
this.delay = delay;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder repeat(TaskSchedule repeat) {
|
||||||
|
this.repeat = repeat;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task schedule() {
|
||||||
|
AtomicBoolean first = new AtomicBoolean();
|
||||||
|
return scheduler.submitTask(() -> {
|
||||||
|
if (first.get()) {
|
||||||
|
first.set(false);
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
runnable.run();
|
||||||
|
return repeat;
|
||||||
|
}, executionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package me.tofaa.entitylib.standalone.task;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
class TaskImpl implements Task {
|
||||||
|
|
||||||
|
// thread safe way to set the parked value of any task, Like VarHandle but for older java versions
|
||||||
|
private static final AtomicIntegerFieldUpdater<TaskImpl> PARKED_UPDATER = AtomicIntegerFieldUpdater.newUpdater(TaskImpl.class, "parked");
|
||||||
|
|
||||||
|
volatile boolean alive = true;
|
||||||
|
volatile int parked = 1; // 1 is true, 0 is false
|
||||||
|
|
||||||
|
final int id;
|
||||||
|
final Supplier<TaskSchedule> task;
|
||||||
|
final ExecutionType type;
|
||||||
|
final Scheduler owner;
|
||||||
|
|
||||||
|
TaskImpl(int id, Supplier<TaskSchedule> task, ExecutionType type, Scheduler owner) {
|
||||||
|
this.id = id;
|
||||||
|
this.task = task;
|
||||||
|
this.type = type;
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int id() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExecutionType executionType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unpark() {
|
||||||
|
this.owner.unparkTask(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (obj == null || getClass() != obj.getClass()) return false;
|
||||||
|
return this.id == ((TaskImpl) obj).id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
// murmur hash 3
|
||||||
|
int h = id;
|
||||||
|
h ^= h >>> 16;
|
||||||
|
h *= 0x85ebca6b;
|
||||||
|
h ^= h >>> 13;
|
||||||
|
h *= 0xc2b2ae35;
|
||||||
|
h ^= h >>> 16;
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SimpleTask(id=" + id + ", task=" + task + ", executionType=" + type + ", owner=" + owner + ", alive=" + alive + ", parked=" + parked + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
void tryUnpark() {
|
||||||
|
PARKED_UPDATER.compareAndSet(this, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isParked() {
|
||||||
|
return parked == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
alive = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package me.tofaa.entitylib.standalone.task;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public interface TaskSchedule {
|
||||||
|
|
||||||
|
static TaskSchedule duration(Duration duration) {
|
||||||
|
return new DurationSchedule(duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TaskSchedule duration(long duration) {
|
||||||
|
return new DurationSchedule(Duration.ofMillis(duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
static TaskSchedule duration(long duration, TimeUnit unit) {
|
||||||
|
return new DurationSchedule(Duration.ofMillis(unit.toMillis(duration)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static TaskSchedule seconds(long seconds) {
|
||||||
|
return new DurationSchedule(Duration.ofSeconds(seconds));
|
||||||
|
}
|
||||||
|
|
||||||
|
static TaskSchedule minutes(long minutes) {
|
||||||
|
return new DurationSchedule(Duration.ofMinutes(minutes));
|
||||||
|
}
|
||||||
|
|
||||||
|
static TaskSchedule hours(long hours) {
|
||||||
|
return new DurationSchedule(Duration.ofHours(hours));
|
||||||
|
}
|
||||||
|
|
||||||
|
static TaskSchedule milliseconds(long milliseconds) {
|
||||||
|
return new DurationSchedule(Duration.ofMillis(milliseconds));
|
||||||
|
}
|
||||||
|
|
||||||
|
static TaskSchedule future(CompletableFuture<?> future) {
|
||||||
|
return new FutureSchedule(future);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TaskSchedule park() {
|
||||||
|
return ParkSchedule.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TaskSchedule stop() {
|
||||||
|
return StopSchedule.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TaskSchedule immediate() {
|
||||||
|
return ImmediateSchedule.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DurationSchedule implements TaskSchedule {
|
||||||
|
Duration duration;
|
||||||
|
DurationSchedule(Duration duration) {
|
||||||
|
this.duration = duration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FutureSchedule implements TaskSchedule {
|
||||||
|
CompletableFuture<?> future;
|
||||||
|
FutureSchedule(CompletableFuture<?> future) {
|
||||||
|
this.future = future;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class ParkSchedule implements TaskSchedule {
|
||||||
|
private static final ParkSchedule INSTANCE = new ParkSchedule();
|
||||||
|
ParkSchedule() {}
|
||||||
|
}
|
||||||
|
class StopSchedule implements TaskSchedule {
|
||||||
|
private static final StopSchedule INSTANCE = new StopSchedule();
|
||||||
|
StopSchedule() {}
|
||||||
|
}
|
||||||
|
class ImmediateSchedule implements TaskSchedule {
|
||||||
|
private static final ImmediateSchedule INSTANCE = new ImmediateSchedule();
|
||||||
|
ImmediateSchedule() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -15,6 +15,6 @@ java.toolchain.languageVersion.set(JavaLanguageVersion.of(17))
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":common"))
|
api(project(":common"))
|
||||||
compileOnly('com.github.retrooper.packetevents:velocity:2.3.0')
|
compileOnly('com.github.retrooper.packetevents:velocity:' + peVersion)
|
||||||
compileOnly 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT'
|
compileOnly 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
package me.tofaa.entitylib.velocity;
|
package me.tofaa.entitylib.velocity;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.world.Location;
|
|
||||||
import com.velocitypowered.api.proxy.ProxyServer;
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
import com.velocitypowered.api.scheduler.ScheduledTask;
|
import com.velocitypowered.api.scheduler.ScheduledTask;
|
||||||
import me.tofaa.entitylib.APIConfig;
|
import me.tofaa.entitylib.APIConfig;
|
||||||
import me.tofaa.entitylib.Platform;
|
|
||||||
import me.tofaa.entitylib.common.AbstractEntityLibAPI;
|
import me.tofaa.entitylib.common.AbstractEntityLibAPI;
|
||||||
import me.tofaa.entitylib.tick.TickContainer;
|
import me.tofaa.entitylib.tick.TickContainer;
|
||||||
import me.tofaa.entitylib.wrapper.WrapperEntity;
|
import me.tofaa.entitylib.wrapper.WrapperEntity;
|
||||||
|
@ -50,7 +48,7 @@ public class VelocityEntityLibAPI extends AbstractEntityLibAPI<ProxyServer, Sche
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public WrapperEntity cloneEntity(@NotNull Object platformEntity, @NotNull Location location) {
|
public <P extends WrapperEntity> P cloneEntity(@NotNull Object platformEntity) {
|
||||||
throw new UnsupportedOperationException("No support for cloning entities on Velocity");
|
throw new UnsupportedOperationException("No support for cloning entities on Velocity");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,3 +16,6 @@ if (!Boolean.parseBoolean(System.getenv("JITPACK"))) {
|
||||||
include 'platforms:velocity'
|
include 'platforms:velocity'
|
||||||
findProject(':platforms:velocity')?.name = 'velocity'
|
findProject(':platforms:velocity')?.name = 'velocity'
|
||||||
|
|
||||||
|
include 'platforms:standalone'
|
||||||
|
findProject(':platforms:standalone')?.name = 'standalone'
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ public class TestEntityLibPlugin extends JavaPlugin {
|
||||||
commandMap.register("testapi", new TestTextDisplayCommand());
|
commandMap.register("testapi", new TestTextDisplayCommand());
|
||||||
commandMap.register("testplayer", new TestPlayerCommand());
|
commandMap.register("testplayer", new TestPlayerCommand());
|
||||||
commandMap.register("testholo", new TestHologramsCommand());
|
commandMap.register("testholo", new TestHologramsCommand());
|
||||||
|
commandMap.register("testmassivepig", new TestMassivePigCommand());
|
||||||
}
|
}
|
||||||
catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
|
@ -3,6 +3,7 @@ package me.tofaa.testentitylib;
|
||||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
|
||||||
|
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||||
import me.tofaa.entitylib.EntityLib;
|
import me.tofaa.entitylib.EntityLib;
|
||||||
import me.tofaa.entitylib.wrapper.WrapperLivingEntity;
|
import me.tofaa.entitylib.wrapper.WrapperLivingEntity;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
@ -30,7 +31,7 @@ public class TestMassivePigCommand extends BukkitCommand {
|
||||||
player.sendMessage("Large pig removed");
|
player.sendMessage("Large pig removed");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
pig = EntityLib.getApi().createEntity(EntityTypes.PIG);
|
pig = new WrapperLivingEntity(EntityTypes.PIG);
|
||||||
pig.getAttributes().setAttribute(
|
pig.getAttributes().setAttribute(
|
||||||
Attributes.GENERIC_SCALE,
|
Attributes.GENERIC_SCALE,
|
||||||
10,
|
10,
|
||||||
|
@ -40,6 +41,8 @@ public class TestMassivePigCommand extends BukkitCommand {
|
||||||
WrapperPlayServerUpdateAttributes.PropertyModifier.Operation.MULTIPLY_BASE
|
WrapperPlayServerUpdateAttributes.PropertyModifier.Operation.MULTIPLY_BASE
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
pig.addViewer(player.getUniqueId());
|
||||||
|
pig.spawn(SpigotConversionUtil.fromBukkitLocation(player.getLocation()));
|
||||||
player.sendMessage("Large pig spawned");
|
player.sendMessage("Large pig spawned");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,19 +22,19 @@ public class TestTextDisplayCommand extends BukkitCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(@NotNull CommandSender commandSender, @NotNull String s, @NotNull String[] strings) {
|
public boolean execute(@NotNull CommandSender commandSender, @NotNull String s, @NotNull String[] strings) {
|
||||||
if (!(commandSender instanceof Player)) return true;
|
// if (!(commandSender instanceof Player)) return true;
|
||||||
Player player = (Player) commandSender;
|
// Player player = (Player) commandSender;
|
||||||
if (e == null) {
|
// if (e == null) {
|
||||||
e = EntityLib.getApi().createEntity(EntityTypes.PIG);
|
// e = EntityLib.getApi().createEntity(EntityTypes.PIG);
|
||||||
e.spawn(SpigotConversionUtil.fromBukkitLocation(player.getLocation()));
|
// e.spawn(SpigotConversionUtil.fromBukkitLocation(player.getLocation()));
|
||||||
e.addViewer(player.getUniqueId());
|
// e.addViewer(player.getUniqueId());
|
||||||
player.sendMessage("Spawned");
|
// player.sendMessage("Spawned");
|
||||||
}
|
// }
|
||||||
String msg = String.join(" ", strings);
|
// String msg = String.join(" ", strings);
|
||||||
PigMeta meta = (PigMeta) e.getEntityMeta();
|
// PigMeta meta = (PigMeta) e.getEntityMeta();
|
||||||
meta.setCustomNameVisible(true);
|
// meta.setCustomNameVisible(true);
|
||||||
meta.setCustomName(Component.text(msg));
|
// meta.setCustomName(Component.text(msg));
|
||||||
player.sendMessage("Set text to: " + msg);
|
// player.sendMessage("Set text to: " + msg);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue