9
0
mirror of https://gitlab.com/SamB440/rpgregions-2.git synced 2025-12-19 14:59:19 +00:00

Fog for 1.19 test

This commit is contained in:
SamB440
2023-11-17 16:48:53 +00:00
parent 2a0152f2af
commit 7a9cddc09c
8 changed files with 311 additions and 138 deletions

View File

@@ -12,14 +12,14 @@ dependencies {
testImplementation("junit:junit:4.13.2")
compileOnly("org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT")
compileOnly("org.spigotmc:spigot-api:1.20.2-R0.1-SNAPSHOT")
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.4-SNAPSHOT") {
exclude("com.destroystokyo.paper")
exclude("org.spigotmc")
}
compileOnly(":Residence4.9.2.2") // residence
compileOnly(":GriefPrevention") // griefprevention
compileOnly("com.github.angeschossen:LandsAPI:6.0.2") // lands
compileOnly("com.github.angeschossen:LandsAPI:6.37.0") // lands
compileOnly("com.griefdefender:api:2.1.0-SNAPSHOT") // GriefDefender
if (ultraRegionsSupport) compileOnly(":UltraRegions") // ultraregions
}

View File

@@ -1,6 +1,12 @@
java {
disableAutoTargetJvm()
}
repositories {
maven("https://betonquest.org/nexus/repository/betonquest/")
maven("https://repo.codemc.io/repository/maven-public/")
maven("https://repo.codemc.io/repository/nms/")
maven("https://repo.papermc.io/repository/maven-public/")
}
dependencies {
@@ -28,7 +34,9 @@ dependencies {
implementation("org.bstats:bstats-bukkit:3.0.2") // plugin stats
implementation("io.papermc:paperlib:1.0.7") // paperlib - async teleport on Paper
compileOnly("org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT")
compileOnly("org.spigotmc:spigot:1.19.4-R0.1-SNAPSHOT")
compileOnly("org.spigotmc:spigot-api:1.20.2-R0.1-SNAPSHOT")
compileOnly("com.mojang:datafixerupper:6.0.8")
compileOnly("com.github.ben-manes.caffeine:caffeine:3.1.8") { // IMPLEMENTED VIA LIBRARIES
exclude("org.checkerframework")
}

View File

@@ -12,7 +12,7 @@ import net.islandearth.rpgregions.api.integrations.rpgregions.RPGRegionsIntegrat
import net.islandearth.rpgregions.api.integrations.rpgregions.region.RPGRegionsRegion;
import net.islandearth.rpgregions.api.schedule.PlatformScheduler;
import net.islandearth.rpgregions.commands.Commands;
import net.islandearth.rpgregions.effects.FogEffect;
import net.islandearth.rpgregions.effects.fog.FogEffect;
import net.islandearth.rpgregions.effects.PotionRegionEffect;
import net.islandearth.rpgregions.effects.RegionEffect;
import net.islandearth.rpgregions.effects.RegionEffectRegistry;

View File

@@ -1,126 +0,0 @@
package net.islandearth.rpgregions.effects;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketContainer;
import net.islandearth.rpgregions.api.IRPGRegionsAPI;
import net.islandearth.rpgregions.gui.GuiEditable;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public class FogEffect extends RegionEffect {
@GuiEditable("Sky Colour") private final String skyColour;
@GuiEditable("Water Colour") private final String waterColour;
@GuiEditable("Water Fog Colour") private final String waterFogColour;
@GuiEditable("Fog Colour") private final String fogColour;
@GuiEditable("Grass Colour") private final String grassColour;
@GuiEditable("Foilage Colour") private final String foilageColour;
//private transient BiomeBase biomeBase;
private transient int biomeId;
private transient List<UUID> effect;
public FogEffect(IRPGRegionsAPI api) {
super(api);
this.skyColour = "FF0000";
this.waterColour = "FF0000";
this.waterFogColour = "FF0000";
this.fogColour = "FF0000";
this.grassColour = "FF0000";
this.foilageColour = "FF0000";
generateBiomes();
}
public void generateBiomes() {
/*ResourceKey<BiomeBase> key = ResourceKey.a(IRegistry.aO, new MinecraftKey(UUID.randomUUID().toString()));
BiomeBase biomeBase = new BiomeBaseWrapper_1_17R1()
.build(fogColour,
waterColour,
waterFogColour,
skyColour,
grassColour.equals("-1") ? null : grassColour,
foilageColour.equals("-1") ? null : foilageColour);
DedicatedServer ds = ((CraftServer) Bukkit.getServer()).getHandle().getServer();
IRegistryWritable<BiomeBase> rw = ds.getCustomRegistry().b(IRegistry.aO);
rw.a(key, biomeBase, Lifecycle.stable());
this.biomeId = ds.getCustomRegistry().d(IRegistry.aO).getId(biomeBase);
this.biomeBase = biomeBase;*/
}
@Override
public void effect(Player player) {
if (this.effect == null) this.effect = new ArrayList<>();
if (!effect.contains(player.getUniqueId())) {
effect.add(player.getUniqueId());
ProtocolManager manager = ProtocolLibrary.getProtocolManager();
for (Chunk chunk : getChunkAround(player.getLocation().getChunk(), Bukkit.getServer().getViewDistance())) {
final PacketContainer packetContainer = new PacketContainer(PacketType.Play.Server.MAP_CHUNK);
//try {
// manager.sendServerPacket(player, packetContainer);
//} catch (InvocationTargetException e) {
// e.printStackTrace();
//}
}
}
}
@Override
public void uneffect(Player player) {
if (this.effect == null) this.effect = new ArrayList<>();
if (effect.contains(player.getUniqueId())) {
effect.remove(player.getUniqueId());
for (Chunk chunk : getChunkAround(player.getLocation().getChunk(), Bukkit.getServer().getViewDistance())) {
//net.minecraft.world.level.chunk.Chunk c = ((CraftChunk)chunk).getHandle();
//((CraftPlayer) player).getHandle().b.sendPacket(new PacketPlayOutMapChunk(c));
}
}
}
public PacketContainer onSendChunk(PacketContainer packet, Player target) {
if (effect != null && effect.contains(target.getUniqueId())) {
int[] biomeIDs = packet.getIntegerArrays().read(0);
Arrays.fill(biomeIDs, biomeId);
packet.getIntegerArrays().write(0, biomeIDs);
}
return packet;
}
@Override
public String getName() {
return "Fog";
}
private Collection<Chunk> getChunkAround(Chunk origin, int radius) {
World world = origin.getWorld();
int length = (radius * 2) + 1;
Set<Chunk> chunks = new HashSet<>(length * length);
int cX = origin.getX();
int cZ = origin.getZ();
for (int x = -radius; x <= radius; x++) {
for (int z = -radius; z <= radius; z++) {
if (world.isChunkLoaded(cX + x, cZ + z)) chunks.add(world.getChunkAt(cX + x, cZ + z));
}
}
return chunks;
}
}

View File

@@ -0,0 +1,53 @@
package net.islandearth.rpgregions.effects.fog;
import net.minecraft.world.level.biome.BiomeBase;
import net.minecraft.world.level.biome.BiomeFog;
import net.minecraft.world.level.biome.BiomeSettingsGeneration;
import net.minecraft.world.level.biome.BiomeSettingsMobs;
public class BiomeBaseWrapper_1_19_R3 {
private String fogColor, waterColor, waterFogColor, skyColor;
private String grassColor, foliageColor;
public BiomeBase build(String fogColor, String waterColor, String waterFogColor, String skyColor) {
return build(fogColor,waterColor,waterFogColor,skyColor,null,null);
}
public BiomeBase build(String fogColor, String waterColor, String waterFogColor, String skyColor,String grassColor, String foliageColor) {
this.fogColor = fogColor;
this.waterColor = waterColor;
this.waterFogColor = waterFogColor;
this.skyColor = skyColor;
this.grassColor = grassColor;
this.foliageColor = foliageColor;
return build();
}
public BiomeBase build() {
BiomeFog.a biomeFogCodec = new BiomeFog.a()
.a(Integer.parseInt(fogColor, 16)) //fog color
.b(Integer.parseInt(waterColor, 16)) //water color
.c(Integer.parseInt(waterFogColor, 16)) //water fog color
.d(Integer.parseInt(skyColor, 16)); //skycolor
//.e() //foliage color (leaves, fines and more)
//.f() //grass blocks color
//.a(BiomeParticle)
//a(Music)
if (foliageColor != null)
biomeFogCodec.e(Integer.parseInt(foliageColor, 16));
if (grassColor != null)
biomeFogCodec.f(Integer.parseInt(grassColor, 16));
return new BiomeBase.a()
.a(BiomeBase.TemperatureModifier.a) //none
.a(BiomeSettingsGeneration.a) //none
.a(0F) //depth ocean or not // var3 ? -1.8F : -1.0F
.b(0F) //scale Lower values produce flatter terrain
.a(biomeFogCodec.a()) //biomefog
.a(BiomeSettingsMobs.b)
.a();
}
}

View File

@@ -0,0 +1,158 @@
package net.islandearth.rpgregions.effects.fog;
import com.mojang.serialization.Lifecycle;
import net.islandearth.rpgregions.api.IRPGRegionsAPI;
import net.islandearth.rpgregions.effects.RegionEffect;
import net.islandearth.rpgregions.gui.GuiEditable;
import net.minecraft.core.Holder;
import net.minecraft.core.IRegistryWritable;
import net.minecraft.core.RegistryMaterials;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.MinecraftKey;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.level.biome.BiomeBase;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.IChunkAccess;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.UUID;
public class FogEffect extends RegionEffect {
@GuiEditable("Sky Colour") private final String skyColour;
@GuiEditable("Water Colour") private final String waterColour;
@GuiEditable("Water Fog Colour") private final String waterFogColour;
@GuiEditable("Fog Colour") private final String fogColour;
@GuiEditable("Grass Colour") private final String grassColour;
@GuiEditable("Foilage Colour") private final String foilageColour;
private transient Holder<BiomeBase> biomeBase;
private transient List<UUID> affectedPlayers;
public Holder<BiomeBase> getBiomeBase() {
return biomeBase;
}
public FogEffect(IRPGRegionsAPI api) {
super(api);
this.skyColour = "FF0000";
this.waterColour = "FF0000";
this.waterFogColour = "FF0000";
this.fogColour = "FF0000";
this.grassColour = "FF0000";
this.foilageColour = "FF0000";
try {
generateBiomes();
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
public void generateBiomes() throws ReflectiveOperationException {
ResourceKey<BiomeBase> key = ResourceKey.a(Registries.an, new MinecraftKey(UUID.randomUUID().toString()));
BiomeBase biomeBase = new BiomeBaseWrapper_1_19_R3()
.build(fogColour,
waterColour,
waterFogColour,
skyColour,
grassColour.equals("-1") ? null : grassColour,
foilageColour.equals("-1") ? null : foilageColour);
//Inject into the biome registry
//al is BIOMES
//aW is registryAccess
//d is registryOrThrow
IRegistryWritable<BiomeBase> registrywritable = (IRegistryWritable<BiomeBase>) MinecraftServer.getServer().aX().d(Registries.an);
//Unfreeze Biome Registry
Field frozen = RegistryMaterials.class.getDeclaredField("l");
frozen.setAccessible(true);
frozen.set(registrywritable, false);
//Inject unregisteredIntrusiveHolders with a new map to allow intrusive holders
//m is unregisteredIntrusiveHolders
Field unregisteredIntrusiveHolders = RegistryMaterials.class.getDeclaredField("m");
unregisteredIntrusiveHolders.setAccessible(true);
unregisteredIntrusiveHolders.set(registrywritable, new IdentityHashMap<>());
//biome is the BiomeBase that you're registering
//f is createIntrusiveHolder
registrywritable.f(biomeBase);
//a is RegistryMaterials.register
this.biomeBase = registrywritable.a(key, biomeBase, Lifecycle.stable());
//Make unregisteredIntrusiveHolders null again to remove potential for undefined behaviour
unregisteredIntrusiveHolders.set(registrywritable, null);
//Refreeze biome registry
frozen.set(registrywritable, true);
}
@Override
public void effect(Player player) {
if (this.affectedPlayers == null) this.affectedPlayers = new ArrayList<>();
if (!affectedPlayers.contains(player.getUniqueId())) {
affectedPlayers.add(player.getUniqueId());
WorldServer level = ((CraftWorld) player.getWorld()).getHandle();
(level.k()).a.a(getChunkAround(player.getLocation().getChunk(), Bukkit.getViewDistance()));
}
}
@Override
public void uneffect(Player player) {
if (this.affectedPlayers == null) this.affectedPlayers = new ArrayList<>();
if (affectedPlayers.contains(player.getUniqueId())) {
// System.out.println("unaffect the player");
affectedPlayers.remove(player.getUniqueId());
WorldServer level = ((CraftWorld) player.getWorld()).getHandle();
(level.k()).a.a(getChunkAround(player.getLocation().getChunk(), Bukkit.getViewDistance()));
}
}
public List<UUID> getAffectedPlayers() {
return affectedPlayers;
}
@Override
public String getName() {
return "Fog";
}
private List<IChunkAccess> getChunkAround(Chunk origin, int radius) {
World world = origin.getWorld();
int length = (radius * 2) + 1;
List<IChunkAccess> chunks = new ArrayList<>(length * length);
int cX = origin.getX();
int cZ = origin.getZ();
WorldServer level = ((CraftWorld) world).getHandle();
for (int x = -radius; x <= radius; x++) {
for (int z = -radius; z <= radius; z++) {
IChunkAccess access = level.a(cX + x, cZ + z, ChunkStatus.o, false);
if (access == null) {
continue;
}
chunks.add(access);
}
}
return chunks;
}
}

View File

@@ -8,30 +8,106 @@ import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import net.islandearth.rpgregions.RPGRegions;
import net.islandearth.rpgregions.effects.FogEffect;
import net.islandearth.rpgregions.effects.RegionEffect;
import net.islandearth.rpgregions.effects.fog.FogEffect;
import net.islandearth.rpgregions.managers.RPGRegionsManagers;
import net.islandearth.rpgregions.managers.data.region.ConfiguredRegion;
import net.minecraft.core.Holder;
import net.minecraft.core.IRegistryWritable;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.protocol.game.ClientboundChunksBiomesPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.level.ChunkCoordIntPair;
import net.minecraft.world.level.biome.BiomeBase;
import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.chunk.Chunk;
import net.minecraft.world.level.chunk.ChunkSection;
import net.minecraft.world.level.chunk.DataPaletteBlock;
import net.minecraft.world.level.material.FluidType;
import net.minecraft.world.ticks.LevelChunkTicks;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class ProtocolCreator {
public ProtocolCreator(final RPGRegions plugin, final RPGRegionsManagers managers) {
ProtocolManager manager = ProtocolLibrary.getProtocolManager();
manager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.MAP_CHUNK) {
// manager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.MAP_CHUNK) {
// @Override
// public void onPacketSending(PacketEvent event) {
// Player player = event.getPlayer();
// PacketContainer packet = event.getPacket();
// for (ConfiguredRegion region : managers.getRegionsCache().getConfiguredRegions().values()) {
// if (region.getEffects() == null) continue;
// for (RegionEffect effect : region.getEffects()) {
// if (effect instanceof FogEffect fogEffect) {
// event.setPacket(fogEffect.onSendChunk(packet, player));
// }
// }
// }
// }
// });
manager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.CHUNKS_BIOMES) {
@Override
public void onPacketSending(PacketEvent event) {
Player player = event.getPlayer();
PacketContainer packet = event.getPacket();
WorldServer level = ((CraftWorld) player.getWorld()).getHandle();
for (ConfiguredRegion region : managers.getRegionsCache().getConfiguredRegions().values()) {
if (region.getEffects() == null) continue;
for (RegionEffect effect : region.getEffects()) {
if (effect instanceof FogEffect fogEffect) {
event.setPacket(fogEffect.onSendChunk(packet, player));
if (!(effect instanceof FogEffect fogEffect)) continue;
if (!fogEffect.getAffectedPlayers().contains(player.getUniqueId())) continue;
final ClientboundChunksBiomesPacket handle = (ClientboundChunksBiomesPacket) packet.getHandle();
List<ClientboundChunksBiomesPacket.a> chunks = new ArrayList<>();
for (ClientboundChunksBiomesPacket.a a : handle.a()) {
final ChunkCoordIntPair coordIntPair = a.b();
final Chunk loadedChunk = level.getChunkIfLoaded(coordIntPair.e, coordIntPair.f);
chunks.add(new ClientboundChunksBiomesPacket.a(remapChunk(loadedChunk, fogEffect.getBiomeBase())));
}
event.setPacket(new PacketContainer(PacketType.Play.Server.CHUNKS_BIOMES, new ClientboundChunksBiomesPacket(chunks)));
return;
}
}
}
});
}
// https://github.com/aecsocket/alexandria/blob/91389b5fca49bac870289152c17b758a06ac7e24/paper/src/main/java/com/github/aecsocket/minecommons/paper/biome/BiomeInjector.java
private Chunk remapChunk(Chunk chunk, Holder<BiomeBase> newBiome) {
WorldServer level = chunk.q;
ChunkCoordIntPair pos = chunk.f();
ChunkSection[] origSections = chunk.d();
ChunkSection[] sections = new ChunkSection[origSections.length];
IRegistryWritable<BiomeBase> nmsBiomes = (IRegistryWritable<BiomeBase>) MinecraftServer.getServer().aX().d(Registries.an);
for (int i = 0; i < origSections.length; i++) {
var origSection = origSections[i];
DataPaletteBlock<Holder<BiomeBase>> biomes = new DataPaletteBlock<>(nmsBiomes.t(), nmsBiomes.f(Biomes.a), DataPaletteBlock.d.e);
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 4; y++) {
for (int z = 0; z < 4; z++) {
biomes.c(x, y, z, newBiome);
}
}
}
sections[i] = new ChunkSection(origSection.g() >> 4,
origSection.i(),
biomes);
}
return new Chunk(level, pos,
chunk.r(), (LevelChunkTicks<Block>) chunk.o(), (LevelChunkTicks<FluidType>) chunk.p(),
chunk.u(), sections,
null, chunk.t());
}
}

View File

@@ -5,7 +5,7 @@ import net.islandearth.rpgregions.api.integrations.IntegrationManager;
import net.islandearth.rpgregions.api.integrations.IntegrationType;
import net.islandearth.rpgregions.api.integrations.hooks.PlaceholderRegionHook;
import net.islandearth.rpgregions.command.IconCommand;
import net.islandearth.rpgregions.effects.FogEffect;
import net.islandearth.rpgregions.effects.fog.FogEffect;
import net.islandearth.rpgregions.effects.PotionRegionEffect;
import net.islandearth.rpgregions.effects.RegionEffect;
import net.islandearth.rpgregions.effects.RegionEffectRegistry;
@@ -178,9 +178,13 @@ public class RPGRegionsManagers implements IRPGRegionsManagers {
guiFieldElementRegistry.register(new CompareTypeGuiFieldElement());
guiFieldElementRegistry.register(new ListGuiFieldElement());
if (Bukkit.getPluginManager().getPlugin("ProtocolLib") != null && Bukkit.getBukkitVersion().contains("1.17")) {
plugin.getLogger().info("Detected ProtcolLib, enabling fog support!");
new ProtocolCreator(plugin, this);
if (Bukkit.getPluginManager().getPlugin("ProtocolLib") != null) {
if (Bukkit.getBukkitVersion().contains("1.19")) {
plugin.getLogger().info("Detected ProtcolLib, enabling fog support!");
new ProtocolCreator(plugin, this);
} else {
plugin.getLogger().info("ProtocolLib was detected, but your server version does not support fog effects at this time.");
}
}
}