Skip to content

Instantly share code, notes, and snippets.

@bfu4
Last active December 27, 2020 09:26
Show Gist options
  • Save bfu4/9de974eb192b35d4cc48b749727874a0 to your computer and use it in GitHub Desktop.
Save bfu4/9de974eb192b35d4cc48b749727874a0 to your computer and use it in GitHub Desktop.
Implementing Prison (core) in your plugin

PrisonHook - a utility class to make hooking into Prison easier

Credit goes to PrisonTeam for their code I stole for isLocationInsideAMine(Location l) as well as for supplying their plugin

Basically, I stumbled upon this issue where I had to deal with mines involving this core. Obviously, I tried everything to work around it, with minimal luck. So the solution was to build with PrisonCore as a dependency, and use their objects.

Prison supplies a PrisonSpigotAPI, which is a bit useful. In the file PrisonHook.java, you can see how I use it. We steal from the core's class MinesCommand.java, and use a slightly modified version of the iterations in the mines whereami command.

You'll have to find a way to add it as a dependency, and using maven, it should look like this. You'll probably need a repository to host the artifact.

pom implementation

    <dependency>
         <groupId>tech.mcprison</groupId>
         <artifactId>prison-core</artifactId>
         <version>LATEST</version>
         <scope>provided</scope>
    </dependency>

Using this in a BlockBreakEvent listener

Due to the lack of reliability between the two functions, to check if a location is in a mine, this is your best shot:

(YourPlugin.getPrisonHook().isLocationInAMine(event.getBlock().getLocation())
   || YourPlugin.getPrisonHook().isLocationInsideAMine(event.getBlock().getLocation())

To get the specific Mine (from Prison):

Mine mine = YourPlugin.getPrisonHook()
               .getMineByName(YourPlugin.getPrisonHook().getMineNameByLocation(event.getBlock().getLocation()));

To get a Block object (from Prison):

   Block block1 = mine.getBlocks().stream().filter(b -> Lib.streamAndMatch(b.getType().toString().split(":")[1]) != null)
               .findFirst().orElse(null);

To get a Material object (from Bukkit):

   Material material = block1 != null ? Lib.streamAndMatch(block1.getType().toString().substring(10).split(":")[0]) : null;

Iterating from a String to find a Material (Lib.streamAndMatch(String s):

public static Material streamAndMatch(String name) {
     return Arrays.stream(Material.values())
        .filter(material -> material.toString().toLowerCase().contains(name)).findFirst().orElse(null);
}
/**
* PrisonHook - a hook for PrisonCore
*
* @link https://github.com/PrisonTeam/Prison
*
* @author bfu4
* @since 26/12/2020 @ 23.22
*/
public class PrisonHook {
private final JavaPlugin plugin;
private final Prison prison;
private final PrisonAPI prisonApi;
private final PrisonSpigotAPI prisonSpigotApi;
private final String versionID;
/**
* Create a new prison hook
*
* @param plugin instance of your Plugin
* @param prison instance of PrisonCore
* @param api instance of PrisonApi
* @param spigotApi instance of PrisonSpigotAPI
*/
public PrisonHook(JavaPlugin plugin, Prison prison, PrisonAPI api, PrisonSpigotAPI spigotApi) {
this.plugin = plugin;
this.prison = prison;
this.prisonApi = api;
this.prisonSpigotApi = spigotApi;
this.versionID = concatenateUUID(UUID.randomUUID().toString().substring(0, 13));
}
public JavaPlugin getPlugin() { return plugin; }
/* <!----- PrisonCore getters -----!> */
public Prison getPrison() { return prison; }
public PrisonAPI getPrisonApi() { return prisonApi; }
public PrisonSpigotAPI getPrisonSpigotApi() { return prisonSpigotApi; }
/* <!------------------------------!> */
public List<Mine> getMines() {
return getPrisonSpigotApi().getMines();
}
/**
* Get a mine by its name
*
* @param name of the mine
* @return mine
*/
public Mine getMineByName(String name) {
return getMines().stream().filter(mine -> mine.getName().equalsIgnoreCase(name)).findFirst().orElse(null);
}
/**
* Check if a player is inside a mine
*
* @param mine to check that player is inside
* @param player to check if a player is in
* @return whether a player is in a mine
*/
public boolean isPlayerInside(Mine mine, Player player) {
Location playerLocation = player.getLocation();
double[] arr1 = new double[] { playerLocation.getBlockX(), playerLocation.getBlockY(), playerLocation.getBlockZ() };
World world = mine.getWorld().orElse(null);
return world != null
&& mine.getBounds().withinIncludeTopOfMine(new tech.mcprison.prison.util.Location(world, arr1[0], arr1[1], arr1[2]));
}
/**
* Yes, I took this from the PrisonCore. I give credit here.
* By the way, IntelliJ screamed at me for shitty iterations, however I'm too tired to care.
* Might want to look into that. ;)
*
* @param l location to check
* @return if a player is inside a mine.
*/
public boolean isLocationInsideAMine(Location l) {
double[] arr1 = {l.getBlockX(), l.getBlockY(), l.getBlockZ()};
PrisonMines pMines = PrisonMines.getInstance();
List<Mine> inMine = new ArrayList<>();
TreeMap<Integer, Mine> nearMine = new TreeMap<>();
Iterator<Mine> var6 = pMines.getMineManager().getMines().iterator();
Mine m;
while (var6.hasNext()) {
m = var6.next();
World world = m.getWorld().orElse(null);
if (world == null) return false;
tech.mcprison.prison.util.Location l2 = new tech.mcprison.prison.util.Location(world, arr1[0], arr1[1], arr1[2]);
if (!m.isVirtual() && m.getBounds().within(l2)) {
inMine.add(m);
} else if (!m.isVirtual() && m.getBounds().within(l2, 25L)) {
double distance = m.getBounds().getDistance3d(l2);
nearMine.put((int) distance, m);
}
}
if (inMine.size() > 0) {
var6 = inMine.iterator();
while (var6.hasNext()) {
m = var6.next();
return true;
}
}
if (nearMine.size() > 0) {
int cnt = 0;
Set<Integer> distances = nearMine.keySet();
Iterator<Integer> var13 = distances.iterator();
while (var13.hasNext()) {
++cnt;
var13.next();
if (cnt >= 5) {
break;
} else {
return true;
}
}
} else if (inMine.size() == 0) {
return false;
}
return false;
}
public boolean isLocationInAMine(Location location) {
double[] arr1 = new double[] { location.getBlockX(), location.getBlockY(), location.getBlockZ() };
Mine mine = null;
try {
mine = getMines().stream().filter(streamedMine -> {
World world1 = streamedMine.getWorld().orElse(null);
assert world1 != null;
return world1.getName().equalsIgnoreCase(location.getWorld().getName()) && streamedMine.getBounds()
.within(new tech.mcprison.prison.util.Location(world1, arr1[0], arr1[1], arr1[2]));
}).findFirst().orElse(null);
} catch (NullPointerException e) {
// Catching this to avoid console spam, however if this is null, then the player is not in a mine!
}
return mine != null && mine.getWorld().isPresent();
}
public String getMineNameByLocation(Location location) {
Mine mine = null;
double[] arr1 = new double[]{location.getBlockX(), location.getBlockY(), location.getBlockZ()};
if (isLocationInAMine(location)) {
try {
mine = getMines().stream().filter(streamedMine -> {
World world1 = streamedMine.getWorld().orElse(null);
assert world1 != null;
return world1.getName().equalsIgnoreCase(location.getWorld().getName()) && streamedMine.getBounds()
.within(new tech.mcprison.prison.util.Location(world1, arr1[0], arr1[1], arr1[2]));
}).findFirst().orElse(null);
} catch (NullPointerException e) {
return "null";
}
}
return mine != null ? mine.getName() : "null";
}
public boolean isValid() {
return plugin.isEnabled() && prison != null && prisonApi != null && prisonSpigotApi != null;
}
public String getVersionID() {
return versionID;
}
private String concatenateUUID(String uuid) {
return uuid.substring(0, 4) + "-" + uuid.substring(4, 8) + "-" + uuid.substring(9);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment