mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-01-09 01:47:39 +01:00
[Merge] Version 4.9.0 (#1120)
This commit is contained in:
commit
152fe9a803
@ -2,7 +2,7 @@ plugins {
|
||||
id "com.jfrog.bintray" version "1.8.4"
|
||||
}
|
||||
|
||||
ext.apiVersion = '0.0.5'
|
||||
ext.apiVersion = '0.0.6'
|
||||
|
||||
bintray {
|
||||
user = System.getenv('BINTRAY_USER')
|
||||
|
@ -50,7 +50,11 @@ enum Capability {
|
||||
* <p>
|
||||
* When the parameter is set to {@code true} the value from this Provider is shown on a table alongside players.
|
||||
*/
|
||||
DATA_EXTENSION_SHOW_IN_PLAYER_TABLE;
|
||||
DATA_EXTENSION_SHOW_IN_PLAYER_TABLE,
|
||||
/**
|
||||
*
|
||||
*/
|
||||
QUERY_API;
|
||||
|
||||
static Optional<Capability> getByName(String name) {
|
||||
if (name == null) {
|
||||
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.query;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Class that allows performing most commonly wanted queries.
|
||||
* <p>
|
||||
* This exists so that SQL does not necessarily need to be written.
|
||||
* Obtain an instance from {@link QueryService}.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public interface CommonQueries {
|
||||
|
||||
/**
|
||||
* Fetch playtime of a player on a server.
|
||||
* <p>
|
||||
* Returns 0 for any non existing players or servers.
|
||||
*
|
||||
* @param playerUUID UUID of the player.
|
||||
* @param serverUUID UUID of the Plan server.
|
||||
* @param after Data after this Epoch ms should be fetched
|
||||
* @param before Data before this Epoch ms should be fetched
|
||||
* @return Milliseconds the player has played with the defined parameters.
|
||||
*/
|
||||
long fetchPlaytime(UUID playerUUID, UUID serverUUID, long after, long before);
|
||||
|
||||
/**
|
||||
* Fetch last seen Epoch ms for a player on a server.
|
||||
*
|
||||
* @param playerUUID UUID of the player.
|
||||
* @param serverUUID UUID of the Plan server.
|
||||
* @return Epoch ms the player was last seen, 0 if player has not played on server.
|
||||
*/
|
||||
long fetchLastSeen(UUID playerUUID, UUID serverUUID);
|
||||
|
||||
Set<UUID> fetchServerUUIDs();
|
||||
|
||||
Optional<UUID> fetchUUIDOf(String playerName);
|
||||
|
||||
Optional<String> fetchNameOf(UUID playerUUID);
|
||||
|
||||
boolean doesDBHaveTable(String table);
|
||||
|
||||
boolean doesDBHaveTableColumn(String table, String column);
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 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.query;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Service for Query API.
|
||||
* <p>
|
||||
* Requires Capability QUERY_API
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public interface QueryService {
|
||||
|
||||
/**
|
||||
* Obtain instance of QueryService.
|
||||
*
|
||||
* @return QueryService implementation.
|
||||
* @throws NoClassDefFoundError If Plan is not installed and this class can not be found or if older Plan version is installed.
|
||||
* @throws IllegalStateException If Plan is installed, but not enabled.
|
||||
*/
|
||||
static QueryService getInstance() {
|
||||
return Optional.ofNullable(QueryService.QueryServiceHolder.service)
|
||||
.orElseThrow(() -> new IllegalStateException("QueryService has not been initialised yet."));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get what kind of database is in use.
|
||||
*
|
||||
* @return H2, SQLITE or MYSQL
|
||||
* @throws IllegalStateException If database has not been initialized (Plugin failed to enable)
|
||||
*/
|
||||
String getDBType();
|
||||
|
||||
/**
|
||||
* Perform a query against Plan database.
|
||||
* <p>
|
||||
* Blocks thread until query is complete.
|
||||
*
|
||||
* @param sql SQL String to execute, can contain parameterized queries ({@code ?}).
|
||||
* @param performQuery set your parameters to the PreparedStatement and execute the query, return results.
|
||||
* @param <T> Type of results.
|
||||
* @return The object returned by {@code results}.
|
||||
* @throws IllegalStateException If something goes wrong with the query. SQLException might be as cause.
|
||||
*/
|
||||
<T> T query(
|
||||
String sql,
|
||||
ThrowingFunction<PreparedStatement, T> performQuery
|
||||
) throws IllegalStateException;
|
||||
|
||||
/**
|
||||
* Execute SQL against Plan database.
|
||||
* <p>
|
||||
* Does not block thread, SQL is executed in a single transaction to the database.
|
||||
* <p>
|
||||
* Differs from {@link QueryService#query(String, ThrowingFunction)} in that no results are returned.
|
||||
*
|
||||
* @param sql SQL String to execute, can contain parameterized queries ({@code ?}).
|
||||
* @param performStatement set your parameters to the PreparedStatement and execute the statement.
|
||||
* @return A Future that tells when the transaction has completed. Blocks thread if Future#get is called.
|
||||
* @throws IllegalStateException If something goes wrong with the query. SQLException might be as cause.
|
||||
*/
|
||||
Future<?> execute(
|
||||
String sql,
|
||||
ThrowingConsumer<PreparedStatement> performStatement
|
||||
) throws IllegalStateException;
|
||||
|
||||
/**
|
||||
* Used for getting notified about removal of player data.
|
||||
* <p>
|
||||
* SQL for removing this player's data should be executed when this occurs.
|
||||
* <p>
|
||||
* Example usage:
|
||||
* subscribeToPlayerRemoveEvent(playerUUID -> { do stuff })
|
||||
*
|
||||
* @param eventListener Functional interface that is called on the event.
|
||||
*/
|
||||
void subscribeToPlayerRemoveEvent(Consumer<UUID> eventListener);
|
||||
|
||||
/**
|
||||
* Used for getting notified about removal of ALL data.
|
||||
* <p>
|
||||
* SQL for removing all extra tables (and data) should be performed
|
||||
* <p>
|
||||
* Example usage:
|
||||
* subscribeDataClearEvent(() -> { do stuff })
|
||||
*
|
||||
* @param eventListener Functional interface that is called on the event.
|
||||
*/
|
||||
void subscribeDataClearEvent(VoidFunction eventListener);
|
||||
|
||||
/**
|
||||
* Get the UUID of this server.
|
||||
*
|
||||
* @return Optinal of the server UUID, empty if server did not start properly.
|
||||
*/
|
||||
Optional<UUID> getServerUUID();
|
||||
|
||||
/**
|
||||
* Perform some commonly wanted queries.
|
||||
*
|
||||
* @return {@link CommonQueries} implementation.
|
||||
* @throws IllegalStateException If database has not been initialized (Plugin failed to enable)
|
||||
*/
|
||||
CommonQueries getCommonQueries();
|
||||
|
||||
/**
|
||||
* See https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
|
||||
*/
|
||||
@FunctionalInterface
|
||||
interface ThrowingConsumer<T> {
|
||||
void accept(T t) throws SQLException;
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
|
||||
*/
|
||||
@FunctionalInterface
|
||||
interface ThrowingFunction<T, R> {
|
||||
R apply(T t) throws SQLException;
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
|
||||
*/
|
||||
@FunctionalInterface
|
||||
interface VoidFunction {
|
||||
void apply();
|
||||
}
|
||||
|
||||
class QueryServiceHolder {
|
||||
static QueryService service;
|
||||
|
||||
private QueryServiceHolder() {
|
||||
/* Static variable holder */
|
||||
}
|
||||
|
||||
static void set(QueryService service) {
|
||||
QueryService.QueryServiceHolder.service = service;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -12,7 +12,7 @@ allprojects {
|
||||
wrapper.gradleVersion = "5.0"
|
||||
|
||||
group "com.djrapitops"
|
||||
version "4.8.8"
|
||||
version "4.9.0"
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
@ -43,11 +43,11 @@ subprojects {
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
ext.daggerVersion = "2.23.2"
|
||||
ext.daggerCompilerVersion = "2.23.2"
|
||||
ext.daggerVersion = "2.24"
|
||||
ext.daggerCompilerVersion = "2.24"
|
||||
|
||||
ext.abstractPluginFrameworkVersion = "3.4.1"
|
||||
ext.planPluginBridgeVersion = "4.8.8-R0.2"
|
||||
ext.planPluginBridgeVersion = "4.9.0-R0.3"
|
||||
|
||||
ext.bukkitVersion = "1.12.2-R0.1-SNAPSHOT"
|
||||
ext.spigotVersion = "1.12.2-R0.1-SNAPSHOT"
|
||||
|
@ -30,6 +30,7 @@ shadowJar {
|
||||
exclude "**/*.woff2"
|
||||
exclude "**/*.psd"
|
||||
|
||||
exclude "**/module-info.class"
|
||||
exclude 'META-INF/versions/' // Causes Sponge to crash
|
||||
|
||||
relocate('org.apache', 'plan.org.apache') {
|
||||
|
@ -16,11 +16,13 @@
|
||||
*/
|
||||
package com.djrapitops.plan.command.commands.manage;
|
||||
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.db.DBType;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.transactions.commands.RemoveEverythingTransaction;
|
||||
import com.djrapitops.plan.query.QueryServiceImplementation;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.system.locale.Locale;
|
||||
import com.djrapitops.plan.system.locale.lang.CmdHelpLang;
|
||||
@ -49,23 +51,29 @@ import java.util.concurrent.ExecutionException;
|
||||
@Singleton
|
||||
public class ManageClearCommand extends CommandNode {
|
||||
|
||||
private final PlanPlugin plugin;
|
||||
private final Locale locale;
|
||||
private final Processing processing;
|
||||
private final DBSystem dbSystem;
|
||||
private final QueryServiceImplementation queryService;
|
||||
private final ErrorHandler errorHandler;
|
||||
|
||||
@Inject
|
||||
public ManageClearCommand(
|
||||
PlanPlugin plugin,
|
||||
Locale locale,
|
||||
Processing processing,
|
||||
DBSystem dbSystem,
|
||||
QueryServiceImplementation queryService,
|
||||
ErrorHandler errorHandler
|
||||
) {
|
||||
super("clear", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS);
|
||||
this.plugin = plugin;
|
||||
|
||||
this.locale = locale;
|
||||
this.processing = processing;
|
||||
this.dbSystem = dbSystem;
|
||||
this.queryService = queryService;
|
||||
this.errorHandler = errorHandler;
|
||||
|
||||
setArguments("<DB>", "[-a]");
|
||||
@ -104,7 +112,9 @@ public class ManageClearCommand extends CommandNode {
|
||||
sender.sendMessage(locale.getString(ManageLang.PROGRESS_START));
|
||||
database.executeTransaction(new RemoveEverythingTransaction())
|
||||
.get(); // Wait for completion
|
||||
queryService.dataCleared();
|
||||
sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS));
|
||||
reloadPlugin(sender);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (DBOpException | ExecutionException e) {
|
||||
@ -113,4 +123,14 @@ public class ManageClearCommand extends CommandNode {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void reloadPlugin(Sender sender) {
|
||||
try {
|
||||
plugin.reloadPlugin(true);
|
||||
} catch (Exception e) {
|
||||
errorHandler.log(L.CRITICAL, this.getClass(), e);
|
||||
sender.sendMessage(locale.getString(CommandLang.RELOAD_FAILED));
|
||||
}
|
||||
sender.sendMessage(locale.getString(CommandLang.RELOAD_COMPLETE));
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.queries.PlayerFetchQueries;
|
||||
import com.djrapitops.plan.db.access.transactions.commands.RemovePlayerTransaction;
|
||||
import com.djrapitops.plan.query.QueryServiceImplementation;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.system.locale.Locale;
|
||||
import com.djrapitops.plan.system.locale.lang.CmdHelpLang;
|
||||
@ -55,6 +56,7 @@ public class ManageRemoveCommand extends CommandNode {
|
||||
private final Locale locale;
|
||||
private final Processing processing;
|
||||
private final DBSystem dbSystem;
|
||||
private final QueryServiceImplementation queryService;
|
||||
private final UUIDUtility uuidUtility;
|
||||
private final ErrorHandler errorHandler;
|
||||
|
||||
@ -63,6 +65,7 @@ public class ManageRemoveCommand extends CommandNode {
|
||||
Locale locale,
|
||||
Processing processing,
|
||||
DBSystem dbSystem,
|
||||
QueryServiceImplementation queryService,
|
||||
UUIDUtility uuidUtility,
|
||||
ErrorHandler errorHandler
|
||||
) {
|
||||
@ -71,6 +74,7 @@ public class ManageRemoveCommand extends CommandNode {
|
||||
this.locale = locale;
|
||||
this.processing = processing;
|
||||
this.dbSystem = dbSystem;
|
||||
this.queryService = queryService;
|
||||
this.uuidUtility = uuidUtility;
|
||||
this.errorHandler = errorHandler;
|
||||
|
||||
@ -120,6 +124,7 @@ public class ManageRemoveCommand extends CommandNode {
|
||||
}
|
||||
|
||||
sender.sendMessage(locale.getString(ManageLang.PROGRESS_START));
|
||||
queryService.playerRemoved(playerUUID);
|
||||
db.executeTransaction(new RemovePlayerTransaction(playerUUID))
|
||||
.get(); // Wait for completion
|
||||
sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS));
|
||||
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.data.time;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Class that tracks the time spent in each World based on GMTimes.
|
||||
@ -171,8 +172,8 @@ public class WorldTimes {
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String getCurrentWorld() {
|
||||
return currentWorld;
|
||||
public Optional<String> getCurrentWorld() {
|
||||
return Optional.ofNullable(currentWorld);
|
||||
}
|
||||
|
||||
public void add(WorldTimes toAdd) {
|
||||
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.db.access;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.query.QueryService;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class QueryAPIExecutable implements Executable {
|
||||
|
||||
private final String sql;
|
||||
private final QueryService.ThrowingConsumer<PreparedStatement> statement;
|
||||
|
||||
public QueryAPIExecutable(
|
||||
String sql,
|
||||
QueryService.ThrowingConsumer<PreparedStatement> statement
|
||||
) {
|
||||
this.sql = sql;
|
||||
this.statement = statement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(Connection connection) {
|
||||
try {
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
|
||||
statement.accept(preparedStatement);
|
||||
return true;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw DBOpException.forCause(sql, e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.db.access;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.db.SQLDB;
|
||||
import com.djrapitops.plan.query.QueryService;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class QueryAPIQuery<T> implements Query<T> {
|
||||
|
||||
private final QueryService.ThrowingFunction<PreparedStatement, T> performQuery;
|
||||
private String sql;
|
||||
|
||||
public QueryAPIQuery(
|
||||
String sql,
|
||||
QueryService.ThrowingFunction<PreparedStatement, T> performQuery
|
||||
) {
|
||||
this.sql = sql;
|
||||
this.performQuery = performQuery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T executeQuery(SQLDB db) {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = db.getConnection();
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
|
||||
return performQuery.apply(preparedStatement);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw DBOpException.forCause(sql, e);
|
||||
} finally {
|
||||
db.returnToPool(connection);
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ import com.djrapitops.plan.db.access.transactions.init.RemoveOldSampledDataTrans
|
||||
import com.djrapitops.plan.db.sql.tables.SessionsTable;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.RemoveUnsatisfiedConditionalPlayerResultsTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.RemoveUnsatisfiedConditionalServerResultsTransaction;
|
||||
import com.djrapitops.plan.query.QueryServiceImplementation;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.system.locale.Locale;
|
||||
@ -58,6 +59,7 @@ public class DBCleanTask extends AbsRunnable {
|
||||
private final Locale locale;
|
||||
private final DBSystem dbSystem;
|
||||
private final PlanConfig config;
|
||||
private final QueryServiceImplementation queryService;
|
||||
private final ServerInfo serverInfo;
|
||||
private final PluginLogger logger;
|
||||
private final ErrorHandler errorHandler;
|
||||
@ -67,6 +69,7 @@ public class DBCleanTask extends AbsRunnable {
|
||||
PlanConfig config,
|
||||
Locale locale,
|
||||
DBSystem dbSystem,
|
||||
QueryServiceImplementation queryService,
|
||||
ServerInfo serverInfo,
|
||||
PluginLogger logger,
|
||||
ErrorHandler errorHandler
|
||||
@ -75,6 +78,7 @@ public class DBCleanTask extends AbsRunnable {
|
||||
|
||||
this.dbSystem = dbSystem;
|
||||
this.config = config;
|
||||
this.queryService = queryService;
|
||||
this.serverInfo = serverInfo;
|
||||
this.logger = logger;
|
||||
this.errorHandler = errorHandler;
|
||||
@ -110,8 +114,9 @@ public class DBCleanTask extends AbsRunnable {
|
||||
long keepActiveAfter = now - config.get(TimeSettings.DELETE_INACTIVE_PLAYERS_AFTER);
|
||||
|
||||
List<UUID> inactivePlayers = database.query(fetchInactivePlayerUUIDs(keepActiveAfter));
|
||||
for (UUID uuid : inactivePlayers) {
|
||||
database.executeTransaction(new RemovePlayerTransaction(uuid));
|
||||
for (UUID playerUUID : inactivePlayers) {
|
||||
queryService.playerRemoved(playerUUID);
|
||||
database.executeTransaction(new RemovePlayerTransaction(playerUUID));
|
||||
}
|
||||
return inactivePlayers.size();
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.system.processing.Processing;
|
||||
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
||||
import com.djrapitops.plugin.api.Check;
|
||||
import com.djrapitops.plugin.logging.L;
|
||||
import com.djrapitops.plugin.logging.console.PluginLogger;
|
||||
import com.djrapitops.plugin.logging.error.ErrorHandler;
|
||||
@ -80,8 +81,10 @@ public class ExtensionServiceImplementation implements ExtensionService {
|
||||
ExtensionService.ExtensionServiceHolder.set(this);
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
public void register() {
|
||||
extensionRegister.registerBuiltInExtensions();
|
||||
if (Check.isBukkitAvailable()) extensionRegister.registerBukkitExtensions();
|
||||
if (Check.isBungeeAvailable()) extensionRegister.registerBungeeExtensions();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -156,7 +159,7 @@ public class ExtensionServiceImplementation implements ExtensionService {
|
||||
// Try again
|
||||
updatePlayerValues(gatherer, playerUUID, playerName, event);
|
||||
} catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError unexpectedError) {
|
||||
logger.warn(gatherer.getPluginName() + " ran into unexpected error (please report this)" + unexpectedError +
|
||||
logger.warn("Encountered unexpected error with " + gatherer.getPluginName() + " Extension (please report this): " + unexpectedError +
|
||||
" (but failed safely) when updating value for '" + playerName +
|
||||
"', stack trace to follow:");
|
||||
errorHandler.log(L.WARN, gatherer.getClass(), unexpectedError);
|
||||
@ -166,8 +169,8 @@ public class ExtensionServiceImplementation implements ExtensionService {
|
||||
private void logFailure(String playerName, DataExtensionMethodCallException methodCallFailed) {
|
||||
Throwable cause = methodCallFailed.getCause();
|
||||
String causeName = cause.getClass().getSimpleName();
|
||||
logger.warn(methodCallFailed.getPluginName() + " ran into " + causeName +
|
||||
" (but failed safely) when updating value for '" + playerName +
|
||||
logger.warn("Encountered " + causeName + " with " + methodCallFailed.getPluginName() + " Extension (please report this)" +
|
||||
" (failed safely) when updating value for '" + playerName +
|
||||
"', the method was disabled temporarily (won't be called until next Plan reload)" +
|
||||
", stack trace to follow:");
|
||||
errorHandler.log(L.WARN, getClass(), cause);
|
||||
@ -195,8 +198,8 @@ public class ExtensionServiceImplementation implements ExtensionService {
|
||||
// Try again
|
||||
updateServerValues(gatherer, event);
|
||||
} catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError unexpectedError) {
|
||||
logger.warn(gatherer.getPluginName() + " ran into unexpected error (please report this)" + unexpectedError +
|
||||
" (but failed safely) when updating value for server, stack trace to follow:");
|
||||
logger.warn("Encountered unexpected error with " + gatherer.getPluginName() + " Extension (please report this): " + unexpectedError +
|
||||
" (failed safely) when updating value for server, stack trace to follow:");
|
||||
errorHandler.log(L.WARN, gatherer.getClass(), unexpectedError);
|
||||
}
|
||||
}
|
||||
|
@ -79,21 +79,21 @@ public class DataProviders {
|
||||
return byReturnType;
|
||||
}
|
||||
|
||||
public void removeProviderWithMethod(MethodWrapper method) {
|
||||
MethodType methodType = method.getMethodType();
|
||||
public void removeProviderWithMethod(MethodWrapper toRemove) {
|
||||
MethodType methodType = toRemove.getMethodType();
|
||||
Map<Class, List<DataProvider>> byResultType = byMethodType.getOrDefault(methodType, Collections.emptyMap());
|
||||
if (byResultType.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Class resultType = method.getResultType();
|
||||
Class resultType = toRemove.getResultType();
|
||||
List<DataProvider> providers = byResultType.getOrDefault(resultType, Collections.emptyList());
|
||||
if (providers.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
byResultType.put(resultType, providers.stream()
|
||||
.filter(provider -> provider.getMethod().equals(method))
|
||||
.filter(provider -> !provider.getMethod().equals(toRemove))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
byMethodType.put(methodType, byResultType);
|
||||
|
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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.query;
|
||||
|
||||
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
||||
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
|
||||
import com.djrapitops.plan.db.DBType;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.queries.containers.ContainerFetchQueries;
|
||||
import com.djrapitops.plan.db.access.queries.objects.ServerQueries;
|
||||
import com.djrapitops.plan.db.access.queries.objects.UserIdentifierQueries;
|
||||
import com.djrapitops.plan.db.access.queries.schema.H2SchemaQueries;
|
||||
import com.djrapitops.plan.db.access.queries.schema.MySQLSchemaQueries;
|
||||
import com.djrapitops.plan.db.access.queries.schema.SQLiteSchemaQueries;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CommonQueriesImplementation implements CommonQueries {
|
||||
|
||||
private final Database db;
|
||||
|
||||
CommonQueriesImplementation(Database db) {
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long fetchPlaytime(UUID playerUUID, UUID serverUUID, long after, long before) {
|
||||
// TODO Replace with single query later
|
||||
PlayerContainer player = db.query(ContainerFetchQueries.fetchPlayerContainer(playerUUID));
|
||||
return SessionsMutator.forContainer(player)
|
||||
.filterSessionsBetween(after, before)
|
||||
.filterPlayedOnServer(serverUUID)
|
||||
.toPlaytime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long fetchLastSeen(UUID playerUUID, UUID serverUUID) {
|
||||
// TODO Replace with single query later
|
||||
PlayerContainer player = db.query(ContainerFetchQueries.fetchPlayerContainer(playerUUID));
|
||||
return SessionsMutator.forContainer(player)
|
||||
.filterPlayedOnServer(serverUUID)
|
||||
.toLastSeen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> fetchServerUUIDs() {
|
||||
return db.query(ServerQueries.fetchServerNames()).keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UUID> fetchUUIDOf(String playerName) {
|
||||
return db.query(UserIdentifierQueries.fetchPlayerUUIDOf(playerName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> fetchNameOf(UUID playerUUID) {
|
||||
return db.query(UserIdentifierQueries.fetchPlayerNameOf(playerUUID));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesDBHaveTable(String table) {
|
||||
DBType dbType = db.getType();
|
||||
switch (dbType) {
|
||||
case H2:
|
||||
return db.query(H2SchemaQueries.doesTableExist(table));
|
||||
case SQLITE:
|
||||
return db.query(SQLiteSchemaQueries.doesTableExist(table));
|
||||
case MYSQL:
|
||||
return db.query(MySQLSchemaQueries.doesTableExist(table));
|
||||
default:
|
||||
throw new IllegalStateException("Unsupported Database Type: " + dbType.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesDBHaveTableColumn(String table, String column) {
|
||||
DBType dbType = db.getType();
|
||||
switch (dbType) {
|
||||
case H2:
|
||||
return db.query(H2SchemaQueries.doesColumnExist(table, column));
|
||||
case MYSQL:
|
||||
return db.query(MySQLSchemaQueries.doesColumnExist(table, column));
|
||||
case SQLITE:
|
||||
return db.query(SQLiteSchemaQueries.doesColumnExist(table, column));
|
||||
default:
|
||||
throw new IllegalStateException("Unsupported Database Type: " + dbType.getName());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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.query;
|
||||
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.QueryAPIExecutable;
|
||||
import com.djrapitops.plan.db.access.QueryAPIQuery;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.system.info.server.Server;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Singleton
|
||||
public class QueryServiceImplementation implements QueryService {
|
||||
|
||||
private DBSystem dbSystem;
|
||||
private ServerInfo serverInfo;
|
||||
|
||||
private Set<Consumer<UUID>> playerRemoveSubscribers;
|
||||
private Set<VoidFunction> clearSubscribers;
|
||||
|
||||
@Inject
|
||||
public QueryServiceImplementation(
|
||||
DBSystem dbSystem,
|
||||
ServerInfo serverInfo
|
||||
) {
|
||||
this.dbSystem = dbSystem;
|
||||
this.serverInfo = serverInfo;
|
||||
|
||||
playerRemoveSubscribers = new HashSet<>();
|
||||
clearSubscribers = new HashSet<>();
|
||||
}
|
||||
|
||||
public void register() {
|
||||
QueryService.QueryServiceHolder.set(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDBType() {
|
||||
Database database = dbSystem.getDatabase();
|
||||
if (database == null) throw new IllegalStateException("Database has not been initialized.");
|
||||
return database.getType().name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T query(String sql, ThrowingFunction<PreparedStatement, T> performQuery) {
|
||||
return dbSystem.getDatabase().query(new QueryAPIQuery<>(sql, performQuery));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<?> execute(String sql, ThrowingConsumer<PreparedStatement> performStatement) {
|
||||
return dbSystem.getDatabase().executeTransaction(
|
||||
new Transaction() {
|
||||
@Override
|
||||
protected void performOperations() {
|
||||
execute(new QueryAPIExecutable(sql, performStatement));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribeToPlayerRemoveEvent(Consumer<UUID> eventListener) {
|
||||
playerRemoveSubscribers.add(eventListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribeDataClearEvent(VoidFunction eventListener) {
|
||||
clearSubscribers.add(eventListener);
|
||||
}
|
||||
|
||||
public void playerRemoved(UUID playerUUID) {
|
||||
playerRemoveSubscribers.forEach(subscriber -> subscriber.accept(playerUUID));
|
||||
}
|
||||
|
||||
public void dataCleared() {
|
||||
clearSubscribers.forEach(VoidFunction::apply);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UUID> getServerUUID() {
|
||||
return Optional.ofNullable(serverInfo.getServer()).map(Server::getUuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonQueries getCommonQueries() {
|
||||
Database database = dbSystem.getDatabase();
|
||||
if (database == null) throw new IllegalStateException("Database has not been initialized.");
|
||||
return new CommonQueriesImplementation(database);
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ import com.djrapitops.plan.capability.CapabilityServiceImplementation;
|
||||
import com.djrapitops.plan.data.plugin.HookHandler;
|
||||
import com.djrapitops.plan.extension.ExtensionService;
|
||||
import com.djrapitops.plan.extension.ExtensionServiceImplementation;
|
||||
import com.djrapitops.plan.query.QueryServiceImplementation;
|
||||
import com.djrapitops.plan.system.cache.CacheSystem;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.system.export.ExportSystem;
|
||||
@ -73,6 +74,7 @@ public class PlanSystem implements SubSystem {
|
||||
private final HtmlUtilities htmlUtilities;
|
||||
private final HookHandler hookHandler;
|
||||
private final ExtensionServiceImplementation extensionService;
|
||||
private final QueryServiceImplementation queryService;
|
||||
private final PlanAPI planAPI;
|
||||
private final ErrorHandler errorHandler;
|
||||
|
||||
@ -95,6 +97,7 @@ public class PlanSystem implements SubSystem {
|
||||
HtmlUtilities htmlUtilities,
|
||||
HookHandler hookHandler,
|
||||
ExtensionServiceImplementation extensionService,
|
||||
QueryServiceImplementation queryService,
|
||||
PlanAPI planAPI,
|
||||
ErrorHandler errorHandler
|
||||
) {
|
||||
@ -115,6 +118,7 @@ public class PlanSystem implements SubSystem {
|
||||
this.htmlUtilities = htmlUtilities;
|
||||
this.hookHandler = hookHandler;
|
||||
this.extensionService = extensionService;
|
||||
this.queryService = queryService;
|
||||
this.planAPI = planAPI;
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
@ -140,7 +144,8 @@ public class PlanSystem implements SubSystem {
|
||||
taskSystem,
|
||||
hookHandler
|
||||
);
|
||||
extensionService.enable();
|
||||
queryService.register();
|
||||
extensionService.register();
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,9 @@ public class ConfigNode {
|
||||
}
|
||||
|
||||
public Optional<ConfigNode> getNode(String path) {
|
||||
if (path == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
String[] parts = splitPathInTwo(path);
|
||||
String key = parts[0];
|
||||
String leftover = parts[1];
|
||||
@ -88,7 +91,7 @@ public class ConfigNode {
|
||||
|
||||
public ConfigNode addNode(String path) {
|
||||
ConfigNode newParent = this;
|
||||
if (!path.isEmpty()) {
|
||||
if (path != null && !path.isEmpty()) {
|
||||
String[] parts = splitPathInTwo(path);
|
||||
String key = parts[0];
|
||||
String leftover = parts[1];
|
||||
@ -105,7 +108,7 @@ public class ConfigNode {
|
||||
// Otherwise continue recursively.
|
||||
return leftover.isEmpty() ? child : child.addNode(leftover);
|
||||
}
|
||||
throw new IllegalArgumentException("Can not add a node with empty path");
|
||||
throw new IllegalArgumentException("Can not add a node with path '" + path + "'");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,8 +157,9 @@ public class WorldAliasSettings {
|
||||
}
|
||||
WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes());
|
||||
if (!session.supports(SessionKeys.END)) {
|
||||
String currentWorld = worldTimes.getCurrentWorld();
|
||||
return "Current: " + (aliases.contains(currentWorld) ? aliases.getString(currentWorld) : currentWorld);
|
||||
return worldTimes.getCurrentWorld()
|
||||
.map(currentWorld -> "Current: " + (aliases.contains(currentWorld) ? aliases.getString(currentWorld) : currentWorld))
|
||||
.orElse("Current: Unavailable");
|
||||
}
|
||||
|
||||
Map<String, Long> playtimePerAlias = getPlaytimePerAlias(worldTimes);
|
||||
|
@ -135,12 +135,19 @@ public enum Html {
|
||||
|
||||
StringBuilder result = new StringBuilder(string.length());
|
||||
String[] split = string.split("§");
|
||||
// Skip first part if it does not start with §
|
||||
boolean skipFirst = !string.startsWith("§");
|
||||
|
||||
int placedSpans = 0;
|
||||
for (String part : split) {
|
||||
if (part.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (skipFirst) {
|
||||
result.append(part);
|
||||
skipFirst = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
char colorChar = part.charAt(0);
|
||||
if (colorChar == 'r') {
|
||||
|
@ -1,7 +1,7 @@
|
||||
name: Plan
|
||||
author: Rsl1122
|
||||
main: com.djrapitops.plan.PlanBungee
|
||||
version: 4.8.8
|
||||
version: 4.9.0
|
||||
softdepend:
|
||||
- AdvancedBan
|
||||
- LiteBans
|
||||
|
@ -1,7 +1,7 @@
|
||||
name: Plan
|
||||
author: Rsl1122
|
||||
main: com.djrapitops.plan.Plan
|
||||
version: 4.8.8
|
||||
version: 4.9.0
|
||||
softdepend:
|
||||
- ASkyBlock
|
||||
- AdvancedAchievements
|
||||
|
@ -67,6 +67,7 @@ import com.djrapitops.plan.extension.implementation.storage.queries.ExtensionSer
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.RemoveUnsatisfiedConditionalPlayerResultsTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.RemoveUnsatisfiedConditionalServerResultsTransaction;
|
||||
import com.djrapitops.plan.extension.table.Table;
|
||||
import com.djrapitops.plan.query.QueryServiceImplementation;
|
||||
import com.djrapitops.plan.system.PlanSystem;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.system.info.server.Server;
|
||||
@ -629,6 +630,7 @@ public abstract class CommonDBTest {
|
||||
system.getConfigSystem().getConfig(),
|
||||
new Locale(),
|
||||
system.getDatabaseSystem(),
|
||||
new QueryServiceImplementation(system.getDatabaseSystem(), system.getServerInfo()),
|
||||
system.getServerInfo(),
|
||||
new TestPluginLogger(),
|
||||
new ConsoleErrorLogger(new TestPluginLogger())
|
||||
|
@ -53,4 +53,12 @@ class HtmlTest {
|
||||
String result = Html.swapColorCodesToSpan(testString);
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void swapColorCodesDoesNotReplaceNonColors() {
|
||||
String testString = "1test§2yes";
|
||||
String expected = "1test" + Html.COLOR_2.parse() + "yes</span>";
|
||||
String result = Html.swapColorCodesToSpan(testString);
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,26 @@
|
||||
dependencies {
|
||||
compile project(path: ":api")
|
||||
compile "com.djrapitops:Extension-AdvancedAchievements:1.1-R0.3"
|
||||
compile "com.djrapitops:Extension-AdvancedBan:2.1.5-R0.6"
|
||||
compile "com.djrapitops:Extension-ASkyBlock:3.0.9.4-R0.4"
|
||||
compile "com.djrapitops:Extension-BanManager:5.15.0-R0.5"
|
||||
compile "com.djrapitops:Extension-CoreProtect:2.16.0-R0.3"
|
||||
compile "com.djrapitops:Extension-DiscordSRV:1.16.6-R0.4"
|
||||
compile "com.djrapitops:Extension-EssentialsX:2.15.0-R0.3"
|
||||
compile "com.djrapitops:Extension-GriefPrevention:16.11.6-R0.2"
|
||||
compile "com.djrapitops:Extension-GriefPrevention-Sponge:4.0.1-R0.2"
|
||||
compile "com.djrapitops:Extension-GriefPreventionPlus:13.3-R0.2"
|
||||
compile "com.djrapitops:Extension-McMMO:2.1.44-R0.2"
|
||||
compile 'com.djrapitops:Extension-AAC:4.0.5-R0.3'
|
||||
compile 'com.djrapitops:Extension-AdvancedAchievements:1.1-R0.3'
|
||||
compile 'com.djrapitops:Extension-AdvancedBan:2.1.5-R0.6'
|
||||
compile 'com.djrapitops:Extension-ASkyBlock:3.0.9.4-R0.4'
|
||||
compile 'com.djrapitops:Extension-BanManager:5.15.0-R0.5'
|
||||
compile 'com.djrapitops:Extension-CoreProtect:2.16.0-R0.3'
|
||||
compile 'com.djrapitops:Extension-DiscordSRV:1.16.6-R0.4'
|
||||
compile 'com.djrapitops:Extension-EssentialsX:2.15.0-R0.3'
|
||||
compile 'com.djrapitops:Extension-GriefPrevention:16.11.6-R0.2'
|
||||
compile 'com.djrapitops:Extension-GriefPrevention-Sponge:4.0.1-R0.2'
|
||||
compile 'com.djrapitops:Extension-GriefPreventionPlus:13.3-R0.2'
|
||||
compile 'com.djrapitops:Extension-McMMO:2.1.44-R0.2'
|
||||
compile 'com.djrapitops:Extension-MinigamesLib:1.14.17-R0.2'
|
||||
compile 'com.djrapitops:Extension-Nucleus:1.9.2-R0.2'
|
||||
compile "com.djrapitops:Extension-RedProtect:7.5.6-R0.2"
|
||||
compile "com.djrapitops:Extension-Sponge-Economy:7.1.0-R0.3"
|
||||
compile "com.djrapitops:Extension-SuperbVote:0.5.4-R0.1"
|
||||
compile "com.djrapitops:Extension-Vault:1.7-R0.2"
|
||||
compile 'com.djrapitops:Extension-nuVotifier:2.3.4-R0.1'
|
||||
compile 'com.djrapitops:Extension-ProtocolSupport:4.29-R0.1'
|
||||
compile 'com.djrapitops:Extension-RedProtect:7.5.6-R0.2'
|
||||
compile 'com.djrapitops:Extension-Sponge-Economy:7.1.0-R0.3'
|
||||
compile 'com.djrapitops:Extension-SuperbVote:0.5.4-R0.1'
|
||||
compile 'com.djrapitops:Extension-Vault:1.7-R0.2'
|
||||
compile 'com.djrapitops:Extension-ViaVersion:2.1.3-R0.3'
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
|
@ -22,6 +22,7 @@ import com.djrapitops.plan.extension.ExtensionService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* In charge of registering built in {@link com.djrapitops.plan.extension.DataExtension} implementations.
|
||||
@ -41,23 +42,43 @@ public class ExtensionRegister {
|
||||
// registerBuiltInExtensions method will not be called unless Plan has enabled properly
|
||||
ExtensionService extensionService = ExtensionService.getInstance();
|
||||
|
||||
new AdvancedAchievementsExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
new AdvancedBanExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
new ASkyBlockExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
new BanManagerExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
new CoreProtectExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
new DiscordSRVExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
Consumer<DataExtension> register = extensionService::register;
|
||||
new AACExtensionFactory().createExtension().ifPresent(register);
|
||||
new AdvancedAchievementsExtensionFactory().createExtension().ifPresent(register);
|
||||
new AdvancedBanExtensionFactory().createExtension().ifPresent(register);
|
||||
new ASkyBlockExtensionFactory().createExtension().ifPresent(register);
|
||||
new BanManagerExtensionFactory().createExtension().ifPresent(register);
|
||||
new CoreProtectExtensionFactory().createExtension().ifPresent(register);
|
||||
new DiscordSRVExtensionFactory().createExtension().ifPresent(register);
|
||||
registerEssentialsExtension(extensionService);
|
||||
new GriefPreventionExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
new GriefPreventionSpongeExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
new GriefPreventionPlusExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
new McMMOExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
new GriefPreventionExtensionFactory().createExtension().ifPresent(register);
|
||||
new GriefPreventionSpongeExtensionFactory().createExtension().ifPresent(register);
|
||||
new GriefPreventionPlusExtensionFactory().createExtension().ifPresent(register);
|
||||
new McMMOExtensionFactory().createExtension().ifPresent(register);
|
||||
registerMinigameLibExtensions(extensionService);
|
||||
new NucleusExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
new RedProtectExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
new SpongeEconomyExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
new SuperbVoteExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
new VaultExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
new NucleusExtensionFactory().createExtension().ifPresent(register);
|
||||
new NuVotifierExtensionFactory().createExtension().ifPresent(register);
|
||||
new ProtocolSupportExtensionFactory().createExtension().ifPresent(register);
|
||||
new RedProtectExtensionFactory().createExtension().ifPresent(register);
|
||||
new SpongeEconomyExtensionFactory().createExtension().ifPresent(register);
|
||||
new SuperbVoteExtensionFactory().createExtension().ifPresent(register);
|
||||
new VaultExtensionFactory().createExtension().ifPresent(register);
|
||||
}
|
||||
|
||||
public void registerBukkitExtensions() {
|
||||
// No need to catch exceptions here,
|
||||
// registerBuiltInExtensions method will not be called unless Plan has enabled properly
|
||||
ExtensionService extensionService = ExtensionService.getInstance();
|
||||
|
||||
new ViaVersionBukkitExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
}
|
||||
|
||||
public void registerBungeeExtensions() {
|
||||
// No need to catch exceptions here,
|
||||
// registerBuiltInExtensions method will not be called unless Plan has enabled properly
|
||||
ExtensionService extensionService = ExtensionService.getInstance();
|
||||
|
||||
new ViaVersionBungeeExtensionFactory().createExtension().ifPresent(extensionService::register);
|
||||
}
|
||||
|
||||
private void registerEssentialsExtension(ExtensionService extensionService) {
|
||||
|
@ -42,7 +42,7 @@ import java.io.InputStream;
|
||||
@Plugin(
|
||||
id = "plan",
|
||||
name = "Plan",
|
||||
version = "4.8.8",
|
||||
version = "4.9.0",
|
||||
description = "Player Analytics Plugin by Rsl1122",
|
||||
authors = {"Rsl1122"},
|
||||
dependencies = {
|
||||
|
@ -46,7 +46,7 @@ import java.nio.file.Path;
|
||||
@Plugin(
|
||||
id = "plan",
|
||||
name = "Plan",
|
||||
version = "4.8.8",
|
||||
version = "4.9.0",
|
||||
description = "Player Analytics Plugin by Rsl1122",
|
||||
authors = {"Rsl1122"}
|
||||
)
|
||||
|
@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.djrapitops</groupId>
|
||||
<artifactId>PlanPluginBridge</artifactId>
|
||||
<version>4.8.8-R0.2</version>
|
||||
<version>4.9.0-R0.3</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.groupId}:${project.artifactId}</name>
|
||||
@ -61,10 +61,6 @@
|
||||
<id>jitpack.io (GriefPrevention)</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>viaversion-repo</id>
|
||||
<url>https://repo.viaversion.com</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>placeholderapi</id>
|
||||
<url>http://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||
@ -116,7 +112,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger</artifactId>
|
||||
<version>2.23.2</version>
|
||||
<version>2.24</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Plugins from repositories -->
|
||||
@ -127,12 +123,6 @@
|
||||
<version>2.10.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>us.myles</groupId>
|
||||
<artifactId>viaversion</artifactId>
|
||||
<version>1.5.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency> <!-- Maven Central -->
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<artifactId>luckperms-api</artifactId>
|
||||
@ -141,13 +131,6 @@
|
||||
</dependency>
|
||||
|
||||
<!-- Plugins requiring local install -->
|
||||
|
||||
<dependency>
|
||||
<groupId>me.konsolas</groupId>
|
||||
<artifactId>AAC</artifactId>
|
||||
<version>4.0.0-b1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.massivecraft</groupId>
|
||||
<artifactId>factions</artifactId>
|
||||
@ -172,12 +155,6 @@
|
||||
<version>0.3.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.ProtocolSupport</groupId>
|
||||
<artifactId>ProtocolSupport</artifactId>
|
||||
<version>4.28</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.volmit</groupId>
|
||||
<artifactId>react</artifactId>
|
||||
|
@ -18,15 +18,12 @@ package com.djrapitops.pluginbridge.plan;
|
||||
|
||||
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
||||
import com.djrapitops.plugin.logging.error.ErrorHandler;
|
||||
import com.djrapitops.pluginbridge.plan.aac.AdvancedAntiCheatHook;
|
||||
import com.djrapitops.pluginbridge.plan.buycraft.BuyCraftHook;
|
||||
import com.djrapitops.pluginbridge.plan.factions.FactionsHook;
|
||||
import com.djrapitops.pluginbridge.plan.jobs.JobsHook;
|
||||
import com.djrapitops.pluginbridge.plan.litebans.LiteBansBukkitHook;
|
||||
import com.djrapitops.pluginbridge.plan.luckperms.LuckPermsHook;
|
||||
import com.djrapitops.pluginbridge.plan.protocolsupport.ProtocolSupportHook;
|
||||
import com.djrapitops.pluginbridge.plan.towny.TownyHook;
|
||||
import com.djrapitops.pluginbridge.plan.viaversion.ViaVersionBukkitHook;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -39,55 +36,42 @@ import javax.inject.Singleton;
|
||||
@Singleton
|
||||
public class BukkitBridge extends AbstractBridge {
|
||||
|
||||
private final AdvancedAntiCheatHook advancedAntiCheatHook;
|
||||
private final BuyCraftHook buyCraftHook;
|
||||
private final FactionsHook factionsHook;
|
||||
private final JobsHook jobsHook;
|
||||
private final LiteBansBukkitHook liteBansHook;
|
||||
private final LuckPermsHook luckPermsHook;
|
||||
private final ProtocolSupportHook protocolSupportHook;
|
||||
private final TownyHook townyHook;
|
||||
private final ViaVersionBukkitHook viaVersionHook;
|
||||
|
||||
@Inject
|
||||
public BukkitBridge(
|
||||
PlanConfig config,
|
||||
ErrorHandler errorHandler,
|
||||
|
||||
AdvancedAntiCheatHook advancedAntiCheatHook,
|
||||
BuyCraftHook buyCraftHook,
|
||||
FactionsHook factionsHook,
|
||||
JobsHook jobsHook,
|
||||
LiteBansBukkitHook liteBansHook,
|
||||
LuckPermsHook luckPermsHook,
|
||||
ProtocolSupportHook protocolSupportHook,
|
||||
TownyHook townyHook,
|
||||
ViaVersionBukkitHook viaVersionHook
|
||||
TownyHook townyHook
|
||||
) {
|
||||
super(config, errorHandler);
|
||||
this.advancedAntiCheatHook = advancedAntiCheatHook;
|
||||
this.buyCraftHook = buyCraftHook;
|
||||
this.factionsHook = factionsHook;
|
||||
this.jobsHook = jobsHook;
|
||||
this.liteBansHook = liteBansHook;
|
||||
this.luckPermsHook = luckPermsHook;
|
||||
this.protocolSupportHook = protocolSupportHook;
|
||||
this.townyHook = townyHook;
|
||||
this.viaVersionHook = viaVersionHook;
|
||||
}
|
||||
|
||||
@Override
|
||||
Hook[] getHooks() {
|
||||
return new Hook[]{
|
||||
advancedAntiCheatHook,
|
||||
buyCraftHook,
|
||||
factionsHook,
|
||||
jobsHook,
|
||||
liteBansHook,
|
||||
luckPermsHook,
|
||||
protocolSupportHook,
|
||||
townyHook,
|
||||
viaVersionHook
|
||||
};
|
||||
}
|
||||
}
|
@ -21,7 +21,6 @@ import com.djrapitops.plugin.logging.error.ErrorHandler;
|
||||
import com.djrapitops.pluginbridge.plan.buycraft.BuyCraftHook;
|
||||
import com.djrapitops.pluginbridge.plan.litebans.LiteBansBungeeHook;
|
||||
import com.djrapitops.pluginbridge.plan.luckperms.LuckPermsHook;
|
||||
import com.djrapitops.pluginbridge.plan.viaversion.ViaVersionBungeeHook;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -37,23 +36,19 @@ public class BungeeBridge extends AbstractBridge {
|
||||
private final BuyCraftHook buyCraftHook;
|
||||
private final LiteBansBungeeHook liteBansHook;
|
||||
private final LuckPermsHook luckPermsHook;
|
||||
private final ViaVersionBungeeHook viaVersionHook;
|
||||
|
||||
@Inject
|
||||
public BungeeBridge(
|
||||
PlanConfig config,
|
||||
ErrorHandler errorHandler,
|
||||
|
||||
BuyCraftHook buyCraftHook,
|
||||
LiteBansBungeeHook liteBansHook,
|
||||
LuckPermsHook luckPermsHook,
|
||||
ViaVersionBungeeHook viaVersionHook
|
||||
LuckPermsHook luckPermsHook
|
||||
) {
|
||||
super(config, errorHandler);
|
||||
this.buyCraftHook = buyCraftHook;
|
||||
this.liteBansHook = liteBansHook;
|
||||
this.luckPermsHook = luckPermsHook;
|
||||
this.viaVersionHook = viaVersionHook;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -62,7 +57,6 @@ public class BungeeBridge extends AbstractBridge {
|
||||
buyCraftHook,
|
||||
liteBansHook,
|
||||
luckPermsHook,
|
||||
viaVersionHook
|
||||
};
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.aac;
|
||||
|
||||
import com.djrapitops.plan.data.element.AnalysisContainer;
|
||||
import com.djrapitops.plan.data.element.InspectContainer;
|
||||
import com.djrapitops.plan.data.element.TableContainer;
|
||||
import com.djrapitops.plan.data.plugin.ContainerSize;
|
||||
import com.djrapitops.plan.data.plugin.PluginData;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.utilities.formatting.Formatter;
|
||||
import com.djrapitops.plan.utilities.html.icon.Color;
|
||||
import com.djrapitops.plan.utilities.html.icon.Family;
|
||||
import com.djrapitops.plan.utilities.html.icon.Icon;
|
||||
import com.djrapitops.plugin.utilities.Format;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* PluginData for AAC plugin.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
class AdvancedAntiCheatData extends PluginData {
|
||||
|
||||
private final Database database;
|
||||
private final Formatter<Long> timestampFormatter;
|
||||
|
||||
AdvancedAntiCheatData(Database database, Formatter<Long> timestampFormatter) {
|
||||
super(ContainerSize.THIRD, "AdvancedAntiCheat");
|
||||
this.timestampFormatter = timestampFormatter;
|
||||
super.setPluginIcon(Icon.called("heart").of(Color.RED).build());
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InspectContainer getPlayerData(UUID uuid, InspectContainer inspectContainer) {
|
||||
List<HackObject> hackObjects = database.query(HackerTable.getHackObjects(uuid));
|
||||
|
||||
inspectContainer.addValue(
|
||||
getWithIcon("Times Kicked for Possible Hacking", Icon.called("exclamation-triangle").of(Color.RED)),
|
||||
hackObjects.size()
|
||||
);
|
||||
|
||||
TableContainer hackTable = new TableContainer(
|
||||
getWithIcon("Kicked", Icon.called("calendar").of(Family.REGULAR)),
|
||||
getWithIcon("Hack", Icon.called("exclamation-triangle")),
|
||||
getWithIcon("Violation Level", Icon.called("gavel"))
|
||||
);
|
||||
hackTable.setColor("red");
|
||||
|
||||
for (HackObject hackObject : hackObjects) {
|
||||
String date = timestampFormatter.apply(hackObject.getDate());
|
||||
String hack = new Format(hackObject.getHackType()).capitalize().toString();
|
||||
hackTable.addRow(date, hack, hackObject.getViolationLevel());
|
||||
}
|
||||
inspectContainer.addTable("hackTable", hackTable);
|
||||
|
||||
return inspectContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnalysisContainer getServerData(Collection<UUID> collection, AnalysisContainer analysisContainer) {
|
||||
Map<UUID, List<HackObject>> hackObjects = database.query(HackerTable.getHackObjects());
|
||||
|
||||
Map<UUID, Integer> violations = hackObjects.entrySet().stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().size()));
|
||||
|
||||
analysisContainer.addPlayerTableValues(getWithIcon("Kicked for Hacking", Icon.called("exclamation-triangle")), violations);
|
||||
|
||||
return analysisContainer;
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.aac;
|
||||
|
||||
import com.djrapitops.plan.Plan;
|
||||
import com.djrapitops.plan.data.plugin.HookHandler;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.utilities.formatting.Formatters;
|
||||
import com.djrapitops.pluginbridge.plan.Hook;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/**
|
||||
* Hook for AAC plugin.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
@Singleton
|
||||
public class AdvancedAntiCheatHook extends Hook {
|
||||
|
||||
private final Plan plugin;
|
||||
private final DBSystem dbSystem;
|
||||
private final Formatters formatters;
|
||||
|
||||
@Inject
|
||||
public AdvancedAntiCheatHook(
|
||||
Plan plugin,
|
||||
DBSystem dbSystem,
|
||||
Formatters formatters
|
||||
) {
|
||||
super("me.konsolas.aac.AAC");
|
||||
this.plugin = plugin;
|
||||
this.dbSystem = dbSystem;
|
||||
this.formatters = formatters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hook(HookHandler hookHandler) throws NoClassDefFoundError {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
Database database = dbSystem.getDatabase();
|
||||
database.executeTransaction(new Transaction() {
|
||||
@Override
|
||||
protected void performOperations() {
|
||||
execute(HackerTable.createTableSQL(database.getType()));
|
||||
}
|
||||
});
|
||||
database.executeTransaction(new HackerTableMissingDateColumnPatch());
|
||||
|
||||
plugin.registerListener(new PlayerHackKickListener(database));
|
||||
hookHandler.addPluginDataSource(new AdvancedAntiCheatData(database, formatters.yearLong()));
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.aac;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Data object for AAC data.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class HackObject {
|
||||
|
||||
private final UUID uuid;
|
||||
private final long date;
|
||||
private final String hackType;
|
||||
private final int violationLevel;
|
||||
|
||||
public HackObject(UUID uuid, long date, String hackType, int violationLevel) {
|
||||
this.uuid = uuid;
|
||||
this.date = date;
|
||||
this.hackType = hackType;
|
||||
this.violationLevel = violationLevel;
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public long getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public String getHackType() {
|
||||
return hackType;
|
||||
}
|
||||
|
||||
public int getViolationLevel() {
|
||||
return violationLevel;
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.aac;
|
||||
|
||||
import com.djrapitops.plan.db.DBType;
|
||||
import com.djrapitops.plan.db.access.Query;
|
||||
import com.djrapitops.plan.db.access.QueryAllStatement;
|
||||
import com.djrapitops.plan.db.access.QueryStatement;
|
||||
import com.djrapitops.plan.db.sql.parsing.CreateTableParser;
|
||||
import com.djrapitops.plan.db.sql.parsing.Select;
|
||||
import com.djrapitops.plan.db.sql.parsing.Sql;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Table information about 'plan_aac_hack_table'.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class HackerTable {
|
||||
|
||||
public static final String TABLE_NAME = "plan_aac_hack_table";
|
||||
public static final String COL_ID = "id";
|
||||
public static final String COL_UUID = "uuid";
|
||||
public static final String COL_DATE = "date";
|
||||
public static final String COL_HACK_TYPE = "hack_type";
|
||||
public static final String COL_VIOLATION_LEVEL = "violation_level";
|
||||
|
||||
private HackerTable() {
|
||||
/* Static information class */
|
||||
}
|
||||
|
||||
public static String createTableSQL(DBType dbType) {
|
||||
return CreateTableParser.create(TABLE_NAME, dbType)
|
||||
.column(COL_ID, Sql.INT).primaryKey()
|
||||
.column(COL_UUID, Sql.varchar(36)).notNull()
|
||||
.column(COL_DATE, Sql.LONG).notNull()
|
||||
.column(COL_HACK_TYPE, Sql.varchar(100)).notNull()
|
||||
.column(COL_VIOLATION_LEVEL, Sql.INT).notNull()
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Query<List<HackObject>> getHackObjects(UUID uuid) {
|
||||
String sql = "SELECT * FROM " + TABLE_NAME + " WHERE " + COL_UUID + "=?";
|
||||
|
||||
return new QueryStatement<List<HackObject>>(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, uuid.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HackObject> processResults(ResultSet set) throws SQLException {
|
||||
List<HackObject> hackObjects = new ArrayList<>();
|
||||
while (set.next()) {
|
||||
UUID uuid = UUID.fromString(set.getString(COL_UUID));
|
||||
long date = set.getLong(COL_DATE);
|
||||
String hackType = set.getString(COL_HACK_TYPE);
|
||||
int violationLevel = set.getInt(COL_VIOLATION_LEVEL);
|
||||
hackObjects.add(new HackObject(uuid, date, hackType, violationLevel));
|
||||
}
|
||||
return hackObjects;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Query<Map<UUID, List<HackObject>>> getHackObjects() {
|
||||
return new QueryAllStatement<Map<UUID, List<HackObject>>>(Select.all(TABLE_NAME).toString(), 5000) {
|
||||
@Override
|
||||
public Map<UUID, List<HackObject>> processResults(ResultSet set) throws SQLException {
|
||||
Map<UUID, List<HackObject>> hackObjects = new HashMap<>();
|
||||
while (set.next()) {
|
||||
UUID uuid = UUID.fromString(set.getString(COL_UUID));
|
||||
long date = set.getLong(COL_DATE);
|
||||
String hackType = set.getString(COL_HACK_TYPE);
|
||||
int violationLevel = set.getInt(COL_VIOLATION_LEVEL);
|
||||
List<HackObject> list = hackObjects.getOrDefault(uuid, new ArrayList<>());
|
||||
list.add(new HackObject(uuid, date, hackType, violationLevel));
|
||||
hackObjects.put(uuid, list);
|
||||
}
|
||||
return hackObjects;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.aac;
|
||||
|
||||
import com.djrapitops.plan.db.patches.Patch;
|
||||
|
||||
/**
|
||||
* Patch to fix a bug
|
||||
* https://github.com/plan-player-analytics/Plan/issues/1027
|
||||
* introduced in commit 530c4a2
|
||||
* https://github.com/plan-player-analytics/Plan/commit/530c4a2ea6fd56fd9a7aa3382f7571f31971dc1a#commitcomment-33415938
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class HackerTableMissingDateColumnPatch extends Patch {
|
||||
|
||||
@Override
|
||||
public boolean hasBeenApplied() {
|
||||
return hasColumn(HackerTable.TABLE_NAME, HackerTable.COL_DATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyPatch() {
|
||||
addColumn(HackerTable.TABLE_NAME, HackerTable.COL_DATE + " bigint NOT NULL DEFAULT 0");
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.aac;
|
||||
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import me.konsolas.aac.api.AACAPIProvider;
|
||||
import me.konsolas.aac.api.HackType;
|
||||
import me.konsolas.aac.api.PlayerViolationCommandEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Class responsible for listening kick events made by AAC.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlayerHackKickListener implements Listener {
|
||||
|
||||
private final Database database;
|
||||
|
||||
PlayerHackKickListener(Database database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onKick(PlayerViolationCommandEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
UUID uuid = player.getUniqueId();
|
||||
HackType hackType = event.getHackType();
|
||||
String hackTypeName = hackType.getName();
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
int violations = new AACAPIProvider().getAPI().getViolationLevel(player, hackType);
|
||||
|
||||
HackObject hackObject = new HackObject(uuid, time, hackTypeName, violations);
|
||||
|
||||
database.executeTransaction(new StoreHackViolationKickTransaction(hackObject));
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.aac;
|
||||
|
||||
import com.djrapitops.plan.db.access.ExecStatement;
|
||||
import com.djrapitops.plan.db.access.Executable;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import static com.djrapitops.pluginbridge.plan.aac.HackerTable.*;
|
||||
|
||||
/**
|
||||
* Transaction to store kick information when AAC kicks a player for hacking.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class StoreHackViolationKickTransaction extends Transaction {
|
||||
|
||||
private final HackObject info;
|
||||
|
||||
public StoreHackViolationKickTransaction(HackObject info) {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performOperations() {
|
||||
execute(storeViolationKick());
|
||||
}
|
||||
|
||||
private Executable storeViolationKick() {
|
||||
String sql = "INSERT INTO " + TABLE_NAME + " ("
|
||||
+ COL_UUID + ", "
|
||||
+ COL_DATE + ", "
|
||||
+ COL_HACK_TYPE + ", "
|
||||
+ COL_VIOLATION_LEVEL
|
||||
+ ") VALUES (?, ?, ?, ?)";
|
||||
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, info.getUuid().toString());
|
||||
statement.setLong(2, info.getDate());
|
||||
statement.setString(3, info.getHackType());
|
||||
statement.setInt(4, info.getViolationLevel());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.protocolsupport;
|
||||
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.pluginbridge.plan.viaversion.StoreUsedProtocolTransaction;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import protocolsupport.api.ProtocolSupportAPI;
|
||||
import protocolsupport.api.ProtocolVersion;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Class responsible for listening join events for Version protocol.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlayerVersionListener implements Listener {
|
||||
|
||||
private final Database database;
|
||||
|
||||
public PlayerVersionListener(Database database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
UUID uuid = player.getUniqueId();
|
||||
ProtocolVersion protocolVersion = ProtocolSupportAPI.getProtocolVersion(player);
|
||||
int playerVersion = protocolVersion.getId();
|
||||
database.executeTransaction(new StoreUsedProtocolTransaction(uuid, playerVersion));
|
||||
}
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.protocolsupport;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.data.element.AnalysisContainer;
|
||||
import com.djrapitops.plan.data.element.InspectContainer;
|
||||
import com.djrapitops.plan.data.element.TableContainer;
|
||||
import com.djrapitops.plan.data.plugin.ContainerSize;
|
||||
import com.djrapitops.plan.data.plugin.PluginData;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.utilities.html.icon.Color;
|
||||
import com.djrapitops.plan.utilities.html.icon.Icon;
|
||||
import com.djrapitops.pluginbridge.plan.viaversion.ProtocolTable;
|
||||
import protocolsupport.api.ProtocolVersion;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* PluginData for ProtocolSupport plugin.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
class ProtocolSupportData extends PluginData {
|
||||
|
||||
private final Database database;
|
||||
|
||||
ProtocolSupportData(Database database) {
|
||||
super(ContainerSize.THIRD, "ProtocolSupport");
|
||||
setPluginIcon(Icon.called("gamepad").of(Color.CYAN).build());
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InspectContainer getPlayerData(UUID uuid, InspectContainer inspectContainer) {
|
||||
try {
|
||||
int protocolVersion = database.query(ProtocolTable.getProtocolVersion(uuid));
|
||||
|
||||
inspectContainer.addValue(getWithIcon("Last Join Version", Icon.called("signal").of(Color.CYAN)),
|
||||
getProtocolVersionString(protocolVersion));
|
||||
} catch (DBOpException ex) {
|
||||
inspectContainer.addValue("Error", ex.toString());
|
||||
}
|
||||
|
||||
return inspectContainer;
|
||||
}
|
||||
|
||||
private String getProtocolVersionString(int number) {
|
||||
if (number == -1) {
|
||||
return "Not Yet Known";
|
||||
}
|
||||
ProtocolVersion[] versions = ProtocolVersion.getAllSupported();
|
||||
for (ProtocolVersion version : versions) {
|
||||
if (version.getId() == number) {
|
||||
String name = version.getName();
|
||||
if (name == null) {
|
||||
break; // Unknown name for the version
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return "Unknown (" + number + ')';
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnalysisContainer getServerData(Collection<UUID> collection, AnalysisContainer analysisContainer) {
|
||||
Map<UUID, Integer> versions;
|
||||
|
||||
try {
|
||||
versions = database.query(ProtocolTable.getProtocolVersions());
|
||||
} catch (DBOpException ex) {
|
||||
analysisContainer.addValue("Error", ex.toString());
|
||||
return analysisContainer;
|
||||
}
|
||||
|
||||
Map<UUID, String> userVersions = versions.entrySet().stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, entry -> getProtocolVersionString(entry.getValue())));
|
||||
|
||||
analysisContainer.addPlayerTableValues(getWithIcon("Last Version", Icon.called("signal")), userVersions);
|
||||
|
||||
String versionS = getWithIcon("Version", Icon.called("signal"));
|
||||
String membersS = getWithIcon("Users", Icon.called("users"));
|
||||
TableContainer versionTable = new TableContainer(versionS, membersS);
|
||||
versionTable.setColor("cyan");
|
||||
Map<String, Integer> usersPerVersion = getUsersPerVersion(userVersions);
|
||||
for (Map.Entry<String, Integer> entry : usersPerVersion.entrySet()) {
|
||||
versionTable.addRow(entry.getKey(), entry.getValue());
|
||||
}
|
||||
analysisContainer.addTable("versionTable", versionTable);
|
||||
|
||||
return analysisContainer;
|
||||
}
|
||||
|
||||
private Map<String, Integer> getUsersPerVersion(Map<UUID, String> userVersions) {
|
||||
Map<String, Integer> usersPerVersion = new HashMap<>();
|
||||
|
||||
for (String version : userVersions.values()) {
|
||||
if (!usersPerVersion.containsKey(version)) {
|
||||
usersPerVersion.put(version, 0);
|
||||
}
|
||||
usersPerVersion.replace(version, usersPerVersion.get(version) + 1);
|
||||
}
|
||||
return usersPerVersion;
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.protocolsupport;
|
||||
|
||||
import com.djrapitops.plan.Plan;
|
||||
import com.djrapitops.plan.data.plugin.HookHandler;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.pluginbridge.plan.Hook;
|
||||
import com.djrapitops.pluginbridge.plan.viaversion.ProtocolTable;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/**
|
||||
* Hook for ProtocolSupport plugin.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
@Singleton
|
||||
public class ProtocolSupportHook extends Hook {
|
||||
|
||||
private final Plan plugin;
|
||||
private final DBSystem dbSystem;
|
||||
|
||||
@Inject
|
||||
public ProtocolSupportHook(
|
||||
Plan plugin,
|
||||
DBSystem dbSystem
|
||||
) {
|
||||
super("protocolsupport.ProtocolSupport");
|
||||
this.plugin = plugin;
|
||||
this.dbSystem = dbSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hook(HookHandler handler) throws NoClassDefFoundError {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
Database database = dbSystem.getDatabase();
|
||||
database.executeTransaction(new Transaction() {
|
||||
@Override
|
||||
protected void performOperations() {
|
||||
execute(ProtocolTable.createTableSQL(database.getType()));
|
||||
}
|
||||
});
|
||||
|
||||
plugin.registerListener(new PlayerVersionListener(database));
|
||||
handler.addPluginDataSource(new ProtocolSupportData(database));
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.viaversion;
|
||||
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import us.myles.ViaVersion.api.ViaAPI;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Class responsible for listening join events for Version protocol.
|
||||
*
|
||||
* @author Rsl1122
|
||||
|
||||
*/
|
||||
public class BukkitPlayerVersionListener implements Listener {
|
||||
|
||||
private final ViaAPI viaAPI;
|
||||
|
||||
private final Database database;
|
||||
|
||||
BukkitPlayerVersionListener(
|
||||
ViaAPI viaAPI,
|
||||
Database database
|
||||
) {
|
||||
this.viaAPI = viaAPI;
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
UUID uuid = event.getPlayer().getUniqueId();
|
||||
int playerVersion = viaAPI.getPlayerVersion(uuid);
|
||||
database.executeTransaction(new StoreUsedProtocolTransaction(uuid, playerVersion));
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.viaversion;
|
||||
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
import us.myles.ViaVersion.api.ViaAPI;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Class responsible for listening join events for Version protocol.
|
||||
*
|
||||
* @author Rsl1122
|
||||
|
||||
*/
|
||||
public class BungeePlayerVersionListener implements Listener {
|
||||
|
||||
private final ViaAPI viaAPI;
|
||||
|
||||
private final Database database;
|
||||
|
||||
BungeePlayerVersionListener(
|
||||
ViaAPI viaAPI,
|
||||
Database database
|
||||
) {
|
||||
this.viaAPI = viaAPI;
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PostLoginEvent event) {
|
||||
UUID uuid = event.getPlayer().getUniqueId();
|
||||
int playerVersion = viaAPI.getPlayerVersion(uuid);
|
||||
database.executeTransaction(new StoreUsedProtocolTransaction(uuid, playerVersion));
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.viaversion;
|
||||
|
||||
import com.djrapitops.plan.db.DBType;
|
||||
import com.djrapitops.plan.db.access.Query;
|
||||
import com.djrapitops.plan.db.access.QueryAllStatement;
|
||||
import com.djrapitops.plan.db.access.QueryStatement;
|
||||
import com.djrapitops.plan.db.sql.parsing.CreateTableParser;
|
||||
import com.djrapitops.plan.db.sql.parsing.Select;
|
||||
import com.djrapitops.plan.db.sql.parsing.Sql;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Class responsible for version protocol information in Plan database.
|
||||
*
|
||||
* @author Rsl1122
|
||||
|
||||
*/
|
||||
public class ProtocolTable {
|
||||
|
||||
public static final String TABLE_NAME = "plan_version_protocol";
|
||||
public static final String COL_ID = "id";
|
||||
public static final String COL_UUID = "uuid";
|
||||
public static final String COL_PROTOCOL_VERSION = "protocol_version";
|
||||
|
||||
private ProtocolTable() {
|
||||
/* Static information class */
|
||||
}
|
||||
|
||||
public static String createTableSQL(DBType dbType) {
|
||||
return CreateTableParser.create(TABLE_NAME, dbType)
|
||||
.column(COL_ID, Sql.INT).primaryKey()
|
||||
.column(COL_UUID, Sql.varchar(36)).notNull().unique()
|
||||
.column(COL_PROTOCOL_VERSION, Sql.INT).notNull()
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Query<Integer> getProtocolVersion(UUID uuid) {
|
||||
String sql = "SELECT " + COL_PROTOCOL_VERSION + " FROM " + TABLE_NAME + " WHERE " + COL_UUID + "=?";
|
||||
|
||||
return new QueryStatement<Integer>(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, uuid.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer processResults(ResultSet set) throws SQLException {
|
||||
if (set.next()) {
|
||||
return set.getInt(COL_PROTOCOL_VERSION);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Query<Map<UUID, Integer>> getProtocolVersions() {
|
||||
return new QueryAllStatement<Map<UUID, Integer>>(Select.all(TABLE_NAME).toString(), 5000) {
|
||||
@Override
|
||||
public Map<UUID, Integer> processResults(ResultSet set) throws SQLException {
|
||||
Map<UUID, Integer> versions = new HashMap<>();
|
||||
while (set.next()) {
|
||||
String uuidS = set.getString(COL_UUID);
|
||||
UUID uuid = UUID.fromString(uuidS);
|
||||
versions.put(uuid, set.getInt(COL_PROTOCOL_VERSION));
|
||||
}
|
||||
return versions;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.viaversion;
|
||||
|
||||
import com.djrapitops.plan.db.access.ExecStatement;
|
||||
import com.djrapitops.plan.db.access.Executable;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE;
|
||||
import static com.djrapitops.pluginbridge.plan.viaversion.ProtocolTable.*;
|
||||
|
||||
/**
|
||||
* Transaction to store used version protocol.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class StoreUsedProtocolTransaction extends Transaction {
|
||||
|
||||
private final UUID playerUUID;
|
||||
private final int protocolVersion;
|
||||
|
||||
public StoreUsedProtocolTransaction(UUID playerUUID, int protocolVersion) {
|
||||
this.playerUUID = playerUUID;
|
||||
this.protocolVersion = protocolVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performOperations() {
|
||||
execute(storeProtocol());
|
||||
}
|
||||
|
||||
private Executable storeProtocol() {
|
||||
return connection -> {
|
||||
if (!updateProtocol().execute(connection)) {
|
||||
return insertProtocol().execute(connection);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
private Executable updateProtocol() {
|
||||
String sql = "UPDATE " + TABLE_NAME + " SET "
|
||||
+ COL_PROTOCOL_VERSION + "=?"
|
||||
+ WHERE + COL_UUID + "=?";
|
||||
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setInt(1, protocolVersion);
|
||||
statement.setString(2, playerUUID.toString());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Executable insertProtocol() {
|
||||
String sql = "INSERT INTO " + TABLE_NAME + " ("
|
||||
+ COL_UUID + ", "
|
||||
+ COL_PROTOCOL_VERSION
|
||||
+ ") VALUES (?, ?)";
|
||||
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, playerUUID.toString());
|
||||
statement.setInt(2, protocolVersion);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.viaversion;
|
||||
|
||||
import com.djrapitops.plan.Plan;
|
||||
import com.djrapitops.plan.data.plugin.HookHandler;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.pluginbridge.plan.Hook;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaAPI;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/**
|
||||
* A Class responsible for hooking to ViaVersion and registering data sources.
|
||||
*
|
||||
* @author Rsl1122
|
||||
|
||||
*/
|
||||
@Singleton
|
||||
public class ViaVersionBukkitHook extends Hook {
|
||||
|
||||
private final Plan plugin;
|
||||
private final DBSystem dbSystem;
|
||||
|
||||
@Inject
|
||||
public ViaVersionBukkitHook(
|
||||
Plan plugin,
|
||||
DBSystem dbSystem
|
||||
) {
|
||||
super("us.myles.ViaVersion.ViaVersionPlugin");
|
||||
this.plugin = plugin;
|
||||
this.dbSystem = dbSystem;
|
||||
}
|
||||
|
||||
public void hook(HookHandler handler) throws NoClassDefFoundError {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
ViaAPI api = Via.getAPI();
|
||||
Database database = dbSystem.getDatabase();
|
||||
database.executeTransaction(new Transaction() {
|
||||
@Override
|
||||
protected void performOperations() {
|
||||
execute(ProtocolTable.createTableSQL(database.getType()));
|
||||
}
|
||||
});
|
||||
|
||||
plugin.registerListener(new BukkitPlayerVersionListener(api, database));
|
||||
handler.addPluginDataSource(new ViaVersionData(database));
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.viaversion;
|
||||
|
||||
import com.djrapitops.plan.PlanBungee;
|
||||
import com.djrapitops.plan.data.plugin.HookHandler;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.pluginbridge.plan.Hook;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaAPI;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/**
|
||||
* A Class responsible for hooking to ViaVersion and registering data sources.
|
||||
*
|
||||
* @author Rsl1122
|
||||
|
||||
*/
|
||||
@Singleton
|
||||
public class ViaVersionBungeeHook extends Hook {
|
||||
|
||||
private final PlanBungee plugin;
|
||||
private final DBSystem dbSystem;
|
||||
|
||||
@Inject
|
||||
public ViaVersionBungeeHook(
|
||||
PlanBungee plugin,
|
||||
DBSystem dbSystem
|
||||
) {
|
||||
super("us.myles.ViaVersion.BungeePlugin");
|
||||
this.plugin = plugin;
|
||||
this.dbSystem = dbSystem;
|
||||
}
|
||||
|
||||
public void hook(HookHandler handler) throws NoClassDefFoundError {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
ViaAPI api = Via.getAPI();
|
||||
Database database = dbSystem.getDatabase();
|
||||
database.executeTransaction(new Transaction() {
|
||||
@Override
|
||||
protected void performOperations() {
|
||||
execute(ProtocolTable.createTableSQL(database.getType()));
|
||||
}
|
||||
});
|
||||
|
||||
plugin.registerListener(new BungeePlayerVersionListener(api, database));
|
||||
handler.addPluginDataSource(new ViaVersionData(database));
|
||||
}
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
/*
|
||||
* 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.pluginbridge.plan.viaversion;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.data.element.AnalysisContainer;
|
||||
import com.djrapitops.plan.data.element.InspectContainer;
|
||||
import com.djrapitops.plan.data.element.TableContainer;
|
||||
import com.djrapitops.plan.data.plugin.ContainerSize;
|
||||
import com.djrapitops.plan.data.plugin.PluginData;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.utilities.html.icon.Color;
|
||||
import com.djrapitops.plan.utilities.html.icon.Icon;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* PluginData for ViaVersion plugin.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
class ViaVersionData extends PluginData {
|
||||
|
||||
private final Database database;
|
||||
|
||||
ViaVersionData(Database database) {
|
||||
super(ContainerSize.THIRD, "ViaVersion");
|
||||
setPluginIcon(Icon.called("gamepad").of(Color.LIGHT_GREEN).build());
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InspectContainer getPlayerData(UUID uuid, InspectContainer inspectContainer) {
|
||||
try {
|
||||
int version = database.query(ProtocolTable.getProtocolVersion(uuid));
|
||||
|
||||
inspectContainer.addValue(getWithIcon("Last Join Version", Icon.called("signal").of(Color.LIGHT_GREEN)),
|
||||
getProtocolVersionString(version));
|
||||
} catch (DBOpException ex) {
|
||||
inspectContainer.addValue("Error", ex.toString());
|
||||
}
|
||||
|
||||
return inspectContainer;
|
||||
}
|
||||
|
||||
private String getProtocolVersionString(int version) {
|
||||
return version != -1 ? ProtocolVersion.getProtocol(version).getName() : "Not Yet Known";
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnalysisContainer getServerData(Collection<UUID> collection, AnalysisContainer analysisContainer) {
|
||||
Map<UUID, Integer> versions;
|
||||
|
||||
try {
|
||||
versions = database.query(ProtocolTable.getProtocolVersions());
|
||||
} catch (DBOpException ex) {
|
||||
analysisContainer.addValue("Error", ex.toString());
|
||||
return analysisContainer;
|
||||
}
|
||||
|
||||
Map<UUID, String> userVersions = versions.entrySet().stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, entry -> getProtocolVersionString(entry.getValue())));
|
||||
|
||||
analysisContainer.addPlayerTableValues(getWithIcon("Last Version", Icon.called("signal")), userVersions);
|
||||
|
||||
String versionS = getWithIcon("Version", Icon.called("signal"));
|
||||
String membersS = getWithIcon("Users", Icon.called("users"));
|
||||
TableContainer versionTable = new TableContainer(versionS, membersS);
|
||||
versionTable.setColor("light-green");
|
||||
Map<String, Integer> usersPerVersion = getUsersPerVersion(userVersions);
|
||||
for (Map.Entry<String, Integer> entry : usersPerVersion.entrySet()) {
|
||||
versionTable.addRow(entry.getKey(), entry.getValue());
|
||||
}
|
||||
analysisContainer.addTable("versionTable", versionTable);
|
||||
|
||||
return analysisContainer;
|
||||
}
|
||||
|
||||
private Map<String, Integer> getUsersPerVersion(Map<UUID, String> userVersions) {
|
||||
Map<String, Integer> usersPerVersion = new HashMap<>();
|
||||
|
||||
for (String version : userVersions.values()) {
|
||||
if (!usersPerVersion.containsKey(version)) {
|
||||
usersPerVersion.put(version, 0);
|
||||
}
|
||||
usersPerVersion.replace(version, usersPerVersion.get(version) + 1);
|
||||
}
|
||||
return usersPerVersion;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user