Skip to content

Commit

Permalink
1.17.1 support
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMolkaPL authored Aug 30, 2021
1 parent 92573c6 commit b87bed5
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 12 deletions.
16 changes: 12 additions & 4 deletions src/main/java/pl/craftserve/radiation/Radiation.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.sk89q.worldguard.protection.regions.RegionContainer;
import org.bukkit.ChatColor;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.boss.BossBar;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
Expand All @@ -42,6 +43,7 @@
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
import pl.craftserve.radiation.nms.RadiationNmsBridge;

import java.text.MessageFormat;
import java.util.ArrayList;
Expand All @@ -54,7 +56,6 @@
import java.util.Set;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Radiation implements Listener {
Expand Down Expand Up @@ -228,20 +229,27 @@ default RegionContainer getRegionContainer() {
* Tests if the given flags matches the radiation IDs.
*/
public static class FlagMatcher implements WorldGuardMatcher {
private final RadiationNmsBridge nmsBridge;
private final Flag<Boolean> isRadioactiveFlag;
private final Flag<String> radiationTypeFlag;
private final Set<String> acceptedRadiationTypes;

public FlagMatcher(Flag<Boolean> isRadioactiveFlag, Flag<String> radiationTypeFlag, Set<String> acceptedRadiationTypes) {
public FlagMatcher(RadiationNmsBridge nmsBridge, Flag<Boolean> isRadioactiveFlag, Flag<String> radiationTypeFlag, Set<String> acceptedRadiationTypes) {
this.nmsBridge = Objects.requireNonNull(nmsBridge, "nmsBridge");
this.isRadioactiveFlag = Objects.requireNonNull(isRadioactiveFlag, "isRadioactiveFlag");
this.radiationTypeFlag = Objects.requireNonNull(radiationTypeFlag, "radiationTypeFlag");
this.acceptedRadiationTypes = Objects.requireNonNull(acceptedRadiationTypes, "acceptedRadiationTypes");
}

@Override
public boolean test(Player player, RegionContainer regionContainer) {
Location location = BukkitAdapter.adapt(player.getLocation());
location = location.setY(Math.max(0, Math.min(255, location.getY())));
org.bukkit.Location bukkitLocation = player.getLocation();
World world = player.getWorld();
int minY = this.nmsBridge.getMinWorldHeight(world);
int maxY = world.getMaxHeight();

Location location = BukkitAdapter.adapt(bukkitLocation);
location = location.setY(Math.max(minY, Math.min(maxY, location.getY())));
ApplicableRegionSet regions = regionContainer.createQuery().getApplicableRegions(location);
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);

Expand Down
20 changes: 14 additions & 6 deletions src/main/java/pl/craftserve/radiation/RadiationCommandHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import pl.craftserve.radiation.nms.RadiationNmsBridge;

import java.util.Collections;
import java.util.List;
Expand All @@ -49,13 +50,15 @@ public class RadiationCommandHandler implements CommandExecutor, TabCompleter {
private static final String REGION_ID = "safe_from_radiation";
private static final String GLOBAL_REGION_ID = "__global__";

private RadiationNmsBridge nmsBridge;
private final Flag<Boolean> flag;
private final Radiation.WorldGuardMatcher worldGuardMatcher = (player, regionContainer) -> {
throw new UnsupportedOperationException();
};
private final LugolsIodinePotion potion;

public RadiationCommandHandler(Flag<Boolean> flag, LugolsIodinePotion potion) {
public RadiationCommandHandler(RadiationNmsBridge nmsBridge, Flag<Boolean> flag, LugolsIodinePotion potion) {
this.nmsBridge = Objects.requireNonNull(nmsBridge, "nmsBridge");
this.flag = Objects.requireNonNull(flag, "flag");
this.potion = potion;
}
Expand Down Expand Up @@ -135,25 +138,30 @@ private boolean define(Player player, RegionContainer container, String regionId
Objects.requireNonNull(container, "container");
Objects.requireNonNull(regionId, "regionId");

World world = BukkitAdapter.adapt(player.getWorld());
org.bukkit.World bukkitWorld = player.getWorld();
World world = BukkitAdapter.adapt(bukkitWorld);
RegionManager regionManager = container.get(world);
if (regionManager == null) {
player.sendMessage(ChatColor.RED + "Sorry, region manager for world " + world.getName() + " is not currently accessible.");
return false;
}

BlockVector3 origin = BukkitAdapter.asBlockVector(player.getLocation());
this.define(regionManager, this.createCuboid(regionId, origin, radius));
this.define(regionManager, this.createCuboid(bukkitWorld, regionId, origin, radius));
this.flagGlobal(regionManager, true);
return true;
}

private ProtectedCuboidRegion createCuboid(String regionId, BlockVector3 origin, int radius) {
private ProtectedCuboidRegion createCuboid(org.bukkit.World bukkitWorld, String regionId, BlockVector3 origin, int radius) {
Objects.requireNonNull(bukkitWorld, "bukkitWorld");
Objects.requireNonNull(regionId, "regionId");
Objects.requireNonNull(origin, "origin");

BlockVector3 min = origin.subtract(radius, 0, radius).withY(0);
BlockVector3 max = origin.add(radius, 0, radius).withY(255);
int minY = this.nmsBridge.getMinWorldHeight(bukkitWorld);
int maxY = bukkitWorld.getMaxHeight();

BlockVector3 min = origin.subtract(radius, 0, radius).withY(minY);
BlockVector3 max = origin.add(radius, 0, radius).withY(maxY);
return new ProtectedCuboidRegion(regionId, min, max);
}

Expand Down
7 changes: 5 additions & 2 deletions src/main/java/pl/craftserve/radiation/RadiationPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.bukkit.plugin.java.JavaPlugin;
import pl.craftserve.radiation.nms.RadiationNmsBridge;
import pl.craftserve.radiation.nms.V1_14ToV1_15NmsBridge;
import pl.craftserve.radiation.nms.V1_17_R1NmsBridge;

import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -92,6 +93,8 @@ private RadiationNmsBridge initializeNmsBridge() {
case "v1_16_R2":
case "v1_16_R3":
return new V1_14ToV1_15NmsBridge(serverVersion);
case "v1_17_R1":
return new V1_17_R1NmsBridge(serverVersion);
default:
throw new RuntimeException("Unsupported server version: " + serverVersion);
}
Expand Down Expand Up @@ -149,12 +152,12 @@ public void onEnable() {

for (Radiation.Config radiationConfig : this.config.radiations()) {
String id = radiationConfig.id();
Radiation.Matcher matcher = new Radiation.FlagMatcher(this.radiationFlag, this.radiationTypeFlag, Collections.singleton(id));
Radiation.Matcher matcher = new Radiation.FlagMatcher(this.radiationNmsBridge, this.radiationFlag, this.radiationTypeFlag, Collections.singleton(id));

this.activeRadiations.put(id, new Radiation(this, matcher, radiationConfig));
}

RadiationCommandHandler radiationCommandHandler = new RadiationCommandHandler(this.radiationFlag, this.potion);
RadiationCommandHandler radiationCommandHandler = new RadiationCommandHandler(this.radiationNmsBridge, this.radiationFlag, this.potion);
radiationCommandHandler.register(this.getCommand("radiation"));

this.craftserveListener = new CraftserveListener(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.bukkit.NamespacedKey;
import org.bukkit.Server;
import org.apache.commons.lang.StringUtils;
import org.bukkit.World;
import pl.craftserve.radiation.LugolsIodinePotion;

import java.util.Objects;
Expand All @@ -28,6 +29,8 @@ public interface RadiationNmsBridge {

void unregisterLugolsIodinePotion(NamespacedKey potionKey);

int getMinWorldHeight(World bukkitWorld);

static String getServerVersion(Server server) {
Objects.requireNonNull(server, "server");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import pl.craftserve.radiation.LugolsIodinePotion;

import java.lang.reflect.Array;
Expand Down Expand Up @@ -107,4 +108,9 @@ public void registerLugolsIodinePotion(NamespacedKey potionKey, LugolsIodinePoti
public void unregisterLugolsIodinePotion(NamespacedKey potionKey) {
// todo unregister potion and brewing recipe
}

@Override
public int getMinWorldHeight(World bukkitWorld) {
return 0;
}
}
102 changes: 102 additions & 0 deletions src/main/java/pl/craftserve/radiation/nms/V1_17_R1NmsBridge.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package pl.craftserve.radiation.nms;

import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import pl.craftserve.radiation.LugolsIodinePotion;

import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;

public class V1_17_R1NmsBridge implements RadiationNmsBridge {
static final Logger logger = Logger.getLogger(V1_17_R1NmsBridge.class.getName());

private final Class<?> itemClass;
private final Class<?> iRegistryClass;
private final Class<?> mobEffectClass;
private final Class<?> potionRegistryClass;
private final Class<?> potionBrewerClass;

private final Method getItem;
private final Method newMinecraftKey;
private final Method getPotion;
private final Method minHeightMethod;

private final Object potionRegistry;

private final Map<UUID, Integer> minWorldHeightMap = new HashMap<>();

public V1_17_R1NmsBridge(String version) {
Objects.requireNonNull(version, "version");

try {
this.itemClass = Class.forName("net.minecraft.world.item.Item");
this.iRegistryClass = Class.forName("net.minecraft.core.IRegistry");
this.mobEffectClass = Class.forName("net.minecraft.world.effect.MobEffect");
this.potionRegistryClass = Class.forName("net.minecraft.world.item.alchemy.PotionRegistry");
this.potionBrewerClass = Class.forName("net.minecraft.world.item.alchemy.PotionBrewer");

Class<?> craftMagicNumbers = Class.forName("org.bukkit.craftbukkit." + version + ".util.CraftMagicNumbers");
this.getItem = craftMagicNumbers.getMethod("getItem", Material.class);
this.minHeightMethod = World.class.getMethod("getMinHeight");

Class<?> minecraftKey = Class.forName("net.minecraft.resources.MinecraftKey");
this.newMinecraftKey = minecraftKey.getMethod("a", String.class);
this.potionRegistry = this.iRegistryClass.getDeclaredField("aa").get(null);
this.getPotion = this.potionRegistry.getClass().getMethod("get", minecraftKey);
} catch (Exception e) {
throw new RuntimeException("Failed to initialize 1.17.1 bridge", e);
}
}

@Override
public void registerLugolsIodinePotion(NamespacedKey potionKey, LugolsIodinePotion.Config.Recipe config) {
Objects.requireNonNull(potionKey, "potionKey");
Objects.requireNonNull(config, "config");

try {
String basePotionName = config.basePotion().name().toLowerCase(Locale.ROOT);
Object basePotion = this.getPotion.invoke(this.potionRegistry, this.newMinecraftKey.invoke(null, basePotionName));
Object ingredient = this.getItem.invoke(null, config.ingredient());

Object mobEffectArray = Array.newInstance(this.mobEffectClass, 0);
Object newPotion = this.potionRegistryClass.getConstructor(mobEffectArray.getClass()).newInstance(mobEffectArray);

Method registerMethod = this.iRegistryClass.getDeclaredMethod("a", this.iRegistryClass, String.class, Object.class);
Object potion = registerMethod.invoke(null, this.potionRegistry, potionKey.getKey(), newPotion);

Method registerBrewingRecipe = this.potionBrewerClass.getDeclaredMethod("a", this.potionRegistryClass, this.itemClass, this.potionRegistryClass);
registerBrewingRecipe.setAccessible(true);
registerBrewingRecipe.invoke(null, basePotion, ingredient, potion);
} catch (Exception e) {
logger.log(Level.SEVERE, "Could not handle reflective operation.", e);
}
}

@Override
public void unregisterLugolsIodinePotion(NamespacedKey potionKey) {
// todo unregister potion and brewing recipe
}

@Override
public int getMinWorldHeight(World bukkitWorld) {
Objects.requireNonNull(bukkitWorld, "bukkitWorld");

return this.minWorldHeightMap.computeIfAbsent(bukkitWorld.getUID(), worldId -> {
try {
return (int) this.minHeightMethod.invoke(bukkitWorld);
} catch (IllegalAccessException | InvocationTargetException e) {
logger.log(Level.SEVERE, "Could not handle min world height on world '" + bukkitWorld.getName() + "' ('" + worldId + "').", e);
return 0;
}
});
}
}

0 comments on commit b87bed5

Please sign in to comment.