Patch proxy server detection

- Added a field is_proxy to plan_servers
  - Patch to populate the new field
  - Field is set to true when proxy enables to fix any broken data
  - Allows any name for a proxy
- Updated server save queries
- Changed isProxy method in Server.java to match the change
- Changed query for fetching the proxy server

Affects issues:
- Close #1678
This commit is contained in:
Risto Lahtela 2021-01-01 11:26:07 +02:00
parent 7f8fd7d235
commit 9b692480da
11 changed files with 123 additions and 24 deletions

View File

@ -67,6 +67,8 @@ public class BungeeServerInfo extends ServerInfo {
this.server = fromFile.load(null).orElseGet(() -> fromDatabase.load(null) this.server = fromFile.load(null).orElseGet(() -> fromDatabase.load(null)
.orElseGet(this::registerServer)); .orElseGet(this::registerServer));
this.server.setProxy(true); // Ensure isProxy if loaded from file
processing.submitNonCritical(this::updateStorage); processing.submitNonCritical(this::updateStorage);
} }
@ -112,6 +114,6 @@ public class BungeeServerInfo extends ServerInfo {
private Server createServerObject() { private Server createServerObject() {
UUID serverUUID = generateNewUUID(); UUID serverUUID = generateNewUUID();
String accessAddress = addresses.getAccessAddress().orElseThrow(() -> new EnableException("Velocity can not have '0.0.0.0' or '' as an address. Set up 'Server.IP' setting.")); String accessAddress = addresses.getAccessAddress().orElseThrow(() -> new EnableException("Velocity can not have '0.0.0.0' or '' as an address. Set up 'Server.IP' setting."));
return new Server(-1, serverUUID, "BungeeCord", accessAddress); return new Server(-1, serverUUID, "BungeeCord", accessAddress, true);
} }
} }

View File

@ -30,16 +30,18 @@ public class Server implements Comparable<Server> {
private Integer id; private Integer id;
private String name; private String name;
private String webAddress; private String webAddress;
private boolean proxy;
public Server(UUID uuid, String name, String webAddress) { public Server(UUID uuid, String name, String webAddress) {
this(null, uuid, name, webAddress); this(null, uuid, name, webAddress, false);
} }
public Server(Integer id, UUID uuid, String name, String webAddress) { public Server(Integer id, UUID uuid, String name, String webAddress, boolean proxy) {
this.id = id; this.id = id;
this.uuid = uuid; this.uuid = uuid;
this.name = name; this.name = name;
this.webAddress = webAddress; this.webAddress = webAddress;
this.proxy = proxy;
} }
public Optional<Integer> getId() { public Optional<Integer> getId() {
@ -105,7 +107,11 @@ public class Server implements Comparable<Server> {
} }
public boolean isProxy() { public boolean isProxy() {
return "BungeeCord".equals(name); return proxy;
}
public void setProxy(boolean proxy) {
this.proxy = proxy;
} }
public boolean isNotProxy() { public boolean isNotProxy() {

View File

@ -72,10 +72,10 @@ public class ServerFileLoader extends Config implements ServerLoader {
UUID serverUUID = UUID.fromString(serverUUIDString); UUID serverUUID = UUID.fromString(serverUUIDString);
String name = config.getNode(PluginSettings.SERVER_NAME.getPath()) String name = config.getNode(PluginSettings.SERVER_NAME.getPath())
.map(ConfigNode::getString) .map(ConfigNode::getString)
.orElse("BungeeCord"); .orElse("Proxy");
String address = getString("Server.Web_address"); String address = getString("Server.Web_address");
return Optional.of(new Server(id, serverUUID, name, address)); return Optional.of(new Server(id, serverUUID, name, address, false));
} catch (IOException e) { } catch (IOException e) {
throw new EnableException("Failed to read ServerInfoFile.yml: " + e.getMessage()); throw new EnableException("Failed to read ServerInfoFile.yml: " + e.getMessage());
} }

View File

@ -173,7 +173,8 @@ public abstract class SQLDB extends AbstractDatabase {
new BadNukkitRegisterValuePatch(), new BadNukkitRegisterValuePatch(),
new LinkedToSecurityTablePatch(), new LinkedToSecurityTablePatch(),
new LinkUsersToPlayersSecurityTablePatch(), new LinkUsersToPlayersSecurityTablePatch(),
new LitebansTableHeaderPatch() new LitebansTableHeaderPatch(),
new ServerIsProxyPatch()
}; };
} }

View File

@ -151,19 +151,17 @@ public class LargeStoreQueries {
return new ExecBatchStatement(ServerTable.INSERT_STATEMENT) { return new ExecBatchStatement(ServerTable.INSERT_STATEMENT) {
@Override @Override
public void prepare(PreparedStatement statement) throws SQLException { public void prepare(PreparedStatement statement) throws SQLException {
for (Server info : servers) { for (Server server : servers) {
UUID uuid = info.getUuid(); UUID uuid = server.getUuid();
String name = info.getName();
String webAddress = info.getWebAddress();
if (uuid == null) { if (uuid == null) {
continue; continue;
} }
statement.setString(1, uuid.toString()); statement.setString(1, uuid.toString());
statement.setString(2, name); statement.setString(2, server.getName());
statement.setString(3, webAddress); statement.setString(3, server.getWebAddress());
statement.setBoolean(4, true); statement.setBoolean(4, true);
statement.setBoolean(5, server.isProxy());
statement.addBatch(); statement.addBatch();
} }
} }

View File

@ -65,7 +65,9 @@ public class ServerQueries {
set.getInt(ServerTable.SERVER_ID), set.getInt(ServerTable.SERVER_ID),
serverUUID, serverUUID,
set.getString(ServerTable.NAME), set.getString(ServerTable.NAME),
set.getString(ServerTable.WEB_ADDRESS))); set.getString(ServerTable.WEB_ADDRESS),
set.getBoolean(ServerTable.PROXY)
));
} }
return servers; return servers;
} }
@ -106,7 +108,8 @@ public class ServerQueries {
set.getInt(ServerTable.SERVER_ID), set.getInt(ServerTable.SERVER_ID),
UUID.fromString(set.getString(ServerTable.SERVER_UUID)), UUID.fromString(set.getString(ServerTable.SERVER_UUID)),
set.getString(ServerTable.NAME), set.getString(ServerTable.NAME),
set.getString(ServerTable.WEB_ADDRESS) set.getString(ServerTable.WEB_ADDRESS),
set.getBoolean(ServerTable.PROXY)
)); ));
} }
return Optional.empty(); return Optional.empty();
@ -115,7 +118,31 @@ public class ServerQueries {
} }
public static Query<Optional<Server>> fetchProxyServerInformation() { public static Query<Optional<Server>> fetchProxyServerInformation() {
return db -> db.query(fetchServerMatchingIdentifier("BungeeCord")); String sql = SELECT + '*' + FROM + ServerTable.TABLE_NAME +
WHERE + ServerTable.INSTALLED + "=?" +
AND + ServerTable.PROXY + "=?" +
" LIMIT 1";
return new QueryStatement<Optional<Server>>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setBoolean(1, true);
statement.setBoolean(2, true);
}
@Override
public Optional<Server> processResults(ResultSet set) throws SQLException {
if (set.next()) {
return Optional.of(new Server(
set.getInt(ServerTable.SERVER_ID),
UUID.fromString(set.getString(ServerTable.SERVER_UUID)),
set.getString(ServerTable.NAME),
set.getString(ServerTable.WEB_ADDRESS),
set.getBoolean(ServerTable.PROXY)
));
}
return Optional.empty();
}
};
} }
public static Query<Map<UUID, String>> fetchServerNames() { public static Query<Map<UUID, String>> fetchServerNames() {
@ -165,7 +192,8 @@ public class ServerQueries {
set.getInt(ServerTable.SERVER_ID), set.getInt(ServerTable.SERVER_ID),
UUID.fromString(set.getString(ServerTable.SERVER_UUID)), UUID.fromString(set.getString(ServerTable.SERVER_UUID)),
set.getString(ServerTable.NAME), set.getString(ServerTable.NAME),
set.getString(ServerTable.WEB_ADDRESS) set.getString(ServerTable.WEB_ADDRESS),
set.getBoolean(ServerTable.PROXY)
)); ));
} }
return matches; return matches;

View File

@ -40,18 +40,20 @@ public class ServerTable {
public static final String NAME = "name"; public static final String NAME = "name";
public static final String WEB_ADDRESS = "web_address"; public static final String WEB_ADDRESS = "web_address";
public static final String INSTALLED = "is_installed"; public static final String INSTALLED = "is_installed";
public static final String PROXY = "is_proxy";
@Deprecated @Deprecated
public static final String MAX_PLAYERS = "max_players"; public static final String MAX_PLAYERS = "max_players";
public static final String INSERT_STATEMENT = Insert.values(TABLE_NAME, public static final String INSERT_STATEMENT = Insert.values(TABLE_NAME,
SERVER_UUID, NAME, SERVER_UUID, NAME,
WEB_ADDRESS, INSTALLED); WEB_ADDRESS, INSTALLED, PROXY);
public static final String UPDATE_STATEMENT = Update.values(TABLE_NAME, public static final String UPDATE_STATEMENT = Update.values(TABLE_NAME,
SERVER_UUID, SERVER_UUID,
NAME, NAME,
WEB_ADDRESS, WEB_ADDRESS,
INSTALLED) INSTALLED,
PROXY)
.where(SERVER_UUID + "=?") .where(SERVER_UUID + "=?")
.toString(); .toString();
@ -71,6 +73,7 @@ public class ServerTable {
.column(NAME, Sql.varchar(100)) .column(NAME, Sql.varchar(100))
.column(WEB_ADDRESS, Sql.varchar(100)) .column(WEB_ADDRESS, Sql.varchar(100))
.column(INSTALLED, Sql.BOOL).notNull().defaultValue(true) .column(INSTALLED, Sql.BOOL).notNull().defaultValue(true)
.column(PROXY, Sql.BOOL).notNull().defaultValue(false)
.column(MAX_PLAYERS, Sql.INT).notNull().defaultValue("-1") .column(MAX_PLAYERS, Sql.INT).notNull().defaultValue("-1")
.toString(); .toString();
} }

View File

@ -25,7 +25,7 @@ import static com.djrapitops.plan.storage.database.sql.tables.ServerTable.INSERT
import static com.djrapitops.plan.storage.database.sql.tables.ServerTable.UPDATE_STATEMENT; import static com.djrapitops.plan.storage.database.sql.tables.ServerTable.UPDATE_STATEMENT;
/** /**
* Transaction for keeping Plan Server serverrmation up to date in the database. * Transaction for keeping Plan Server information up to date in the database.
* *
* @author Rsl1122 * @author Rsl1122
*/ */
@ -53,7 +53,8 @@ public class StoreServerInformationTransaction extends Transaction {
statement.setString(2, server.getName()); statement.setString(2, server.getName());
statement.setString(3, server.getWebAddress()); statement.setString(3, server.getWebAddress());
statement.setBoolean(4, true); statement.setBoolean(4, true);
statement.setString(5, serverUUIDString); statement.setBoolean(5, server.isProxy());
statement.setString(6, serverUUIDString);
} }
}; };
} }
@ -66,6 +67,7 @@ public class StoreServerInformationTransaction extends Transaction {
statement.setString(2, server.getName()); statement.setString(2, server.getName());
statement.setString(3, server.getWebAddress()); statement.setString(3, server.getWebAddress());
statement.setBoolean(4, true); statement.setBoolean(4, true);
statement.setBoolean(5, server.isProxy());
} }
}; };
} }

View File

@ -0,0 +1,56 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.storage.database.transactions.patches;
import com.djrapitops.plan.storage.database.sql.building.Sql;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import static com.djrapitops.plan.storage.database.sql.building.Sql.WHERE;
/**
* Adds a is_proxy field to remove technical debt assuming name field "BungeeCord" being the proxy.
* <p>
* See https://github.com/plan-player-analytics/Plan/issues/1678 for more details
*
* @author Rsl1122
*/
public class ServerIsProxyPatch extends Patch {
@Override
public boolean hasBeenApplied() {
return hasColumn(ServerTable.TABLE_NAME, ServerTable.PROXY);
}
@Override
protected void applyPatch() {
addColumn(ServerTable.TABLE_NAME, ServerTable.PROXY + ' ' + Sql.BOOL + " DEFAULT 0");
String populateFieldSql = "UPDATE " + ServerTable.TABLE_NAME + " SET " + ServerTable.PROXY + "=?" +
WHERE + ServerTable.NAME + "=?";
execute(new ExecStatement(populateFieldSql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setBoolean(1, true);
statement.setString(2, "BungeeCord");
}
});
}
}

View File

@ -57,6 +57,7 @@ public interface ServerQueriesTest extends DatabaseTestPreparer {
UUID bungeeUUID = UUID.randomUUID(); UUID bungeeUUID = UUID.randomUUID();
Server bungeeCord = new Server(bungeeUUID, "BungeeCord", "Random:1234"); Server bungeeCord = new Server(bungeeUUID, "BungeeCord", "Random:1234");
bungeeCord.setProxy(true);
db().executeTransaction(new StoreServerInformationTransaction(bungeeCord)); db().executeTransaction(new StoreServerInformationTransaction(bungeeCord));
forcePersistenceCheck(); forcePersistenceCheck();

View File

@ -66,6 +66,8 @@ public class VelocityServerInfo extends ServerInfo {
this.server = fromFile.load(null).orElseGet(() -> fromDatabase.load(null) this.server = fromFile.load(null).orElseGet(() -> fromDatabase.load(null)
.orElseGet(this::registerServer)); .orElseGet(this::registerServer));
this.server.setProxy(true); // Ensure isProxy if loaded from file
processing.submitNonCritical(this::updateStorage); processing.submitNonCritical(this::updateStorage);
} }
@ -108,7 +110,7 @@ public class VelocityServerInfo extends ServerInfo {
private Server createServerObject() { private Server createServerObject() {
UUID serverUUID = generateNewUUID(); UUID serverUUID = generateNewUUID();
String accessAddress = addresses.getAccessAddress().orElseThrow(() -> new EnableException("Velocity can not have '0.0.0.0' or '' as an address. Set up 'Server.IP' setting.")); String accessAddress = addresses.getAccessAddress().orElseThrow(() -> new EnableException("Velocity can not have '0.0.0.0' or '' as an address. Set up 'Server.IP' setting."));
// TODO Rework to allow Velocity as a name
return new Server(-1, serverUUID, "BungeeCord", accessAddress); return new Server(-1, serverUUID, "Velocity", accessAddress, true);
} }
} }