Release ViaPotions-OG
This commit is contained in:
1 parent
b9a976d3d3
commit
e473f50b79
11 files changed
+303
-109
No files matched your search
@@ -1,8 +1,20 @@
|
||||
# ViaPotions
|
||||
Translates thrown potions for ViaRewind
|
||||
# ViaPotions-OG
|
||||
|
||||
## To Build:
|
||||
Translates thrown and lingering potion visuals for legacy ViaVersion stacks on Purpur 1.19.4.
|
||||
|
||||
```./mvnw clean package```
|
||||
## Compatibility
|
||||
|
||||
*The jar file will be in target/*
|
||||
- Server: Purpur 1.19.4
|
||||
- Clients: 1.8 through 1.21.11, where the connected ViaVersion stack exposes those protocol translations
|
||||
- Required: ProtocolLib, ViaVersion
|
||||
- Optional: ViaRewind for 1.8 support
|
||||
- Optional: ViaBackwards for 1.9-1.10 support
|
||||
- Optional: ViaRewind-Legacy-Support if you already provide its area effect cloud particle fallback
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
./gradlew build
|
||||
```
|
||||
|
||||
The shaded jar is written to `build/libs/`.
|
||||
+2
-2
@@ -7,7 +7,7 @@ plugins {
|
||||
id("java") // Import Java plugin.
|
||||
id("java-library") // Import Java Library plugin.
|
||||
id("com.diffplug.spotless") version "7.0.4" // Import Spotless plugin.
|
||||
id("com.gradleup.shadow") version "8.3.8" // Import Shadow plugin.
|
||||
id("com.gradleup.shadow") version "8.3.9" // Import Shadow plugin.
|
||||
id("checkstyle") // Import Checkstyle plugin.
|
||||
eclipse // Import Eclipse plugin.
|
||||
kotlin("jvm") version "2.1.21" // Import Kotlin JVM plugin.
|
||||
@@ -31,7 +31,7 @@ kotlin { jvmToolchain(17) }
|
||||
/* ----------------------------- Metadata ------------------------------ */
|
||||
group = "dev._2lstudios" // Declare bundle identifier.
|
||||
|
||||
version = "0.0.4" // Declare plugin version (will be in .jar).
|
||||
version = "0.0.5" // Declare plugin version (will be in .jar).
|
||||
|
||||
val apiVersion = "1.19" // Declare minecraft server target version.
|
||||
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
rootProject.name = "ViaPotions"
|
||||
rootProject.name = "ViaPotions-OG"
|
||||
@@ -14,40 +14,58 @@ import dev._2lstudios.viapotions.utils.VersionUtil;
|
||||
|
||||
public class ViaPotions extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
||||
final ConfigurationUtil configurationUtil = new ConfigurationUtil(this);
|
||||
final VersionUtil versionUtil = new VersionUtil(this);
|
||||
final PluginManager pluginManager = getServer().getPluginManager();
|
||||
final ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
|
||||
final boolean hasViaVersion = versionUtil.isViaVersionAvailable();
|
||||
final boolean hasViaBackwards = pluginManager.isPluginEnabled("ViaBackwards");
|
||||
final boolean hasViaRewind = pluginManager.isPluginEnabled("ViaRewind");
|
||||
|
||||
if (pluginManager.isPluginEnabled("ViaRewind")) {
|
||||
if (!hasViaVersion) {
|
||||
|
||||
getLogger().info("ViaRewind detected, enabling integration.");
|
||||
|
||||
} else if (pluginManager.isPluginEnabled("ViaBackwards")) {
|
||||
|
||||
getLogger().warning(
|
||||
"ViaBackwards detected. In order to make ViaPotions work correctly, it is required that you have ViaRewind installed.");
|
||||
|
||||
} else {
|
||||
|
||||
getLogger().severe("No compatible plugins have been detected, disabling the plugin.");
|
||||
getLogger().severe("In order to make ViaPotions functional, ViaRewind must be installed.");
|
||||
getLogger().severe("ViaVersion was not found, disabling the plugin.");
|
||||
pluginManager.disablePlugin(this);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (pluginManager.getPlugin("ViaRewind-Legacy-Support") == null
|
||||
if (!hasViaBackwards && !hasViaRewind) {
|
||||
|
||||
getLogger().warning("Neither ViaBackwards nor ViaRewind was found, disabling the plugin.");
|
||||
pluginManager.disablePlugin(this);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (hasViaRewind) {
|
||||
|
||||
getLogger().info("ViaRewind detected, enabling legacy 1.8 potion support.");
|
||||
|
||||
} else {
|
||||
|
||||
getLogger().info("ViaBackwards detected, enabling 1.9-1.10 splash event translation.");
|
||||
|
||||
}
|
||||
|
||||
if (hasViaRewind && (pluginManager.getPlugin("ViaRewind-Legacy-Support") == null
|
||||
|| !configurationUtil.getConfiguration("%datafolder%/ViaRewind-Legacy-Support/config.yml")
|
||||
.getBoolean("area-effect-cloud-particles"))
|
||||
.getBoolean("area-effect-cloud-particles")))
|
||||
{
|
||||
|
||||
pluginManager.registerEvents(new AreaEffectCloudListener(this, versionUtil), this);
|
||||
|
||||
}
|
||||
|
||||
protocolManager.addPacketListener(new SpawnEntityListener(this, versionUtil));
|
||||
if (hasViaRewind) {
|
||||
|
||||
protocolManager.addPacketListener(new SpawnEntityListener(this, versionUtil));
|
||||
|
||||
}
|
||||
|
||||
protocolManager.addPacketListener(new WorldEventAdapter(this, versionUtil));
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import dev._2lstudios.viapotions.utils.SplashTranslator;
|
||||
import dev._2lstudios.viapotions.utils.TranslationData;
|
||||
import dev._2lstudios.viapotions.utils.VersionUtil;
|
||||
|
||||
public class WorldEventAdapter extends PacketAdapter {
|
||||
@@ -27,7 +26,7 @@ public class WorldEventAdapter extends PacketAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
public void onPacketSending(final PacketEvent event) {
|
||||
|
||||
if (event.isPlayerTemporary()) {
|
||||
|
||||
@@ -35,54 +34,69 @@ public class WorldEventAdapter extends PacketAdapter {
|
||||
|
||||
}
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
final int version = versionUtil.getVersion(player);
|
||||
|
||||
if (!versionUtil.needsSplashPotionTranslation(version)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final PacketContainer packet = event.getPacket();
|
||||
final int effectId = packet.getIntegers().read(0);
|
||||
final StructureModifier<Integer> integers = packet.getIntegers();
|
||||
|
||||
if (effectId == 2002 || effectId == 2007) {
|
||||
if (integers.size() < 2) {
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
final int version = versionUtil.getVersion(player);
|
||||
final PacketContainer edited = packet.deepClone();
|
||||
final StructureModifier<Integer> editedIntegers = edited.getIntegers();
|
||||
return;
|
||||
|
||||
if (version <= 210) {
|
||||
}
|
||||
|
||||
editedIntegers.write(0, 2002);
|
||||
final int effectId = integers.read(0);
|
||||
|
||||
}
|
||||
if (effectId != 2002 && effectId != 2007) {
|
||||
|
||||
for (final SplashTranslator translator : SplashTranslator.values()) {
|
||||
return;
|
||||
|
||||
if (editedIntegers.read(1) == translator.getRGB()) {
|
||||
}
|
||||
|
||||
for (final TranslationData data : translator.getDatas()) {
|
||||
final PacketContainer edited = packet.deepClone();
|
||||
final StructureModifier<Integer> editedIntegers = edited.getIntegers();
|
||||
boolean changed = false;
|
||||
|
||||
if (data.getLowestVersion() <= version && data.getHighestVersion() >= version) {
|
||||
if (effectId == 2007) {
|
||||
|
||||
editedIntegers.write(1, data.getRemap());
|
||||
editedIntegers.write(0, 2002);
|
||||
changed = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
final Integer remap = SplashTranslator.findRemap(editedIntegers.read(1), version);
|
||||
|
||||
}
|
||||
if (remap != null && editedIntegers.read(1) != remap.intValue()) {
|
||||
|
||||
}
|
||||
editedIntegers.write(1, remap);
|
||||
changed = true;
|
||||
|
||||
try {
|
||||
}
|
||||
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, edited, false);
|
||||
if (!changed) {
|
||||
|
||||
} catch (Exception e) {
|
||||
return;
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
try {
|
||||
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, edited, false);
|
||||
event.setCancelled(true);
|
||||
|
||||
} catch (final Exception exception) {
|
||||
|
||||
exception.printStackTrace();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,13 @@
|
||||
package dev._2lstudios.viapotions.listeners;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.entity.AreaEffectCloud;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -10,16 +17,15 @@ import org.bukkit.plugin.Plugin;
|
||||
|
||||
import dev._2lstudios.viapotions.utils.VersionUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
public class AreaEffectCloudListener implements Listener {
|
||||
|
||||
final private List<AreaEffectCloud> effectClouds;
|
||||
private static final Particle LEGACY_PARTICLE = Particle.SPELL_MOB;
|
||||
|
||||
private final Set<AreaEffectCloud> effectClouds;
|
||||
|
||||
public AreaEffectCloudListener(final Plugin plugin, final VersionUtil versionUtil) {
|
||||
|
||||
effectClouds = new CopyOnWriteArrayList<>();
|
||||
effectClouds = ConcurrentHashMap.newKeySet();
|
||||
|
||||
plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, () -> {
|
||||
|
||||
@@ -28,35 +34,45 @@ public class AreaEffectCloudListener implements Listener {
|
||||
if (cloud == null || cloud.isDead() || !cloud.isValid()) {
|
||||
|
||||
effectClouds.remove(cloud);
|
||||
continue;
|
||||
|
||||
} else {
|
||||
}
|
||||
|
||||
final Location location = cloud.getLocation();
|
||||
final float radius = cloud.getRadius();
|
||||
final float area = (float) Math.PI * radius * radius;
|
||||
final List<Player> legacyPlayers = getLegacyPlayers(cloud, versionUtil);
|
||||
|
||||
final int color = cloud.getColor().asRGB();
|
||||
final int red = color >> 16 & 255;
|
||||
final int green = color >> 8 & 255;
|
||||
final int blue = color & 255;
|
||||
if (legacyPlayers.isEmpty()) {
|
||||
|
||||
for (int i = 0; i < area; i++) {
|
||||
continue;
|
||||
|
||||
float f1 = (float) Math.random() * 6.2831855F;
|
||||
float f2 = (float) Math.sqrt(Math.random()) * radius;
|
||||
float f3 = (float) Math.cos(f1) * f2;
|
||||
float f4 = (float) Math.sin(f1) * f2;
|
||||
}
|
||||
|
||||
for (final Player player : cloud.getWorld().getPlayers()) {
|
||||
final Color color = cloud.getColor();
|
||||
|
||||
if (versionUtil.getVersion(player) <= 106) {
|
||||
if (color == null) {
|
||||
|
||||
player.spawnParticle(cloud.getParticle(), location.getX() + f3, location.getY(),
|
||||
location.getZ() + f4, 0, red / 255f, green / 255f, blue / 255f);
|
||||
continue;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
final Location location = cloud.getLocation();
|
||||
final float radius = cloud.getRadius();
|
||||
final int samples = Math.max(1, Math.round(radius * radius * 2.0F));
|
||||
final int rgb = color.asRGB();
|
||||
final float red = (rgb >> 16 & 255) / 255f;
|
||||
final float green = (rgb >> 8 & 255) / 255f;
|
||||
final float blue = (rgb & 255) / 255f;
|
||||
|
||||
for (int i = 0; i < samples; i++) {
|
||||
|
||||
final float angle = (float) (Math.random() * Math.PI * 2.0D);
|
||||
final float distance = (float) Math.sqrt(Math.random()) * radius;
|
||||
final double offsetX = Math.cos(angle) * distance;
|
||||
final double offsetZ = Math.sin(angle) * distance;
|
||||
|
||||
for (final Player player : legacyPlayers) {
|
||||
|
||||
player.spawnParticle(LEGACY_PARTICLE, location.getX() + offsetX, location.getY(),
|
||||
location.getZ() + offsetZ, 0, red, green, blue);
|
||||
|
||||
}
|
||||
|
||||
@@ -75,4 +91,22 @@ public class AreaEffectCloudListener implements Listener {
|
||||
|
||||
}
|
||||
|
||||
private List<Player> getLegacyPlayers(final AreaEffectCloud cloud, final VersionUtil versionUtil) {
|
||||
|
||||
final List<Player> legacyPlayers = new ArrayList<>();
|
||||
|
||||
for (final Player player : cloud.getWorld().getPlayers()) {
|
||||
|
||||
if (versionUtil.needsAreaEffectCloudFallback(versionUtil.getVersion(player))) {
|
||||
|
||||
legacyPlayers.add(player);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return legacyPlayers;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -13,7 +14,6 @@ import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import dev._2lstudios.viapotions.utils.PotionTranslator;
|
||||
import dev._2lstudios.viapotions.utils.TranslationData;
|
||||
import dev._2lstudios.viapotions.utils.VersionUtil;
|
||||
|
||||
public class SpawnEntityListener extends PacketAdapter {
|
||||
@@ -31,52 +31,93 @@ public class SpawnEntityListener extends PacketAdapter {
|
||||
@Override
|
||||
public void onPacketSending(final PacketEvent event) {
|
||||
|
||||
if (event.isPlayerTemporary()) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
final int version = versionUtil.getVersion(player);
|
||||
|
||||
if (!versionUtil.needsPotionDataTranslation(version)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final PacketContainer packet = event.getPacket();
|
||||
final Entity entity = packet.getEntityModifier(event).read(0);
|
||||
final Entity entity = packet.getEntityModifier(event).readSafely(0);
|
||||
|
||||
if (packet.getIntegers().read(6) == 73 && entity instanceof ThrownPotion) {
|
||||
if (!(entity instanceof ThrownPotion)) {
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
final int version = versionUtil.getVersion(player);
|
||||
final PacketContainer edited = packet.deepClone();
|
||||
final ThrownPotion potion = (ThrownPotion) entity;
|
||||
return;
|
||||
|
||||
for (final PotionEffect effect : potion.getEffects()) {
|
||||
}
|
||||
|
||||
for (final PotionTranslator translator : PotionTranslator.values()) {
|
||||
final Integer dataIndex = getPotionDataIndex(packet);
|
||||
|
||||
if (effect.getType().equals(translator.getPotionEffectType())) {
|
||||
if (dataIndex == null) {
|
||||
|
||||
for (TranslationData data : translator.getDatas()) {
|
||||
return;
|
||||
|
||||
if (data.getLowestVersion() <= version && data.getHighestVersion() >= version) {
|
||||
}
|
||||
|
||||
edited.getIntegers().write(7, data.getRemap());
|
||||
final Integer remap = getPotionRemap((ThrownPotion) entity, version);
|
||||
|
||||
}
|
||||
if (remap == null) {
|
||||
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
final PacketContainer edited = packet.deepClone();
|
||||
edited.getIntegers().write(dataIndex.intValue(), remap);
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, edited, false);
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
try {
|
||||
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, edited, false);
|
||||
event.setCancelled(true);
|
||||
|
||||
} catch (final Exception exception) {
|
||||
|
||||
exception.printStackTrace();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Integer getPotionDataIndex(final PacketContainer packet) {
|
||||
|
||||
final StructureModifier<Integer> integers = packet.getIntegers();
|
||||
final int size = integers.size();
|
||||
|
||||
if (size < 2) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
return Integer.valueOf(size - 1);
|
||||
|
||||
}
|
||||
|
||||
private Integer getPotionRemap(final ThrownPotion potion, final int version) {
|
||||
|
||||
for (final PotionEffect effect : potion.getEffects()) {
|
||||
|
||||
final Integer remap = PotionTranslator.findRemap(effect.getType(), version);
|
||||
|
||||
if (remap != null) {
|
||||
|
||||
return remap;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -44,4 +44,30 @@ public enum PotionTranslator {
|
||||
|
||||
}
|
||||
|
||||
public static Integer findRemap(final PotionEffectType effectType, final int version) {
|
||||
|
||||
for (final PotionTranslator translator : values()) {
|
||||
|
||||
if (translator.getPotionEffectType().equals(effectType)) {
|
||||
|
||||
for (final TranslationData data : translator.getDatas()) {
|
||||
|
||||
if (data.getLowestVersion() <= version && data.getHighestVersion() >= version) {
|
||||
|
||||
return data.getRemap();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,4 +42,30 @@ public enum SplashTranslator {
|
||||
|
||||
}
|
||||
|
||||
public static Integer findRemap(final int rgb, final int version) {
|
||||
|
||||
for (final SplashTranslator translator : values()) {
|
||||
|
||||
if (translator.getRGB() == rgb) {
|
||||
|
||||
for (final TranslationData data : translator.getDatas()) {
|
||||
|
||||
if (data.getLowestVersion() <= version && data.getHighestVersion() >= version) {
|
||||
|
||||
return data.getRemap();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,6 +7,9 @@ import com.viaversion.viaversion.api.Via;
|
||||
|
||||
public class VersionUtil {
|
||||
|
||||
public static final int LEGACY_POTION_DATA_MAX_PROTOCOL = 106;
|
||||
public static final int LEGACY_SPLASH_EVENT_MAX_PROTOCOL = 210;
|
||||
|
||||
private final Plugin viaVersion;
|
||||
|
||||
public VersionUtil(final Plugin plugin) {
|
||||
@@ -17,11 +20,11 @@ public class VersionUtil {
|
||||
|
||||
}
|
||||
|
||||
public int getVersion(Player player) {
|
||||
public int getVersion(final Player player) {
|
||||
|
||||
if (viaVersion != null) {
|
||||
|
||||
return getViaVersionVersion(player);
|
||||
return Via.getAPI().getPlayerVersion(player.getUniqueId());
|
||||
|
||||
}
|
||||
|
||||
@@ -29,9 +32,27 @@ public class VersionUtil {
|
||||
|
||||
}
|
||||
|
||||
private int getViaVersionVersion(Player player) {
|
||||
public boolean isViaVersionAvailable() {
|
||||
|
||||
return Via.getAPI().getPlayerVersion(player.getUniqueId());
|
||||
return viaVersion != null;
|
||||
|
||||
}
|
||||
|
||||
public boolean needsPotionDataTranslation(final int version) {
|
||||
|
||||
return version >= 0 && version <= LEGACY_POTION_DATA_MAX_PROTOCOL;
|
||||
|
||||
}
|
||||
|
||||
public boolean needsSplashPotionTranslation(final int version) {
|
||||
|
||||
return version >= 0 && version <= LEGACY_SPLASH_EVENT_MAX_PROTOCOL;
|
||||
|
||||
}
|
||||
|
||||
public boolean needsAreaEffectCloudFallback(final int version) {
|
||||
|
||||
return needsPotionDataTranslation(version);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
name: ViaPotions
|
||||
version: 0.0.5
|
||||
description: Translates thrown potions for ViaRewind
|
||||
name: ViaPotions-OG
|
||||
version: ${version}
|
||||
description: Translates potion visuals for legacy ViaVersion clients
|
||||
depend: [ProtocolLib]
|
||||
api-version: 1.13
|
||||
api-version: ${apiVersion}
|
||||
softdepend:
|
||||
- "ViaVersion"
|
||||
- "ViaBackwards"
|
||||
- "ViaRewind"
|
||||
- "ViaRewind-Legacy-Support"
|
||||
main: dev._2lstudios.viapotions.ViaPotions
|
||||
Reference in new issue
Block a user