Initial commit: LoParkour v1.1.0
This commit is contained in:
commit
aecb03ccf8
120 changed files with 9668 additions and 0 deletions
125
src/main/java/dev/loki/loparkour/world/Divider.java
Normal file
125
src/main/java/dev/loki/loparkour/world/Divider.java
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
package dev.loki.loparkour.world;
|
||||
|
||||
import dev.loki.loparkour.LoParkour;
|
||||
import dev.loki.loparkour.config.Option;
|
||||
import dev.loki.loparkour.session.Session;
|
||||
import dev.efnilite.vilib.util.Locations;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* <p>Divides the parkour world in sections, each with an active session.</p>
|
||||
* <p>Iteration 2.</p>
|
||||
*
|
||||
* @author loki
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public class Divider {
|
||||
|
||||
/**
|
||||
* Map with all session ids map to the session instances.
|
||||
*/
|
||||
public static final Map<Session, Integer> sections = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Associates a session to a specific section.
|
||||
*
|
||||
* @param session The session.
|
||||
*/
|
||||
public static synchronized Location add(Session session) {
|
||||
// attempts to get the closest available section to the center
|
||||
var missing = IntStream.range(0, sections.size() + 1)
|
||||
.filter(i -> !sections.containsValue(i))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
|
||||
sections.put(session, missing);
|
||||
|
||||
var location = toLocation(session);
|
||||
|
||||
LoParkour.log("Added session at %s".formatted(Locations.toString(location, true)));
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disassociates a session from a specific section.
|
||||
*
|
||||
* @param session The session.
|
||||
*/
|
||||
public static void remove(Session session) {
|
||||
LoParkour.log("Removed session at %s".formatted(Locations.toString(toLocation(session), true)));
|
||||
|
||||
sections.remove(session);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param session The session.
|
||||
* @return The location at the center of section n.
|
||||
*/
|
||||
private static Location toLocation(Session session) {
|
||||
int[] xz = spiralAt(sections.get(session));
|
||||
|
||||
return new Location(World.getWorld(),
|
||||
xz[0] * Option.BORDER_SIZE,
|
||||
(Option.MAX_Y + Option.MIN_Y) / 2.0,
|
||||
xz[1] * Option.BORDER_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param session The session.
|
||||
* @return Array where the first item is the smallest location and second item is the largest.
|
||||
*/
|
||||
public static Location[] toSelection(Session session) {
|
||||
Location center = toLocation(session);
|
||||
|
||||
// get the min and max locations
|
||||
Location max = center.clone().add(Option.BORDER_SIZE / 2, 0, Option.BORDER_SIZE / 2);
|
||||
Location min = center.clone().subtract(Option.BORDER_SIZE / 2, 0, Option.BORDER_SIZE / 2);
|
||||
|
||||
max.setY(Option.MAX_Y);
|
||||
min.setY(Option.MIN_Y);
|
||||
|
||||
return new Location[]{min, max};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a spiral
|
||||
*
|
||||
* @param n The number of value
|
||||
* @return the coords of this value
|
||||
*/
|
||||
// https://math.stackexchange.com/a/163101
|
||||
private static int[] spiralAt(int n) {
|
||||
if (n < 0) {
|
||||
throw new IllegalArgumentException("Invalid n bound: %d".formatted(n));
|
||||
}
|
||||
|
||||
n++; // one-index
|
||||
int k = (int) Math.ceil((Math.sqrt(n) - 1) / 2);
|
||||
int t = 2 * k + 1;
|
||||
int m = t * t;
|
||||
t--;
|
||||
|
||||
if (n > m - t) {
|
||||
return new int[]{k - (m - n), -k};
|
||||
} else {
|
||||
m -= t;
|
||||
}
|
||||
|
||||
if (n > m - t) {
|
||||
return new int[]{-k, -k + (m - n)};
|
||||
} else {
|
||||
m -= t;
|
||||
}
|
||||
|
||||
if (n > m - t) {
|
||||
return new int[]{-k + (m - n), k};
|
||||
} else {
|
||||
return new int[]{k, k - (m - n - t)};
|
||||
}
|
||||
}
|
||||
}
|
||||
126
src/main/java/dev/loki/loparkour/world/World.java
Normal file
126
src/main/java/dev/loki/loparkour/world/World.java
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
package dev.loki.loparkour.world;
|
||||
|
||||
import dev.loki.loparkour.LoParkour;
|
||||
import dev.loki.loparkour.config.Config;
|
||||
import dev.efnilite.vilib.util.VoidGenerator;
|
||||
import org.bukkit.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Comparator;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class World {
|
||||
|
||||
private static String name;
|
||||
private static org.bukkit.World world;
|
||||
|
||||
/**
|
||||
* Creates a new world and sets all according settings in it.
|
||||
*/
|
||||
public static void create() {
|
||||
name = Config.CONFIG.getString("world.name");
|
||||
|
||||
var world = Bukkit.getWorld(name);
|
||||
|
||||
if (!Config.CONFIG.getBoolean("joining")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (world != null) {
|
||||
LoParkour.logging().warn("Crash detected! The parkour world loading twice is not usual behaviour. This only happens after a server crash.");
|
||||
}
|
||||
|
||||
if (Config.CONFIG.getBoolean("world.delete-on-reload")) {
|
||||
deleteWorld();
|
||||
}
|
||||
|
||||
createWorld();
|
||||
setup();
|
||||
}
|
||||
|
||||
private static void createWorld() {
|
||||
LoParkour.log("Creating Spigot world");
|
||||
|
||||
try {
|
||||
WorldCreator creator = new WorldCreator(name)
|
||||
.generateStructures(false)
|
||||
.type(WorldType.NORMAL)
|
||||
.generator(VoidGenerator.getGenerator()) // to fix No keys in MapLayer etc.
|
||||
.environment(org.bukkit.World.Environment.NORMAL);
|
||||
|
||||
world = Bukkit.createWorld(creator);
|
||||
} catch (Exception ex) {
|
||||
LoParkour.logging().stack("Error while trying to create the parkour world", "delete the parkour world folder and restart the server", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setup() {
|
||||
LoParkour.log("Initializing world rules");
|
||||
|
||||
world.setGameRule(GameRule.DO_FIRE_TICK, false);
|
||||
world.setGameRule(GameRule.DO_MOB_SPAWNING, false);
|
||||
world.setGameRule(GameRule.DO_TILE_DROPS, false);
|
||||
world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false);
|
||||
world.setGameRule(GameRule.DO_WEATHER_CYCLE, false);
|
||||
world.setGameRule(GameRule.LOG_ADMIN_COMMANDS, false);
|
||||
world.setGameRule(GameRule.KEEP_INVENTORY, true);
|
||||
world.setGameRule(GameRule.ANNOUNCE_ADVANCEMENTS, false);
|
||||
|
||||
world.getWorldBorder().setCenter(0, 0);
|
||||
world.getWorldBorder().setSize(10_000_000);
|
||||
world.setDifficulty(Difficulty.PEACEFUL);
|
||||
world.setClearWeatherDuration(1000000);
|
||||
world.setAutoSave(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the world.
|
||||
*/
|
||||
public static void delete() {
|
||||
if (!Config.CONFIG.getBoolean("world.delete-on-reload") || !Config.CONFIG.getBoolean("joining")) {
|
||||
return;
|
||||
}
|
||||
LoParkour.log("Deleting world");
|
||||
|
||||
getWorld().getPlayers().forEach(player -> player.kickPlayer("Server is restarting"));
|
||||
|
||||
deleteWorld();
|
||||
}
|
||||
|
||||
private static void deleteWorld() {
|
||||
LoParkour.log("Deleting Spigot world");
|
||||
|
||||
File file = new File(name);
|
||||
|
||||
// world has already been deleted
|
||||
if (!file.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.unloadWorld(name, false);
|
||||
|
||||
try (Stream<Path> files = Files.walk(file.toPath())) {
|
||||
files.sorted(Comparator.reverseOrder())
|
||||
.map(Path::toFile)
|
||||
.forEach(File::delete);
|
||||
} catch (Exception ex) {
|
||||
LoParkour.logging().stack("Error while trying to delete the parkour world", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of the parkour world.
|
||||
*/
|
||||
public static String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Bukkit world wherein LoParkour is currently active.
|
||||
*/
|
||||
public static org.bukkit.World getWorld() {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue