Skip to content

Commit 09463cc

Browse files
Merge pull request #1016 from JasperLorelai/1.21.5
Added 1.21.5 support
2 parents 9872fba + d3dfbad commit 09463cc

File tree

10 files changed

+587
-13
lines changed

10 files changed

+587
-13
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
plugins {
22
id("dev.magicspells.msjava")
3+
id("io.papermc.paperweight.userdev") version "2.0.0-beta.16" apply false
34
}
45

56
subprojects {

core/build.gradle

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

1515
shadow(project(path: ":nms:shared", configuration: "apiElements"))
1616
shadow(project(path: ":nms:latest")) { transitive = false }
17+
shadow(project(path: ":nms:v1_21_4")) { transitive = false }
1718

1819
implementation(group: "com.github.retrooper", name: "packetevents-spigot", version: "2.7.0")
1920
implementation(group: "com.comphenix.protocol", name: "ProtocolLib", version: "5.3.0") { transitive = false }

gradle.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
version = 4.0-Beta-17
22
groupId = com.nisovin.magicspells
3+
4+
org.gradle.parallel=true

nms/latest/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
plugins {
2-
id "io.papermc.paperweight.userdev" version "2.0.0-beta.13"
2+
id "io.papermc.paperweight.userdev"
33
}
44

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

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818
import org.bukkit.craftbukkit.CraftServer;
1919
import org.bukkit.craftbukkit.entity.CraftEntity;
2020
import org.bukkit.craftbukkit.entity.CraftPlayer;
21+
import org.bukkit.craftbukkit.util.CraftLocation;
2122
import org.bukkit.craftbukkit.entity.CraftTNTPrimed;
2223
import org.bukkit.craftbukkit.inventory.CraftItemStack;
2324
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
2425

2526
import net.kyori.adventure.text.Component;
2627

27-
import io.papermc.paper.util.MCUtil;
2828
import io.papermc.paper.adventure.PaperAdventure;
2929
import io.papermc.paper.advancement.AdvancementDisplay;
3030

@@ -161,12 +161,13 @@ public void setClientVelocity(Player player, Vector velocity) {
161161
@Override
162162
public void playHurtSound(LivingEntity entity) {
163163
var nmsEntity = ((CraftLivingEntity) entity).getHandle();
164+
var sound = nmsEntity.getHurtSound(nmsEntity.damageSources().generic());
164165

165-
if (nmsEntity.isSilent()) return;
166+
if (sound == null || nmsEntity.isSilent()) return;
166167
nmsEntity.level().playSound(
167168
null,
168169
nmsEntity.blockPosition(),
169-
nmsEntity.getHurtSound0(nmsEntity.damageSources().generic()),
170+
sound,
170171
nmsEntity.getSoundSource(),
171172
nmsEntity.getSoundVolume(),
172173
nmsEntity.getVoicePitch()
@@ -198,19 +199,21 @@ public void sendToastEffect(Player receiver, ItemStack icon, AdvancementDisplay.
198199
false,
199200
Collections.singleton(advancement),
200201
Collections.emptySet(),
201-
Collections.singletonMap(TOAST_KEY, progress)
202+
Collections.singletonMap(TOAST_KEY, progress),
203+
true
202204
));
203205
player.connection.send(new ClientboundUpdateAdvancementsPacket(
204206
false,
205207
Collections.emptySet(),
206208
Collections.singleton(TOAST_KEY),
207-
Collections.emptyMap()
209+
Collections.emptyMap(),
210+
true
208211
));
209212
}
210213

211214
@Override
212215
public void addGameTestMarker(Player player, Location location, int color, String name, int lifetime) {
213-
GameTestAddMarkerDebugPayload payload = new GameTestAddMarkerDebugPayload(MCUtil.toBlockPosition(location), color, name, lifetime);
216+
GameTestAddMarkerDebugPayload payload = new GameTestAddMarkerDebugPayload(CraftLocation.toBlockPosition(location), color, name, lifetime);
214217
((CraftPlayer) player).getHandle().connection.send(new ClientboundCustomPayloadPacket(payload));
215218
}
216219

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.lang.invoke.MethodType;
77
import java.lang.invoke.MethodHandle;
88
import java.lang.invoke.MethodHandles;
9+
import java.util.function.Function;
910

1011
import io.netty.channel.ChannelPromise;
1112
import io.netty.channel.ChannelPipeline;
@@ -16,6 +17,7 @@
1617
import net.minecraft.network.protocol.Packet;
1718
import net.minecraft.world.scores.PlayerTeam;
1819
import net.minecraft.world.scores.Scoreboard;
20+
import net.minecraft.util.StringRepresentable;
1921
import net.minecraft.world.scores.Team.Visibility;
2022
import net.minecraft.world.scores.Team.CollisionRule;
2123
import net.minecraft.network.syncher.SynchedEntityData;
@@ -87,8 +89,8 @@ protected Collection<ClientboundSetPlayerTeamPacket> createAddTeamPackets() {
8789

8890
ConfigurationSection config = helper.getMainConfig();
8991
boolean seeFriendlyInvisibles = config.getBoolean("general.glow-spell-scoreboard-teams.see-friendly-invisibles", false);
90-
CollisionRule collision = getStringOption("collision-rule", CollisionRule.ALWAYS, CollisionRule::byName, config, helper::error);
91-
Visibility visibility = getStringOption("name-tag-visibility", Visibility.ALWAYS, Visibility::byName, config, helper::error);
92+
CollisionRule collision = getStringOption("collision-rule", CollisionRule.ALWAYS, StringRepresentable.createNameLookup(CollisionRule.values(), Function.identity()), config, helper::error);
93+
Visibility visibility = getStringOption("name-tag-visibility", Visibility.ALWAYS, StringRepresentable.createNameLookup(Visibility.values(), Function.identity()), config, helper::error);
9294

9395
Scoreboard scoreboard = new Scoreboard();
9496
for (ChatFormatting formatting : ChatFormatting.values()) {

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

0 commit comments

Comments
 (0)