Adds methods to Stargate for easier logging and less redundancy Loads the language loader in two parts to make it available while loading Adds a translated string to the reload-message Uses String.format to make long messages more readable Makes it possible to get strings directly from the backup language to make debugging easier
276 lines
11 KiB
Java
276 lines
11 KiB
Java
package net.knarcraft.stargate.utility;
|
|
|
|
import net.knarcraft.stargate.Stargate;
|
|
import net.knarcraft.stargate.container.BlockLocation;
|
|
import net.knarcraft.stargate.portal.Gate;
|
|
import net.knarcraft.stargate.portal.GateHandler;
|
|
import net.knarcraft.stargate.portal.Portal;
|
|
import net.knarcraft.stargate.portal.PortalHandler;
|
|
import net.knarcraft.stargate.portal.PortalLocation;
|
|
import net.knarcraft.stargate.portal.PortalOptions;
|
|
import net.knarcraft.stargate.portal.PortalOwner;
|
|
import net.knarcraft.stargate.portal.PortalRegistry;
|
|
import org.bukkit.ChatColor;
|
|
import org.bukkit.World;
|
|
import org.bukkit.block.Sign;
|
|
|
|
import java.io.BufferedWriter;
|
|
import java.io.File;
|
|
import java.io.FileWriter;
|
|
import java.io.IOException;
|
|
import java.util.Scanner;
|
|
|
|
/**
|
|
* Helper class for saving and loading portal save files
|
|
*/
|
|
public final class PortalFileHelper {
|
|
|
|
private PortalFileHelper() {
|
|
|
|
}
|
|
|
|
/**
|
|
* Saves all portals for the given world
|
|
*
|
|
* @param world <p>The world to save portals for</p>
|
|
*/
|
|
public static void saveAllPortals(World world) {
|
|
Stargate.getStargateConfig().addManagedWorld(world.getName());
|
|
String saveFileLocation = Stargate.getPortalFolder() + "/" + world.getName() + ".db";
|
|
|
|
try {
|
|
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(saveFileLocation, false));
|
|
|
|
for (Portal portal : PortalRegistry.getAllPortals()) {
|
|
//Skip portals in other worlds
|
|
String worldName = portal.getWorld().getName();
|
|
if (!worldName.equalsIgnoreCase(world.getName())) {
|
|
continue;
|
|
}
|
|
//Save the portal
|
|
savePortal(bufferedWriter, portal);
|
|
}
|
|
|
|
bufferedWriter.close();
|
|
} catch (Exception e) {
|
|
Stargate.logSevere(String.format("Exception while writing stargates to %s: %s", saveFileLocation, e));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Saves one portal
|
|
*
|
|
* @param bufferedWriter <p>The buffered writer to write to</p>
|
|
* @param portal <p>The portal to save</p>
|
|
* @throws IOException <p>If unable to write to the buffered writer</p>
|
|
*/
|
|
private static void savePortal(BufferedWriter bufferedWriter, Portal portal) throws IOException {
|
|
StringBuilder builder = new StringBuilder();
|
|
BlockLocation button = portal.getStructure().getButton();
|
|
|
|
//WARNING: Because of the primitive save format, any change in order will break everything!
|
|
builder.append(portal.getName()).append(':');
|
|
builder.append(portal.getSignLocation().toString()).append(':');
|
|
builder.append((button != null) ? button.toString() : "").append(':');
|
|
|
|
//Add removes config values to keep indices consistent
|
|
builder.append(0).append(':');
|
|
builder.append(0).append(':');
|
|
|
|
builder.append(portal.getYaw()).append(':');
|
|
builder.append(portal.getTopLeft().toString()).append(':');
|
|
builder.append(portal.getGate().getFilename()).append(':');
|
|
|
|
//Only save the destination name if the gate is fixed as it doesn't matter otherwise
|
|
builder.append(portal.getOptions().isFixed() ? portal.getDestinationName() : "").append(':');
|
|
|
|
builder.append(portal.getNetwork()).append(':');
|
|
|
|
//Name is saved as a fallback if the UUID is unavailable
|
|
builder.append(portal.getOwner().getIdentifier());
|
|
|
|
//Save all the portal options
|
|
savePortalOptions(portal, builder);
|
|
|
|
bufferedWriter.append(builder.toString());
|
|
bufferedWriter.newLine();
|
|
}
|
|
|
|
/**
|
|
* Saves all portal options for the given portal
|
|
*
|
|
* @param portal <p>The portal to save</p>
|
|
* @param builder <p>The string builder to append to</p>
|
|
*/
|
|
private static void savePortalOptions(Portal portal, StringBuilder builder) {
|
|
PortalOptions options = portal.getOptions();
|
|
builder.append(':');
|
|
builder.append(options.isHidden()).append(':');
|
|
builder.append(options.isAlwaysOn()).append(':');
|
|
builder.append(options.isPrivate()).append(':');
|
|
builder.append(portal.getWorld().getName()).append(':');
|
|
builder.append(options.isFree()).append(':');
|
|
builder.append(options.isBackwards()).append(':');
|
|
builder.append(options.isShown()).append(':');
|
|
builder.append(options.isNoNetwork()).append(':');
|
|
builder.append(options.isRandom()).append(':');
|
|
builder.append(options.isBungee());
|
|
}
|
|
|
|
/**
|
|
* Loads all portals for the given world
|
|
*
|
|
* @param world <p>The world to load portals for</p>
|
|
* @return <p>True if portals could be loaded</p>
|
|
*/
|
|
public static boolean loadAllPortals(World world) {
|
|
String location = Stargate.getPortalFolder();
|
|
|
|
File database = new File(location, world.getName() + ".db");
|
|
|
|
if (database.exists()) {
|
|
return loadPortals(world, database);
|
|
} else {
|
|
Stargate.logInfo(String.format("{%s} No stargates for world ", world.getName()));
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Loads all the given portals
|
|
*
|
|
* @param world <p>The world to load portals for</p>
|
|
* @param database <p>The database file containing the portals</p>
|
|
* @return <p>True if the portals were loaded successfully</p>
|
|
*/
|
|
private static boolean loadPortals(World world, File database) {
|
|
int lineIndex = 0;
|
|
try {
|
|
Scanner scanner = new Scanner(database);
|
|
while (scanner.hasNextLine()) {
|
|
//Read the line and do whatever needs to be done
|
|
readPortalLine(scanner, ++lineIndex, world);
|
|
}
|
|
scanner.close();
|
|
|
|
//Do necessary tasks after all portals have loaded
|
|
doPostLoadTasks(world);
|
|
return true;
|
|
} catch (Exception e) {
|
|
Stargate.logSevere(String.format("Exception while reading stargates from %s: %d", database.getName(),
|
|
lineIndex));
|
|
e.printStackTrace();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Reads one file line containing information about one portal
|
|
*
|
|
* @param scanner <p>The scanner to read</p>
|
|
* @param lineIndex <p>The index of the read line</p>
|
|
* @param world <p>The world for which portals are currently being read</p>
|
|
*/
|
|
private static void readPortalLine(Scanner scanner, int lineIndex, World world) {
|
|
String line = scanner.nextLine().trim();
|
|
|
|
//Ignore empty and comment lines
|
|
if (line.startsWith("#") || line.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
//Check if the min. required portal data is present
|
|
String[] portalData = line.split(":");
|
|
if (portalData.length < 8) {
|
|
Stargate.logInfo(String.format("Invalid line - %s", lineIndex));
|
|
return;
|
|
}
|
|
|
|
//Load the portal defined in the current line
|
|
loadPortal(portalData, world, lineIndex);
|
|
}
|
|
|
|
/**
|
|
* Performs tasks which must be run after portals have loaded
|
|
*
|
|
* <p>This will open always on portals, print info about loaded stargates and re-draw portal signs for loaded
|
|
* portals.</p>
|
|
*
|
|
* @param world <p>The world portals have been loaded for</p>
|
|
*/
|
|
private static void doPostLoadTasks(World world) {
|
|
//Open any always-on portals. Do this here as it should be more efficient than in the loop.
|
|
PortalHandler.verifyAllPortals();
|
|
int portalCount = PortalRegistry.getAllPortals().size();
|
|
int openCount = PortalHandler.openAlwaysOpenPortals();
|
|
|
|
//Print info about loaded stargates so that admins can see if all stargates loaded
|
|
Stargate.logInfo(String.format("{%s} Loaded %d stargates with %d set as always-on", world.getName(),
|
|
portalCount, openCount));
|
|
|
|
//Re-draw the signs in case a bug in the config prevented the portal from loading and has been fixed since
|
|
for (Portal portal : PortalRegistry.getAllPortals()) {
|
|
portal.drawSign();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Loads one portal from a data array
|
|
*
|
|
* @param portalData <p>The array describing the portal</p>
|
|
* @param world <p>The world to create the portal in</p>
|
|
* @param lineIndex <p>The line index to report in case the user needs to fix an error</p>
|
|
*/
|
|
private static void loadPortal(String[] portalData, World world, int lineIndex) {
|
|
//Load min. required portal data
|
|
String name = portalData[0];
|
|
BlockLocation button = (portalData[2].length() > 0) ? new BlockLocation(world, portalData[2]) : null;
|
|
|
|
//Load the portal's location
|
|
PortalLocation portalLocation = new PortalLocation();
|
|
portalLocation.setSignLocation(new BlockLocation(world, portalData[1]));
|
|
portalLocation.setYaw(Float.parseFloat(portalData[5]));
|
|
portalLocation.setTopLeft(new BlockLocation(world, portalData[6]));
|
|
|
|
//Check if the portal's gate type exists and is loaded
|
|
Gate gate = GateHandler.getGateByName(portalData[7]);
|
|
if (gate == null) {
|
|
//Mark the sign as invalid to reduce some player confusion
|
|
markPortalWithInvalidGate(portalLocation, portalData[7], lineIndex);
|
|
return;
|
|
}
|
|
|
|
//Load extra portal data
|
|
String destination = (portalData.length > 8) ? portalData[8] : "";
|
|
String network = (portalData.length > 9 && !portalData[9].isEmpty()) ? portalData[9] : Stargate.getDefaultNetwork();
|
|
String ownerString = (portalData.length > 10) ? portalData[10] : "";
|
|
|
|
//Get the owner from the owner string
|
|
PortalOwner owner = new PortalOwner(ownerString);
|
|
|
|
//Create the new portal
|
|
Portal portal = new Portal(portalLocation, button, destination, name, network, gate, owner,
|
|
PortalHandler.getPortalOptions(portalData));
|
|
|
|
//Register the portal, and close it in case it wasn't properly closed when the server stopped
|
|
PortalHandler.registerPortal(portal);
|
|
portal.getPortalOpener().closePortal(true);
|
|
}
|
|
|
|
/**
|
|
* Marks a portal with an invalid gate by changing its sign and writing to the console
|
|
*
|
|
* @param portalLocation <p>The location of the portal with an invalid gate</p>
|
|
* @param gateName <p>The name of the invalid gate type</p>
|
|
* @param lineIndex <p>The index of the line the invalid portal was found at</p>
|
|
*/
|
|
private static void markPortalWithInvalidGate(PortalLocation portalLocation, String gateName, int lineIndex) {
|
|
Sign sign = (Sign) portalLocation.getSignLocation().getBlock().getState();
|
|
sign.setLine(3, ChatColor.DARK_RED + Stargate.getString("signInvalidGate"));
|
|
sign.update();
|
|
|
|
Stargate.logInfo(String.format("Gate layout on line %d does not exist [%s]", lineIndex, gateName));
|
|
}
|
|
|
|
}
|