Files
SteamWar/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/Region.java
T

389 lines
13 KiB
Java

/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.world.regions;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
import com.sk89q.worldedit.EditSession;
import de.steamwar.bausystem.commands.CommandTNT.TNTMode;
import de.steamwar.bausystem.world.Color;
import de.steamwar.bausystem.world.SizedStack;
import de.steamwar.sql.NoClipboardException;
import de.steamwar.sql.SchematicNode;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.logging.Level;
public class Region {
private static final List<Region> regions = new ArrayList<>();
static boolean buildArea = false;
static boolean extensionArea = false;
private static JsonObject regionsObject = new JsonObject();
static {
File regionsFile = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "regions.json");
if (regionsFile.exists()) {
try {
regionsObject = new JsonParser().parse(new FileReader(regionsFile)).getAsJsonObject();
} catch (JsonSyntaxException | IOException e) {
Bukkit.getLogger().log(Level.WARNING, "Item JSON error");
}
}
YamlConfiguration config = new YamlConfiguration();
try {
config.load(new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections.yml"));
} catch (InvalidConfigurationException | IOException e) {
Bukkit.getLogger().log(Level.SEVERE, "Failed to load sections.yml", e);
}
ConfigurationSection prototypes = config.getConfigurationSection("prototypes");
assert prototypes != null;
for (String prototype : prototypes.getKeys(false)) {
new Prototype(Objects.requireNonNull(prototypes.getConfigurationSection(prototype)));
}
ConfigurationSection regions = config.getConfigurationSection("regions");
assert regions != null;
for (String region : regions.getKeys(false)) {
new Region(Objects.requireNonNull(regions.getConfigurationSection(region)));
}
}
public static boolean buildAreaEnabled() {
return buildArea;
}
public static boolean extensionAreaEnabled() {
return extensionArea;
}
public static Region getRegion(Location location) {
for (Region region : regions) {
if (region.inRegion(location, RegionType.NORMAL, RegionExtensionType.NORMAL)) {
return region;
}
}
return GlobalRegion.getInstance();
}
public static void setGlobalColor(Color color) {
for (Region region : regions) {
region.setColor(color);
}
}
public static void save() {
File colorsFile = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "regions.json");
if (!colorsFile.exists()) {
try {
colorsFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
return;
}
}
try (FileOutputStream fileOutputStream = new FileOutputStream(colorsFile)) {
fileOutputStream.write(regionsObject.toString().getBytes());
} catch (IOException e) {
e.printStackTrace();
// Ignored
}
}
private final String name;
final Point minPoint;
private final Prototype prototype;
private final String optionsLinkedWith; // nullable
private Region linkedRegion = null; // nullable
private SizedStack<EditSession> undosessions;
private SizedStack<EditSession> redosessions;
private JsonObject regionOptions = new JsonObject();
@Getter
private TNTMode tntMode = Region.buildAreaEnabled() ? TNTMode.ONLY_TB : TNTMode.OFF;
@Getter
private boolean freeze = false;
@Getter
private boolean fire = false;
@Getter
private boolean protect = false;
@Getter
private Color color = Color.YELLOW;
private Region(ConfigurationSection config) {
name = config.getName();
minPoint = new Point(config.getInt("minX"), config.getInt("minY"), config.getInt("minZ"));
prototype = Prototype.prototypes.get(config.getString("prototype"));
optionsLinkedWith = config.getString("optionsLinkedWith", null);
if (!hasTestblock()) tntMode = TNTMode.OFF;
regions.add(this);
load();
}
public Region(String name) {
this.name = name;
this.minPoint = new Point(0, 0, 0);
this.prototype = null;
this.optionsLinkedWith = null;
tntMode = TNTMode.OFF;
load();
}
private void load() {
if (regionsObject.has(name)) {
regionOptions = regionsObject.getAsJsonObject(name);
if (regionOptions.has("tnt")) {
String tntName = regionsObject.getAsJsonObject(name).getAsJsonPrimitive("tnt").getAsString();
try {
tntMode = TNTMode.valueOf(tntName);
} catch (Exception e) {
// Ignored
}
}
if (regionOptions.has("fire")) {
fire = regionOptions.getAsJsonPrimitive("fire").getAsBoolean();
}
if (regionOptions.has("freeze")) {
freeze = regionOptions.getAsJsonPrimitive("freeze").getAsBoolean();
}
if (regionOptions.has("protect")) {
protect = regionOptions.getAsJsonPrimitive("protect").getAsBoolean();
}
if (regionOptions.has("color")) {
String colorName = regionOptions.getAsJsonPrimitive("color").getAsString();
try {
color = Color.valueOf(colorName);
} catch (Exception e) {
// Ignored
}
}
} else {
regionsObject.add(name, regionOptions);
}
}
public void setColor(Color color) {
this.color = color;
regionOptions.add("color", new JsonPrimitive(color.name()));
}
private void setLinkedRegion(Consumer<Region> regionConsumer) {
if (optionsLinkedWith == null) {
return;
}
if (linkedRegion != null) {
regionConsumer.accept(linkedRegion);
return;
}
for (Region region : regions) {
if (region.name.equals(name)) {
linkedRegion = region;
regionConsumer.accept(linkedRegion);
return;
}
}
}
public void setTntMode(TNTMode tntMode) {
this.tntMode = tntMode;
setLinkedRegion(region -> {
region.tntMode = tntMode;
region.regionOptions.add("tnt", new JsonPrimitive(tntMode.name()));
});
regionOptions.add("tnt", new JsonPrimitive(tntMode.name()));
}
public void setFreeze(boolean freeze) {
this.freeze = freeze;
setLinkedRegion(region -> {
region.freeze = freeze;
region.regionOptions.add("freeze", new JsonPrimitive(freeze));
});
regionOptions.add("freeze", new JsonPrimitive(freeze));
}
public void setFire(boolean fire) {
this.fire = fire;
setLinkedRegion(region -> {
region.fire = fire;
region.regionOptions.add("fire", new JsonPrimitive(fire));
});
regionOptions.add("fire", new JsonPrimitive(fire));
}
public void setProtect(boolean protect) {
this.protect = protect;
setLinkedRegion(region -> {
region.protect = protect;
region.regionOptions.add("protect", new JsonPrimitive(protect));
});
regionOptions.add("protect", new JsonPrimitive(protect));
}
public Point getMinPoint(RegionType regionType, RegionExtensionType regionExtensionType) {
switch (regionType) {
case BUILD:
return prototype.buildArea.getMinPoint(this, regionExtensionType);
case TESTBLOCK:
return prototype.testblock.getMinPoint(this, regionExtensionType);
default:
case NORMAL:
return prototype.getMinPoint(this, regionExtensionType);
}
}
public Point getMaxPoint(RegionType regionType, RegionExtensionType regionExtensionType) {
switch (regionType) {
case BUILD:
return prototype.buildArea.getMaxPoint(this, regionExtensionType);
case TESTBLOCK:
return prototype.testblock.getMaxPoint(this, regionExtensionType);
default:
case NORMAL:
return prototype.getMaxPoint(this, regionExtensionType);
}
}
public boolean inRegion(Location l, RegionType regionType, RegionExtensionType regionExtensionType) {
switch (regionType) {
case BUILD:
return prototype.buildArea.inRegion(this, l, regionExtensionType);
case TESTBLOCK:
return prototype.testblock.inRegion(this, l, regionExtensionType);
default:
case NORMAL:
return prototype.inRegion(this, l, regionExtensionType);
}
}
public boolean hasBuildRegion() {
return prototype.buildArea != null;
}
public void reset(SchematicNode schem, boolean ignoreAir) throws IOException, NoClipboardException {
initSessions();
undosessions.push(prototype.reset(this, schem, ignoreAir, color));
}
public boolean hasTestblock() {
return prototype.hasTestblock();
}
public void resetTestblock(SchematicNode schem, boolean reset) throws IOException, NoClipboardException {
initSessions();
undosessions.push(prototype.resetTestblock(this, schem, color, reset));
}
public boolean hasProtection() {
return prototype.hasProtection();
}
public void protect(SchematicNode schem) throws IOException, NoClipboardException {
initSessions();
undosessions.push(prototype.protect(this, schem));
}
public int getProtectYLevel() {
return getMinPoint(RegionType.TESTBLOCK, RegionExtensionType.NORMAL).getY();
}
public boolean hasExtensionArea(RegionType regionType) {
switch (regionType) {
case BUILD:
return prototype.buildArea.extensionPrototypeArea;
case TESTBLOCK:
return prototype.testblock.extensionPrototypeArea;
default:
case NORMAL:
return prototype.extensionPrototypeArea;
}
}
private void initSessions() {
if (undosessions == null) {
undosessions = new SizedStack<>(20);
redosessions = new SizedStack<>(20);
}
}
public boolean undo() {
initSessions();
EditSession session = null;
try {
session = undosessions.pop();
if (session == null) {
return false;
}
session.undo(session);
redosessions.push(session);
return true;
} finally {
if (session != null) {
session.flushQueue();
}
}
}
public boolean redo() {
initSessions();
EditSession session = null;
try {
session = redosessions.pop();
if (session == null) {
return false;
}
session.redo(session);
undosessions.push(session);
return true;
} finally {
if (session != null) {
session.flushQueue();
}
}
}
}