Dateien nach "src/main/java/net/licks92/wirelessredstone/storage" hochladen

This commit is contained in:
2025-08-15 19:24:21 +00:00
parent 5cb78e80c4
commit 5f413f7bb2
6 changed files with 1410 additions and 0 deletions

View File

@@ -0,0 +1,770 @@
package net.licks92.wirelessredstone.storage;
import com.tylersuehr.sql.ContentValues;
import com.tylersuehr.sql.SQLiteDatabase;
import com.tylersuehr.sql.SQLiteOpenHelper;
import net.licks92.wirelessredstone.ConfigManager;
import net.licks92.wirelessredstone.Utils;
import net.licks92.wirelessredstone.WirelessRedstone;
import net.licks92.wirelessredstone.signs.SignType;
import net.licks92.wirelessredstone.signs.WirelessChannel;
import net.licks92.wirelessredstone.signs.WirelessPoint;
import net.licks92.wirelessredstone.signs.WirelessReceiver;
import net.licks92.wirelessredstone.signs.WirelessReceiverClock;
import net.licks92.wirelessredstone.signs.WirelessReceiverDelayer;
import net.licks92.wirelessredstone.signs.WirelessReceiverInverter;
import net.licks92.wirelessredstone.signs.WirelessReceiverSwitch;
import net.licks92.wirelessredstone.signs.WirelessScreen;
import net.licks92.wirelessredstone.signs.WirelessTransmitter;
import org.bukkit.block.BlockFace;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Objects;
import java.util.stream.Collectors;
public class DatabaseClient extends SQLiteOpenHelper {
private static final String DB_NAME = "WirelessRedstoneDatabase";
private static final int DB_VERSION = 1;
private static final String TB_CHANNELS = "channel";
private static final String TB_OWNERS = "owner";
private static final String TB_TRANSMITTERS = "transmitter";
private static final String TB_RECEIVERS = "receiver";
private static final String TB_SCREENS = "screen";
private static final String TB_INVERTERS = "inverter";
private static final String TB_DELAYERS = "delayer";
private static final String TB_SWITCH = "switch";
private static final String TB_CLOCKS = "clock";
private static volatile DatabaseClient instance;
private final SQLiteDatabase db;
private DatabaseClient(String channelFolder) {
super(channelFolder + File.separator + DB_NAME, DB_VERSION);
this.db = getWritableInstance();
}
protected static synchronized DatabaseClient getInstance() {
if (instance == null) {
throw new IllegalStateException("DatabaseClient hasn't been initialized");
}
return instance;
}
protected static synchronized DatabaseClient init(String channelFolder) {
if (instance == null) {
Objects.requireNonNull(channelFolder, "Channel folder can't be null");
instance = new DatabaseClient(channelFolder);
}
return instance;
}
@Override
protected void onCreate(SQLiteDatabase db) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(
Objects.requireNonNull(WirelessRedstone.getInstance().getResource("database/Database_1.sql")),
StandardCharsets.UTF_8))) {
String sql = br.lines().collect(Collectors.joining(System.lineSeparator()));;
db.execSql(sql);
} catch (IOException ex) {
WirelessRedstone.getWRLogger().info("There was an error while initializing the database.");
ex.printStackTrace();
}
}
@Override
protected void onUpdate(SQLiteDatabase db, int oldVersion, int newVersion) {
WirelessRedstone.getWRLogger().info("Updating SQLite database. This could take a while. As a precaution, a backup will be created.");
if (WirelessRedstone.getStorage().backupData()) {
if (oldVersion == 0) {
try {
performUpdate1(db);
} catch (SQLException | IOException ex) {
ex.printStackTrace();
throw new RuntimeException("There was an error while performing database update 1.");
}
}
} else {
throw new RuntimeException("There was an error while backing up the database. The channels folder couldn't be accessed.");
}
WirelessRedstone.getWRLogger().info("Updating SQLite database done.");
}
/**
* Expose the SQLiteDatabase to anything that wants to use it.
*/
protected SQLiteDatabase getDatabase() {
return db;
}
protected Collection<WirelessChannel> getAllChannels() {
Collection<WirelessChannel> channels = new ArrayList<>();
try {
ResultSet resultSet = getDatabase().query(TB_CHANNELS, null, null, null);
while (resultSet.next()) {
channels.add(new WirelessChannel(resultSet.getString("name"), resultSet.getBoolean("locked")));
}
resultSet.close();
Iterator<WirelessChannel> iterator = channels.iterator();
while (iterator.hasNext()) {
WirelessChannel channel = iterator.next();
resultSet = getDatabase().query(TB_OWNERS, new String[]{"user"}, "[channel_name]='" + channel.getName() + "'", null, null);
while (resultSet.next()) {
channel.addOwner(resultSet.getString("user"));
}
resultSet.close();
resultSet = getDatabase().query(TB_TRANSMITTERS, "[channel_name]='" + channel.getName() + "'", null, null);
while (resultSet.next()) {
WirelessPoint point = new WirelessTransmitter(
resultSet.getInt("x"),
resultSet.getInt("y"),
resultSet.getInt("z"),
resultSet.getString("world"),
resultSet.getInt("is_wallsign") != 0,
BlockFace.valueOf(resultSet.getString("direction")),
resultSet.getString("owner")
);
channel.addWirelessPoint(point);
WirelessRedstone.getWRLogger().debug("Transmitter found: " + point);
}
resultSet.close();
resultSet = getDatabase().query(TB_RECEIVERS, "[channel_name]='" + channel.getName() + "'", null, null);
while (resultSet.next()) {
WirelessPoint point = new WirelessReceiver(
resultSet.getInt("x"),
resultSet.getInt("y"),
resultSet.getInt("z"),
resultSet.getString("world"),
resultSet.getInt("is_wallsign") != 0,
BlockFace.valueOf(resultSet.getString("direction")),
resultSet.getString("owner")
);
channel.addWirelessPoint(point);
WirelessRedstone.getWRLogger().debug("Receiver found: " + point);
}
resultSet.close();
resultSet = getDatabase().query(TB_SCREENS, "[channel_name]='" + channel.getName() + "'", null, null);
while (resultSet.next()) {
WirelessPoint point = new WirelessScreen(
resultSet.getInt("x"),
resultSet.getInt("y"),
resultSet.getInt("z"),
resultSet.getString("world"),
resultSet.getInt("is_wallsign") != 0,
BlockFace.valueOf(resultSet.getString("direction")),
resultSet.getString("owner")
);
channel.addWirelessPoint(point);
WirelessRedstone.getWRLogger().debug("Screen found: " + point);
}
resultSet.close();
resultSet = getDatabase().query(TB_INVERTERS, "[channel_name]='" + channel.getName() + "'", null, null);
while (resultSet.next()) {
WirelessPoint point = new WirelessReceiverInverter(
resultSet.getInt("x"),
resultSet.getInt("y"),
resultSet.getInt("z"),
resultSet.getString("world"),
resultSet.getInt("is_wallsign") != 0,
BlockFace.valueOf(resultSet.getString("direction")),
resultSet.getString("owner")
);
channel.addWirelessPoint(point);
WirelessRedstone.getWRLogger().debug("Inverter found: " + point);
}
resultSet.close();
resultSet = getDatabase().query(TB_DELAYERS, "[channel_name]='" + channel.getName() + "'", null, null);
while (resultSet.next()) {
WirelessPoint point = new WirelessReceiverDelayer(
resultSet.getInt("x"),
resultSet.getInt("y"),
resultSet.getInt("z"),
resultSet.getString("world"),
resultSet.getInt("is_wallsign") != 0,
BlockFace.valueOf(resultSet.getString("direction")),
resultSet.getString("owner"),
resultSet.getInt("delay")
);
channel.addWirelessPoint(point);
WirelessRedstone.getWRLogger().debug("Delayer found: " + point);
}
resultSet.close();
resultSet = getDatabase().query(TB_SWITCH, "[channel_name]='" + channel.getName() + "'", null, null);
while (resultSet.next()) {
WirelessPoint point = new WirelessReceiverSwitch(
resultSet.getInt("x"),
resultSet.getInt("y"),
resultSet.getInt("z"),
resultSet.getString("world"),
resultSet.getInt("is_wallsign") != 0,
BlockFace.valueOf(resultSet.getString("direction")),
resultSet.getString("owner"),
resultSet.getBoolean("powered")
);
channel.addWirelessPoint(point);
WirelessRedstone.getWRLogger().debug("Switch found: " + point);
}
resultSet.close();
resultSet = getDatabase().query(TB_CLOCKS, "[channel_name]='" + channel.getName() + "'", null, null);
while (resultSet.next()) {
WirelessPoint point = new WirelessReceiverClock(
resultSet.getInt("x"),
resultSet.getInt("y"),
resultSet.getInt("z"),
resultSet.getString("world"),
resultSet.getInt("is_wallsign") != 0,
BlockFace.valueOf(resultSet.getString("direction")),
resultSet.getString("owner"),
resultSet.getInt("delay")
);
channel.addWirelessPoint(point);
WirelessRedstone.getWRLogger().debug("Clock found: " + point);
}
resultSet.close();
}
} catch (SQLException ex) {
WirelessRedstone.getWRLogger().severe("Couldn't retrieve channels from the database!");
ex.printStackTrace();
}
return channels;
}
protected void recreateDatabase() {
onCreate(getDatabase());
}
protected boolean insertWirelessPoint(WirelessChannel channel, WirelessPoint point) {
if (point == null) {
throw new IllegalArgumentException("WirelessPoint can not be null.");
}
try {
if (isWirelessPointInDb(point)) {
WirelessRedstone.getWRLogger().warning("WirelesPoint " + point + " is a duplicate in the storage. Skipping saving the WirelessPoint");
return false;
}
} catch (SQLException ex) {
WirelessRedstone.getWRLogger().warning("Database exception, enable debug mode to see the full stacktrace.");
if (ConfigManager.getConfig().getDebugMode()) {
ex.printStackTrace();
}
}
ContentValues values = new ContentValues();
try {
if (!isChannelInDb(channel.getName())) {
values.put("name", escape(channel.getName()));
values.put("locked", channel.isLocked());
getDatabase().insert(TB_CHANNELS, values);
WirelessRedstone.getWRLogger().debug("Channel created in database. " + channel.getName());
}
} catch (SQLException ex) {
WirelessRedstone.getWRLogger().warning("Database exception, enable debug mode to see the full stacktrace.");
if (ConfigManager.getConfig().getDebugMode()) {
ex.printStackTrace();
}
}
String table;
values = new ContentValues();
values.put("x", point.getX());
values.put("y", point.getY());
values.put("z", point.getZ());
values.put("world", point.getWorld());
values.put("channel_name", channel.getName());
values.put("direction", point.getDirection().toString());
values.put("owner", point.getOwner());
values.put("is_wallsign", point.isWallSign());
if (point instanceof WirelessTransmitter) {
table = TB_TRANSMITTERS;
} else if (point instanceof WirelessScreen) {
table = TB_SCREENS;
} else if (point instanceof WirelessReceiver) {
if (point instanceof WirelessReceiverInverter) {
table = TB_INVERTERS;
} else if (point instanceof WirelessReceiverDelayer) {
table = TB_DELAYERS;
values.put("delay", ((WirelessReceiverDelayer) point).getDelay());
} else if (point instanceof WirelessReceiverSwitch) {
table = TB_SWITCH;
values.put("powered", ((WirelessReceiverSwitch) point).isActive());
} else if (point instanceof WirelessReceiverClock) {
table = TB_CLOCKS;
values.put("delay", ((WirelessReceiverClock) point).getDelay());
} else {
table = TB_RECEIVERS;
}
} else {
WirelessRedstone.getWRLogger().debug("Can't add wirelesspoint to database. Couldn't find what type the wirelesspoint is.");
WirelessRedstone.getWRLogger().debug(point.toString());
return false;
}
getDatabase().insert(table, values);
WirelessRedstone.getWRLogger().debug("Placed new WirelessPoint in the database");
return true;
}
protected void updateSwitch(WirelessReceiverSwitch receiver) {
ContentValues values = new ContentValues();
values.put("powered", receiver.isActive());
getDatabase().update(TB_SWITCH, values,
"[x]=" + receiver.getX() + " AND [y]=" + receiver.getY() + " AND [z]=" + receiver.getZ() + " AND [world]='" + receiver.getWorld() + "'");
}
protected boolean isChannelInDb(String channelName) throws SQLException {
boolean exists = false;
ResultSet resultSet = getDatabase().query(TB_CHANNELS, "[name]='" + escape(channelName) + "'", null, null);
while (resultSet.next() && !exists) {
exists = true;
}
resultSet.close();
return exists;
}
protected boolean isWirelessPointInDb(WirelessPoint point) throws SQLException {
boolean exists = false;
String table;
if (point instanceof WirelessTransmitter) {
table = TB_TRANSMITTERS;
} else if (point instanceof WirelessScreen) {
table = TB_SCREENS;
} else if (point instanceof WirelessReceiver) {
if (point instanceof WirelessReceiverInverter) {
table = TB_INVERTERS;
} else if (point instanceof WirelessReceiverDelayer) {
table = TB_DELAYERS;
} else if (point instanceof WirelessReceiverSwitch) {
table = TB_SWITCH;
} else if (point instanceof WirelessReceiverClock) {
table = TB_CLOCKS;
} else {
table = TB_RECEIVERS;
}
} else {
WirelessRedstone.getWRLogger().debug("Can't find wirelesspoint in database. Couldn't find what type the wirelesspoint is.");
WirelessRedstone.getWRLogger().debug(point.toString());
return false;
}
ResultSet resultSet = getDatabase().query(table,
"[x]=" + point.getX() + " AND [y]=" + point.getY() + " AND [z]=" + point.getZ() + " AND [world]='" + point.getWorld() + "'",
null, null);
while (resultSet.next() && !exists) {
exists = true;
}
resultSet.close();
return exists;
}
private void performUpdate1(SQLiteDatabase db) throws SQLException, IOException {
Collection<WirelessChannel> channels = new ArrayList<>();
Collection<String> channelNames = new ArrayList<>();
int channelIteration = 0;
int progress = 0;
ResultSet resultSet = db.rawQuery("SELECT [name] FROM [sqlite_master] WHERE [type] = 'table'");
while (resultSet.next()) {
WirelessRedstone.getWRLogger().debug("Found channel: " + resultSet.getString(1));
channelNames.add(resultSet.getString(1));
}
resultSet.close();
for (String channelName : channelNames) {
if ((int) Math.floor((float) channelIteration / (float) channelNames.size() * 100) % 5 == 0
&& (int) Math.floor((float) channelIteration / (float) channelNames.size() * 100) != progress) {
progress = (int) Math.floor((float) channelIteration / (float) channelNames.size() * 100);
WirelessRedstone.getWRLogger().info("Database upgrade stage 1/2; Progress: " + progress + "%");
}
WirelessChannel channel = null;
int channelInfoIteration = 0;
resultSet = db.query(channelName, null, null, null);
while (resultSet.next()) {
if (channelInfoIteration == 0) {
if (resultSet.getString("name") != null) {
WirelessRedstone.getWRLogger().debug("---------------");
WirelessRedstone.getWRLogger().debug("Created channel: " + resultSet.getString("name") + " | " +
Collections.singletonList(resultSet.getString("owners")) + " | " +
resultSet.getBoolean("locked")
);
channel = new WirelessChannel(
resultSet.getString("name"),
Collections.singletonList(resultSet.getString("owners")),
resultSet.getBoolean("locked")
);
}
}
if (channelInfoIteration > 0 && channel == null) {
continue;
}
WirelessRedstone.getWRLogger().debug("---------------");
if (channelInfoIteration > 0) {
if (resultSet.getString("signType") != null) {
String signTypeSerialized = resultSet.getString("signType");
SignType signType = getSignType(signTypeSerialized);
WirelessRedstone.getWRLogger().debug("SignType " + signType);
if (signType == null) {
continue;
}
switch (signType) {
case TRANSMITTER:
WirelessPoint point = new WirelessTransmitter(
resultSet.getInt("x"),
resultSet.getInt("y"),
resultSet.getInt("z"),
resultSet.getString("world"),
resultSet.getInt("isWallSign") != 0,
getBlockFaceOldDatabase(resultSet),
resultSet.getString("signOwner")
);
channel.addWirelessPoint(point);
WirelessRedstone.getWRLogger().debug(point.toString());
break;
case RECEIVER:
point = new WirelessReceiver(
resultSet.getInt("x"),
resultSet.getInt("y"),
resultSet.getInt("z"),
resultSet.getString("world"),
resultSet.getInt("isWallSign") != 0,
getBlockFaceOldDatabase(resultSet),
resultSet.getString("signOwner")
);
channel.addWirelessPoint(point);
WirelessRedstone.getWRLogger().debug(point.toString());
break;
case SCREEN:
point = new WirelessScreen(
resultSet.getInt("x"),
resultSet.getInt("y"),
resultSet.getInt("z"),
resultSet.getString("world"),
resultSet.getInt("isWallSign") != 0,
getBlockFaceOldDatabase(resultSet),
resultSet.getString("signOwner")
);
channel.addWirelessPoint(point);
WirelessRedstone.getWRLogger().debug(point.toString());
break;
case RECEIVER_INVERTER:
point = new WirelessReceiverInverter(
resultSet.getInt("x"),
resultSet.getInt("y"),
resultSet.getInt("z"),
resultSet.getString("world"),
resultSet.getInt("isWallSign") != 0,
getBlockFaceOldDatabase(resultSet),
resultSet.getString("signOwner")
);
channel.addWirelessPoint(point);
WirelessRedstone.getWRLogger().debug(point.toString());
break;
case RECEIVER_DELAYER:
int delay;
try {
delay = Integer.parseInt(signTypeSerialized.split("_")[2]);
} catch (NumberFormatException e) {
continue;
}
point = new WirelessReceiverDelayer(
resultSet.getInt("x"),
resultSet.getInt("y"),
resultSet.getInt("z"),
resultSet.getString("world"),
resultSet.getInt("isWallSign") != 0,
getBlockFaceOldDatabase(resultSet),
resultSet.getString("signOwner"),
delay
);
channel.addWirelessPoint(point);
WirelessRedstone.getWRLogger().debug(point.toString());
break;
case RECEIVER_SWITCH:
boolean state;
state = Boolean.parseBoolean(signTypeSerialized.split("_")[2]);
point = new WirelessReceiverSwitch(
resultSet.getInt("x"),
resultSet.getInt("y"),
resultSet.getInt("z"),
resultSet.getString("world"),
resultSet.getInt("isWallSign") != 0,
getBlockFaceOldDatabase(resultSet),
resultSet.getString("signOwner"),
state
);
channel.addWirelessPoint(point);
WirelessRedstone.getWRLogger().debug(point.toString());
break;
case RECEIVER_CLOCK:
try {
delay = Integer.parseInt(signTypeSerialized.split("_")[2]);
} catch (NumberFormatException e) {
continue;
}
point = new WirelessReceiverClock(
resultSet.getInt("x"),
resultSet.getInt("y"),
resultSet.getInt("z"),
resultSet.getString("world"),
resultSet.getInt("isWallSign") != 0,
getBlockFaceOldDatabase(resultSet),
resultSet.getString("signOwner"),
delay
);
channel.addWirelessPoint(point);
WirelessRedstone.getWRLogger().debug(point.toString());
break;
}
}
}
channelInfoIteration++;
}
resultSet.close();
channels.add(channel);
channelIteration++;
db.execSql("DROP TABLE IF EXISTS [" + channelName + "];");
}
WirelessRedstone.getWRLogger().debug("---------------");
onCreate(db);
progress = 0;
channelIteration = 0;
for (WirelessChannel channel : channels) {
if ((int) Math.floor((float) channelIteration / (float) channels.size() * 100) % 5 == 0
&& (int) Math.floor((float) channelIteration / (float) channels.size() * 100) != progress) {
progress = (int) Math.floor((float) channelIteration / (float) channels.size() * 100);
WirelessRedstone.getWRLogger().info("Database upgrade stage 2/2; Progress: " + progress + "%");
}
ContentValues values = new ContentValues();
values.put("name", channel.getName());
values.put("locked", channel.isLocked());
db.insert(TB_CHANNELS, values);
WirelessRedstone.getWRLogger().debug("Inserted channel " + channel.getName());
for (String owner : channel.getOwners()) {
values = new ContentValues();
values.put("channel_name", channel.getName());
values.put("user", owner);
db.insert(TB_OWNERS, values);
WirelessRedstone.getWRLogger().debug("Inserted owner " + owner + "|" + channel.getName());
}
for (WirelessTransmitter point : channel.getTransmitters()) {
values = new ContentValues();
values.put("x", point.getX());
values.put("y", point.getY());
values.put("z", point.getZ());
values.put("world", point.getWorld());
values.put("channel_name", channel.getName());
values.put("direction", point.getDirection().toString());
values.put("owner", point.getOwner());
values.put("is_wallsign", point.isWallSign());
db.insert(TB_TRANSMITTERS, values);
WirelessRedstone.getWRLogger().debug("Inserted transmitter " + point.toString() + "|" + channel.getName());
}
for (WirelessScreen point : channel.getScreens()) {
values = new ContentValues();
values.put("x", point.getX());
values.put("y", point.getY());
values.put("z", point.getZ());
values.put("world", point.getWorld());
values.put("channel_name", channel.getName());
values.put("direction", point.getDirection().toString());
values.put("owner", point.getOwner());
values.put("is_wallsign", point.isWallSign());
db.insert(TB_SCREENS, values);
WirelessRedstone.getWRLogger().debug("Inserted screen " + point.toString() + "|" + channel.getName());
}
for (WirelessReceiver point : channel.getReceivers()) {
if (point instanceof WirelessReceiverInverter) {
values = new ContentValues();
values.put("x", point.getX());
values.put("y", point.getY());
values.put("z", point.getZ());
values.put("world", point.getWorld());
values.put("channel_name", channel.getName());
values.put("direction", point.getDirection().toString());
values.put("owner", point.getOwner());
values.put("is_wallsign", point.isWallSign());
db.insert(TB_INVERTERS, values);
WirelessRedstone.getWRLogger().debug("Inserted inverter " + point.toString() + "|" + channel.getName());
} else if (point instanceof WirelessReceiverDelayer) {
values = new ContentValues();
values.put("x", point.getX());
values.put("y", point.getY());
values.put("z", point.getZ());
values.put("world", point.getWorld());
values.put("channel_name", channel.getName());
values.put("direction", point.getDirection().toString());
values.put("owner", point.getOwner());
values.put("is_wallsign", point.isWallSign());
values.put("delay", ((WirelessReceiverDelayer) point).getDelay());
db.insert(TB_DELAYERS, values);
WirelessRedstone.getWRLogger().debug("Inserted delayer " + point.toString() + "|" + channel.getName());
} else if (point instanceof WirelessReceiverSwitch) {
values = new ContentValues();
values.put("x", point.getX());
values.put("y", point.getY());
values.put("z", point.getZ());
values.put("world", point.getWorld());
values.put("channel_name", channel.getName());
values.put("direction", point.getDirection().toString());
values.put("owner", point.getOwner());
values.put("is_wallsign", point.isWallSign());
values.put("powered", ((WirelessReceiverSwitch) point).isActive());
db.insert(TB_SWITCH, values);
WirelessRedstone.getWRLogger().debug("Inserted switch " + point.toString() + "|" + channel.getName());
} else if (point instanceof WirelessReceiverClock) {
values = new ContentValues();
values.put("x", point.getX());
values.put("y", point.getY());
values.put("z", point.getZ());
values.put("world", point.getWorld());
values.put("channel_name", channel.getName());
values.put("direction", point.getDirection().toString());
values.put("owner", point.getOwner());
values.put("is_wallsign", point.isWallSign());
values.put("delay", ((WirelessReceiverClock) point).getDelay());
db.insert(TB_CLOCKS, values);
WirelessRedstone.getWRLogger().debug("Inserted clock " + point.toString() + "|" + channel.getName());
} else {
values = new ContentValues();
values.put("x", point.getX());
values.put("y", point.getY());
values.put("z", point.getZ());
values.put("world", point.getWorld());
values.put("channel_name", channel.getName());
values.put("direction", point.getDirection().toString());
values.put("owner", point.getOwner());
values.put("is_wallsign", point.isWallSign());
db.insert(TB_RECEIVERS, values);
WirelessRedstone.getWRLogger().debug("Inserted receiver " + point.toString() + "|" + channel.getName());
}
}
channelIteration++;
}
}
private SignType getSignType(String signTypeSerialized) {
if (signTypeSerialized.equalsIgnoreCase("transmitter")) {
return SignType.TRANSMITTER;
} else if (signTypeSerialized.equalsIgnoreCase("receiver")) {
return SignType.RECEIVER;
} else if (signTypeSerialized.equalsIgnoreCase("screen")) {
return SignType.SCREEN;
} else if (signTypeSerialized.contains("receiver")) {
String[] receiver = signTypeSerialized.split("_");
if (receiver[1].equalsIgnoreCase("inverter")) {
return SignType.RECEIVER_INVERTER;
} else if (receiver[1].equalsIgnoreCase("delayer")) {
return SignType.RECEIVER_DELAYER;
} else if (receiver[1].equalsIgnoreCase("switch")) {
return SignType.RECEIVER_SWITCH;
} else if (receiver[1].equalsIgnoreCase("clock")) {
return SignType.RECEIVER_CLOCK;
}
}
return null;
}
private BlockFace getBlockFaceOldDatabase(ResultSet resultSet) throws SQLException {
Object directionObject = resultSet.getObject("direction");
if (directionObject instanceof Integer) {
return Utils.getBlockFace(false, (int) directionObject);
} else if (directionObject instanceof String) {
return BlockFace.valueOf(directionObject.toString().toUpperCase());
} else {
throw new IllegalArgumentException("Direction (" + directionObject + ") row inside database isn't parsable.");
}
}
private String escape(String str) {
if (str == null || str.length() == 0) {
throw new IllegalArgumentException();
}
str = str.replace("\\", "\\\\");
str = str.replace("'", "\\'");
str = str.replace("\0", "\\0");
str = str.replace("\n", "\\n");
str = str.replace("\r", "\\r");
str = str.replace("\"", "\\\"");
str = str.replace("\\x1a", "\\Z");
return str;
}
}

View File

@@ -0,0 +1,113 @@
package net.licks92.wirelessredstone.storage;
import net.licks92.wirelessredstone.signs.WirelessChannel;
import net.licks92.wirelessredstone.signs.WirelessPoint;
import net.licks92.wirelessredstone.signs.WirelessReceiver;
import net.licks92.wirelessredstone.signs.WirelessReceiverSwitch;
import net.licks92.wirelessredstone.WirelessRedstone;
import java.io.File;
import java.util.Collection;
import java.util.Objects;
public class SQLiteStorage extends StorageConfiguration {
private final File channelFolder;
public SQLiteStorage(String channelFolder) {
this.channelFolder = new File(WirelessRedstone.getInstance().getDataFolder(), channelFolder);
}
@Override
public boolean initStorage() {
try {
DatabaseClient.init(channelFolder.toString());
WirelessRedstone.getStorageManager().updateChannels(false);
StorageType oldStorageType = canConvertFromType();
if (oldStorageType != null) {
return WirelessRedstone.getStorageManager().moveStorageFromType(oldStorageType);
}
return true;
} catch (RuntimeException ex) {
WirelessRedstone.getWRLogger().severe("There was an error accessing the database!");
ex.printStackTrace();
return false;
}
}
@Override
public boolean close() {
DatabaseClient.getInstance().getDatabase().close();
return true;
}
@Override
protected Collection<WirelessChannel> getAllChannels() {
return DatabaseClient.getInstance().getAllChannels();
}
@Override
public boolean createChannel(WirelessChannel channel) {
channel.getSigns()
.forEach(wirelessPoint -> DatabaseClient.getInstance().insertWirelessPoint(channel, wirelessPoint));
return super.createChannel(channel);
}
@Override
public boolean createWirelessPoint(String channelName, WirelessPoint wirelessPoint) {
WirelessChannel channel = WirelessRedstone.getStorageManager().getChannel(channelName);
channel.addWirelessPoint(wirelessPoint);
DatabaseClient.getInstance().insertWirelessPoint(channel, wirelessPoint);
return super.createWirelessPoint(channelName, wirelessPoint);
}
@Override
public boolean removeWirelessPoint(String channelName, WirelessPoint wirelessPoint) {
WirelessChannel channel = WirelessRedstone.getStorageManager().getChannel(channelName);
channel.removeWirelessPoint(wirelessPoint);
return super.removeWirelessPoint(channelName, wirelessPoint);
}
@Override
public boolean updateChannel(String channelName, WirelessChannel channel) {
return super.updateChannel(channelName, channel);
}
@Override
public boolean removeChannel(String channelName, boolean removeSigns) {
return super.removeChannel(channelName, removeSigns);
}
@Override
public boolean wipeData() {
DatabaseClient.getInstance().recreateDatabase();
return super.wipeData();
}
@Override
protected StorageType canConvertFromType() {
for (File file : Objects.requireNonNull(channelFolder.listFiles())) {
if (file.getName().contains(".yml")) {
return StorageType.YAML;
}
}
return null;
}
@Override
public void updateSwitchState(WirelessChannel channel) {
for (WirelessReceiver receiver : channel.getReceivers()) {
if (receiver instanceof WirelessReceiverSwitch) {
DatabaseClient.getInstance().updateSwitch((WirelessReceiverSwitch) receiver);
}
}
}
}

View File

@@ -0,0 +1,164 @@
package net.licks92.wirelessredstone.storage;
import net.licks92.wirelessredstone.WirelessRedstone;
import net.licks92.wirelessredstone.signs.WirelessChannel;
import net.licks92.wirelessredstone.signs.WirelessPoint;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public abstract class StorageConfiguration {
public abstract boolean initStorage();
public abstract boolean close();
protected abstract Collection<WirelessChannel> getAllChannels();
public abstract void updateSwitchState(WirelessChannel channel);
protected abstract StorageType canConvertFromType();
public boolean createChannel(WirelessChannel channel) {
WirelessRedstone.getStorageManager().updateList(channel.getName(), channel);
return true;
}
public boolean createWirelessPoint(String channelName, WirelessPoint wirelessPoint) {
WirelessChannel channel = WirelessRedstone.getStorageManager().getChannel(channelName);
//TODO: Investigate if this duplicates the wirelesspoint into the channel
channel.addWirelessPoint(wirelessPoint);
WirelessRedstone.getStorageManager().updateList(channelName, channel);
return true;
}
public boolean removeWirelessPoint(String channelName, WirelessPoint wirelessPoint) {
WirelessChannel channel = WirelessRedstone.getStorageManager().getChannel(channelName);
//TODO: Investigate if this duplicates the wirelesspoint into the channel
channel.removeWirelessPoint(wirelessPoint);
if (channel.isEmpty()) {
WirelessRedstone.getStorage().removeChannel(channelName, false);
} else {
WirelessRedstone.getStorageManager().updateList(channelName, channel);
}
return true;
}
public boolean updateChannel(String channelName, WirelessChannel channel) {
WirelessRedstone.getStorageManager().updateList(channel.getName(), channel);
return true;
}
public boolean removeChannel(String channelName, boolean removeSigns) {
if (removeSigns) {
WirelessChannel channel = WirelessRedstone.getStorageManager().getChannel(channelName);
for (WirelessPoint point : channel.getSigns()) {
World world = Bukkit.getWorld(point.getWorld());
if (world == null)
continue;
Location loc = new Location(world, point.getX(), point.getY(), point.getZ());
loc.getBlock().setType(Material.AIR);
}
}
WirelessRedstone.getStorageManager().updateList(channelName, null);
return true;
}
public int purgeData() {
int response = 0;
for (Map.Entry<WirelessChannel, Collection<WirelessPoint>> entry : WirelessRedstone.getSignManager().getAllInvalidPoints().entrySet()) {
for (WirelessPoint point : entry.getValue()) {
if (!WirelessRedstone.getStorage().removeWirelessPoint(entry.getKey().getName(), point)) {
response = -1;
break;
}
WirelessRedstone.getWRLogger().debug("Purged WirelessPoint " + point.getLocation().toString() + " because the location is invalid.");
response++;
}
}
List<WirelessChannel> emptyChannels = new ArrayList<>();
for (WirelessChannel channel : WirelessRedstone.getStorageManager().getChannels()) {
if (channel.isEmpty()) {
emptyChannels.add(channel);
}
}
for (WirelessChannel channel : emptyChannels) {
WirelessRedstone.getStorage().removeChannel(channel.getName(), false);
response++;
}
return response;
}
public boolean backupData() {
byte[] buffer = new byte[1024];
if (!(new File(WirelessRedstone.getInstance().getDataFolder(), WirelessRedstone.CHANNEL_FOLDER).exists())) {
return false;
}
try {
String zipName = "WRBackup "
+ Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + "-"
+ Calendar.getInstance().get(Calendar.MONTH) + "-"
+ Calendar.getInstance().get(Calendar.YEAR) + "_"
+ Calendar.getInstance().get(Calendar.HOUR_OF_DAY) + "."
+ Calendar.getInstance().get(Calendar.MINUTE) + "."
+ Calendar.getInstance().get(Calendar.SECOND);
FileOutputStream fos = new FileOutputStream(WirelessRedstone.getInstance().getDataFolder() + File.separator + zipName + ".zip");
ZipOutputStream zos = new ZipOutputStream(fos);
for (File file : (new File(WirelessRedstone.getInstance().getDataFolder(), WirelessRedstone.CHANNEL_FOLDER)).listFiles()) {
ZipEntry ze = new ZipEntry(file.getName());
zos.putNextEntry(ze);
FileInputStream in = new FileInputStream(file);
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
in.close();
}
zos.closeEntry();
zos.close();
} catch (IOException ex) {
ex.printStackTrace();
return false;
}
return true;
}
public boolean wipeData() {
WirelessRedstone.getStorageManager().wipeList();
return true;
}
}

View File

@@ -0,0 +1,150 @@
package net.licks92.wirelessredstone.storage;
import net.licks92.wirelessredstone.ConfigManager;
import net.licks92.wirelessredstone.signs.WirelessChannel;
import net.licks92.wirelessredstone.signs.WirelessPoint;
import net.licks92.wirelessredstone.WirelessRedstone;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitTask;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
public class StorageManager {
private final ConcurrentHashMap<String, WirelessChannel> allChannels = new ConcurrentHashMap<>();
private final BukkitTask refreshingTask;
private final StorageType storageType;
private final StorageConfiguration storage;
private final String channelFolder;
private final File channelFolderFile;
public StorageManager(StorageType type, String channelFolder) {
this.storageType = type;
this.channelFolder = channelFolder;
this.channelFolderFile = new File(WirelessRedstone.getInstance().getDataFolder(), channelFolder);
this.channelFolderFile.mkdir();
switch (type) {
case SQLITE:
storage = new SQLiteStorage(channelFolder);
break;
case YAML:
storage = new YamlStorage(channelFolder);
break;
default:
storage = new YamlStorage(channelFolder);
break;
}
int refreshRate = ConfigManager.getConfig().getCacheRefreshRate();
if (refreshRate < 60) {
refreshRate = 60;
ConfigManager.getConfig().setValue(ConfigManager.ConfigPaths.CACHEREFRESHRATE, 60);
}
if (refreshRate > 480) {
refreshRate = 480;
ConfigManager.getConfig().setValue(ConfigManager.ConfigPaths.CACHEREFRESHRATE, 480);
}
int timeInTicks = refreshRate * 20;
refreshingTask = Bukkit.getScheduler().runTaskTimerAsynchronously(WirelessRedstone.getInstance(), new Runnable() {
@Override
public void run() {
//TODO: Check if this is necessary
// updateList();
}
}, timeInTicks, timeInTicks);
}
public void updateChannels(boolean async) {
if (async) {
Bukkit.getServer().getScheduler().runTaskAsynchronously(WirelessRedstone.getInstance(), this::updateList);
} else {
updateList();
}
}
protected void updateList() {
allChannels.clear();
Collection<WirelessChannel> channels = getStorage().getAllChannels();
channels.forEach(channel -> allChannels.put(channel.getName(), channel));
}
protected void updateList(String channelName, WirelessChannel channel) {
if (channel == null) {
allChannels.remove(channelName);
} else {
allChannels.put(channelName, channel);
}
}
protected void wipeList() {
allChannels.clear();
}
public StorageConfiguration getStorage() {
return storage;
}
public Collection<WirelessChannel> getChannels() {
return allChannels.values();
}
public WirelessChannel getChannel(String channelName) {
return allChannels.get(channelName);
}
public Collection<WirelessPoint> getAllSigns() {
List<WirelessPoint> collection = new ArrayList<>();
getChannels().stream()
.map(WirelessChannel::getSigns)
.forEach(collection::addAll);
return collection;
}
protected boolean moveStorageFromType(StorageType storageType) {
if (!getStorage().backupData()) {
WirelessRedstone.getWRLogger().severe("Porting data to other storage type failed due to a backup problem!");
return false;
}
StorageConfiguration storage;
if (storageType == StorageType.YAML) {
storage = new YamlStorage(channelFolder);
} else if (storageType == StorageType.SQLITE) {
storage = new SQLiteStorage(channelFolder);
DatabaseClient.init(new File(WirelessRedstone.getInstance().getDataFolder(), channelFolder).toString());
} else {
return false;
}
Collection<WirelessChannel> channels = storage.getAllChannels();
channels.forEach(getStorage()::createChannel);
storage.close();
if (storageType == StorageType.YAML) {
final FilenameFilter filter = (dir, name) -> name.toLowerCase().endsWith(".yml");
Arrays.stream(Objects.requireNonNull(channelFolderFile.listFiles(filter)))
.forEach(File::delete);
} else {
final FilenameFilter filter = (dir, name) -> name.toLowerCase().endsWith(".db");
Arrays.stream(Objects.requireNonNull(channelFolderFile.listFiles(filter)))
.forEach(File::delete);
}
WirelessRedstone.getStorageManager().updateChannels(false);
return true;
}
}

View File

@@ -0,0 +1,5 @@
package net.licks92.wirelessredstone.storage;
public enum StorageType {
SQLITE, YAML
}

View File

@@ -0,0 +1,208 @@
package net.licks92.wirelessredstone.storage;
import net.licks92.wirelessredstone.signs.WirelessChannel;
import net.licks92.wirelessredstone.signs.WirelessPoint;
import net.licks92.wirelessredstone.signs.WirelessReceiver;
import net.licks92.wirelessredstone.signs.WirelessReceiverClock;
import net.licks92.wirelessredstone.signs.WirelessReceiverDelayer;
import net.licks92.wirelessredstone.signs.WirelessReceiverInverter;
import net.licks92.wirelessredstone.signs.WirelessReceiverSwitch;
import net.licks92.wirelessredstone.signs.WirelessScreen;
import net.licks92.wirelessredstone.signs.WirelessTransmitter;
import net.licks92.wirelessredstone.WirelessRedstone;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;
@SuppressWarnings("ResultOfMethodCallIgnored")
public class YamlStorage extends StorageConfiguration {
private final File channelFolder;
private final FilenameFilter yamlFilter = (dir, name) -> name.toLowerCase().endsWith(".yml");
public YamlStorage(String channelFolder) {
this.channelFolder = new File(WirelessRedstone.getInstance().getDataFolder(), channelFolder);
//Initialize the serialization
ConfigurationSerialization.registerClass(WirelessChannel.class, "WirelessChannel");
ConfigurationSerialization.registerClass(WirelessTransmitter.class, "WirelessTransmitter");
ConfigurationSerialization.registerClass(WirelessScreen.class, "WirelessScreen");
ConfigurationSerialization.registerClass(WirelessReceiver.class, "WirelessReceiver");
ConfigurationSerialization.registerClass(WirelessReceiverInverter.class, "WirelessReceiverInverter");
ConfigurationSerialization.registerClass(WirelessReceiverDelayer.class, "WirelessReceiverDelayer");
ConfigurationSerialization.registerClass(WirelessReceiverClock.class, "WirelessReceiverClock");
ConfigurationSerialization.registerClass(WirelessReceiverSwitch.class, "WirelessReceiverSwitch");
}
@Override
public boolean initStorage() {
//TODO: Initstorage
WirelessRedstone.getStorageManager().updateChannels(false);
StorageType oldStorageType = canConvertFromType();
if (oldStorageType != null) {
return WirelessRedstone.getStorageManager().moveStorageFromType(oldStorageType);
}
return true;
}
@Override
public boolean close() {
//TODO: See if there is a better way to save active state
for (WirelessChannel channel : WirelessRedstone.getStorageManager().getChannels()) {
setChannel(channel.getName(), channel);
}
return true;
}
@Override
protected Collection<WirelessChannel> getAllChannels() {
Collection<WirelessChannel> channels = new ArrayList<>();
for (File f : Objects.requireNonNull(channelFolder.listFiles(yamlFilter))) {
FileConfiguration channelConfig = new YamlConfiguration();
try {
channelConfig.load(f);
} catch (InvalidConfigurationException | IOException ex) {
ex.printStackTrace();
}
String channelName;
try {
channelName = f.getName().split(".yml")[0];
} catch (ArrayIndexOutOfBoundsException ex) {
continue;
}
Object channel = channelConfig.get(channelName);
if (channel instanceof WirelessChannel) {
channels.add((WirelessChannel) channel);
WirelessRedstone.getWRLogger().debug("Found channel: " + ((WirelessChannel) channel).getName());
} else if (channel == null) {
WirelessRedstone.getWRLogger().debug("File " + f.getName() + " does not contain a Wireless Channel. Removing it.");
f.delete();
} else
WirelessRedstone.getWRLogger().warning("Channel " + channel + " is not of type WirelessChannel.");
}
return channels;
}
@Override
public boolean createChannel(WirelessChannel channel) {
if (!setChannel(channel.getName(), channel))
return false;
return super.createChannel(channel);
}
@Override
public boolean createWirelessPoint(String channelName, WirelessPoint wirelessPoint) {
WirelessChannel channel = WirelessRedstone.getStorageManager().getChannel(channelName);
channel.addWirelessPoint(wirelessPoint);
if (!setChannel(channelName, channel))
return false;
return super.createWirelessPoint(channelName, wirelessPoint);
}
@Override
public boolean removeWirelessPoint(String channelName, WirelessPoint wirelessPoint) {
WirelessChannel channel = WirelessRedstone.getStorageManager().getChannel(channelName);
channel.removeWirelessPoint(wirelessPoint);
if (!setChannel(channelName, channel))
return false;
return super.removeWirelessPoint(channelName, wirelessPoint);
}
@Override
public boolean updateChannel(String channelName, WirelessChannel channel) {
if (!setChannel(channelName, channel))
return false;
return super.updateChannel(channelName, channel);
}
@Override
public boolean removeChannel(String channelName, boolean removeSigns) {
File file = new File(channelFolder, channelName + ".yml");
if (file.exists())
file.delete();
return super.removeChannel(channelName, removeSigns);
}
@Override
public boolean wipeData() {
for (File f : Objects.requireNonNull(channelFolder.listFiles(yamlFilter))) {
f.delete();
}
return super.wipeData();
}
@Override
public void updateSwitchState(WirelessChannel channel) {
for (WirelessReceiver receiver : channel.getReceivers()) {
if (receiver instanceof WirelessReceiverSwitch) {
setChannel(channel.getName(), channel);
break;
}
}
}
@Override
protected StorageType canConvertFromType() {
for (File file : Objects.requireNonNull(channelFolder.listFiles())) {
if (file.getName().contains(".db")) {
return StorageType.SQLITE;
}
}
return null;
}
private boolean setChannel(String channelName, WirelessChannel channel) {
FileConfiguration channelConfig = new YamlConfiguration();
try {
File channelFile = new File(channelFolder, channelName + ".yml");
if (channel != null)
channelFile.createNewFile();
channelConfig.load(channelFile);
} catch (FileNotFoundException e) {
return false;
} catch (IOException | InvalidConfigurationException ex) {
ex.printStackTrace();
}
channelConfig.set(channelName, channel);
try {
channelConfig.save(new File(channelFolder, channelName + ".yml"));
} catch (IOException ex) {
ex.printStackTrace();
return false;
}
return true;
}
}