Skip to content

Commit bb4f96f

Browse files
Merge pull request #1065 from JasperLorelai/main
Add 1.21.11 support
2 parents 5ec8294 + 1cb2582 commit bb4f96f

8 files changed

Lines changed: 570 additions & 11 deletions

File tree

core/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ dependencies {
1616

1717
shadow(project(path: ":nms:shared", configuration: "apiElements"))
1818
shadow(project(path: ":nms:latest")) { transitive = false }
19+
shadow(project(path: ":nms:v1_21_10")) { transitive = false }
1920

2021
implementation("com.github.retrooper:packetevents-spigot:2.10.1")
2122
implementation("net.dmulloy2:ProtocolLib:5.4.0") { transitive = false }

nms/latest/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ plugins {
33
}
44

55
dependencies {
6-
paperweight.paperDevBundle("1.21.10-R0.1-SNAPSHOT")
6+
paperweight.paperDevBundle("1.21.11-rc2-R0.1-SNAPSHOT")
77
implementation project(":nms:shared")
88
}

nms/latest/src/main/java/com/nisovin/magicspells/volatilecode/latest/VolatileCodeLatest.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import org.bukkit.craftbukkit.inventory.CraftItemStack;
2323
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
2424

25+
import org.jetbrains.annotations.NotNull;
26+
2527
import net.kyori.adventure.text.Component;
2628

2729
import io.papermc.paper.adventure.PaperAdventure;
@@ -35,27 +37,27 @@
3537
import net.minecraft.core.BlockPos;
3638
import net.minecraft.advancements.*;
3739
import net.minecraft.world.phys.Vec3;
40+
import net.minecraft.resources.Identifier;
3841
import net.minecraft.world.entity.EntityType;
3942
import net.minecraft.network.protocol.game.*;
4043
import net.minecraft.server.level.ServerLevel;
4144
import net.minecraft.server.level.ServerPlayer;
42-
import net.minecraft.resources.ResourceLocation;
4345
import net.minecraft.world.entity.item.PrimedTnt;
4446
import net.minecraft.core.particles.ParticleTypes;
4547
import net.minecraft.core.particles.ParticleOptions;
4648
import net.minecraft.network.syncher.SynchedEntityData;
4749
import net.minecraft.network.syncher.EntityDataAccessor;
4850
import net.minecraft.core.particles.ColorParticleOption;
49-
import net.minecraft.advancements.critereon.ImpossibleTrigger;
51+
import net.minecraft.advancements.criterion.ImpossibleTrigger;
5052
import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
5153

5254
public class VolatileCodeLatest extends VolatileCodeHandle {
5355

54-
private final ResourceLocation TOAST_KEY = ResourceLocation.fromNamespaceAndPath("magicspells", "toast_effect");
56+
private final Identifier TOAST_KEY = Identifier.fromNamespaceAndPath("magicspells", "toast_effect");
5557

56-
private final EntityDataAccessor<List<ParticleOptions>> DATA_EFFECT_PARTICLES;
57-
private final EntityDataAccessor<Boolean> DATA_EFFECT_AMBIENCE_ID;
58-
private final EntityDataAccessor<Byte> DATA_SHARED_FLAGS_ID;
58+
private final EntityDataAccessor<@NotNull List<ParticleOptions>> DATA_EFFECT_PARTICLES;
59+
private final EntityDataAccessor<@NotNull Boolean> DATA_EFFECT_AMBIENCE_ID;
60+
private final EntityDataAccessor<@NotNull Byte> DATA_SHARED_FLAGS_ID;
5961
private final Method UPDATE_EFFECT_PARTICLES;
6062

6163
@SuppressWarnings("unchecked")
@@ -64,17 +66,17 @@ public VolatileCodeLatest(VolatileCodeHelper helper) throws Exception {
6466

6567
Field dataSharedFlagsIdField = net.minecraft.world.entity.Entity.class.getDeclaredField("DATA_SHARED_FLAGS_ID");
6668
dataSharedFlagsIdField.setAccessible(true);
67-
DATA_SHARED_FLAGS_ID = (EntityDataAccessor<Byte>) dataSharedFlagsIdField.get(null);
69+
DATA_SHARED_FLAGS_ID = (EntityDataAccessor<@NotNull Byte>) dataSharedFlagsIdField.get(null);
6870

6971
Class<?> nmsEntityClass = net.minecraft.world.entity.LivingEntity.class;
7072

7173
Field dataEffectParticlesField = nmsEntityClass.getDeclaredField("DATA_EFFECT_PARTICLES");
7274
dataEffectParticlesField.setAccessible(true);
73-
DATA_EFFECT_PARTICLES = (EntityDataAccessor<List<ParticleOptions>>) dataEffectParticlesField.get(null);
75+
DATA_EFFECT_PARTICLES = (EntityDataAccessor<@NotNull List<ParticleOptions>>) dataEffectParticlesField.get(null);
7476

7577
Field dataEffectAmbienceIdField = nmsEntityClass.getDeclaredField("DATA_EFFECT_AMBIENCE_ID");
7678
dataEffectAmbienceIdField.setAccessible(true);
77-
DATA_EFFECT_AMBIENCE_ID = (EntityDataAccessor<Boolean>) dataEffectAmbienceIdField.get(null);
79+
DATA_EFFECT_AMBIENCE_ID = (EntityDataAccessor<@NotNull Boolean>) dataEffectAmbienceIdField.get(null);
7880

7981
UPDATE_EFFECT_PARTICLES = nmsEntityClass.getDeclaredMethod("updateSynchronizedMobEffectParticles");
8082
UPDATE_EFFECT_PARTICLES.setAccessible(true);

nms/latest/src/main/java/com/nisovin/magicspells/volatilecode/latest/VolatileGlowManagerLatest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
public class VolatileGlowManagerLatest extends PacketBasedGlowManager<Packet<?>, ClientboundSetEntityDataPacket, ClientboundSetPlayerTeamPacket> {
4646

47-
private static final EntityDataAccessor<Byte> DATA_SHARED_FLAGS_ID = new EntityDataAccessor<>(0, EntityDataSerializers.BYTE);
47+
private static final EntityDataAccessor<@NotNull Byte> DATA_SHARED_FLAGS_ID = new EntityDataAccessor<>(0, EntityDataSerializers.BYTE);
4848

4949
private final Set<Packet<?>> handled = Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap<>()));
5050
private final MethodHandle teamPacketHandle;

nms/v1_21_10/build.gradle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
plugins {
2+
id "io.papermc.paperweight.userdev"
3+
}
4+
5+
dependencies {
6+
paperweight.paperDevBundle("1.21.10-R0.1-SNAPSHOT")
7+
implementation project(":nms:shared")
8+
}
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
package com.nisovin.magicspells.volatilecode.v1_21_10;
2+
3+
import java.util.*;
4+
import java.lang.reflect.Field;
5+
import java.lang.reflect.Method;
6+
7+
import org.bukkit.World;
8+
import org.bukkit.Bukkit;
9+
import org.bukkit.Location;
10+
import org.bukkit.util.Vector;
11+
import org.bukkit.entity.Entity;
12+
import org.bukkit.entity.Player;
13+
import org.bukkit.entity.LivingEntity;
14+
import org.bukkit.inventory.ItemStack;
15+
import org.bukkit.event.entity.ExplosionPrimeEvent;
16+
17+
import org.bukkit.craftbukkit.CraftWorld;
18+
import org.bukkit.craftbukkit.CraftServer;
19+
import org.bukkit.craftbukkit.entity.CraftEntity;
20+
import org.bukkit.craftbukkit.entity.CraftPlayer;
21+
import org.bukkit.craftbukkit.entity.CraftTNTPrimed;
22+
import org.bukkit.craftbukkit.inventory.CraftItemStack;
23+
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
24+
25+
import net.kyori.adventure.text.Component;
26+
27+
import io.papermc.paper.adventure.PaperAdventure;
28+
import io.papermc.paper.advancement.AdvancementDisplay;
29+
30+
import com.nisovin.magicspells.util.glow.GlowManager;
31+
import com.nisovin.magicspells.volatilecode.VolatileCodeHandle;
32+
import com.nisovin.magicspells.volatilecode.VolatileCodeHelper;
33+
34+
import net.minecraft.util.ARGB;
35+
import net.minecraft.core.BlockPos;
36+
import net.minecraft.advancements.*;
37+
import net.minecraft.world.phys.Vec3;
38+
import net.minecraft.world.entity.EntityType;
39+
import net.minecraft.network.protocol.game.*;
40+
import net.minecraft.server.level.ServerLevel;
41+
import net.minecraft.server.level.ServerPlayer;
42+
import net.minecraft.resources.ResourceLocation;
43+
import net.minecraft.world.entity.item.PrimedTnt;
44+
import net.minecraft.core.particles.ParticleTypes;
45+
import net.minecraft.core.particles.ParticleOptions;
46+
import net.minecraft.network.syncher.SynchedEntityData;
47+
import net.minecraft.network.syncher.EntityDataAccessor;
48+
import net.minecraft.core.particles.ColorParticleOption;
49+
import net.minecraft.advancements.critereon.ImpossibleTrigger;
50+
import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
51+
52+
public class VolatileCode_v1_21_10 extends VolatileCodeHandle {
53+
54+
private final ResourceLocation TOAST_KEY = ResourceLocation.fromNamespaceAndPath("magicspells", "toast_effect");
55+
56+
private final EntityDataAccessor<List<ParticleOptions>> DATA_EFFECT_PARTICLES;
57+
private final EntityDataAccessor<Boolean> DATA_EFFECT_AMBIENCE_ID;
58+
private final EntityDataAccessor<Byte> DATA_SHARED_FLAGS_ID;
59+
private final Method UPDATE_EFFECT_PARTICLES;
60+
61+
@SuppressWarnings("unchecked")
62+
public VolatileCode_v1_21_10(VolatileCodeHelper helper) throws Exception {
63+
super(helper);
64+
65+
Field dataSharedFlagsIdField = net.minecraft.world.entity.Entity.class.getDeclaredField("DATA_SHARED_FLAGS_ID");
66+
dataSharedFlagsIdField.setAccessible(true);
67+
DATA_SHARED_FLAGS_ID = (EntityDataAccessor<Byte>) dataSharedFlagsIdField.get(null);
68+
69+
Class<?> nmsEntityClass = net.minecraft.world.entity.LivingEntity.class;
70+
71+
Field dataEffectParticlesField = nmsEntityClass.getDeclaredField("DATA_EFFECT_PARTICLES");
72+
dataEffectParticlesField.setAccessible(true);
73+
DATA_EFFECT_PARTICLES = (EntityDataAccessor<List<ParticleOptions>>) dataEffectParticlesField.get(null);
74+
75+
Field dataEffectAmbienceIdField = nmsEntityClass.getDeclaredField("DATA_EFFECT_AMBIENCE_ID");
76+
dataEffectAmbienceIdField.setAccessible(true);
77+
DATA_EFFECT_AMBIENCE_ID = (EntityDataAccessor<Boolean>) dataEffectAmbienceIdField.get(null);
78+
79+
UPDATE_EFFECT_PARTICLES = nmsEntityClass.getDeclaredMethod("updateSynchronizedMobEffectParticles");
80+
UPDATE_EFFECT_PARTICLES.setAccessible(true);
81+
}
82+
83+
@Override
84+
public void addPotionGraphicalEffect(LivingEntity entity, int color, long duration) {
85+
var nmsEntity = (((CraftLivingEntity) entity)).getHandle();
86+
SynchedEntityData entityData = nmsEntity.getEntityData();
87+
88+
entityData.set(
89+
DATA_EFFECT_PARTICLES,
90+
List.of(ColorParticleOption.create(ParticleTypes.ENTITY_EFFECT, ARGB.opaque(color)))
91+
);
92+
93+
entityData.set(DATA_EFFECT_AMBIENCE_ID, false);
94+
95+
if (duration <= 0) return;
96+
helper.scheduleDelayedTask(() -> {
97+
try {
98+
UPDATE_EFFECT_PARTICLES.invoke(nmsEntity);
99+
} catch (Exception e) {
100+
e.printStackTrace();
101+
}
102+
}, duration);
103+
}
104+
105+
@Override
106+
public void sendFakeSlotUpdate(Player player, int slot, ItemStack item) {
107+
var nmsItem = CraftItemStack.asNMSCopy(item);
108+
ClientboundContainerSetSlotPacket packet = new ClientboundContainerSetSlotPacket(0, 0, slot + 36, nmsItem);
109+
110+
((CraftPlayer) player).getHandle().connection.send(packet);
111+
}
112+
113+
@Override
114+
public boolean simulateTnt(Location target, LivingEntity source, float explosionSize, boolean fire) {
115+
ServerLevel world = ((CraftWorld) target.getWorld()).getHandle();
116+
var igniter = ((CraftLivingEntity) source).getHandle();
117+
118+
PrimedTnt tnt = new PrimedTnt(world, target.x(), target.y(), target.z(), igniter);
119+
CraftTNTPrimed craftTNT = new CraftTNTPrimed((CraftServer) Bukkit.getServer(), tnt);
120+
121+
return !new ExplosionPrimeEvent(craftTNT, explosionSize, fire).callEvent();
122+
}
123+
124+
@Override
125+
public void playDragonDeathEffect(Location location) {
126+
EnderDragon dragon = new EnderDragon(EntityType.ENDER_DRAGON, ((CraftWorld) location.getWorld()).getHandle());
127+
dragon.setPos(location.x(), location.y(), location.z());
128+
129+
BlockPos pos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
130+
ClientboundAddEntityPacket addMobPacket = new ClientboundAddEntityPacket(dragon, 0, pos);
131+
ClientboundEntityEventPacket entityEventPacket = new ClientboundEntityEventPacket(dragon, (byte) 3);
132+
ClientboundRemoveEntitiesPacket removeEntityPacket = new ClientboundRemoveEntitiesPacket(dragon.getId());
133+
134+
List<Player> players = new ArrayList<>();
135+
for (Player player : location.getNearbyPlayers(64.0)) {
136+
players.add(player);
137+
ServerPlayer nmsPlayer = ((CraftPlayer) player).getHandle();
138+
nmsPlayer.connection.send(addMobPacket);
139+
nmsPlayer.connection.send(entityEventPacket);
140+
}
141+
142+
helper.scheduleDelayedTask(() -> {
143+
for (Player player : players) {
144+
if (!player.isValid()) continue;
145+
((CraftPlayer) player).getHandle().connection.send(removeEntityPacket);
146+
}
147+
}, 200);
148+
}
149+
150+
@Override
151+
public void setClientVelocity(Player player, Vector velocity) {
152+
Vec3 pos = new Vec3(velocity.getX(), velocity.getY(), velocity.getZ());
153+
ClientboundSetEntityMotionPacket packet = new ClientboundSetEntityMotionPacket(player.getEntityId(), pos);
154+
((CraftPlayer) player).getHandle().connection.send(packet);
155+
}
156+
157+
@Override
158+
public void playHurtSound(LivingEntity entity) {
159+
var nmsEntity = ((CraftLivingEntity) entity).getHandle();
160+
var sound = nmsEntity.getHurtSound(nmsEntity.damageSources().generic());
161+
162+
if (sound == null || nmsEntity.isSilent()) return;
163+
nmsEntity.level().playSound(
164+
null,
165+
nmsEntity.blockPosition(),
166+
sound,
167+
nmsEntity.getSoundSource(),
168+
nmsEntity.getSoundVolume(),
169+
nmsEntity.getVoicePitch()
170+
);
171+
}
172+
173+
@Override
174+
public void sendToastEffect(Player receiver, ItemStack icon, AdvancementDisplay.Frame frameType, Component text) {
175+
var iconNms = CraftItemStack.asNMSCopy(icon);
176+
var textNms = PaperAdventure.asVanilla(text);
177+
var description = PaperAdventure.asVanilla(Component.empty());
178+
AdvancementType frame;
179+
try {
180+
frame = AdvancementType.valueOf(frameType.name());
181+
} catch (IllegalArgumentException ignored) {
182+
frame = AdvancementType.TASK;
183+
}
184+
185+
AdvancementHolder advancement = Advancement.Builder.advancement()
186+
.display(iconNms, textNms, description, null, frame, true, false, true)
187+
.addCriterion("impossible", new Criterion<>(new ImpossibleTrigger(), new ImpossibleTrigger.TriggerInstance()))
188+
.build(TOAST_KEY);
189+
AdvancementProgress progress = new AdvancementProgress();
190+
progress.update(new AdvancementRequirements(List.of(List.of("impossible"))));
191+
progress.grantProgress("impossible");
192+
193+
ServerPlayer player = ((CraftPlayer) receiver).getHandle();
194+
player.connection.send(new ClientboundUpdateAdvancementsPacket(
195+
false,
196+
Collections.singleton(advancement),
197+
Collections.emptySet(),
198+
Collections.singletonMap(TOAST_KEY, progress),
199+
true
200+
));
201+
player.connection.send(new ClientboundUpdateAdvancementsPacket(
202+
false,
203+
Collections.emptySet(),
204+
Collections.singleton(TOAST_KEY),
205+
Collections.emptyMap(),
206+
true
207+
));
208+
}
209+
210+
@Override
211+
public byte getEntityMetadata(Entity entity) {
212+
return ((CraftEntity) entity).getHandle().getEntityData().get(DATA_SHARED_FLAGS_ID);
213+
}
214+
215+
@Override
216+
public Entity getEntityFromId(World world, int id) {
217+
var entity = ((CraftWorld) world).getHandle().moonrise$getEntityLookup().get(id);
218+
return entity == null ? null : entity.getBukkitEntity();
219+
}
220+
221+
@Override
222+
public GlowManager getGlowManager() {
223+
return new VolatileGlowManager_v1_21_10(helper);
224+
}
225+
226+
}

0 commit comments

Comments
 (0)