mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-25 01:49:30 +00:00
@@ -1,6 +1,8 @@
|
||||
package net.momirealms.craftengine.bukkit.entity.projectile;
|
||||
|
||||
import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent;
|
||||
import io.papermc.paper.event.player.PlayerStopUsingItemEvent;
|
||||
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.plugin.scheduler.impl.FoliaTask;
|
||||
@@ -9,22 +11,22 @@ import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
import net.momirealms.craftengine.core.entity.projectile.CustomProjectile;
|
||||
import net.momirealms.craftengine.core.entity.projectile.ProjectileManager;
|
||||
import net.momirealms.craftengine.core.entity.projectile.ProjectileMeta;
|
||||
import net.momirealms.craftengine.core.item.CustomItem;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.plugin.scheduler.SchedulerTask;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.ThrowableProjectile;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.ProjectileLaunchEvent;
|
||||
import org.bukkit.event.player.PlayerItemConsumeEvent;
|
||||
import org.bukkit.event.world.EntitiesLoadEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -95,6 +97,48 @@ public class BukkitProjectileManager implements Listener, ProjectileManager {
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteract(PlayerItemConsumeEvent event) {
|
||||
ItemStack item = event.getItem();
|
||||
String type = getType(item);
|
||||
if (type == null) return;
|
||||
if (type.equals("bow") || type.equals("spear")) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerStopUsingItem(PlayerStopUsingItemEvent event) {
|
||||
ItemStack item = event.getItem();
|
||||
String type = getType(item);
|
||||
if (type == null) return;
|
||||
int ticksHeldFor = event.getTicksHeldFor();
|
||||
Player player = event.getPlayer();
|
||||
if (type.equals("bow")) {
|
||||
if (ticksHeldFor < 3) return;
|
||||
// player.sendMessage("可以投出自定义弓: " + item.getType() + " 持续 " + ticksHeldFor + " 刻");
|
||||
} else if (type.equals("trident")) {
|
||||
if (ticksHeldFor < 10) return;
|
||||
// player.sendMessage("可以投出自定义三叉戟: " + item.getType() + " 持续 " + ticksHeldFor + " 刻");
|
||||
Object nmsItemStack = FastNMS.INSTANCE.field$CraftItemStack$handle(item);
|
||||
Object nmsServerLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(player.getWorld());
|
||||
Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(player);
|
||||
boolean success = TridentRelease.releaseUsing(nmsItemStack, nmsServerLevel, nmsEntity);
|
||||
// player.sendMessage("释放成功: " + success);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getType(ItemStack item) {
|
||||
Item<ItemStack> wrapped = BukkitItemManager.instance().wrap(item);
|
||||
Optional<CustomItem<ItemStack>> optionalCustomItem = wrapped.getCustomItem();
|
||||
if (optionalCustomItem.isEmpty()) return null;
|
||||
CustomItem<ItemStack> customItem = optionalCustomItem.get();
|
||||
ProjectileMeta meta = customItem.settings().projectileMeta();
|
||||
if (meta == null) return null;
|
||||
return meta.type();
|
||||
}
|
||||
|
||||
public class ProjectileInjectTask implements Runnable {
|
||||
private final Projectile projectile;
|
||||
private final SchedulerTask task;
|
||||
|
||||
@@ -0,0 +1,515 @@
|
||||
package net.momirealms.craftengine.bukkit.entity.projectile;
|
||||
|
||||
import com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
import net.momirealms.craftengine.core.util.MCUtils;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
|
||||
public class TridentRelease {
|
||||
|
||||
private TridentRelease() {}
|
||||
|
||||
public static boolean releaseUsing(Object stack, Object level, Object entity) {
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
return releaseUsing_1_21_2(stack, level, entity);
|
||||
} else if (VersionHelper.isOrAbove1_21()) {
|
||||
return releaseUsing_1_21(stack, level, entity);
|
||||
} else if (VersionHelper.isOrAbove1_20_5()) {
|
||||
return releaseUsing_1_20_5(stack, level, entity);
|
||||
} else if (VersionHelper.isOrAbove1_20_3()) {
|
||||
return releaseUsing_1_20_3(stack, level, entity);
|
||||
} else if (VersionHelper.isOrAbove1_20()) {
|
||||
return releaseUsing_1_20(stack, level, entity);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean releaseUsing_1_21_2(Object stack, Object level, Object entity) {
|
||||
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copyWithCount(stack, 1);
|
||||
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
|
||||
Object copyStack1 = FastNMS.INSTANCE.method$ItemStack$copy(stack);
|
||||
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack1)) return false;
|
||||
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
|
||||
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
|
||||
return false;
|
||||
}
|
||||
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
|
||||
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack1, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
|
||||
|
||||
Object sound = FastNMS.INSTANCE.method$EnchantmentHelper$pickHighestLevel(stack);
|
||||
|
||||
if (spinStrength == 0.0F) {
|
||||
Object projectile = FastNMS.INSTANCE.method$Projectile$ThrownTrident$spawnProjectileFromRotationDelayed(
|
||||
level,
|
||||
copyStack,
|
||||
entity,
|
||||
0.0F,
|
||||
2.5F,
|
||||
1.0F
|
||||
);
|
||||
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
|
||||
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
|
||||
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
|
||||
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(FastNMS.INSTANCE.method$Projectile$Delayed$projectile(projectile))
|
||||
);
|
||||
|
||||
if (!event.callEvent() || !FastNMS.INSTANCE.method$Projectile$Delayed$attemptSpawn(projectile)) {
|
||||
FastNMS.INSTANCE.method$AbstractContainerMenu$sendAllDataToRemote(FastNMS.INSTANCE.field$Player$containerMenu(entity));
|
||||
return false;
|
||||
}
|
||||
|
||||
Object trident = FastNMS.INSTANCE.method$Projectile$Delayed$projectile(projectile);
|
||||
if (event.shouldConsume()) {
|
||||
FastNMS.INSTANCE.method$ItemStack$hurtWithoutBreaking(stack, 1, entity);
|
||||
FastNMS.INSTANCE.method$ItemStack$consume(stack, 1, entity);
|
||||
}
|
||||
|
||||
FastNMS.INSTANCE.field$AbstractArrow$pickupItemStack(trident, copyStack1);
|
||||
if (FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
|
||||
FastNMS.INSTANCE.field$AbstractArrow$pickup(trident, Reflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
|
||||
}
|
||||
|
||||
FastNMS.INSTANCE.method$Level$playSound(
|
||||
level,
|
||||
null,
|
||||
trident,
|
||||
FastNMS.INSTANCE.method$Holder$value(sound),
|
||||
Reflections.instance$SoundSource$PLAYERS,
|
||||
1.0F, 1.0F
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
|
||||
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
|
||||
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
|
||||
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
|
||||
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
|
||||
|
||||
float length = MCUtils.sqrt(x * x + y * y + z * z);
|
||||
x = x / length * spinStrength;
|
||||
y = y / length * spinStrength;
|
||||
z = z / length * spinStrength;
|
||||
|
||||
FastNMS.INSTANCE.method$CraftEventFactory$callPlayerRiptideEvent(entity, stack, x, y, z);
|
||||
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
|
||||
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
|
||||
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
|
||||
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, 8.0F, stack);
|
||||
|
||||
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
|
||||
FastNMS.INSTANCE.method$Entity$move(entity, Reflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
|
||||
}
|
||||
|
||||
FastNMS.INSTANCE.method$Level$playSound(
|
||||
level,
|
||||
null,
|
||||
entity,
|
||||
FastNMS.INSTANCE.method$Holder$value(sound),
|
||||
Reflections.instance$SoundSource$PLAYERS,
|
||||
1.0F, 1.0F
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean releaseUsing_1_21(Object stack, Object level, Object entity) {
|
||||
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copy(stack);
|
||||
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
|
||||
|
||||
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
|
||||
|
||||
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
|
||||
return false;
|
||||
}
|
||||
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
|
||||
|
||||
Object sound = FastNMS.INSTANCE.method$EnchantmentHelper$pickHighestLevel(stack);
|
||||
|
||||
if (spinStrength == 0.0F) {
|
||||
Object entitythrowntrident = FastNMS.INSTANCE.constructor$ThrownTrident(level, entity, stack);
|
||||
FastNMS.INSTANCE.method$ThrownTrident$shootFromRotation(
|
||||
entitythrowntrident,
|
||||
entity,
|
||||
FastNMS.INSTANCE.method$Entity$getXRot(entity),
|
||||
FastNMS.INSTANCE.method$Entity$getYRot(entity),
|
||||
0.0F, 2.5F, 1.0F
|
||||
);
|
||||
if (FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
|
||||
FastNMS.INSTANCE.field$AbstractArrow$pickup(entitythrowntrident, Reflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
|
||||
}
|
||||
|
||||
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
|
||||
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
|
||||
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
|
||||
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entitythrowntrident)
|
||||
);
|
||||
if (!event.callEvent() || !FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(level, entitythrowntrident)) {
|
||||
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity);
|
||||
if (bukkitEntity instanceof Player player) {
|
||||
player.updateInventory();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.shouldConsume()) {
|
||||
FastNMS.INSTANCE.method$ItemStack$hurtAndBreak(
|
||||
stack, 1, entity,
|
||||
FastNMS.INSTANCE.method$LivingEntity$getSlotForHand(FastNMS.INSTANCE.method$LivingEntity$getUsedItemHand(entity))
|
||||
);
|
||||
}
|
||||
|
||||
FastNMS.INSTANCE.field$AbstractArrow$pickupItemStack(entitythrowntrident, copyStack);
|
||||
FastNMS.INSTANCE.method$Level$playSound(
|
||||
level,
|
||||
null,
|
||||
entitythrowntrident,
|
||||
FastNMS.INSTANCE.method$Holder$value(sound),
|
||||
Reflections.instance$SoundSource$PLAYERS,
|
||||
1.0F, 1.0F
|
||||
);
|
||||
if (event.shouldConsume() && !FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
|
||||
FastNMS.INSTANCE.method$Inventory$removeItem(FastNMS.INSTANCE.method$Player$getInventory(entity), stack);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
|
||||
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
|
||||
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
|
||||
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
|
||||
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
|
||||
|
||||
float length = MCUtils.sqrt(x * x + y * y + z * z);
|
||||
x = x / length * spinStrength;
|
||||
y = y / length * spinStrength;
|
||||
z = z / length * spinStrength;
|
||||
|
||||
FastNMS.INSTANCE.method$CraftEventFactory$callPlayerRiptideEvent(entity, stack, x, y, z);
|
||||
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
|
||||
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
|
||||
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
|
||||
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, 8.0F, stack);
|
||||
|
||||
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
|
||||
FastNMS.INSTANCE.method$Entity$move(entity, Reflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
|
||||
}
|
||||
|
||||
FastNMS.INSTANCE.method$Level$playSound(
|
||||
level,
|
||||
null,
|
||||
entity,
|
||||
FastNMS.INSTANCE.method$Holder$value(sound),
|
||||
Reflections.instance$SoundSource$PLAYERS,
|
||||
1.0F, 1.0F
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean releaseUsing_1_20_5(Object stack, Object level, Object entity) {
|
||||
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copy(stack);
|
||||
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
|
||||
|
||||
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
|
||||
|
||||
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
|
||||
return false;
|
||||
}
|
||||
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
|
||||
|
||||
if (spinStrength == 0.0F) {
|
||||
Object entitythrowntrident = FastNMS.INSTANCE.constructor$ThrownTrident(level, entity, stack);
|
||||
FastNMS.INSTANCE.method$ThrownTrident$shootFromRotation(
|
||||
entitythrowntrident,
|
||||
entity,
|
||||
FastNMS.INSTANCE.method$Entity$getXRot(entity),
|
||||
FastNMS.INSTANCE.method$Entity$getYRot(entity),
|
||||
0.0F, 2.5F, 1.0F
|
||||
);
|
||||
if (FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
|
||||
FastNMS.INSTANCE.field$AbstractArrow$pickup(entitythrowntrident, Reflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
|
||||
}
|
||||
|
||||
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
|
||||
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
|
||||
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
|
||||
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entitythrowntrident)
|
||||
);
|
||||
if (!event.callEvent() || !FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(level, entitythrowntrident)) {
|
||||
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity);
|
||||
if (bukkitEntity instanceof Player player) {
|
||||
player.updateInventory();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.shouldConsume()) {
|
||||
FastNMS.INSTANCE.method$ItemStack$hurtAndBreak(
|
||||
stack, 1, entity,
|
||||
FastNMS.INSTANCE.method$LivingEntity$getSlotForHand(FastNMS.INSTANCE.method$LivingEntity$getUsedItemHand(entity))
|
||||
);
|
||||
}
|
||||
|
||||
FastNMS.INSTANCE.field$AbstractArrow$pickupItemStack(entitythrowntrident, copyStack);
|
||||
FastNMS.INSTANCE.method$Level$playSound(
|
||||
level,
|
||||
null,
|
||||
entitythrowntrident,
|
||||
Reflections.instance$SoundEvent$TRIDENT_THROW,
|
||||
Reflections.instance$SoundSource$PLAYERS,
|
||||
1.0F, 1.0F
|
||||
);
|
||||
if (event.shouldConsume() && !FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
|
||||
FastNMS.INSTANCE.method$Inventory$removeItem(FastNMS.INSTANCE.method$Player$getInventory(entity), stack);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
|
||||
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
|
||||
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
|
||||
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
|
||||
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
|
||||
|
||||
float length = MCUtils.sqrt(x * x + y * y + z * z);
|
||||
x = x / length * spinStrength;
|
||||
y = y / length * spinStrength;
|
||||
z = z / length * spinStrength;
|
||||
|
||||
FastNMS.INSTANCE.method$CraftEventFactory$callPlayerRiptideEvent(entity, stack, x, y, z);
|
||||
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
|
||||
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
|
||||
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
|
||||
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, -1.0F, null);
|
||||
|
||||
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
|
||||
FastNMS.INSTANCE.method$Entity$move(entity, Reflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
|
||||
}
|
||||
|
||||
Object soundeffect;
|
||||
if (spinStrength >= 3) {
|
||||
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_3;
|
||||
} else if (spinStrength == 2) {
|
||||
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_2;
|
||||
} else {
|
||||
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_1;
|
||||
}
|
||||
|
||||
FastNMS.INSTANCE.method$Level$playSound(
|
||||
level,
|
||||
null,
|
||||
entity,
|
||||
soundeffect,
|
||||
Reflections.instance$SoundSource$PLAYERS,
|
||||
1.0F, 1.0F
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean releaseUsing_1_20_3(Object stack, Object level, Object entity) {
|
||||
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copy(stack);
|
||||
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
|
||||
|
||||
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
|
||||
|
||||
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
|
||||
return false;
|
||||
}
|
||||
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
|
||||
|
||||
if (spinStrength == 0.0F) {
|
||||
Object entitythrowntrident = FastNMS.INSTANCE.constructor$ThrownTrident(level, entity, stack);
|
||||
FastNMS.INSTANCE.method$ThrownTrident$shootFromRotation(
|
||||
entitythrowntrident,
|
||||
entity,
|
||||
FastNMS.INSTANCE.method$Entity$getXRot(entity),
|
||||
FastNMS.INSTANCE.method$Entity$getYRot(entity),
|
||||
0.0F, 2.5F, 1.0F
|
||||
);
|
||||
if (FastNMS.INSTANCE.field$Abilities$instabuild(FastNMS.INSTANCE.method$Player$getAbilities(entity))) {
|
||||
FastNMS.INSTANCE.field$AbstractArrow$pickup(entitythrowntrident, Reflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
|
||||
}
|
||||
|
||||
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
|
||||
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
|
||||
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
|
||||
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entitythrowntrident)
|
||||
);
|
||||
if (!event.callEvent() || !FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(level, entitythrowntrident)) {
|
||||
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity);
|
||||
if (bukkitEntity instanceof Player player) {
|
||||
player.updateInventory();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.shouldConsume()) {
|
||||
FastNMS.INSTANCE.method$ItemStack$hurtAndBreak(
|
||||
stack, 1, entity,
|
||||
(player1) -> FastNMS.INSTANCE.method$LivingEntity$broadcastBreakEvent(player1, FastNMS.INSTANCE.method$LivingEntity$getUsedItemHand(entity))
|
||||
);
|
||||
}
|
||||
|
||||
FastNMS.INSTANCE.field$AbstractArrow$pickupItemStack(entitythrowntrident, copyStack);
|
||||
FastNMS.INSTANCE.method$Level$playSound(
|
||||
level,
|
||||
null,
|
||||
entitythrowntrident,
|
||||
Reflections.instance$SoundEvent$TRIDENT_THROW,
|
||||
Reflections.instance$SoundSource$PLAYERS,
|
||||
1.0F, 1.0F
|
||||
);
|
||||
if (event.shouldConsume() && !FastNMS.INSTANCE.field$Abilities$instabuild(FastNMS.INSTANCE.method$Player$getAbilities(entity))) {
|
||||
FastNMS.INSTANCE.method$Inventory$removeItem(FastNMS.INSTANCE.method$Player$getInventory(entity), stack);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
|
||||
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
|
||||
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
|
||||
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
|
||||
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
|
||||
|
||||
float length = MCUtils.sqrt(x * x + y * y + z * z);
|
||||
x = x / length * spinStrength;
|
||||
y = y / length * spinStrength;
|
||||
z = z / length * spinStrength;
|
||||
|
||||
FastNMS.INSTANCE.method$CraftEventFactory$callPlayerRiptideEvent(entity, stack, x, y, z);
|
||||
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
|
||||
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
|
||||
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
|
||||
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, -1.0F, null);
|
||||
|
||||
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
|
||||
FastNMS.INSTANCE.method$Entity$move(entity, Reflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
|
||||
}
|
||||
|
||||
Object soundeffect;
|
||||
if (spinStrength >= 3) {
|
||||
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_3;
|
||||
} else if (spinStrength == 2) {
|
||||
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_2;
|
||||
} else {
|
||||
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_1;
|
||||
}
|
||||
|
||||
FastNMS.INSTANCE.method$Level$playSound(
|
||||
level,
|
||||
null,
|
||||
entity,
|
||||
soundeffect,
|
||||
Reflections.instance$SoundSource$PLAYERS,
|
||||
1.0F, 1.0F
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean releaseUsing_1_20(Object stack, Object level, Object entity) {
|
||||
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copy(stack);
|
||||
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
|
||||
|
||||
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
|
||||
|
||||
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
|
||||
return false;
|
||||
}
|
||||
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
|
||||
|
||||
if (spinStrength == 0.0F) {
|
||||
Object entitythrowntrident = FastNMS.INSTANCE.constructor$ThrownTrident(level, entity, stack);
|
||||
FastNMS.INSTANCE.method$ThrownTrident$shootFromRotation(
|
||||
entitythrowntrident,
|
||||
entity,
|
||||
FastNMS.INSTANCE.method$Entity$getXRot(entity),
|
||||
FastNMS.INSTANCE.method$Entity$getYRot(entity),
|
||||
0.0F, 2.5F, 1.0F
|
||||
);
|
||||
if (FastNMS.INSTANCE.field$Abilities$instabuild(FastNMS.INSTANCE.method$Player$getAbilities(entity))) {
|
||||
FastNMS.INSTANCE.field$AbstractArrow$pickup(entitythrowntrident, Reflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
|
||||
}
|
||||
|
||||
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
|
||||
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
|
||||
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
|
||||
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entitythrowntrident)
|
||||
);
|
||||
if (!event.callEvent() || !FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(level, entitythrowntrident)) {
|
||||
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity);
|
||||
if (bukkitEntity instanceof Player player) {
|
||||
player.updateInventory();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.shouldConsume()) {
|
||||
FastNMS.INSTANCE.method$ItemStack$hurtAndBreak(
|
||||
stack, 1, entity,
|
||||
(player1) -> FastNMS.INSTANCE.method$LivingEntity$broadcastBreakEvent(player1, FastNMS.INSTANCE.method$LivingEntity$getUsedItemHand(entity))
|
||||
);
|
||||
}
|
||||
|
||||
FastNMS.INSTANCE.field$ThrownTrident$tridentItem(entitythrowntrident, copyStack);
|
||||
FastNMS.INSTANCE.method$Level$playSound(
|
||||
level,
|
||||
null,
|
||||
entitythrowntrident,
|
||||
Reflections.instance$SoundEvent$TRIDENT_THROW,
|
||||
Reflections.instance$SoundSource$PLAYERS,
|
||||
1.0F, 1.0F
|
||||
);
|
||||
if (event.shouldConsume() && !FastNMS.INSTANCE.field$Abilities$instabuild(FastNMS.INSTANCE.method$Player$getAbilities(entity))) {
|
||||
FastNMS.INSTANCE.method$Inventory$removeItem(FastNMS.INSTANCE.method$Player$getInventory(entity), stack);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
|
||||
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
|
||||
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
|
||||
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
|
||||
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
|
||||
|
||||
float length = MCUtils.sqrt(x * x + y * y + z * z);
|
||||
x = x / length * spinStrength;
|
||||
y = y / length * spinStrength;
|
||||
z = z / length * spinStrength;
|
||||
|
||||
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
|
||||
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
|
||||
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
|
||||
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, -1.0F, null);
|
||||
|
||||
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
|
||||
FastNMS.INSTANCE.method$Entity$move(entity, Reflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
|
||||
}
|
||||
|
||||
Object soundeffect;
|
||||
if (spinStrength >= 3) {
|
||||
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_3;
|
||||
} else if (spinStrength == 2) {
|
||||
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_2;
|
||||
} else {
|
||||
soundeffect = Reflections.instance$SoundEvent$TRIDENT_RIPTIDE_1;
|
||||
}
|
||||
|
||||
FastNMS.INSTANCE.method$Level$playSound(
|
||||
level,
|
||||
null,
|
||||
entity,
|
||||
soundeffect,
|
||||
Reflections.instance$SoundSource$PLAYERS,
|
||||
1.0F, 1.0F
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3368,11 +3368,23 @@ public class Reflections {
|
||||
);
|
||||
|
||||
public static final Object instance$SoundEvent$EMPTY;
|
||||
public static final Object instance$SoundEvent$TRIDENT_RIPTIDE_1;
|
||||
public static final Object instance$SoundEvent$TRIDENT_RIPTIDE_2;
|
||||
public static final Object instance$SoundEvent$TRIDENT_RIPTIDE_3;
|
||||
public static final Object instance$SoundEvent$TRIDENT_THROW;
|
||||
|
||||
static {
|
||||
try {
|
||||
Object key = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "intentionally_empty");
|
||||
instance$SoundEvent$EMPTY = method$Registry$get.invoke(instance$BuiltInRegistries$SOUND_EVENT, key);
|
||||
Object intentionallyEmpty = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "intentionally_empty");
|
||||
instance$SoundEvent$EMPTY = method$Registry$get.invoke(instance$BuiltInRegistries$SOUND_EVENT, intentionallyEmpty);
|
||||
Object tridentRiptide1 = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "item.trident_riptide_1");
|
||||
instance$SoundEvent$TRIDENT_RIPTIDE_1 = method$Registry$get.invoke(instance$BuiltInRegistries$SOUND_EVENT, tridentRiptide1);
|
||||
Object tridentRiptide2 = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "item.trident_riptide_2");
|
||||
instance$SoundEvent$TRIDENT_RIPTIDE_2 = method$Registry$get.invoke(instance$BuiltInRegistries$SOUND_EVENT, tridentRiptide2);
|
||||
Object tridentRiptide3 = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "item.trident.riptide_3");
|
||||
instance$SoundEvent$TRIDENT_RIPTIDE_3 = method$Registry$get.invoke(instance$BuiltInRegistries$SOUND_EVENT, tridentRiptide3);
|
||||
Object tridentThrow = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "item.trident.throw");
|
||||
instance$SoundEvent$TRIDENT_THROW = method$Registry$get.invoke(instance$BuiltInRegistries$SOUND_EVENT, tridentThrow);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -6669,7 +6681,7 @@ public class Reflections {
|
||||
);
|
||||
|
||||
public static final Constructor<?> constructor$ClientboundCustomPayloadPacket = requireNonNull(
|
||||
ReflectionUtils.getTheOnlyConstructor(clazz$ClientboundCustomPayloadPacket)
|
||||
ReflectionUtils.getConstructor(clazz$ClientboundCustomPayloadPacket, 0)
|
||||
);
|
||||
|
||||
// 1.20.2+
|
||||
@@ -6684,4 +6696,100 @@ public class Reflections {
|
||||
public static final Field field$PaperPluginClassLoader$libraryLoader = Optional.ofNullable(clazz$PaperPluginClassLoader)
|
||||
.map(it -> ReflectionUtils.getDeclaredField(it, URLClassLoader.class, 0))
|
||||
.orElse(null);
|
||||
|
||||
public static final Method method$SoundSource$values = requireNonNull(
|
||||
ReflectionUtils.getStaticMethod(
|
||||
clazz$SoundSource, clazz$SoundSource.arrayType()
|
||||
)
|
||||
);
|
||||
|
||||
public static final Object instance$SoundSource$MASTER;
|
||||
public static final Object instance$SoundSource$MUSIC;
|
||||
public static final Object instance$SoundSource$RECORDS;
|
||||
public static final Object instance$SoundSource$WEATHER;
|
||||
public static final Object instance$SoundSource$BLOCKS;
|
||||
public static final Object instance$SoundSource$HOSTILE;
|
||||
public static final Object instance$SoundSource$NEUTRAL;
|
||||
public static final Object instance$SoundSource$PLAYERS;
|
||||
public static final Object instance$SoundSource$AMBIENT;
|
||||
public static final Object instance$SoundSource$VOICE;
|
||||
|
||||
static {
|
||||
try {
|
||||
Object[] values = (Object[]) method$SoundSource$values.invoke(null);
|
||||
instance$SoundSource$MASTER = values[0];
|
||||
instance$SoundSource$MUSIC = values[1];
|
||||
instance$SoundSource$RECORDS = values[2];
|
||||
instance$SoundSource$WEATHER = values[3];
|
||||
instance$SoundSource$BLOCKS = values[4];
|
||||
instance$SoundSource$HOSTILE = values[5];
|
||||
instance$SoundSource$NEUTRAL = values[6];
|
||||
instance$SoundSource$PLAYERS = values[7];
|
||||
instance$SoundSource$AMBIENT = values[8];
|
||||
instance$SoundSource$VOICE = values[9];
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Class<?> clazz$MoverType = requireNonNull(
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.entity.EnumMoveType",
|
||||
"world.entity.MoverType"
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$MoverType$values = requireNonNull(
|
||||
ReflectionUtils.getStaticMethod(
|
||||
clazz$MoverType, clazz$MoverType.arrayType()
|
||||
)
|
||||
);
|
||||
|
||||
public static final Object instance$MoverType$SELF;
|
||||
public static final Object instance$MoverType$PLAYER;
|
||||
public static final Object instance$MoverType$PISTON;
|
||||
public static final Object instance$MoverType$SHULKER_BOX;
|
||||
public static final Object instance$MoverType$SHULKER;
|
||||
|
||||
static {
|
||||
try {
|
||||
Object[] values = (Object[]) method$MoverType$values.invoke(null);
|
||||
instance$MoverType$SELF = values[0];
|
||||
instance$MoverType$PLAYER = values[1];
|
||||
instance$MoverType$PISTON = values[2];
|
||||
instance$MoverType$SHULKER_BOX = values[3];
|
||||
instance$MoverType$SHULKER = values[4];
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Class<?> clazz$AbstractArrow$Pickup = requireNonNull(
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.entity.projectile.EntityArrow$PickupStatus",
|
||||
"world.entity.projectile.AbstractArrow$Pickup"
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$AbstractArrow$Pickup$values = requireNonNull(
|
||||
ReflectionUtils.getStaticMethod(
|
||||
clazz$AbstractArrow$Pickup, clazz$AbstractArrow$Pickup.arrayType()
|
||||
)
|
||||
);
|
||||
|
||||
public static final Object instance$AbstractArrow$Pickup$DISALLOWED;
|
||||
public static final Object instance$AbstractArrow$Pickup$ALLOWED;
|
||||
public static final Object instance$AbstractArrow$Pickup$CREATIVE_ONLY;
|
||||
|
||||
static {
|
||||
try {
|
||||
Object[] values = (Object[]) method$AbstractArrow$Pickup$values.invoke(null);
|
||||
instance$AbstractArrow$Pickup$DISALLOWED = values[0];
|
||||
instance$AbstractArrow$Pickup$ALLOWED = values[1];
|
||||
instance$AbstractArrow$Pickup$CREATIVE_ONLY = values[2];
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ import net.momirealms.craftengine.core.util.Key;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public record ProjectileMeta(Key item, ItemDisplayContext displayType, Vector3f scale, Vector3f translation, Quaternionf rotation) {
|
||||
public record ProjectileMeta(Key item, ItemDisplayContext displayType, Vector3f scale, Vector3f translation, Quaternionf rotation, String type) {
|
||||
}
|
||||
|
||||
@@ -226,7 +226,8 @@ public class ItemSettings {
|
||||
Vector3f translation = MiscUtils.getAsVector3f(args.getOrDefault("translation", "0"), "translation");
|
||||
Vector3f scale = MiscUtils.getAsVector3f(args.getOrDefault("scale", "1"), "scale");
|
||||
Quaternionf rotation = MiscUtils.getAsQuaternionf(ResourceConfigUtils.get(args, "rotation-left", "rotation"), "rotation-left");
|
||||
return settings -> settings.projectileMeta(new ProjectileMeta(customTridentItemId, displayType, scale, translation, rotation));
|
||||
String type = args.getOrDefault("type", "none").toString();
|
||||
return settings -> settings.projectileMeta(new ProjectileMeta(customTridentItemId, displayType, scale, translation, rotation, type));
|
||||
}));
|
||||
registerFactory("dyeable", (value -> {
|
||||
boolean bool = (boolean) value;
|
||||
|
||||
@@ -12,6 +12,8 @@ public class MCUtils {
|
||||
|
||||
private MCUtils() {}
|
||||
|
||||
public static final float DEG_TO_RAD = ((float)Math.PI / 180F);
|
||||
|
||||
private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[]{0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
|
||||
private static final float[] SIN = make(new float[65536], (sineTable) -> {
|
||||
for(int i = 0; i < sineTable.length; ++i) {
|
||||
@@ -231,6 +233,14 @@ public class MCUtils {
|
||||
return SIN[(int) (value * 10430.378F) & '\uffff'];
|
||||
}
|
||||
|
||||
public static float cos(float value) {
|
||||
return SIN[(int)(value * 10430.378F + 16384.0F) & '\uffff'];
|
||||
}
|
||||
|
||||
public static float sqrt(float value) {
|
||||
return (float)Math.sqrt(value);
|
||||
}
|
||||
|
||||
public static <T> T findNextInIterable(Iterable<T> iterable, @Nullable T object) {
|
||||
Iterator<T> iterator = iterable.iterator();
|
||||
T next = iterator.next();
|
||||
|
||||
@@ -50,7 +50,7 @@ byte_buddy_version=1.17.5
|
||||
ahocorasick_version=0.6.3
|
||||
snake_yaml_version=2.4
|
||||
anti_grief_version=0.15
|
||||
nms_helper_version=0.65.21
|
||||
nms_helper_version=0.65.23
|
||||
evalex_version=3.5.0
|
||||
reactive_streams_version=1.0.4
|
||||
amazon_awssdk_version=2.31.23
|
||||
|
||||
Reference in New Issue
Block a user