9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-30 12:29:15 +00:00

优化落地弹射物

This commit is contained in:
XiaoMoMi
2025-06-09 19:31:58 +08:00
parent a20dac328b
commit 43b2cd3093
8 changed files with 53 additions and 68 deletions

View File

@@ -365,7 +365,7 @@ public class BukkitFurniture implements Furniture {
public static void injectFurnitureEntity(Object nmsEntity) {
try {
Object trackedEntity = FastNMS.INSTANCE.field$Entity$trackedEntity(nmsEntity);
Object serverEntity = FastNMS.INSTANCE.filed$ChunkMap$TrackedEntity$serverEntity(trackedEntity);
Object serverEntity = FastNMS.INSTANCE.field$ChunkMap$TrackedEntity$serverEntity(trackedEntity);
CoreReflections.handle$ServerEntity$broadcastSetter.invokeExact(serverEntity, Handlers.DO_NOTHING);
CoreReflections.handle$ServerEntity$updateIntervalSetter.invokeExact(serverEntity, Integer.MAX_VALUE);
} catch (Throwable e) {

View File

@@ -11,4 +11,9 @@ public class BukkitCustomProjectile extends AbstractCustomProjectile {
public BukkitCustomProjectile(ProjectileMeta meta, Projectile projectile, Item<ItemStack> projectileItem) {
super(meta, new BukkitProjectile(projectile), projectileItem);
}
@Override
public BukkitProjectile projectile() {
return (BukkitProjectile) super.projectile();
}
}

View File

@@ -38,11 +38,11 @@ import java.util.concurrent.ConcurrentHashMap;
public class BukkitProjectileManager implements Listener, ProjectileManager {
private static BukkitProjectileManager instance;
private final BukkitCraftEngine plugin;
private final Map<Integer, BukkitCustomProjectile> projectiles;
// 会被netty线程访问
private final Map<Integer, BukkitCustomProjectile> projectiles = new ConcurrentHashMap<>();
public BukkitProjectileManager(BukkitCraftEngine plugin) {
this.plugin = plugin;
this.projectiles = new ConcurrentHashMap<>();
instance = this;
}
@@ -114,7 +114,8 @@ public class BukkitProjectileManager implements Listener, ProjectileManager {
wrapped.getCustomItem().ifPresent(it -> {
ProjectileMeta meta = it.settings().projectileMeta();
if (meta != null) {
this.projectiles.put(projectile.getEntityId(), new BukkitCustomProjectile(meta, projectile, wrapped));
BukkitCustomProjectile customProjectile = new BukkitCustomProjectile(meta, projectile, wrapped);
this.projectiles.put(projectile.getEntityId(), customProjectile);
new ProjectileInjectTask(projectile);
}
});
@@ -162,9 +163,7 @@ public class BukkitProjectileManager implements Listener, ProjectileManager {
private final Projectile projectile;
private final SchedulerTask task;
private Object cachedServerEntity;
private boolean injected;
private int lastInjectedInterval = -1;
private boolean wasInGround;
private int lastInjectedInterval = 0;
public ProjectileInjectTask(Projectile projectile) {
this.projectile = projectile;
@@ -181,44 +180,35 @@ public class BukkitProjectileManager implements Listener, ProjectileManager {
this.task.cancel();
return;
}
Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(this.projectile);
if (!this.injected) {
injectProjectile(nmsEntity, 1);
this.injected = true;
this.lastInjectedInterval = 1;
// 获取server entity
if (this.cachedServerEntity == null) {
Object trackedEntity = FastNMS.INSTANCE.field$Entity$trackedEntity(nmsEntity);
if (trackedEntity == null) return;
Object serverEntity = FastNMS.INSTANCE.field$ChunkMap$TrackedEntity$serverEntity(trackedEntity);
if (serverEntity == null) return;
this.cachedServerEntity = serverEntity;
}
boolean inGround = FastNMS.INSTANCE.method$AbstractArrow$isInGround(nmsEntity);
if (canSpawnParticle(nmsEntity, inGround)) {
this.projectile.getWorld().spawnParticle(ParticleUtils.BUBBLE, this.projectile.getLocation(), 3, 0.1, 0.1, 0.1, 0);
}
projectileByEntityId(this.projectile.getEntityId()).ifPresent(customProjectile -> {
customProjectile.setInGroundTime(inGround ? customProjectile.inGroundTime() + 1 : 0);
if (customProjectile.inGroundTime() > 5) {
if (lastInjectedInterval != Integer.MAX_VALUE) {
injectProjectile(nmsEntity, Integer.MAX_VALUE);
}
} else if (!inGround && wasInGround) {
if (lastInjectedInterval != 1) {
injectProjectile(nmsEntity, 1);
}
}
this.wasInGround = inGround;
});
if (inGround) {
updateProjectileUpdateInterval(Integer.MAX_VALUE);
} else {
updateProjectileUpdateInterval(1);
}
}
private void injectProjectile(Object entity, int updateInterval) {
if (this.cachedServerEntity == null) {
Object trackedEntity = FastNMS.INSTANCE.field$Entity$trackedEntity(entity);
if (trackedEntity == null) return;
Object serverEntity = FastNMS.INSTANCE.filed$ChunkMap$TrackedEntity$serverEntity(trackedEntity);
if (serverEntity == null) return;
this.cachedServerEntity = serverEntity;
}
private void updateProjectileUpdateInterval(int updateInterval) {
if (this.lastInjectedInterval == updateInterval) return;
try {
CoreReflections.handle$ServerEntity$updateIntervalSetter.invokeExact(this.cachedServerEntity, updateInterval);
this.lastInjectedInterval = updateInterval;
} catch (Throwable e) {
plugin.logger().warn("Failed to update server entity tracking interval", e);
BukkitProjectileManager.this.plugin.logger().warn("Failed to update server entity update interval for " + this.projectile.getType().getKey() + "[" + this.projectile.getUniqueId() + "]", e);
}
}