Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
goodroach committed Oct 23, 2023
2 parents da4c931 + cec098d commit e400d37
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 62 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>java.net.countercraft.movecraft.combat</groupId>
<artifactId>Movecraft-Combat</artifactId>
<version>2.0.0_beta-2</version>
<version>2.0.0_beta-3</version>
<packaging>jar</packaging>

<name>Movecraft-Combat</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.lang.reflect.FieldUtils;
import org.bukkit.Bukkit;
import org.bukkit.Material;
Expand All @@ -18,6 +19,7 @@

public class BlastResistanceOverride {
public static Map<Material, Float> BlastResistanceOverride = null;
private static BlastResistanceNMS nmsInterface;

public static void load(@NotNull FileConfiguration config) {
if (!config.contains("BlastResistanceOverride"))
Expand All @@ -44,23 +46,21 @@ public static void load(@NotNull FileConfiguration config) {
BlastResistanceOverride.put(m, value);
}
}

String packageName = Bukkit.getServer().getClass().getPackage().getName();
String version = packageName.substring(packageName.lastIndexOf('.') + 1);
int major_version = Integer.parseInt(version.split("_")[1]);
if (major_version < 17) {
nmsInterface = new BlastResistanceNMS_V1(); // Tested on 1.14.4 and 1.16.5
} else if (major_version == 20) {
nmsInterface = new BlastResistanceNMS_v1_20(); // Tested on 1.20.1
} else {
nmsInterface = new BlastResistanceNMS_V2(); // Tested on 1.19.4 and 1.18.2
}
}

public static boolean setBlastResistance(Material m, float resistance) {
try {
String packageName = Bukkit.getServer().getClass().getPackage().getName();
String version = packageName.substring(packageName.lastIndexOf('.') + 1);
Class<?> clazz = Class.forName("org.bukkit.craftbukkit." + version + ".util.CraftMagicNumbers");
Method method = clazz.getMethod("getBlock", Material.class);
Object block = method.invoke(null, m);
Field field = FieldUtils.getField(block.getClass(), "durability", true);
FieldUtils.writeField(field, block, resistance);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
| SecurityException | ClassNotFoundException e) {
e.printStackTrace();
return false;
}
return true;
return nmsInterface.setBlastResistance(m, resistance);
}

public static boolean revertToVanilla(Material m) {
Expand All @@ -69,13 +69,85 @@ public static boolean revertToVanilla(Material m) {

public static void enable() {
for (var entry : BlastResistanceOverride.entrySet()) {
setBlastResistance(entry.getKey(), entry.getValue());
if (!setBlastResistance(entry.getKey(), entry.getValue()))
MovecraftCombat.getInstance().getLogger()
.warning("Unable to set " + entry.getKey().name() + ": " + entry.getValue());
}
}

public static void disable() {
for (Material m : BlastResistanceOverride.keySet()) {
revertToVanilla(m);
if (!revertToVanilla(m))
MovecraftCombat.getInstance().getLogger().warning("Unable to reset " + m.name());
}
}

private static class BlastResistanceNMS {
public boolean setBlastResistance(Material m, float resistance) {
throw new NotImplementedException();
}

protected static Class<?> getCraftMagicNumbersClass() throws ClassNotFoundException {
String packageName = Bukkit.getServer().getClass().getPackage().getName();
String version = packageName.substring(packageName.lastIndexOf('.') + 1);
return Class.forName("org.bukkit.craftbukkit." + version + ".util.CraftMagicNumbers");
}

protected static Object getBlockClass(Class<?> magicNumbers, Material m)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Method method = magicNumbers.getMethod("getBlock", Material.class);
return method.invoke(null, m);
}

protected static void writeField(Object block, String fieldName, float resistance)
throws IllegalAccessException {
Field field = FieldUtils.getField(block.getClass(), fieldName, true);
FieldUtils.writeField(field, block, resistance);
}
}

private static class BlastResistanceNMS_V1 extends BlastResistanceNMS {
public boolean setBlastResistance(Material m, float resistance) {
try {
Object block = getBlockClass(getCraftMagicNumbersClass(), m);
writeField(block, "durability", resistance);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException
| SecurityException | ClassNotFoundException e) {
e.printStackTrace();
return false;
}
return true;
}
}

private static class BlastResistanceNMS_V2 extends BlastResistanceNMS {
public boolean setBlastResistance(Material m, float resistance) {
try {
Object block = getBlockClass(getCraftMagicNumbersClass(), m);
writeField(block, "aH", resistance); // obfuscated explosionResistance
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException
| SecurityException | ClassNotFoundException e) {
e.printStackTrace();
return false;
}
return true;
}
}

private static class BlastResistanceNMS_v1_20 extends BlastResistanceNMS {
public boolean setBlastResistance(Material m, float resistance) {
try {
Object block = getBlockClass(getCraftMagicNumbersClass(), m);
writeField(block, "aF", resistance); // obfuscated explosionResistance
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException
| SecurityException | ClassNotFoundException e) {
e.printStackTrace();
return false;
}
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Dispenser;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
Expand All @@ -22,6 +24,7 @@
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockDispenseEvent;
import org.bukkit.event.entity.EntitySpawnEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
Expand Down Expand Up @@ -77,59 +80,31 @@ private Vector getTNTVector() {
return v;
}

private boolean subtractItem(@NotNull Inventory inv, @NotNull ItemStack item) {
int count = item.getAmount();
for (int i = 0; i < inv.getSize(); i++) {
ItemStack temp = inv.getItem(i);
if (temp == null || !temp.isSimilar(item))
continue;

if (temp.getAmount() <= count) {
count -= temp.getAmount();
inv.remove(temp);
} else {
temp.setAmount(temp.getAmount() - count);
return true;
}
}
return false;
}

@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onBlockDispense(@NotNull BlockDispenseEvent e) {
@EventHandler
public void onEntitySpawn (@NotNull EntitySpawnEvent e) {
if (!DamageTracking.EnableTNTTracking)
return;
if (e.getBlock().getType() != Material.DISPENSER || e.getItem().getType() != Material.TNT)
if(!e.getEntityType().equals(EntityType.PRIMED_TNT))
return;

// Cancel dispense event
e.setCancelled(true);

// Subtract item yourself
Dispenser d = (Dispenser) e.getBlock().getState();
Inventory inv = d.getInventory();
if (!subtractItem(inv, e.getItem())) {
Bukkit.getScheduler().runTask(MovecraftCombat.getInstance(), () -> {
subtractItem(inv, e.getItem());
});
}

// Spawn TNT
Location l = e.getVelocity().toLocation(e.getBlock().getWorld());
TNTPrimed tnt = (TNTPrimed) e.getBlock().getWorld().spawnEntity(l, EntityType.PRIMED_TNT);
Vector velocity = getTNTVector();
tnt.setVelocity(velocity);
for (Player p : Bukkit.getServer().getOnlinePlayers()) {
p.playSound(l, Sound.ENTITY_TNT_PRIMED, 1.5f, 1.5f);
}
TNTPrimed tnt = (TNTPrimed)e.getEntity();

// Find nearest craft
Craft craft = MathUtils.fastNearestCraftToLoc(CraftManager.getInstance().getCrafts(),
e.getBlock().getLocation());
tnt.getLocation());
if (!(craft instanceof PlayerCraft))
return;
if (!craft.getHitBox().contains(MathUtils.bukkit2MovecraftLoc(e.getBlock().getLocation())))
return;
if (!craft.getHitBox().contains(MathUtils.bukkit2MovecraftLoc(tnt.getLocation()))) {
//check adjacent blocks
boolean found = false;
Block center = tnt.getLocation().getBlock();
for (BlockFace face : BlockFace.values()) {
if (craft.getHitBox().contains(MathUtils.bukkit2MovecraftLoc(center.getRelative(face).getLocation()))) {
found = true;
break;
}
}
if (!found) return;
}

// Report to tracking
PlayerCraft playerCraft = (PlayerCraft) craft;
Expand Down

0 comments on commit e400d37

Please sign in to comment.