Skip to content

Commit 157786a

Browse files
committed
use packet event for fullbright
1 parent a6a94e0 commit 157786a

File tree

1 file changed

+113
-25
lines changed

1 file changed

+113
-25
lines changed
Lines changed: 113 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,157 @@
11
package com.uravgcode.modernessentials.module;
22

3+
import com.github.retrooper.packetevents.PacketEvents;
4+
import com.github.retrooper.packetevents.event.PacketListener;
5+
import com.github.retrooper.packetevents.event.PacketListenerCommon;
6+
import com.github.retrooper.packetevents.event.PacketListenerPriority;
7+
import com.github.retrooper.packetevents.event.PacketSendEvent;
8+
import com.github.retrooper.packetevents.protocol.world.chunk.LightData;
9+
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChunkData;
10+
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateLight;
311
import com.uravgcode.modernessentials.annotation.CommandModule;
412
import com.uravgcode.modernessentials.event.FullBrightEvent;
513
import net.kyori.adventure.text.Component;
614
import net.kyori.adventure.text.format.NamedTextColor;
15+
import net.minecraft.network.protocol.game.ClientboundLightUpdatePacket;
16+
import net.minecraft.world.level.ChunkPos;
717
import org.bukkit.NamespacedKey;
18+
import org.bukkit.craftbukkit.CraftWorld;
19+
import org.bukkit.craftbukkit.entity.CraftPlayer;
820
import org.bukkit.entity.Player;
921
import org.bukkit.event.EventHandler;
1022
import org.bukkit.event.EventPriority;
11-
import org.bukkit.event.player.PlayerChangedWorldEvent;
23+
import org.bukkit.event.HandlerList;
1224
import org.bukkit.event.player.PlayerJoinEvent;
13-
import org.bukkit.event.player.PlayerRespawnEvent;
25+
import org.bukkit.event.player.PlayerQuitEvent;
1426
import org.bukkit.persistence.PersistentDataType;
1527
import org.bukkit.plugin.java.JavaPlugin;
16-
import org.bukkit.potion.PotionEffect;
17-
import org.bukkit.potion.PotionEffectType;
18-
import org.jetbrains.annotations.NotNull;
28+
import org.jspecify.annotations.NullMarked;
1929

30+
import java.util.Arrays;
31+
import java.util.BitSet;
32+
import java.util.Set;
33+
import java.util.UUID;
34+
import java.util.concurrent.ConcurrentHashMap;
35+
36+
import static com.github.retrooper.packetevents.protocol.packettype.PacketType.Play.Server.CHUNK_DATA;
37+
import static com.github.retrooper.packetevents.protocol.packettype.PacketType.Play.Server.UPDATE_LIGHT;
38+
39+
@NullMarked
2040
@CommandModule(name = "fullbright")
21-
public final class FullBrightModule extends PluginModule {
41+
public final class FullBrightModule extends PluginModule implements PacketListener {
2242
public final NamespacedKey fullBrightKey;
43+
private final Set<UUID> fullBrightPlayers;
2344

24-
public FullBrightModule(@NotNull JavaPlugin plugin) {
45+
private final PacketListenerCommon packetListener;
46+
private final LightData lightData;
47+
48+
public FullBrightModule(JavaPlugin plugin) {
2549
super(plugin);
26-
fullBrightKey = new NamespacedKey(plugin, "fullbright");
50+
this.fullBrightKey = new NamespacedKey(plugin, "fullbright");
51+
this.fullBrightPlayers = ConcurrentHashMap.newKeySet();
52+
this.packetListener = this.asAbstract(PacketListenerPriority.HIGH);
53+
54+
final int lightCount = 24;
55+
56+
final var fullBrightSection = new byte[2048];
57+
Arrays.fill(fullBrightSection, (byte) 0xFF);
58+
59+
final var lightArray = new byte[lightCount][];
60+
for (int i = 0; i < lightCount; ++i) lightArray[i] = fullBrightSection.clone();
61+
62+
final var lightMask = new BitSet(lightCount);
63+
lightMask.set(0, lightCount);
64+
65+
final var emptyLightMask = new BitSet(lightCount);
66+
67+
this.lightData = new LightData(
68+
true,
69+
lightMask, lightMask,
70+
emptyLightMask, emptyLightMask,
71+
lightCount, lightCount,
72+
lightArray, lightArray
73+
);
74+
}
75+
76+
@Override
77+
public void enable() {
78+
if (!enabled) {
79+
enabled = true;
80+
plugin.getServer().getPluginManager().registerEvents(this, plugin);
81+
PacketEvents.getAPI().getEventManager().registerListener(packetListener);
82+
}
83+
}
84+
85+
@Override
86+
public void disable() {
87+
if (enabled) {
88+
enabled = false;
89+
HandlerList.unregisterAll(this);
90+
PacketEvents.getAPI().getEventManager().unregisterListener(packetListener);
91+
}
92+
}
93+
94+
@Override
95+
public void onPacketSend(PacketSendEvent event) {
96+
if (!fullBrightPlayers.contains(event.getUser().getUUID())) return;
97+
98+
switch (event.getPacketType()) {
99+
case CHUNK_DATA -> {
100+
var wrapper = new WrapperPlayServerChunkData(event);
101+
wrapper.setLightData(lightData.clone());
102+
event.markForReEncode(true);
103+
}
104+
case UPDATE_LIGHT -> {
105+
var wrapper = new WrapperPlayServerUpdateLight(event);
106+
wrapper.setLightData(lightData.clone());
107+
event.markForReEncode(true);
108+
}
109+
default -> {
110+
}
111+
}
27112
}
28113

29114
@EventHandler(priority = EventPriority.MONITOR)
30115
public void onFullBright(FullBrightEvent event) {
31116
final var player = event.getPlayer();
117+
final var uuid = player.getUniqueId();
32118
final var dataContainer = player.getPersistentDataContainer();
33119

34120
if (dataContainer.has(fullBrightKey)) {
121+
fullBrightPlayers.remove(uuid);
35122
dataContainer.remove(fullBrightKey);
36-
player.sendPotionEffectChangeRemove(player, PotionEffectType.NIGHT_VISION);
37123
player.sendMessage(Component.text("Fullbright disabled", NamedTextColor.RED));
38124
} else {
125+
fullBrightPlayers.add(uuid);
39126
dataContainer.set(fullBrightKey, PersistentDataType.BYTE, (byte) 1);
40-
applyFullBright(event.getPlayer());
41127
player.sendMessage(Component.text("Fullbright enabled", NamedTextColor.GREEN));
42128
}
43-
}
44129

45-
@EventHandler(priority = EventPriority.MONITOR)
46-
public void onPlayerJoin(PlayerJoinEvent event) {
47-
applyFullBright(event.getPlayer());
130+
sendLightUpdates(player);
48131
}
49132

50133
@EventHandler(priority = EventPriority.MONITOR)
51-
public void onPlayerChangedWorld(PlayerChangedWorldEvent event) {
52-
applyFullBright(event.getPlayer());
134+
public void onPlayerJoin(PlayerJoinEvent event) {
135+
final var player = event.getPlayer();
136+
if (player.getPersistentDataContainer().has(fullBrightKey) && player.hasPermission("essentials.fullbright")) {
137+
fullBrightPlayers.add(player.getUniqueId());
138+
}
53139
}
54140

55141
@EventHandler(priority = EventPriority.MONITOR)
56-
public void onPlayerRespawn(PlayerRespawnEvent event) {
57-
applyFullBright(event.getPlayer());
142+
public void onPlayerQuit(PlayerQuitEvent event) {
143+
fullBrightPlayers.remove(event.getPlayer().getUniqueId());
58144
}
59145

60-
private void applyFullBright(@NotNull Player player) {
61-
if (!shouldEnableFullBright(player)) return;
62-
final var effect = new PotionEffect(PotionEffectType.NIGHT_VISION, -1, 0, false, false, false);
63-
player.getScheduler().run(plugin, task -> player.sendPotionEffectChange(player, effect), null);
64-
}
146+
@SuppressWarnings("UnstableApiUsage")
147+
private void sendLightUpdates(Player player) {
148+
if (!(player instanceof CraftPlayer craftPlayer && player.getWorld() instanceof CraftWorld craftWorld)) return;
149+
final var lightEngine = craftWorld.getHandle().getLightEngine();
65150

66-
private boolean shouldEnableFullBright(@NotNull Player player) {
67-
return player.getPersistentDataContainer().has(fullBrightKey) && player.hasPermission("essentials.fullbright");
151+
for (final var chunkKey : player.getSentChunkKeys()) {
152+
final var chunkPosition = new ChunkPos(chunkKey);
153+
final var packet = new ClientboundLightUpdatePacket(chunkPosition, lightEngine, null, null);
154+
craftPlayer.getHandle().connection.send(packet);
155+
}
68156
}
69157
}

0 commit comments

Comments
 (0)