mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-01-25 01:21:41 +01:00
[Merge] Version 4.8.2 (#1036)
This commit is contained in:
commit
b0717f7ff0
@ -1,8 +1,8 @@
|
||||
plugins {
|
||||
id "com.jfrog.bintray" version "1.8.1"
|
||||
id "com.jfrog.bintray" version "1.8.4"
|
||||
}
|
||||
|
||||
ext.apiVersion = '0.0.3'
|
||||
ext.apiVersion = '0.0.4'
|
||||
|
||||
bintray {
|
||||
user = System.getenv('BINTRAY_USER')
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.capability;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* List of different capabilities current version provides.
|
||||
* <p>
|
||||
* The enum is package private to restrict direct access. This is to avoid NoClassDefFoundError in case
|
||||
* a wanted Capability is not provided in an earlier version.
|
||||
* <p>
|
||||
* Use {@link CapabilityService#hasCapability(String)} with name of a Capability to figure out if an API is available.
|
||||
* Example usage: {@code CapabilityService.getInstance().hasCapability("DATA_EXTENSION_VALUES")}.
|
||||
* <p>
|
||||
* If a capability is not available, attempting to use the capability might lead to exceptions.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
enum Capability {
|
||||
|
||||
/**
|
||||
* ExtensionService, DataExtension API base package, PluginInfo, Conditional, Tab, TabInfo, TabOrder and BooleanProvider, DoubleProvider, PercentageProvider, NumberProvider, StringProvider annotations.
|
||||
*/
|
||||
DATA_EXTENSION_VALUES,
|
||||
/**
|
||||
* DataExtension API table package, TableProvider, Table and Table.Factory
|
||||
*/
|
||||
DATA_EXTENSION_TABLES;
|
||||
|
||||
static Optional<Capability> getByName(String name) {
|
||||
if (name == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
try {
|
||||
return Optional.of(valueOf(name));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.capability;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Service for figuring out provided API capabilities.
|
||||
* <p>
|
||||
* {@link CapabilityService#registerEnableListener(Consumer)} to be notified of Plan reloads
|
||||
* {@link CapabilityService#hasCapability(String)} to check if a capability is available.
|
||||
* <p>
|
||||
* See {@link Capability} for list of capabilities provided by the current version.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public interface CapabilityService {
|
||||
|
||||
/**
|
||||
* Obtain instance of CapabilityService.
|
||||
*
|
||||
* @return CapabilityService 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 CapabilityService getInstance() {
|
||||
return Optional.ofNullable(CapabilityServiceHolder.service)
|
||||
.orElseThrow(() -> new IllegalStateException("CapabilityService has not been initialised yet."));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a method to be called when Plan reloads.
|
||||
*
|
||||
* @param isEnabledListener The boolean given to the method tells if Plan has enabled successfully.
|
||||
*/
|
||||
void registerEnableListener(Consumer<Boolean> isEnabledListener);
|
||||
|
||||
/**
|
||||
* Check if the API on the current version provides a capability.
|
||||
*
|
||||
* @param capabilityName Name of a capability
|
||||
* @return true if the capability is available.
|
||||
* @see Capability for different capabilityNames.
|
||||
*/
|
||||
default boolean hasCapability(String capabilityName) {
|
||||
return Capability.getByName(capabilityName).isPresent();
|
||||
}
|
||||
|
||||
class CapabilityServiceHolder {
|
||||
static CapabilityService service;
|
||||
|
||||
private CapabilityServiceHolder() {
|
||||
/* Static variable holder */
|
||||
}
|
||||
|
||||
static void set(CapabilityService service) {
|
||||
CapabilityServiceHolder.service = service;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -32,14 +32,14 @@ public enum ElementOrder {
|
||||
* Represents text - value pair box.
|
||||
*/
|
||||
VALUES,
|
||||
/**
|
||||
* Represents tables.
|
||||
*/
|
||||
TABLE,
|
||||
/**
|
||||
* Represents graphs.
|
||||
*/
|
||||
GRAPH;
|
||||
GRAPH,
|
||||
/**
|
||||
* Represents tables.
|
||||
*/
|
||||
TABLE;
|
||||
|
||||
public static String serialize(ElementOrder[] order) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
@ -43,6 +43,9 @@ public enum FormatType {
|
||||
NONE;
|
||||
|
||||
public static Optional<FormatType> getByName(String name) {
|
||||
if (name == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
try {
|
||||
return Optional.of(valueOf(name));
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.extension.annotation;
|
||||
|
||||
import com.djrapitops.plan.extension.icon.Color;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Method annotation to provide a Table.
|
||||
* <p>
|
||||
* Usage: {@code @TableProvider Table method(UUID playerUUID)}
|
||||
* <p>
|
||||
* Tables about players can have up to 4 columns.
|
||||
* Tables about server can have up to 5 columns.
|
||||
* <p>
|
||||
* It is recommended to place each table on their own tab with a {@link Tab} annotation on the same method.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface TableProvider {
|
||||
|
||||
/**
|
||||
* Determine the color of the table header.
|
||||
*
|
||||
* @return Preferred color. If none are specified defaults are used.
|
||||
*/
|
||||
Color tableColor() default Color.NONE;
|
||||
|
||||
}
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.extension.extractor;
|
||||
import com.djrapitops.plan.extension.DataExtension;
|
||||
import com.djrapitops.plan.extension.Group;
|
||||
import com.djrapitops.plan.extension.annotation.*;
|
||||
import com.djrapitops.plan.extension.table.Table;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
@ -103,6 +104,8 @@ public final class ExtensionExtractor {
|
||||
|
||||
MethodAnnotations.get(method, Conditional.class).ifPresent(annotation -> methodAnnotations.put(method, Conditional.class, annotation));
|
||||
MethodAnnotations.get(method, Tab.class).ifPresent(annotation -> methodAnnotations.put(method, Tab.class, annotation));
|
||||
|
||||
MethodAnnotations.get(method, TableProvider.class).ifPresent(annotation -> methodAnnotations.put(method, TableProvider.class, annotation));
|
||||
}
|
||||
|
||||
if (methodAnnotations.isEmpty()) {
|
||||
@ -166,6 +169,7 @@ public final class ExtensionExtractor {
|
||||
validateDoubleProviderAnnotations();
|
||||
validatePercentageProviderAnnotations();
|
||||
validateStringProviderAnnotations();
|
||||
validateTableProviderAnnotations();
|
||||
}
|
||||
|
||||
private void validateBooleanProviderAnnotations() {
|
||||
@ -238,6 +242,13 @@ public final class ExtensionExtractor {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateTableProviderAnnotations() {
|
||||
for (Method method : methodAnnotations.getMethodAnnotations(TableProvider.class).keySet()) {
|
||||
validateReturnType(method, Table.class);
|
||||
validateMethodArguments(method, false, UUID.class, String.class, Group.class);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateConditionals() {
|
||||
Collection<Conditional> conditionals = methodAnnotations.getAnnotations(Conditional.class);
|
||||
Collection<BooleanProvider> conditionProviders = methodAnnotations.getAnnotations(BooleanProvider.class);
|
||||
|
@ -48,6 +48,9 @@ public enum Color {
|
||||
NONE;
|
||||
|
||||
public static Optional<Color> getByName(String name) {
|
||||
if (name == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
try {
|
||||
return Optional.of(valueOf(name));
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
@ -29,6 +29,9 @@ public enum Family {
|
||||
BRAND;
|
||||
|
||||
public static Optional<Family> getByName(String name) {
|
||||
if (name == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
try {
|
||||
return Optional.of(valueOf(name));
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
@ -64,8 +64,9 @@ public class Icon {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
public Icon setColor(Color color) {
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,213 @@
|
||||
/*
|
||||
* 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.extension.table;
|
||||
|
||||
import com.djrapitops.plan.extension.ElementOrder;
|
||||
import com.djrapitops.plan.extension.icon.Color;
|
||||
import com.djrapitops.plan.extension.icon.Icon;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Object for giving Plan table data.
|
||||
* <p>
|
||||
* Usage: {@code Table.builder().columnOne("columnName", new Icon(...)).addRow("Your", "Row", "Data").build()}
|
||||
* <p>
|
||||
* Tables about players can have up to 4 columns.
|
||||
* Tables about server can have up to 5 columns.
|
||||
* <p>
|
||||
* Icon colors are ignored.
|
||||
* <p>
|
||||
* If a row has more values than the column limit, they are ignored.
|
||||
* If a row has less values than table columns, a '-' is displayed to distinguish a missing value.
|
||||
* <p>
|
||||
* If a table has no columns or rows, it is ignored.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.extension.annotation.TableProvider for associated annotation.
|
||||
*/
|
||||
public final class Table {
|
||||
|
||||
private final String[] columns;
|
||||
private final Icon[] icons;
|
||||
|
||||
private final List<Object[]> rows;
|
||||
|
||||
private Table() {
|
||||
/* Tables are constructed with the factory. */
|
||||
|
||||
columns = new String[5];
|
||||
icons = new Icon[5];
|
||||
rows = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Table Factory.
|
||||
*
|
||||
* @return a new Table Factory.
|
||||
*/
|
||||
public static Table.Factory builder() {
|
||||
return new Table.Factory();
|
||||
}
|
||||
|
||||
public String[] getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
public int getMaxColumnSize() {
|
||||
int columnCount = 0;
|
||||
for (String column : columns) {
|
||||
if (column == null) {
|
||||
break; // Prevent having one null column between two columns
|
||||
}
|
||||
columnCount++;
|
||||
}
|
||||
return columnCount;
|
||||
}
|
||||
|
||||
public Icon[] getIcons() {
|
||||
return icons;
|
||||
}
|
||||
|
||||
public List<Object[]> getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for creating new {@link Table} objects.
|
||||
*/
|
||||
public static final class Factory {
|
||||
|
||||
private final Table building;
|
||||
|
||||
// These variable are related to implementation, and is used when the table is being fetched from the database.
|
||||
Color color; // Table color is defined with TableProvider annotation.
|
||||
String tableName; // tableName is defined by method name annotated by TableProvider.
|
||||
String tabName; // Tab name is defined with Tab annotation
|
||||
int tabPriority; // Tab priority is defined with TabOrder annotation
|
||||
ElementOrder[] tabOrder; // Tab element order is defined with TabInfo annotation
|
||||
Icon tabIcon; // Tab icon is defined with TabInfo annotation
|
||||
|
||||
private Factory() {
|
||||
building = new Table();
|
||||
}
|
||||
|
||||
private Factory column(int indx, String columnName, Icon icon) {
|
||||
building.columns[indx] = columnName;
|
||||
building.icons[indx] = icon != null ? Icon.called(icon.getName()).of(icon.getFamily()).build() : Icon.called("question").build();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set first column name and icon.
|
||||
*
|
||||
* @param columnName Name of the column.
|
||||
* @param icon Icon of the column, color is ignored.
|
||||
* @return Factory.
|
||||
*/
|
||||
public Factory columnOne(String columnName, Icon icon) {
|
||||
return column(0, columnName, icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set second column name and icon.
|
||||
*
|
||||
* @param columnName Name of the column.
|
||||
* @param icon Icon of the column, color is ignored.
|
||||
* @return Factory.
|
||||
*/
|
||||
public Factory columnTwo(String columnName, Icon icon) {
|
||||
return column(1, columnName, icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set third column name and icon.
|
||||
*
|
||||
* @param columnName Name of the column.
|
||||
* @param icon Icon of the column, color is ignored.
|
||||
* @return Factory.
|
||||
*/
|
||||
public Factory columnThree(String columnName, Icon icon) {
|
||||
return column(2, columnName, icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set fourth column name and icon.
|
||||
*
|
||||
* @param columnName Name of the column.
|
||||
* @param icon Icon of the column, color is ignored.
|
||||
* @return Factory.
|
||||
*/
|
||||
public Factory columnFour(String columnName, Icon icon) {
|
||||
return column(3, columnName, icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set fifth column name and icon.
|
||||
*
|
||||
* @param columnName Name of the column.
|
||||
* @param icon Icon of the column, color is ignored.
|
||||
* @return Factory.
|
||||
*/
|
||||
public Factory columnFive(String columnName, Icon icon) {
|
||||
return column(4, columnName, icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a row of values to the table.
|
||||
*
|
||||
* @param values One value per column you have defined, {@code Object#toString()} will be called on the objects.
|
||||
* @return Factory.
|
||||
* @throws IllegalArgumentException If given varargs for 'values' is null.
|
||||
*/
|
||||
public Factory addRow(Object... values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("'values' for Table#addRow can not be null!");
|
||||
}
|
||||
|
||||
if (values.length == 0 || areAllValuesNull(values)) {
|
||||
return this; // Ignore row when all values are null or no values are present.
|
||||
}
|
||||
|
||||
building.rows.add(Arrays.copyOf(values, 5));
|
||||
return this;
|
||||
}
|
||||
|
||||
private boolean areAllValuesNull(Object[] values) {
|
||||
boolean allNull = true;
|
||||
for (Object value : values) {
|
||||
if (value != null) {
|
||||
allNull = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return allNull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish building the table.
|
||||
*
|
||||
* @return Finished Table object.
|
||||
*/
|
||||
public Table build() {
|
||||
return building;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -166,6 +166,20 @@ class ExtensionExtractorTest {
|
||||
assertEquals("Extension.method has invalid return type. was: java.lang.Double, expected: java.lang.String", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void tableProviderMustReturnTable() {
|
||||
@PluginInfo(name = "Extension")
|
||||
class Extension implements DataExtension {
|
||||
@TableProvider
|
||||
public Double method(UUID playerUUID) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
ExtensionExtractor underTest = new ExtensionExtractor(new Extension());
|
||||
assertEquals("Extension.method has invalid return type. was: java.lang.Double, expected: com.djrapitops.plan.extension.table.Table", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void booleanProviderCanNotSupplyItsOwnConditional() {
|
||||
@PluginInfo(name = "Extension")
|
||||
|
@ -2,9 +2,9 @@ plugins {
|
||||
id "java"
|
||||
id "jacoco"
|
||||
id "checkstyle"
|
||||
id "org.sonarqube" version "2.6.2"
|
||||
id "net.ltgt.apt" version "0.19"
|
||||
id "net.ltgt.apt-idea" version "0.19"
|
||||
id "org.sonarqube" version "2.7"
|
||||
id "net.ltgt.apt" version "0.21"
|
||||
id "net.ltgt.apt-idea" version "0.21"
|
||||
id "com.github.johnrengelman.shadow" version "5.0.0"
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ allprojects {
|
||||
wrapper.gradleVersion = "5.0"
|
||||
|
||||
group "com.djrapitops"
|
||||
version "4.8.1"
|
||||
version "4.8.2"
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
@ -43,11 +43,11 @@ subprojects {
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
ext.daggerVersion = "2.21"
|
||||
ext.daggerCompilerVersion = "2.21"
|
||||
ext.daggerVersion = "2.22.1"
|
||||
ext.daggerCompilerVersion = "2.22.1"
|
||||
|
||||
ext.abstractPluginFrameworkVersion = "3.4.1"
|
||||
ext.planPluginBridgeVersion = "4.7.0"
|
||||
ext.planPluginBridgeVersion = "4.8.2-R0.3"
|
||||
|
||||
ext.bukkitVersion = "1.12.2-R0.1-SNAPSHOT"
|
||||
ext.spigotVersion = "1.12.2-R0.1-SNAPSHOT"
|
||||
@ -61,12 +61,12 @@ subprojects {
|
||||
ext.commonsTextVersion = "1.6"
|
||||
ext.htmlCompressorVersion = "1.5.2"
|
||||
ext.caffeineVersion = "2.7.0"
|
||||
ext.h2Version = "1.4.196"
|
||||
ext.h2Version = "1.4.199"
|
||||
ext.hikariVersion = "3.3.1"
|
||||
ext.slf4jVersion = "1.7.26"
|
||||
ext.geoIpVersion = "2.12.0"
|
||||
ext.guavaVersion = "26.0-jre"
|
||||
ext.bstatsVersion = "1.2"
|
||||
ext.bstatsVersion = "1.4"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@ -89,7 +89,7 @@ subprojects {
|
||||
url = "https://repo.velocitypowered.com/snapshots/"
|
||||
}
|
||||
maven { // bStats Repository
|
||||
url = "http://repo.bstats.org/content/repositories/releases/"
|
||||
url = "https://repo.codemc.org/repository/maven-public"
|
||||
}
|
||||
maven { // PlanPluginBridge Repository
|
||||
url = "https://dl.bintray.com/rsl1122/Plan-repository"
|
||||
@ -103,18 +103,18 @@ subprojects {
|
||||
testAnnotationProcessor "com.google.dagger:dagger-compiler:$daggerCompilerVersion"
|
||||
|
||||
// Test Tooling Dependencies
|
||||
testCompile "org.junit.jupiter:junit-jupiter-engine:5.4.1" // JUnit 5
|
||||
testCompile "org.junit.platform:junit-platform-runner:1.4.1" // JUnit 4 runner for JUnit 5 tests
|
||||
testCompile "org.junit.vintage:junit-vintage-engine:5.4.1" // JUnit 4 compatibility for JUnit 5
|
||||
testCompile "org.junit.jupiter:junit-jupiter-params:5.4.1" // JUnit 5, parameterized tests
|
||||
testCompile "org.mockito:mockito-core:2.25.1" // Mockito Core
|
||||
testCompile "org.mockito:mockito-junit-jupiter:2.25.1" // Mockito JUnit 5 Extension
|
||||
testCompile "org.junit.jupiter:junit-jupiter-engine:5.4.2" // JUnit 5
|
||||
testCompile "org.junit.platform:junit-platform-runner:1.4.2" // JUnit 4 runner for JUnit 5 tests
|
||||
testCompile "org.junit.vintage:junit-vintage-engine:5.4.2" // JUnit 4 compatibility for JUnit 5
|
||||
testCompile "org.junit.jupiter:junit-jupiter-params:5.4.2" // JUnit 5, parameterized tests
|
||||
testCompile "org.mockito:mockito-core:2.27.0" // Mockito Core
|
||||
testCompile "org.mockito:mockito-junit-jupiter:2.27.0" // Mockito JUnit 5 Extension
|
||||
testCompile "org.seleniumhq.selenium:selenium-java:3.141.59" // Selenium (Browser tests)
|
||||
testCompile "com.jayway.awaitility:awaitility:1.7.0" // Awaitility (Concurrent wait conditions)
|
||||
|
||||
// Testing dependencies required by Plan
|
||||
testCompile "org.xerial:sqlite-jdbc:3.27.2.1" // SQLite
|
||||
testCompile "mysql:mysql-connector-java:8.0.15" // MySQL
|
||||
testCompile "mysql:mysql-connector-java:8.0.16" // MySQL
|
||||
}
|
||||
|
||||
configurations {
|
||||
|
@ -26,6 +26,7 @@ import com.djrapitops.plan.system.settings.theme.PlanColorScheme;
|
||||
import com.djrapitops.plugin.BukkitPlugin;
|
||||
import com.djrapitops.plugin.benchmarking.Benchmark;
|
||||
import com.djrapitops.plugin.command.ColorScheme;
|
||||
import com.djrapitops.plugin.task.AbsRunnable;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.util.logging.Level;
|
||||
@ -52,7 +53,7 @@ public class Plan extends BukkitPlugin implements PlanPlugin {
|
||||
locale = system.getLocaleSystem().getLocale();
|
||||
system.enable();
|
||||
|
||||
new BStatsBukkit(this).registerMetrics();
|
||||
registerMetrics();
|
||||
|
||||
logger.debug("Verbose debug messages are enabled.");
|
||||
String benchTime = " (" + timings.end("Enable").map(Benchmark::toDurationString).orElse("-") + ")";
|
||||
@ -80,6 +81,19 @@ public class Plan extends BukkitPlugin implements PlanPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
private void registerMetrics() {
|
||||
Plan plugin = this;
|
||||
// Spigot 1.14 requires Sync events to be fired from a server thread.
|
||||
// Registering a service fires a sync event, and bStats registers a service,
|
||||
// so this has to be run on the server thread.
|
||||
runnableFactory.create("Register Metrics task", new AbsRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
new BStatsBukkit(plugin).registerMetrics();
|
||||
}
|
||||
}).runTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorScheme getColorScheme() {
|
||||
return PlanColorScheme.create(system.getConfigSystem().getConfig(), logger);
|
||||
|
@ -33,10 +33,8 @@ import com.djrapitops.plan.system.importing.data.BukkitUserImportRefiner;
|
||||
import com.djrapitops.plan.system.importing.data.ServerImportData;
|
||||
import com.djrapitops.plan.system.importing.data.UserImportData;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.utilities.SHA256Hash;
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
@ -177,11 +175,11 @@ public abstract class BukkitImporter implements Importer {
|
||||
}
|
||||
|
||||
private BaseUser toBaseUser(UserImportData userImportData) {
|
||||
UUID uuid = userImportData.getUuid();
|
||||
String name = userImportData.getName();
|
||||
UUID playerUUID = userImportData.getUuid();
|
||||
String playerName = userImportData.getName();
|
||||
long registered = userImportData.getRegistered();
|
||||
int timesKicked = userImportData.getTimesKicked();
|
||||
return new BaseUser(uuid, name, registered, timesKicked);
|
||||
return new BaseUser(playerUUID, playerName, registered, timesKicked);
|
||||
}
|
||||
|
||||
private UserInfo toUserInfo(UserImportData userImportData) {
|
||||
@ -211,11 +209,7 @@ public abstract class BukkitImporter implements Importer {
|
||||
return userImportData.getIps().parallelStream()
|
||||
.map(ip -> {
|
||||
String geoLoc = geolocationCache.getCountry(ip);
|
||||
try {
|
||||
return new GeoInfo(ip, geoLoc, date, new SHA256Hash(ip).create());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
return new GeoInfo(ip, geoLoc, date);
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ public class BukkitServerProperties extends ServerProperties {
|
||||
|
||||
public BukkitServerProperties(Server server) {
|
||||
super(
|
||||
server.getServerId(),
|
||||
server.getName(),
|
||||
server.getPort(),
|
||||
server.getVersion(),
|
||||
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.system.listeners;
|
||||
import com.djrapitops.plan.Plan;
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.api.events.PlanBukkitEnableEvent;
|
||||
import com.djrapitops.plan.capability.CapabilityServiceImplementation;
|
||||
import com.djrapitops.plan.system.listeners.bukkit.*;
|
||||
import com.djrapitops.plan.system.status.Status;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -83,7 +84,9 @@ public class BukkitListenerSystem extends ListenerSystem {
|
||||
|
||||
@Override
|
||||
public void callEnableEvent(PlanPlugin plugin) {
|
||||
PlanBukkitEnableEvent event = new PlanBukkitEnableEvent(plugin.isSystemEnabled());
|
||||
boolean isEnabled = plugin.isSystemEnabled();
|
||||
PlanBukkitEnableEvent event = new PlanBukkitEnableEvent(isEnabled);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
CapabilityServiceImplementation.notifyAboutEnable(isEnabled);
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import com.djrapitops.plan.ShutdownHook;
|
||||
import com.djrapitops.plan.db.tasks.DBCleanTask;
|
||||
import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask;
|
||||
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.system.settings.paths.DataGatheringSettings;
|
||||
import com.djrapitops.plan.system.settings.paths.TimeSettings;
|
||||
import com.djrapitops.plan.system.tasks.bukkit.BukkitTPSCountTimer;
|
||||
import com.djrapitops.plan.system.tasks.bukkit.PaperTPSCountTimer;
|
||||
@ -90,9 +91,12 @@ public class BukkitTaskSystem extends ServerTaskSystem {
|
||||
public void enable() {
|
||||
super.enable();
|
||||
try {
|
||||
plugin.registerListener(pingCountTimer);
|
||||
long startDelay = TimeAmount.toTicks(config.get(TimeSettings.PING_SERVER_ENABLE_DELAY), TimeUnit.MILLISECONDS);
|
||||
registerTask(pingCountTimer).runTaskTimer(startDelay, 40L);
|
||||
Long pingDelay = config.get(TimeSettings.PING_SERVER_ENABLE_DELAY);
|
||||
if (pingDelay < TimeUnit.HOURS.toMillis(1L) && config.get(DataGatheringSettings.PING)) {
|
||||
plugin.registerListener(pingCountTimer);
|
||||
long startDelay = TimeAmount.toTicks(pingDelay, TimeUnit.MILLISECONDS);
|
||||
registerTask(pingCountTimer).runTaskTimer(startDelay, 40L);
|
||||
}
|
||||
} catch (ExceptionInInitializerError | NoClassDefFoundError ignore) {
|
||||
// Running CraftBukkit
|
||||
}
|
||||
|
@ -64,7 +64,6 @@ public class PingCountTimerBukkit extends AbsRunnable implements Listener {
|
||||
|
||||
//the server is pinging the client every 40 Ticks (2 sec) - so check it then
|
||||
//https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/PlayerConnection.java#L178
|
||||
public static final int PING_INTERVAL = 2 * 20;
|
||||
|
||||
private static final boolean PING_METHOD_AVAILABLE;
|
||||
|
||||
@ -196,6 +195,10 @@ public class PingCountTimerBukkit extends AbsRunnable implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent joinEvent) {
|
||||
Player player = joinEvent.getPlayer();
|
||||
Long pingDelay = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY);
|
||||
if (pingDelay >= TimeUnit.HOURS.toMillis(2L)) {
|
||||
return;
|
||||
}
|
||||
runnableFactory.create("Add Player to Ping list", new AbsRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -203,7 +206,7 @@ public class PingCountTimerBukkit extends AbsRunnable implements Listener {
|
||||
addPlayer(player);
|
||||
}
|
||||
}
|
||||
}).runTaskLater(TimeAmount.toTicks(config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY), TimeUnit.MILLISECONDS));
|
||||
}).runTaskLater(TimeAmount.toTicks(pingDelay, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -122,7 +122,7 @@ public final class Reflection {
|
||||
try {
|
||||
return (T) field.get(target);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("Cannot access reflection.", e);
|
||||
throw new IllegalStateException("Cannot access reflection.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ public final class Reflection {
|
||||
try {
|
||||
field.set(target, value);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("Cannot access reflection.", e);
|
||||
throw new IllegalStateException("Cannot access reflection.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ public final class Reflection {
|
||||
try {
|
||||
return method.invoke(target, arguments);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot invoke method " + method, e);
|
||||
throw new IllegalStateException("Cannot invoke method " + method, e);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -240,7 +240,7 @@ public final class Reflection {
|
||||
try {
|
||||
return constructor.newInstance(arguments);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot invoke constructor " + constructor, e);
|
||||
throw new IllegalStateException("Cannot invoke constructor " + constructor, e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -17,7 +17,10 @@
|
||||
package com.djrapitops.plan;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.EnableException;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.queries.objects.ServerQueries;
|
||||
import com.djrapitops.plan.system.PlanSystem;
|
||||
import com.djrapitops.plan.system.info.server.Server;
|
||||
import com.djrapitops.plan.system.settings.ConfigSettingKeyTest;
|
||||
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.system.settings.paths.WebserverSettings;
|
||||
@ -31,9 +34,11 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import rules.BukkitComponentMocker;
|
||||
import rules.ComponentMocker;
|
||||
import utilities.OptionalAssert;
|
||||
import utilities.RandomData;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@ -71,6 +76,21 @@ public class BukkitSystemTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctWebAddressInDatabaseAfterEnable() throws EnableException {
|
||||
try {
|
||||
system.enable();
|
||||
Database database = system.getDatabaseSystem().getDatabase();
|
||||
String expectedAddress = system.getWebServerSystem().getWebServer().getAccessAddress();
|
||||
Optional<String> found = database.query(ServerQueries.fetchServerMatchingIdentifier(system.getServerInfo().getServerUUID()))
|
||||
.map(Server::getWebAddress);
|
||||
|
||||
OptionalAssert.equals(expectedAddress, found);
|
||||
} finally {
|
||||
system.disable();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bukkitSystemHasDefaultConfigValuesAfterEnable() throws EnableException, IllegalAccessException {
|
||||
try {
|
||||
|
@ -31,7 +31,6 @@ public class BungeeServerProperties extends ServerProperties {
|
||||
|
||||
public BungeeServerProperties(ProxyServer server, PlanConfig config) {
|
||||
super(
|
||||
server.getServers().toString(),
|
||||
"BungeeCord",
|
||||
-1,
|
||||
server.getVersion(),
|
||||
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.system.listeners;
|
||||
import com.djrapitops.plan.PlanBungee;
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.api.events.PlanBungeeEnableEvent;
|
||||
import com.djrapitops.plan.capability.CapabilityServiceImplementation;
|
||||
import com.djrapitops.plan.system.listeners.bungee.PlayerOnlineListener;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -46,7 +47,9 @@ public class BungeeListenerSystem extends ListenerSystem {
|
||||
|
||||
@Override
|
||||
public void callEnableEvent(PlanPlugin plugin) {
|
||||
PlanBungeeEnableEvent event = new PlanBungeeEnableEvent(plugin.isSystemEnabled());
|
||||
boolean isEnabled = plugin.isSystemEnabled();
|
||||
PlanBungeeEnableEvent event = new PlanBungeeEnableEvent(isEnabled);
|
||||
((PlanBungee) plugin).getProxy().getPluginManager().callEvent(event);
|
||||
CapabilityServiceImplementation.notifyAboutEnable(isEnabled);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import com.djrapitops.plan.PlanBungee;
|
||||
import com.djrapitops.plan.db.tasks.DBCleanTask;
|
||||
import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask;
|
||||
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.system.settings.paths.DataGatheringSettings;
|
||||
import com.djrapitops.plan.system.settings.paths.TimeSettings;
|
||||
import com.djrapitops.plan.system.tasks.bungee.BungeeTPSCountTimer;
|
||||
import com.djrapitops.plan.system.tasks.bungee.PingCountTimerBungee;
|
||||
@ -87,9 +88,12 @@ public class BungeeTaskSystem extends TaskSystem {
|
||||
registerTask(networkPageRefreshTask).runTaskTimerAsynchronously(1500, TimeAmount.toTicks(5L, TimeUnit.MINUTES));
|
||||
registerTask(logsFolderCleanTask).runTaskLaterAsynchronously(TimeAmount.toTicks(30L, TimeUnit.SECONDS));
|
||||
|
||||
plugin.registerListener(pingCountTimer);
|
||||
long startDelay = TimeAmount.toTicks(config.get(TimeSettings.PING_SERVER_ENABLE_DELAY), TimeUnit.MILLISECONDS);
|
||||
registerTask(pingCountTimer).runTaskTimer(startDelay, PingCountTimerBungee.PING_INTERVAL);
|
||||
Long pingDelay = config.get(TimeSettings.PING_SERVER_ENABLE_DELAY);
|
||||
if (pingDelay < TimeUnit.HOURS.toMillis(1L) && config.get(DataGatheringSettings.PING)) {
|
||||
plugin.registerListener(pingCountTimer);
|
||||
long startDelay = TimeAmount.toTicks(pingDelay, TimeUnit.MILLISECONDS);
|
||||
registerTask(pingCountTimer).runTaskTimer(startDelay, 40L);
|
||||
}
|
||||
|
||||
registerTask(playersPageRefreshTask)
|
||||
.runTaskTimerAsynchronously(TimeAmount.toTicks(5L, TimeUnit.MINUTES), TimeAmount.toTicks(5L, TimeUnit.MINUTES));
|
||||
|
@ -52,10 +52,6 @@ import java.util.concurrent.TimeUnit;
|
||||
@Singleton
|
||||
public class PingCountTimerBungee extends AbsRunnable implements Listener {
|
||||
|
||||
//the server is pinging the client every 40 Ticks (2 sec) - so check it then
|
||||
//https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/PlayerConnection.java#L178
|
||||
public static final int PING_INTERVAL = 2 * 20;
|
||||
|
||||
private final Map<UUID, List<DateObj<Integer>>> playerHistory;
|
||||
|
||||
private final PlanConfig config;
|
||||
@ -121,6 +117,10 @@ public class PingCountTimerBungee extends AbsRunnable implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerJoin(ServerConnectedEvent joinEvent) {
|
||||
ProxiedPlayer player = joinEvent.getPlayer();
|
||||
Long pingDelay = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY);
|
||||
if (pingDelay >= TimeUnit.HOURS.toMillis(2L)) {
|
||||
return;
|
||||
}
|
||||
runnableFactory.create("Add Player to Ping list", new AbsRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -128,7 +128,7 @@ public class PingCountTimerBungee extends AbsRunnable implements Listener {
|
||||
addPlayer(player);
|
||||
}
|
||||
}
|
||||
}).runTaskLater(TimeAmount.toTicks(config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY), TimeUnit.MILLISECONDS));
|
||||
}).runTaskLater(TimeAmount.toTicks(pingDelay, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -21,6 +21,7 @@ import com.djrapitops.plan.db.SQLiteDB;
|
||||
import com.djrapitops.plan.system.PlanSystem;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.system.settings.paths.DatabaseSettings;
|
||||
import com.djrapitops.plan.system.settings.paths.ProxySettings;
|
||||
import com.djrapitops.plan.system.settings.paths.WebserverSettings;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
@ -33,9 +34,11 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import rules.BungeeComponentMocker;
|
||||
import rules.ComponentMocker;
|
||||
import utilities.CIProperties;
|
||||
import utilities.RandomData;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
/**
|
||||
* Test for Bungee PlanSystem.
|
||||
@ -69,6 +72,7 @@ public class BungeeSystemTest {
|
||||
dbSystem.setActiveDatabase(db);
|
||||
|
||||
bungeeSystem.enable();
|
||||
assertTrue(bungeeSystem.isEnabled());
|
||||
} finally {
|
||||
bungeeSystem.disable();
|
||||
}
|
||||
@ -90,8 +94,7 @@ public class BungeeSystemTest {
|
||||
db.setTransactionExecutorServiceProvider(MoreExecutors::newDirectExecutorService);
|
||||
dbSystem.setActiveDatabase(db);
|
||||
|
||||
bungeeSystem.enable();
|
||||
assertTrue(bungeeSystem.isEnabled());
|
||||
bungeeSystem.enable(); // Throws EnableException
|
||||
} finally {
|
||||
bungeeSystem.disable();
|
||||
}
|
||||
@ -107,7 +110,31 @@ public class BungeeSystemTest {
|
||||
config.set(WebserverSettings.PORT, TEST_PORT_NUMBER);
|
||||
config.set(ProxySettings.IP, "8.8.8.8");
|
||||
|
||||
bungeeSystem.enable(); // Throws EnableException
|
||||
} finally {
|
||||
bungeeSystem.disable();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnableWithMySQL() throws EnableException {
|
||||
boolean isCI = Boolean.parseBoolean(System.getenv(CIProperties.IS_CI_SERVICE));
|
||||
assumeTrue(isCI);
|
||||
|
||||
PlanSystem bungeeSystem = component.getPlanSystem();
|
||||
try {
|
||||
PlanConfig config = bungeeSystem.getConfigSystem().getConfig();
|
||||
config.set(DatabaseSettings.MYSQL_DATABASE, "Plan");
|
||||
config.set(DatabaseSettings.MYSQL_USER, "travis");
|
||||
config.set(DatabaseSettings.MYSQL_PASS, "");
|
||||
config.set(DatabaseSettings.MYSQL_HOST, "127.0.0.1");
|
||||
config.set(DatabaseSettings.TYPE, "MySQL");
|
||||
|
||||
config.set(WebserverSettings.PORT, TEST_PORT_NUMBER);
|
||||
config.set(ProxySettings.IP, "8.8.8.8");
|
||||
|
||||
bungeeSystem.enable();
|
||||
assertTrue(bungeeSystem.isEnabled());
|
||||
} finally {
|
||||
bungeeSystem.disable();
|
||||
}
|
||||
|
@ -14,31 +14,31 @@
|
||||
* 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.redprotect;
|
||||
package com.djrapitops.plan.api.exceptions;
|
||||
|
||||
import com.djrapitops.plan.data.plugin.HookHandler;
|
||||
import com.djrapitops.pluginbridge.plan.Hook;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import com.djrapitops.plan.extension.implementation.providers.MethodWrapper;
|
||||
|
||||
/**
|
||||
* Hook for RedProtect plugin.
|
||||
* Exception that is thrown when a call to a DataExtension method throws an exception.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
@Singleton
|
||||
public class RedProtectHook extends Hook {
|
||||
public class DataExtensionMethodCallException extends IllegalStateException {
|
||||
|
||||
@Inject
|
||||
public RedProtectHook() {
|
||||
super("br.net.fabiozumbi12.RedProtect.Bukkit.RedProtect");
|
||||
private final String pluginName;
|
||||
private final MethodWrapper method;
|
||||
|
||||
public DataExtensionMethodCallException(Throwable cause, String pluginName, MethodWrapper method) {
|
||||
super(cause);
|
||||
this.pluginName = pluginName;
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hook(HookHandler handler) throws NoClassDefFoundError {
|
||||
if (enabled) {
|
||||
handler.addPluginDataSource(new RedProtectData());
|
||||
}
|
||||
public String getPluginName() {
|
||||
return pluginName;
|
||||
}
|
||||
|
||||
public MethodWrapper getMethod() {
|
||||
return method;
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.capability;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Singleton instance implementation for {@link CapabilityService}.
|
||||
* <p>
|
||||
* Only one instance exists per runtime in order to notify others when the plugin enables.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class CapabilityServiceImplementation implements CapabilityService {
|
||||
|
||||
private List<Consumer<Boolean>> enableListeners;
|
||||
|
||||
private CapabilityServiceImplementation() {
|
||||
/* Inject required for dagger */
|
||||
CapabilityServiceHolder.set(this);
|
||||
enableListeners = new ArrayList<>();
|
||||
}
|
||||
|
||||
private static CapabilityServiceImplementation get() {
|
||||
if (CapabilityServiceHolder.service == null) {
|
||||
return new CapabilityServiceImplementation();
|
||||
}
|
||||
return (CapabilityServiceImplementation) CapabilityServiceHolder.service;
|
||||
}
|
||||
|
||||
public static void notifyAboutEnable(boolean isEnabled) {
|
||||
for (Consumer<Boolean> enableListener : get().enableListeners) {
|
||||
enableListener.accept(isEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEnableListener(Consumer<Boolean> enableListener) {
|
||||
enableListeners.add(enableListener);
|
||||
}
|
||||
}
|
@ -32,7 +32,6 @@ import com.djrapitops.plan.system.locale.lang.ManageLang;
|
||||
import com.djrapitops.plan.system.processing.Processing;
|
||||
import com.djrapitops.plan.system.settings.Permissions;
|
||||
import com.djrapitops.plan.system.webserver.WebServer;
|
||||
import com.djrapitops.plugin.api.Check;
|
||||
import com.djrapitops.plugin.command.ColorScheme;
|
||||
import com.djrapitops.plugin.command.CommandNode;
|
||||
import com.djrapitops.plugin.command.CommandType;
|
||||
@ -82,7 +81,7 @@ public class ManageConDebugCommand extends CommandNode {
|
||||
this.webServer = webServer;
|
||||
this.dbSystem = dbSystem;
|
||||
|
||||
setShortHelp(locale.getString(Check.isBungeeAvailable() || Check.isVelocityAvailable() ? CmdHelpLang.CON : CmdHelpLang.MANAGE_CON));
|
||||
setShortHelp(locale.getString(serverInfo.getServer().isProxy() ? CmdHelpLang.CON : CmdHelpLang.MANAGE_CON));
|
||||
setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_CON));
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ public class ManageDisableCommand extends CommandNode {
|
||||
Verify.isTrue(args.length >= 1,
|
||||
() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments()))));
|
||||
|
||||
if ("kickcount".equals(args[0].toLowerCase())) {
|
||||
if ("kickcount".equalsIgnoreCase(args[0])) {
|
||||
status.setCountKicks(false);
|
||||
sender.sendMessage(locale.getString(CommandLang.FEATURE_DISABLED, "Kick Counting"));
|
||||
} else {
|
||||
|
@ -18,13 +18,11 @@ package com.djrapitops.plan.data.container;
|
||||
|
||||
import com.djrapitops.plan.data.store.objects.DateHolder;
|
||||
import com.djrapitops.plan.data.store.objects.DateMap;
|
||||
import com.djrapitops.plan.utilities.SHA256Hash;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* Data class that contains information about IP and Geolocation.
|
||||
@ -35,18 +33,16 @@ public class GeoInfo implements DateHolder, Serializable {
|
||||
|
||||
private final String ip;
|
||||
private final String geolocation;
|
||||
private final String ipHash;
|
||||
private final long date;
|
||||
|
||||
public GeoInfo(InetAddress address, String geolocation, long lastUsed) throws NoSuchAlgorithmException {
|
||||
this(formatIP(address), geolocation, lastUsed, new SHA256Hash(address.getHostAddress()).create());
|
||||
public GeoInfo(InetAddress address, String geolocation, long lastUsed) {
|
||||
this(formatIP(address), geolocation, lastUsed);
|
||||
}
|
||||
|
||||
public GeoInfo(String ip, String geolocation, long date, String ipHash) {
|
||||
public GeoInfo(String ip, String geolocation, long date) {
|
||||
this.ip = ip;
|
||||
this.geolocation = geolocation;
|
||||
this.date = date;
|
||||
this.ipHash = ipHash;
|
||||
}
|
||||
|
||||
public static DateMap<GeoInfo> intoDateMap(Iterable<GeoInfo> geoInfo) {
|
||||
@ -106,23 +102,18 @@ public class GeoInfo implements DateHolder, Serializable {
|
||||
return date;
|
||||
}
|
||||
|
||||
public String getIpHash() {
|
||||
return ipHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
GeoInfo geoInfo = (GeoInfo) o;
|
||||
return Objects.equal(ip, geoInfo.ip) &&
|
||||
Objects.equal(geolocation, geoInfo.geolocation) &&
|
||||
Objects.equal(ipHash, geoInfo.ipHash);
|
||||
Objects.equal(geolocation, geoInfo.geolocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(ip, geolocation, ipHash);
|
||||
return Objects.hashCode(ip, geolocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -130,7 +121,6 @@ public class GeoInfo implements DateHolder, Serializable {
|
||||
return "GeoInfo{" +
|
||||
"ip='" + ip + '\'' +
|
||||
", geolocation='" + geolocation + '\'' +
|
||||
", ipHash='" + ipHash + '\'' +
|
||||
", date=" + date +
|
||||
'}';
|
||||
}
|
||||
|
@ -92,10 +92,7 @@ public class TableContainer {
|
||||
if (i > maxIndex) {
|
||||
body.append("<td>-");
|
||||
} else {
|
||||
Serializable value = row[i];
|
||||
Formatter formatter = formatters[i];
|
||||
body.append("<td").append(formatter != null ? " data-order=\"" + value + "\">" : ">");
|
||||
body.append(formatter != null ? formatter.apply(value) : (value != null ? value : '-'));
|
||||
appendValue(body, row[i], formatters[i]);
|
||||
}
|
||||
body.append("</td>");
|
||||
} catch (ClassCastException | ArrayIndexOutOfBoundsException e) {
|
||||
@ -105,6 +102,15 @@ public class TableContainer {
|
||||
body.append("</tr>");
|
||||
}
|
||||
|
||||
private void appendValue(StringBuilder body, Serializable value, Formatter formatter) {
|
||||
body.append("<td").append(formatter != null ? " data-order=\"" + value + "\">" : ">");
|
||||
if (formatter != null) {
|
||||
body.append(formatter.apply(value));
|
||||
} else {
|
||||
body.append(value != null ? value : '-');
|
||||
}
|
||||
}
|
||||
|
||||
public final void setColor(String color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
public abstract class AbstractHealthInfo {
|
||||
|
||||
protected final String subNote = "<br> ";
|
||||
protected static final String SUB_NOTE = "<br> ";
|
||||
|
||||
protected final List<String> notes;
|
||||
protected final long now;
|
||||
@ -109,7 +109,7 @@ public abstract class AbstractHealthInfo {
|
||||
|
||||
StringBuilder remainNote = new StringBuilder();
|
||||
if (activeFWAGNum != 0) {
|
||||
remainNote.append(subNote);
|
||||
remainNote.append(SUB_NOTE);
|
||||
if (percRemain > 0.5) {
|
||||
remainNote.append(Icons.GREEN_THUMB);
|
||||
} else if (percRemain > 0.2) {
|
||||
|
@ -124,7 +124,7 @@ public class HealthInformation extends AbstractHealthInfo {
|
||||
double aboveThreshold = tpsMutator.percentageTPSAboveThreshold(lowTPSThreshold);
|
||||
long tpsSpikeMonth = analysisContainer.getValue(AnalysisKeys.TPS_SPIKE_MONTH).orElse(0);
|
||||
|
||||
StringBuilder avgLowThresholdString = new StringBuilder(subNote);
|
||||
StringBuilder avgLowThresholdString = new StringBuilder(SUB_NOTE);
|
||||
if (aboveThreshold >= 0.96) {
|
||||
avgLowThresholdString.append(Icons.GREEN_THUMB);
|
||||
} else if (aboveThreshold >= 0.9) {
|
||||
|
@ -112,7 +112,7 @@ public class NetworkHealthInformation extends AbstractHealthInfo {
|
||||
.map(c -> {
|
||||
int playersPerMonth = c.getUnsafe(AnalysisKeys.AVG_PLAYERS_MONTH);
|
||||
Server server = c.getUnsafe(serverKey);
|
||||
return subNote + (playersPerMonth >= average && playersPerMonth > 0 ? Icons.GREEN_PLUS : Icons.RED_MINUS) + " " +
|
||||
return SUB_NOTE + (playersPerMonth >= average && playersPerMonth > 0 ? Icons.GREEN_PLUS : Icons.RED_MINUS) + " " +
|
||||
server.getName() + ": " + playersPerMonth;
|
||||
}).forEach(subNotes::append);
|
||||
addNote(icon + " " + decimalFormatter.apply(average) + uniquePlayersNote + subNotes.toString());
|
||||
@ -139,7 +139,7 @@ public class NetworkHealthInformation extends AbstractHealthInfo {
|
||||
.map(c -> {
|
||||
int playersPerMonth = c.getUnsafe(AnalysisKeys.AVG_PLAYERS_NEW_MONTH);
|
||||
Server server = c.getUnsafe(serverKey);
|
||||
return subNote + (playersPerMonth >= average && playersPerMonth > 0 ? Icons.GREEN_PLUS : Icons.RED_MINUS) + " " +
|
||||
return SUB_NOTE + (playersPerMonth >= average && playersPerMonth > 0 ? Icons.GREEN_PLUS : Icons.RED_MINUS) + " " +
|
||||
server.getName() + ": " + playersPerMonth;
|
||||
}).forEach(subNotes::append);
|
||||
addNote(icon + " " + decimalFormatter.apply(average) + newPlayersNote + subNotes.toString());
|
||||
@ -179,7 +179,7 @@ public class NetworkHealthInformation extends AbstractHealthInfo {
|
||||
.map(c -> {
|
||||
int playersPerMonth = c.getUnsafe(AnalysisKeys.PLAYERS_MONTH);
|
||||
Server server = c.getUnsafe(serverKey);
|
||||
return subNote + (playersPerMonth > 0 ? Icons.GREEN_PLUS : Icons.RED_MINUS) + " " +
|
||||
return SUB_NOTE + (playersPerMonth > 0 ? Icons.GREEN_PLUS : Icons.RED_MINUS) + " " +
|
||||
server.getName() + ": " + playersPerMonth;
|
||||
}).forEach(subNotes::append);
|
||||
addNote(icon.toHtml() + " " + uniquePlayersNote + subNotes.toString());
|
||||
|
@ -92,7 +92,7 @@ public class H2DB extends SQLDB {
|
||||
String password = config.get(DatabaseSettings.MYSQL_PASS);
|
||||
|
||||
JdbcDataSource jdbcDataSource = new JdbcDataSource();
|
||||
jdbcDataSource.setURL("jdbc:h2:file:" + dbFilePath + ";mode=MySQL");
|
||||
jdbcDataSource.setURL("jdbc:h2:file:" + dbFilePath + ";mode=MySQL;DATABASE_TO_UPPER=false");
|
||||
jdbcDataSource.setUser(username);
|
||||
jdbcDataSource.setPassword(password);
|
||||
|
||||
|
@ -115,6 +115,10 @@ public abstract class SQLDB extends AbstractDatabase {
|
||||
transactionExecutor.shutdown();
|
||||
try {
|
||||
Long waitMs = config.getOrDefault(TimeSettings.DB_TRANSACTION_FINISH_WAIT_DELAY, TimeUnit.SECONDS.toMillis(20L));
|
||||
if (waitMs > TimeUnit.MINUTES.toMillis(5L)) {
|
||||
logger.warn(TimeSettings.DB_TRANSACTION_FINISH_WAIT_DELAY.getPath() + " was set to over 5 minutes, using 5 min instead.");
|
||||
waitMs = TimeUnit.MINUTES.toMillis(5L);
|
||||
}
|
||||
if (!transactionExecutor.awaitTermination(waitMs, TimeUnit.MILLISECONDS)) {
|
||||
List<Runnable> unfinished = transactionExecutor.shutdownNow();
|
||||
int unfinishedCount = unfinished.size();
|
||||
@ -149,9 +153,9 @@ public abstract class SQLDB extends AbstractDatabase {
|
||||
new UserInfoOptimizationPatch(),
|
||||
new GeoInfoOptimizationPatch(),
|
||||
new TransferTableRemovalPatch(),
|
||||
new IPHashPatch(),
|
||||
new IPAnonPatch(),
|
||||
new BadAFKThresholdValuePatch()
|
||||
new BadAFKThresholdValuePatch(),
|
||||
new DeleteIPHashesPatch()
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ import com.djrapitops.plan.db.access.ExecBatchStatement;
|
||||
import com.djrapitops.plan.db.access.ExecStatement;
|
||||
import com.djrapitops.plan.db.access.Executable;
|
||||
import com.djrapitops.plan.db.sql.tables.*;
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
@ -88,7 +89,7 @@ public class DataStoreQueries {
|
||||
* @throws IllegalArgumentException If {@link Session#endSession(long)} has not yet been called.
|
||||
*/
|
||||
public static Executable storeSession(Session session) {
|
||||
session.getValue(SessionKeys.END).orElseThrow(() -> new IllegalArgumentException("Attempted to save a session that has not ended."));
|
||||
Verify.isTrue(session.supports(SessionKeys.END), () -> new IllegalArgumentException("Attempted to save a session that has not ended."));
|
||||
return connection -> {
|
||||
storeSessionInformation(session).execute(connection);
|
||||
storeSessionKills(session).execute(connection);
|
||||
@ -164,8 +165,7 @@ public class DataStoreQueries {
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setLong(1, geoInfo.getDate());
|
||||
statement.setString(2, playerUUID.toString());
|
||||
statement.setString(3, geoInfo.getIpHash());
|
||||
statement.setString(4, geoInfo.getGeolocation());
|
||||
statement.setString(3, geoInfo.getGeolocation());
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -176,9 +176,8 @@ public class DataStoreQueries {
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, playerUUID.toString());
|
||||
statement.setString(2, geoInfo.getIp());
|
||||
statement.setString(3, geoInfo.getIpHash());
|
||||
statement.setString(4, geoInfo.getGeolocation());
|
||||
statement.setLong(5, geoInfo.getDate());
|
||||
statement.setString(3, geoInfo.getGeolocation());
|
||||
statement.setLong(4, geoInfo.getDate());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -97,15 +97,13 @@ public class LargeStoreQueries {
|
||||
// Every GeoInfo
|
||||
for (GeoInfo info : playerEntry.getValue()) {
|
||||
String ip = info.getIp();
|
||||
String ipHash = info.getIpHash();
|
||||
String geoLocation = info.getGeolocation();
|
||||
long lastUsed = info.getDate();
|
||||
|
||||
statement.setString(1, playerUUID.toString());
|
||||
statement.setString(2, ip);
|
||||
statement.setString(3, ipHash);
|
||||
statement.setString(4, geoLocation);
|
||||
statement.setLong(5, lastUsed);
|
||||
statement.setString(3, geoLocation);
|
||||
statement.setLong(4, lastUsed);
|
||||
|
||||
statement.addBatch();
|
||||
}
|
||||
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.queries.containers;
|
||||
|
||||
import com.djrapitops.plan.data.container.BaseUser;
|
||||
import com.djrapitops.plan.data.container.GeoInfo;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
||||
import com.djrapitops.plan.data.store.keys.PlayerKeys;
|
||||
import com.djrapitops.plan.db.SQLDB;
|
||||
import com.djrapitops.plan.db.access.Query;
|
||||
import com.djrapitops.plan.db.access.queries.objects.BaseUserQueries;
|
||||
import com.djrapitops.plan.db.access.queries.objects.GeoInfoQueries;
|
||||
import com.djrapitops.plan.db.access.queries.objects.SessionQueries;
|
||||
import com.djrapitops.plan.db.access.queries.objects.UserInfoQueries;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Optimized version of {@link ServerPlayerContainersQuery} for /server page Players table.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.utilities.html.tables.PlayersTableJSONParser For what needs to be included.
|
||||
*/
|
||||
public class ServerPlayersTableContainersQuery implements Query<List<PlayerContainer>> {
|
||||
|
||||
private final UUID serverUUID;
|
||||
|
||||
public ServerPlayersTableContainersQuery(UUID serverUUID) {
|
||||
this.serverUUID = serverUUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PlayerContainer> executeQuery(SQLDB db) {
|
||||
List<PlayerContainer> containers = new ArrayList<>();
|
||||
|
||||
Collection<BaseUser> baseUsers = db.query(BaseUserQueries.fetchServerBaseUsers(serverUUID));
|
||||
|
||||
Map<UUID, List<GeoInfo>> geoInformation = db.query(GeoInfoQueries.fetchServerGeoInformation(serverUUID));
|
||||
Map<UUID, List<Session>> sessions = db.query(SessionQueries.fetchSessionsOfServer(serverUUID));
|
||||
Set<UUID> bannedUsers = db.query(UserInfoQueries.fetchBannedUUIDsOfServer(serverUUID));
|
||||
|
||||
for (BaseUser user : baseUsers) {
|
||||
PlayerContainer container = new PlayerContainer();
|
||||
|
||||
// BaseUser
|
||||
UUID uuid = user.getUuid();
|
||||
container.putRawData(PlayerKeys.UUID, uuid);
|
||||
container.putRawData(PlayerKeys.NAME, user.getName());
|
||||
container.putRawData(PlayerKeys.REGISTERED, user.getRegistered());
|
||||
container.putRawData(PlayerKeys.BANNED, bannedUsers.contains(uuid));
|
||||
|
||||
// GeoInfo
|
||||
container.putRawData(PlayerKeys.GEO_INFO, geoInformation.getOrDefault(uuid, new ArrayList<>()));
|
||||
|
||||
container.putCachingSupplier(PlayerKeys.SESSIONS, () -> {
|
||||
List<Session> playerSessions = sessions.getOrDefault(uuid, new ArrayList<>());
|
||||
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add);
|
||||
return playerSessions;
|
||||
}
|
||||
);
|
||||
|
||||
containers.add(container);
|
||||
}
|
||||
return containers;
|
||||
}
|
||||
|
||||
}
|
@ -49,7 +49,6 @@ public class GeoInfoQueries {
|
||||
GeoInfoTable.IP + ", " +
|
||||
GeoInfoTable.GEOLOCATION + ", " +
|
||||
GeoInfoTable.LAST_USED + ", " +
|
||||
GeoInfoTable.IP_HASH + ", " +
|
||||
GeoInfoTable.USER_UUID +
|
||||
" FROM " + GeoInfoTable.TABLE_NAME;
|
||||
|
||||
@ -64,9 +63,8 @@ public class GeoInfoQueries {
|
||||
|
||||
String ip = set.getString(GeoInfoTable.IP);
|
||||
String geolocation = set.getString(GeoInfoTable.GEOLOCATION);
|
||||
String ipHash = set.getString(GeoInfoTable.IP_HASH);
|
||||
long lastUsed = set.getLong(GeoInfoTable.LAST_USED);
|
||||
userGeoInfo.add(new GeoInfo(ip, geolocation, lastUsed, ipHash));
|
||||
userGeoInfo.add(new GeoInfo(ip, geolocation, lastUsed));
|
||||
|
||||
geoInformation.put(uuid, userGeoInfo);
|
||||
}
|
||||
@ -97,9 +95,8 @@ public class GeoInfoQueries {
|
||||
while (set.next()) {
|
||||
String ip = set.getString(GeoInfoTable.IP);
|
||||
String geolocation = set.getString(GeoInfoTable.GEOLOCATION);
|
||||
String ipHash = set.getString(GeoInfoTable.IP_HASH);
|
||||
long lastUsed = set.getLong(GeoInfoTable.LAST_USED);
|
||||
geoInfo.add(new GeoInfo(ip, geolocation, lastUsed, ipHash));
|
||||
geoInfo.add(new GeoInfo(ip, geolocation, lastUsed));
|
||||
}
|
||||
return geoInfo;
|
||||
}
|
||||
@ -110,8 +107,7 @@ public class GeoInfoQueries {
|
||||
String sql = "SELECT " + GeoInfoTable.TABLE_NAME + "." + GeoInfoTable.USER_UUID + ", " +
|
||||
GeoInfoTable.GEOLOCATION + ", " +
|
||||
GeoInfoTable.LAST_USED + ", " +
|
||||
GeoInfoTable.IP + ", " +
|
||||
GeoInfoTable.IP_HASH +
|
||||
GeoInfoTable.IP +
|
||||
" FROM " + GeoInfoTable.TABLE_NAME +
|
||||
" INNER JOIN " + UserInfoTable.TABLE_NAME + " on " +
|
||||
GeoInfoTable.TABLE_NAME + "." + GeoInfoTable.USER_UUID + "=" + UserInfoTable.TABLE_NAME + "." + UserInfoTable.USER_UUID +
|
||||
@ -132,9 +128,8 @@ public class GeoInfoQueries {
|
||||
|
||||
String ip = set.getString(GeoInfoTable.IP);
|
||||
String geolocation = set.getString(GeoInfoTable.GEOLOCATION);
|
||||
String ipHash = set.getString(GeoInfoTable.IP_HASH);
|
||||
long lastUsed = set.getLong(GeoInfoTable.LAST_USED);
|
||||
userGeoInfo.add(new GeoInfo(ip, geolocation, lastUsed, ipHash));
|
||||
userGeoInfo.add(new GeoInfo(ip, geolocation, lastUsed));
|
||||
|
||||
geoInformation.put(uuid, userGeoInfo);
|
||||
}
|
||||
|
@ -114,6 +114,12 @@ public class UserInfoQueries {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Query database for all User information of a specific server.
|
||||
*
|
||||
* @param serverUUID UUID of the Plan server.
|
||||
* @return Map: Player UUID - user information
|
||||
*/
|
||||
public static Query<Map<UUID, UserInfo>> fetchUserInformationOfServer(UUID serverUUID) {
|
||||
String sql = SELECT +
|
||||
UserInfoTable.REGISTERED + ", " +
|
||||
@ -146,4 +152,34 @@ public class UserInfoQueries {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Query database for UUIDs of banned players on a server.
|
||||
*
|
||||
* @param serverUUID UUID of the Plan server.
|
||||
* @return Set: Player UUID of a banned player.
|
||||
*/
|
||||
public static Query<Set<UUID>> fetchBannedUUIDsOfServer(UUID serverUUID) {
|
||||
String sql = SELECT +
|
||||
UserInfoTable.USER_UUID +
|
||||
FROM + UserInfoTable.TABLE_NAME +
|
||||
WHERE + UserInfoTable.SERVER_UUID + "=?" +
|
||||
AND + UserInfoTable.BANNED + "=?";
|
||||
return new QueryStatement<Set<UUID>>(sql, 1000) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, serverUUID.toString());
|
||||
statement.setBoolean(2, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> processResults(ResultSet set) throws SQLException {
|
||||
Set<UUID> bannedUsers = new HashSet<>();
|
||||
while (set.next()) {
|
||||
bannedUsers.add(UUID.fromString(set.getString(UserInfoTable.USER_UUID)));
|
||||
}
|
||||
return bannedUsers;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -157,4 +157,8 @@ public abstract class Transaction {
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + (success ? " (finished)" : "");
|
||||
}
|
||||
|
||||
public boolean wasSuccessful() {
|
||||
return success;
|
||||
}
|
||||
}
|
@ -47,6 +47,9 @@ public class RemoveEverythingTransaction extends Transaction {
|
||||
clearTable(ExtensionPlayerValueTable.TABLE_NAME);
|
||||
clearTable(ExtensionServerValueTable.TABLE_NAME);
|
||||
clearTable(ExtensionProviderTable.TABLE_NAME);
|
||||
clearTable(ExtensionPlayerTableValueTable.TABLE_NAME);
|
||||
clearTable(ExtensionServerTableValueTable.TABLE_NAME);
|
||||
clearTable(ExtensionTableProviderTable.TABLE_NAME);
|
||||
clearTable(ExtensionTabTable.TABLE_NAME);
|
||||
clearTable(ExtensionPluginTable.TABLE_NAME);
|
||||
clearTable(ExtensionIconTable.TABLE_NAME);
|
||||
|
@ -53,5 +53,8 @@ public class CreateTablesTransaction extends OperationCriticalTransaction {
|
||||
execute(ExtensionProviderTable.createTableSQL(dbType));
|
||||
execute(ExtensionPlayerValueTable.createTableSQL(dbType));
|
||||
execute(ExtensionServerValueTable.createTableSQL(dbType));
|
||||
execute(ExtensionTableProviderTable.createTableSQL(dbType));
|
||||
execute(ExtensionPlayerTableValueTable.createTableSQL(dbType));
|
||||
execute(ExtensionServerTableValueTable.createTableSQL(dbType));
|
||||
}
|
||||
}
|
@ -23,7 +23,6 @@ import com.djrapitops.plan.db.access.queries.objects.TPSQueries;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.db.sql.tables.PingTable;
|
||||
import com.djrapitops.plan.db.sql.tables.TPSTable;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
@ -38,11 +37,17 @@ import java.util.UUID;
|
||||
public class RemoveOldSampledDataTransaction extends Transaction {
|
||||
|
||||
private final UUID serverUUID;
|
||||
private final long deleteTPSOlderThanMs;
|
||||
private final long deletePingOlderThanMs;
|
||||
|
||||
public RemoveOldSampledDataTransaction(
|
||||
UUID serverUUID
|
||||
UUID serverUUID,
|
||||
long deleteTPSOlderThanMs,
|
||||
long deletePingOlderThanMs
|
||||
) {
|
||||
this.serverUUID = serverUUID;
|
||||
this.deleteTPSOlderThanMs = deleteTPSOlderThanMs;
|
||||
this.deletePingOlderThanMs = deletePingOlderThanMs;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -61,9 +66,7 @@ public class RemoveOldSampledDataTransaction extends Transaction {
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
// More than 3 Months ago.
|
||||
long threeMonths = TimeAmount.MONTH.toMillis(3L);
|
||||
statement.setLong(1, System.currentTimeMillis() - threeMonths);
|
||||
statement.setLong(1, System.currentTimeMillis() - deleteTPSOlderThanMs);
|
||||
statement.setInt(2, allTimePlayerPeak);
|
||||
}
|
||||
};
|
||||
@ -77,8 +80,7 @@ public class RemoveOldSampledDataTransaction extends Transaction {
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
long twoWeeks = TimeAmount.WEEK.toMillis(2L);
|
||||
statement.setLong(1, System.currentTimeMillis() - twoWeeks);
|
||||
statement.setLong(1, System.currentTimeMillis() - deletePingOlderThanMs);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.patches;
|
||||
|
||||
import com.djrapitops.plan.db.access.ExecStatement;
|
||||
import com.djrapitops.plan.db.access.HasMoreThanZeroQueryStatement;
|
||||
import com.djrapitops.plan.db.sql.tables.GeoInfoTable;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.*;
|
||||
|
||||
/**
|
||||
* Patch for removing ip_hash values from plan_ips table.
|
||||
* <p>
|
||||
* The patch is a response to a concern:
|
||||
* "Hashed IP addresses are pseudonymised not anonymised and can be easily decoded using a rainbow table".
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class DeleteIPHashesPatch extends Patch {
|
||||
|
||||
private static final String IP_HASH = "ip_hash";
|
||||
|
||||
private boolean hasNoHashColumn;
|
||||
|
||||
@Override
|
||||
public boolean hasBeenApplied() {
|
||||
hasNoHashColumn = !hasColumn(GeoInfoTable.TABLE_NAME, IP_HASH);
|
||||
|
||||
String sql = SELECT + "COUNT(1) as c" + FROM + GeoInfoTable.TABLE_NAME +
|
||||
WHERE + IP_HASH + IS_NOT_NULL;
|
||||
|
||||
return hasNoHashColumn || !query(new HasMoreThanZeroQueryStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) {
|
||||
/* No variables needed */
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyPatch() {
|
||||
if (hasNoHashColumn) {
|
||||
return;
|
||||
}
|
||||
|
||||
String sql = "UPDATE " + GeoInfoTable.TABLE_NAME + " SET ip_hash=?" + WHERE + IP_HASH + IS_NOT_NULL;
|
||||
execute(new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setNull(1, Types.VARCHAR);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -44,13 +44,11 @@ public class GeoInfoOptimizationPatch extends Patch {
|
||||
execute("INSERT INTO " + tableName + " (" +
|
||||
GeoInfoTable.USER_UUID + ", " +
|
||||
GeoInfoTable.IP + ", " +
|
||||
GeoInfoTable.IP_HASH + ", " +
|
||||
GeoInfoTable.LAST_USED + ", " +
|
||||
GeoInfoTable.GEOLOCATION +
|
||||
") SELECT " +
|
||||
"(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".user_id LIMIT 1), " +
|
||||
GeoInfoTable.IP + ", " +
|
||||
GeoInfoTable.IP_HASH + ", " +
|
||||
GeoInfoTable.LAST_USED + ", " +
|
||||
GeoInfoTable.GEOLOCATION +
|
||||
" FROM " + tempTableName
|
||||
|
@ -24,7 +24,6 @@ import com.djrapitops.plan.db.sql.tables.GeoInfoTable;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
@ -73,8 +72,7 @@ public class IPAnonPatch extends Patch {
|
||||
|
||||
private void anonymizeIPs(Map<UUID, List<GeoInfo>> allGeoInfo) {
|
||||
String sql = "UPDATE " + GeoInfoTable.TABLE_NAME + " SET " +
|
||||
GeoInfoTable.IP + "=?, " +
|
||||
GeoInfoTable.IP_HASH + "=? " +
|
||||
GeoInfoTable.IP + "=? " +
|
||||
"WHERE " + GeoInfoTable.IP + "=?";
|
||||
|
||||
execute(new ExecBatchStatement(sql) {
|
||||
@ -99,11 +97,10 @@ public class IPAnonPatch extends Patch {
|
||||
geoInfo.getDate()
|
||||
);
|
||||
statement.setString(1, updatedInfo.getIp());
|
||||
statement.setString(2, updatedInfo.getIpHash());
|
||||
statement.setString(3, geoInfo.getIp());
|
||||
statement.setString(2, geoInfo.getIp());
|
||||
statement.addBatch();
|
||||
} catch (UnknownHostException | NoSuchAlgorithmException ignore) {
|
||||
// This ip is already anonymised or completely unusable.
|
||||
} catch (UnknownHostException ignore) {
|
||||
// This ip is completely unusable.
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -120,11 +117,11 @@ public class IPAnonPatch extends Patch {
|
||||
String identifiers = hasUserIdColumn ? userIdColumn : "id, uuid";
|
||||
|
||||
execute("INSERT INTO plan_ips (" +
|
||||
identifiers + ", ip, ip_hash, geolocation, last_used" +
|
||||
identifiers + ", ip, geolocation, last_used" +
|
||||
") SELECT " +
|
||||
identifiers + ", ip, ip_hash, geolocation, MAX(last_used) FROM plan_ips_temp GROUP BY ip_hash, " +
|
||||
identifiers + ", ip, geolocation, MAX(last_used) FROM plan_ips_temp GROUP BY ip, " +
|
||||
(hasUserIdColumn ? userIdColumn : "uuid") +
|
||||
", ip, geolocation");
|
||||
", geolocation");
|
||||
dropTable(tempTableName);
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.*;
|
||||
|
||||
@ -54,9 +55,15 @@ public class ExtensionIconTable {
|
||||
}
|
||||
|
||||
public static void set3IconValuesToStatement(PreparedStatement statement, int parameterIndex, Icon icon) throws SQLException {
|
||||
statement.setString(parameterIndex, StringUtils.truncate(icon.getName(), 50));
|
||||
statement.setString(parameterIndex + 1, icon.getFamily().name());
|
||||
statement.setString(parameterIndex + 2, icon.getColor().name());
|
||||
if (icon != null) {
|
||||
statement.setString(parameterIndex, StringUtils.truncate(icon.getName(), 50));
|
||||
statement.setString(parameterIndex + 1, icon.getFamily().name());
|
||||
statement.setString(parameterIndex + 2, icon.getColor().name());
|
||||
} else {
|
||||
statement.setNull(parameterIndex, Types.VARCHAR);
|
||||
statement.setNull(parameterIndex + 1, Types.VARCHAR);
|
||||
statement.setNull(parameterIndex + 2, Types.VARCHAR);
|
||||
}
|
||||
}
|
||||
|
||||
private ExtensionIconTable() {
|
||||
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.sql.tables;
|
||||
|
||||
import com.djrapitops.plan.db.DBType;
|
||||
import com.djrapitops.plan.db.sql.parsing.CreateTableParser;
|
||||
import com.djrapitops.plan.db.sql.parsing.Sql;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.INT;
|
||||
|
||||
/**
|
||||
* Table information about 'plan_extension_user_table_values'.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ExtensionPlayerTableValueTable {
|
||||
|
||||
public static final String TABLE_NAME = "plan_extension_user_table_values";
|
||||
|
||||
public static final String ID = "id";
|
||||
public static final String TABLE_ID = "table_id";
|
||||
public static final String USER_UUID = "uuid";
|
||||
|
||||
// All values can be null
|
||||
public static final String VALUE_1 = "col_1_value";
|
||||
public static final String VALUE_2 = "col_2_value";
|
||||
public static final String VALUE_3 = "col_3_value";
|
||||
public static final String VALUE_4 = "col_4_value";
|
||||
|
||||
private ExtensionPlayerTableValueTable() {
|
||||
/* Static information class */
|
||||
}
|
||||
|
||||
public static String createTableSQL(DBType dbType) {
|
||||
return CreateTableParser.create(TABLE_NAME, dbType)
|
||||
.column(ID, INT).primaryKey()
|
||||
.column(USER_UUID, Sql.varchar(36)).notNull()
|
||||
.column(VALUE_1, Sql.varchar(50))
|
||||
.column(VALUE_2, Sql.varchar(50))
|
||||
.column(VALUE_3, Sql.varchar(50))
|
||||
.column(VALUE_4, Sql.varchar(50))
|
||||
.column(TABLE_ID, INT).notNull()
|
||||
.foreignKey(TABLE_ID, ExtensionTableProviderTable.TABLE_NAME, ExtensionPluginTable.ID)
|
||||
.build();
|
||||
}
|
||||
}
|
@ -37,7 +37,7 @@ public class ExtensionProviderTable {
|
||||
|
||||
public static final String ID = "id";
|
||||
public static final String PROVIDER_NAME = "name";
|
||||
public static final String TEXT = "text"; // Can be null
|
||||
public static final String TEXT = "text";
|
||||
public static final String DESCRIPTION = "description"; // Can be null
|
||||
public static final String PRIORITY = "priority";
|
||||
public static final String GROUPABLE = "groupable"; // default false
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.sql.tables;
|
||||
|
||||
import com.djrapitops.plan.db.DBType;
|
||||
import com.djrapitops.plan.db.sql.parsing.CreateTableParser;
|
||||
import com.djrapitops.plan.db.sql.parsing.Sql;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.INT;
|
||||
|
||||
/**
|
||||
* Table information about 'plan_extension_server_table_values'.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ExtensionServerTableValueTable {
|
||||
|
||||
public static final String TABLE_NAME = "plan_extension_server_table_values";
|
||||
|
||||
public static final String ID = "id";
|
||||
public static final String TABLE_ID = "table_id";
|
||||
public static final String SERVER_UUID = "uuid";
|
||||
|
||||
// All values can be null
|
||||
public static final String VALUE_1 = "col_1_value";
|
||||
public static final String VALUE_2 = "col_2_value";
|
||||
public static final String VALUE_3 = "col_3_value";
|
||||
public static final String VALUE_4 = "col_4_value";
|
||||
public static final String VALUE_5 = "col_5_value";
|
||||
|
||||
private ExtensionServerTableValueTable() {
|
||||
/* Static information class */
|
||||
}
|
||||
|
||||
public static String createTableSQL(DBType dbType) {
|
||||
return CreateTableParser.create(TABLE_NAME, dbType)
|
||||
.column(ID, INT).primaryKey()
|
||||
.column(SERVER_UUID, Sql.varchar(36)).notNull()
|
||||
.column(VALUE_1, Sql.varchar(50))
|
||||
.column(VALUE_2, Sql.varchar(50))
|
||||
.column(VALUE_3, Sql.varchar(50))
|
||||
.column(VALUE_4, Sql.varchar(50))
|
||||
.column(VALUE_5, Sql.varchar(50))
|
||||
.column(TABLE_ID, INT).notNull()
|
||||
.foreignKey(TABLE_ID, ExtensionTableProviderTable.TABLE_NAME, ExtensionPluginTable.ID)
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.sql.tables;
|
||||
|
||||
import com.djrapitops.plan.db.DBType;
|
||||
import com.djrapitops.plan.db.sql.parsing.CreateTableParser;
|
||||
import com.djrapitops.plan.db.sql.parsing.Sql;
|
||||
import com.djrapitops.plan.extension.icon.Color;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.*;
|
||||
|
||||
/**
|
||||
* Table information about 'plan_extension_tables'.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ExtensionTableProviderTable {
|
||||
|
||||
public static final String TABLE_NAME = "plan_extension_tables";
|
||||
|
||||
public static final String ID = "id";
|
||||
public static final String PROVIDER_NAME = "name";
|
||||
public static final String COLOR = "color";
|
||||
public static final String CONDITION = "condition_name"; // Can be null, related to @Conditional
|
||||
public static final String PLUGIN_ID = "plugin_id";
|
||||
public static final String TAB_ID = "tab_id"; // Can be null, related to @Tab
|
||||
|
||||
// All columns can be null
|
||||
public static final String COL_1 = "col_1_name";
|
||||
public static final String COL_2 = "col_2_name";
|
||||
public static final String COL_3 = "col_3_name";
|
||||
public static final String COL_4 = "col_4_name";
|
||||
public static final String COL_5 = "col_5_name";
|
||||
|
||||
// All icons can be null
|
||||
public static final String ICON_1_ID = "icon_1_id";
|
||||
public static final String ICON_2_ID = "icon_2_id";
|
||||
public static final String ICON_3_ID = "icon_3_id";
|
||||
public static final String ICON_4_ID = "icon_4_id";
|
||||
public static final String ICON_5_ID = "icon_5_id";
|
||||
|
||||
public static final String STATEMENT_SELECT_TABLE_ID = "(" + SELECT + ID + FROM + TABLE_NAME +
|
||||
WHERE + PROVIDER_NAME + "=?" +
|
||||
AND + PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ")";
|
||||
|
||||
private ExtensionTableProviderTable() {
|
||||
/* Static information class */
|
||||
}
|
||||
|
||||
public static void set3PluginValuesToStatement(PreparedStatement statement, int parameterIndex, String providerName, String pluginName, UUID serverUUID) throws SQLException {
|
||||
statement.setString(parameterIndex, providerName);
|
||||
ExtensionPluginTable.set2PluginValuesToStatement(statement, parameterIndex + 1, pluginName, serverUUID);
|
||||
}
|
||||
|
||||
public static String createTableSQL(DBType dbType) {
|
||||
return CreateTableParser.create(TABLE_NAME, dbType)
|
||||
.column(ID, INT).primaryKey()
|
||||
.column(PROVIDER_NAME, Sql.varchar(50)).notNull()
|
||||
.column(COLOR, Sql.varchar(25)).notNull().defaultValue("'" + Color.NONE.name() + "'")
|
||||
.column(CONDITION, Sql.varchar(54)) // 50 + 4 for "not_"
|
||||
.column(COL_1, Sql.varchar(50))
|
||||
.column(COL_2, Sql.varchar(50))
|
||||
.column(COL_3, Sql.varchar(50))
|
||||
.column(COL_4, Sql.varchar(50))
|
||||
.column(COL_5, Sql.varchar(50))
|
||||
.column(PLUGIN_ID, INT).notNull()
|
||||
.column(ICON_1_ID, INT)
|
||||
.column(ICON_2_ID, INT)
|
||||
.column(ICON_3_ID, INT)
|
||||
.column(ICON_4_ID, INT)
|
||||
.column(ICON_5_ID, INT)
|
||||
.column(TAB_ID, INT)
|
||||
.foreignKey(PLUGIN_ID, ExtensionPluginTable.TABLE_NAME, ExtensionPluginTable.ID)
|
||||
.foreignKey(ICON_1_ID, ExtensionIconTable.TABLE_NAME, ExtensionIconTable.ID)
|
||||
.foreignKey(ICON_2_ID, ExtensionIconTable.TABLE_NAME, ExtensionIconTable.ID)
|
||||
.foreignKey(ICON_3_ID, ExtensionIconTable.TABLE_NAME, ExtensionIconTable.ID)
|
||||
.foreignKey(ICON_4_ID, ExtensionIconTable.TABLE_NAME, ExtensionIconTable.ID)
|
||||
.foreignKey(ICON_5_ID, ExtensionIconTable.TABLE_NAME, ExtensionIconTable.ID)
|
||||
.foreignKey(TAB_ID, ExtensionTabTable.TABLE_NAME, ExtensionTabTable.ID)
|
||||
.build();
|
||||
}
|
||||
}
|
@ -28,8 +28,8 @@ import com.djrapitops.plan.db.sql.parsing.Sql;
|
||||
* {@link Version10Patch}
|
||||
* {@link GeoInfoLastUsedPatch}
|
||||
* {@link IPAnonPatch}
|
||||
* {@link IPHashPatch}
|
||||
* {@link GeoInfoOptimizationPatch}
|
||||
* {@link DeleteIPHashesPatch}
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
@ -40,22 +40,19 @@ public class GeoInfoTable {
|
||||
public static final String ID = "id";
|
||||
public static final String USER_UUID = "uuid";
|
||||
public static final String IP = "ip";
|
||||
public static final String IP_HASH = "ip_hash";
|
||||
public static final String GEOLOCATION = "geolocation";
|
||||
public static final String LAST_USED = "last_used";
|
||||
|
||||
public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " ("
|
||||
+ USER_UUID + ", "
|
||||
+ IP + ", "
|
||||
+ IP_HASH + ", "
|
||||
+ GEOLOCATION + ", "
|
||||
+ LAST_USED
|
||||
+ ") VALUES (?, ?, ?, ?, ?)";
|
||||
+ ") VALUES (?, ?, ?, ?)";
|
||||
|
||||
public static final String UPDATE_STATEMENT = "UPDATE " + TABLE_NAME + " SET "
|
||||
+ LAST_USED + "=?" +
|
||||
" WHERE " + USER_UUID + "=?" +
|
||||
" AND " + IP_HASH + "=?" +
|
||||
" AND " + GEOLOCATION + "=?";
|
||||
|
||||
private GeoInfoTable() {
|
||||
@ -68,7 +65,6 @@ public class GeoInfoTable {
|
||||
.column(USER_UUID, Sql.varchar(36)).notNull()
|
||||
.column(IP, Sql.varchar(39)).notNull()
|
||||
.column(GEOLOCATION, Sql.varchar(50)).notNull()
|
||||
.column(IP_HASH, Sql.varchar(200))
|
||||
.column(LAST_USED, Sql.LONG).notNull().defaultValue("0")
|
||||
.toString();
|
||||
}
|
||||
|
@ -24,7 +24,8 @@ import com.djrapitops.plan.db.access.transactions.commands.RemovePlayerTransacti
|
||||
import com.djrapitops.plan.db.access.transactions.init.RemoveDuplicateUserInfoTransaction;
|
||||
import com.djrapitops.plan.db.access.transactions.init.RemoveOldSampledDataTransaction;
|
||||
import com.djrapitops.plan.db.sql.tables.SessionsTable;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.RemoveUnsatisfiedConditionalResultsTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.RemoveUnsatisfiedConditionalPlayerResultsTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.RemoveUnsatisfiedConditionalServerResultsTransaction;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.system.locale.Locale;
|
||||
@ -84,9 +85,14 @@ public class DBCleanTask extends AbsRunnable {
|
||||
Database database = dbSystem.getDatabase();
|
||||
try {
|
||||
if (database.getState() != Database.State.CLOSED) {
|
||||
database.executeTransaction(new RemoveOldSampledDataTransaction(serverInfo.getServerUUID()));
|
||||
database.executeTransaction(new RemoveOldSampledDataTransaction(
|
||||
serverInfo.getServerUUID(),
|
||||
config.get(TimeSettings.DELETE_TPS_DATA_AFTER),
|
||||
config.get(TimeSettings.DELETE_PING_DATA_AFTER)
|
||||
));
|
||||
database.executeTransaction(new RemoveDuplicateUserInfoTransaction());
|
||||
database.executeTransaction(new RemoveUnsatisfiedConditionalResultsTransaction());
|
||||
database.executeTransaction(new RemoveUnsatisfiedConditionalPlayerResultsTransaction());
|
||||
database.executeTransaction(new RemoveUnsatisfiedConditionalServerResultsTransaction());
|
||||
int removed = cleanOldPlayers(database);
|
||||
if (removed > 0) {
|
||||
logger.info(locale.getString(PluginLang.DB_NOTIFY_CLEAN, removed));
|
||||
@ -101,7 +107,7 @@ public class DBCleanTask extends AbsRunnable {
|
||||
@VisibleForTesting
|
||||
public int cleanOldPlayers(Database database) {
|
||||
long now = System.currentTimeMillis();
|
||||
long keepActiveAfter = now - config.get(TimeSettings.KEEP_INACTIVE_PLAYERS);
|
||||
long keepActiveAfter = now - config.get(TimeSettings.DELETE_INACTIVE_PLAYERS_AFTER);
|
||||
|
||||
List<UUID> inactivePlayers = database.query(fetchInactivePlayerUUIDs(keepActiveAfter));
|
||||
for (UUID uuid : inactivePlayers) {
|
||||
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.djrapitops.plan.extension;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.DataExtensionMethodCallException;
|
||||
import com.djrapitops.plan.data.plugin.PluginsConfigSection;
|
||||
import com.djrapitops.plan.extension.implementation.CallerImplementation;
|
||||
import com.djrapitops.plan.extension.implementation.DataProviderExtractor;
|
||||
@ -94,11 +95,11 @@ public class ExtensionServiceImplementation implements ExtensionService {
|
||||
logger.warn("DataExtension API implementation mistake for " + pluginName + ": " + warning);
|
||||
}
|
||||
|
||||
ProviderValueGatherer gatherer = new ProviderValueGatherer(extension, extractor, dbSystem, serverInfo, logger);
|
||||
ProviderValueGatherer gatherer = new ProviderValueGatherer(extension, extractor, dbSystem, serverInfo);
|
||||
gatherer.storeExtensionInformation();
|
||||
extensionGatherers.put(pluginName, gatherer);
|
||||
|
||||
updateServerValues(gatherer, CallEvents.SERVER_EXTENSION_REGISTER);
|
||||
processing.submitNonCritical(() -> updateServerValues(gatherer, CallEvents.SERVER_EXTENSION_REGISTER));
|
||||
|
||||
logger.getDebugLogger().logOn(DebugChannels.DATA_EXTENSIONS, pluginName + " extension registered.");
|
||||
return Optional.of(new CallerImplementation(gatherer, this, processing));
|
||||
@ -111,7 +112,6 @@ public class ExtensionServiceImplementation implements ExtensionService {
|
||||
if (extensionGatherers.remove(pluginName) != null) {
|
||||
logger.getDebugLogger().logOn(DebugChannels.DATA_EXTENSIONS, pluginName + " extension unregistered.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean shouldNotAllowRegistration(String pluginName) {
|
||||
@ -150,16 +150,29 @@ public class ExtensionServiceImplementation implements ExtensionService {
|
||||
gatherer.updateValues(playerUUID, playerName);
|
||||
|
||||
logger.getDebugLogger().logOn(DebugChannels.DATA_EXTENSIONS, "Gathering completed: " + playerName);
|
||||
} catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) {
|
||||
logger.warn(gatherer.getPluginName() + " ran into (but failed safely) " + e.getClass().getSimpleName() +
|
||||
" when updating value for '" + playerName +
|
||||
"', (You can disable integration with setting 'Plugins." + gatherer.getPluginName() + ".Enabled')" +
|
||||
" reason: '" + e.getMessage() +
|
||||
} catch (DataExtensionMethodCallException methodCallFailed) {
|
||||
logFailure(playerName, methodCallFailed);
|
||||
gatherer.disableMethodFromUse(methodCallFailed.getMethod());
|
||||
// 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 +
|
||||
" (but failed safely) when updating value for '" + playerName +
|
||||
"', stack trace to follow:");
|
||||
errorHandler.log(L.WARN, gatherer.getClass(), e);
|
||||
errorHandler.log(L.WARN, gatherer.getClass(), unexpectedError);
|
||||
}
|
||||
}
|
||||
|
||||
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 +
|
||||
"', the method was disabled temporarily (won't be called until next Plan reload)" +
|
||||
", stack trace to follow:");
|
||||
errorHandler.log(L.WARN, getClass(), cause);
|
||||
}
|
||||
|
||||
public void updateServerValues(CallEvents event) {
|
||||
for (ProviderValueGatherer gatherer : extensionGatherers.values()) {
|
||||
updateServerValues(gatherer, event);
|
||||
@ -176,13 +189,15 @@ public class ExtensionServiceImplementation implements ExtensionService {
|
||||
gatherer.updateValues();
|
||||
|
||||
logger.getDebugLogger().logOn(DebugChannels.DATA_EXTENSIONS, "Gathering completed for server");
|
||||
} catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) {
|
||||
logger.warn(gatherer.getPluginName() + " ran into (but failed safely) " + e.getClass().getSimpleName() +
|
||||
" when updating value for server" +
|
||||
", (You can disable integration with setting 'Plugins." + gatherer.getPluginName() + ".Enabled')" +
|
||||
" reason: '" + e.getMessage() +
|
||||
"', stack trace to follow:");
|
||||
errorHandler.log(L.WARN, gatherer.getClass(), e);
|
||||
} catch (DataExtensionMethodCallException methodCallFailed) {
|
||||
logFailure("server", methodCallFailed);
|
||||
gatherer.disableMethodFromUse(methodCallFailed.getMethod());
|
||||
// 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:");
|
||||
errorHandler.log(L.WARN, gatherer.getClass(), unexpectedError);
|
||||
}
|
||||
}
|
||||
}
|
@ -47,7 +47,7 @@ public class CallerImplementation implements Caller {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePlayerData(UUID playerUUID, String playerName) throws IllegalArgumentException {
|
||||
public void updatePlayerData(UUID playerUUID, String playerName) {
|
||||
Verify.nullCheck(playerUUID, () -> new IllegalArgumentException("'playerUUID' can not be null!"));
|
||||
Verify.nullCheck(playerName, () -> new IllegalArgumentException("'playerName' can not be null!"));
|
||||
processing.submitNonCritical(() -> extensionServiceImplementation.updatePlayerValues(gatherer, playerUUID, playerName, CallEvents.MANUAL));
|
||||
|
@ -124,6 +124,7 @@ public class DataProviderExtractor {
|
||||
extractDataProviders(pluginInfo, tabs, conditions, PercentageProvider.class, PercentageDataProvider::placeToDataProviders);
|
||||
extractDataProviders(pluginInfo, tabs, conditions, NumberProvider.class, NumberDataProvider::placeToDataProviders);
|
||||
extractDataProviders(pluginInfo, tabs, conditions, StringProvider.class, StringDataProvider::placeToDataProviders);
|
||||
extractDataProviders(pluginInfo, tabs, conditions, TableProvider.class, TableDataProvider::placeToDataProviders);
|
||||
}
|
||||
|
||||
private <T extends Annotation> void extractDataProviders(PluginInfo pluginInfo, Map<Method, Tab> tabs, Map<Method, Conditional> conditions, Class<T> ofKind, DataProviderFactory<T> factory) {
|
||||
|
@ -21,6 +21,7 @@ import com.djrapitops.plan.extension.icon.Icon;
|
||||
import com.djrapitops.plan.extension.implementation.results.ExtensionDescriptive;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
@ -48,10 +49,38 @@ public class ProviderInformation extends ExtensionDescriptive {
|
||||
}
|
||||
|
||||
public Optional<String> getTab() {
|
||||
return tab == null || tab.isEmpty() ? Optional.empty() : Optional.of(StringUtils.truncate(tab, 50));
|
||||
return tab == null || tab.isEmpty()
|
||||
? Optional.empty()
|
||||
: Optional.of(StringUtils.truncate(tab, 50));
|
||||
}
|
||||
|
||||
public Optional<String> getCondition() {
|
||||
return condition == null || condition.value().isEmpty() ? Optional.empty() : Optional.of((condition.negated() ? "not_" : "") + StringUtils.truncate(condition.value(), 50));
|
||||
if (condition == null || condition.value().isEmpty()) {
|
||||
return Optional.empty();
|
||||
} else if (condition.negated()) {
|
||||
return Optional.of("not_" + getTruncatedConditionName());
|
||||
} else {
|
||||
return Optional.of(getTruncatedConditionName());
|
||||
}
|
||||
}
|
||||
|
||||
private String getTruncatedConditionName() {
|
||||
return StringUtils.truncate(condition.value(), 50);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ProviderInformation)) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
ProviderInformation that = (ProviderInformation) o;
|
||||
return pluginName.equals(that.pluginName) &&
|
||||
Objects.equals(tab, that.tab) &&
|
||||
Objects.equals(condition, that.condition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), pluginName, tab, condition);
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.extension.implementation.providers;
|
||||
import com.djrapitops.plan.extension.implementation.MethodType;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Group class for handling multiple different types of {@link DataProvider}s.
|
||||
@ -77,4 +78,24 @@ public class DataProviders {
|
||||
}
|
||||
return byReturnType;
|
||||
}
|
||||
|
||||
public void removeProviderWithMethod(MethodWrapper method) {
|
||||
MethodType methodType = method.getMethodType();
|
||||
Map<Class, List<DataProvider>> byResultType = byMethodType.getOrDefault(methodType, Collections.emptyMap());
|
||||
if (byResultType.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Class resultType = method.getResultType();
|
||||
List<DataProvider> providers = byResultType.getOrDefault(resultType, Collections.emptyList());
|
||||
if (providers.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
byResultType.put(resultType, providers.stream()
|
||||
.filter(provider -> provider.getMethod().equals(method))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
byMethodType.put(methodType, byResultType);
|
||||
}
|
||||
}
|
@ -20,8 +20,10 @@ import com.djrapitops.plan.extension.DataExtension;
|
||||
import com.djrapitops.plan.extension.Group;
|
||||
import com.djrapitops.plan.extension.implementation.MethodType;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -29,7 +31,7 @@ import java.util.UUID;
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class MethodWrapper<T> {
|
||||
public class MethodWrapper<T> implements Serializable {
|
||||
|
||||
private final Method method;
|
||||
private final Class<T> resultType;
|
||||
@ -41,39 +43,46 @@ public class MethodWrapper<T> {
|
||||
methodType = MethodType.forMethod(this.method);
|
||||
}
|
||||
|
||||
public T callMethod(DataExtension extension, UUID playerUUID, String playerName) throws InvocationTargetException, IllegalAccessException {
|
||||
public T callMethod(DataExtension extension, UUID playerUUID, String playerName) {
|
||||
if (methodType != MethodType.PLAYER_NAME && methodType != MethodType.PLAYER_UUID) {
|
||||
throw new IllegalStateException(method.getDeclaringClass() + " method " + method.getName() + " is not GROUP method.");
|
||||
}
|
||||
return callMethod(extension, playerUUID, playerName, null);
|
||||
}
|
||||
|
||||
public T callMethod(DataExtension extension, Group group) throws InvocationTargetException, IllegalAccessException {
|
||||
public T callMethod(DataExtension extension, Group group) {
|
||||
if (methodType != MethodType.GROUP) {
|
||||
throw new IllegalStateException(method.getDeclaringClass() + " method " + method.getName() + " is not GROUP method.");
|
||||
}
|
||||
return callMethod(extension, null, null, group);
|
||||
}
|
||||
|
||||
public T callMethod(DataExtension extension) throws InvocationTargetException, IllegalAccessException {
|
||||
public T callMethod(DataExtension extension) {
|
||||
if (methodType != MethodType.SERVER) {
|
||||
throw new IllegalStateException(method.getDeclaringClass() + " method " + method.getName() + " is not SERVER method.");
|
||||
}
|
||||
return callMethod(extension, null, null, null);
|
||||
}
|
||||
|
||||
public T callMethod(DataExtension extension, UUID playerUUID, String playerName, Group group) throws InvocationTargetException, IllegalAccessException {
|
||||
switch (methodType) {
|
||||
case SERVER:
|
||||
return resultType.cast(method.invoke(extension));
|
||||
case PLAYER_UUID:
|
||||
return resultType.cast(method.invoke(extension, playerUUID));
|
||||
case PLAYER_NAME:
|
||||
return resultType.cast(method.invoke(extension, playerName));
|
||||
case GROUP:
|
||||
return resultType.cast(method.invoke(extension, group));
|
||||
default:
|
||||
throw new IllegalArgumentException(method.getDeclaringClass() + " method " + method.getName() + " had invalid parameters.");
|
||||
public T callMethod(DataExtension extension, UUID playerUUID, String playerName, Group group) {
|
||||
try {
|
||||
switch (methodType) {
|
||||
case SERVER:
|
||||
return resultType.cast(method.invoke(extension));
|
||||
case PLAYER_UUID:
|
||||
return resultType.cast(method.invoke(extension, playerUUID));
|
||||
case PLAYER_NAME:
|
||||
return resultType.cast(method.invoke(extension, playerName));
|
||||
case GROUP:
|
||||
return resultType.cast(method.invoke(extension, group));
|
||||
default:
|
||||
throw new IllegalArgumentException(method.getDeclaringClass() + " method " + method.getName() + " had invalid parameters.");
|
||||
}
|
||||
} catch (InvocationTargetException | IllegalAccessException e) {
|
||||
Throwable cause = e.getCause();
|
||||
boolean hasCause = cause != null;
|
||||
throw new IllegalArgumentException(method.getDeclaringClass() + " method " + method.getName() + " had invalid parameters; caused " +
|
||||
(hasCause ? cause.toString() : e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,4 +97,19 @@ public class MethodWrapper<T> {
|
||||
public Class<T> getResultType() {
|
||||
return resultType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof MethodWrapper)) return false;
|
||||
MethodWrapper<?> that = (MethodWrapper<?>) o;
|
||||
return method.equals(that.method) &&
|
||||
resultType.equals(that.resultType) &&
|
||||
methodType == that.methodType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(method, resultType, methodType);
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.extension.implementation.providers;
|
||||
|
||||
import com.djrapitops.plan.extension.annotation.Conditional;
|
||||
import com.djrapitops.plan.extension.annotation.TableProvider;
|
||||
import com.djrapitops.plan.extension.icon.Color;
|
||||
import com.djrapitops.plan.extension.implementation.ProviderInformation;
|
||||
import com.djrapitops.plan.extension.table.Table;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Represents a DataExtension API method annotated with {@link com.djrapitops.plan.extension.annotation.TableProvider} annotation.
|
||||
* <p>
|
||||
* Used to obtain data to place in the database.
|
||||
* <p>
|
||||
* Please note that not all {@link ProviderInformation} is present.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class TableDataProvider extends DataProvider<Table> {
|
||||
|
||||
private final Color tableColor;
|
||||
|
||||
private TableDataProvider(ProviderInformation providerInformation, MethodWrapper<Table> methodWrapper, Color tableColor) {
|
||||
super(providerInformation, methodWrapper);
|
||||
|
||||
this.tableColor = tableColor;
|
||||
}
|
||||
|
||||
public static void placeToDataProviders(
|
||||
DataProviders dataProviders, Method method, TableProvider annotation,
|
||||
Conditional condition, String tab, String pluginName
|
||||
) {
|
||||
MethodWrapper<Table> methodWrapper = new MethodWrapper<>(method, Table.class);
|
||||
|
||||
ProviderInformation providerInformation = new ProviderInformation(
|
||||
pluginName, method.getName(), null, null, null, 0, tab, condition
|
||||
);
|
||||
|
||||
dataProviders.put(new TableDataProvider(providerInformation, methodWrapper, annotation.tableColor()));
|
||||
}
|
||||
|
||||
public static Color getTableColor(DataProvider<Table> provider) {
|
||||
if (provider instanceof TableDataProvider) {
|
||||
return ((TableDataProvider) provider).getTableColor();
|
||||
}
|
||||
return Color.NONE;
|
||||
}
|
||||
|
||||
public Color getTableColor() {
|
||||
return tableColor;
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.djrapitops.plan.extension.implementation.providers.gathering;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.DataExtensionMethodCallException;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.extension.DataExtension;
|
||||
@ -28,7 +29,6 @@ import com.djrapitops.plan.extension.implementation.storage.transactions.StoreIc
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.providers.StoreBooleanProviderTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.StorePlayerBooleanResultTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.StoreServerBooleanResultTransaction;
|
||||
import com.djrapitops.plugin.logging.console.PluginLogger;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
@ -48,20 +48,17 @@ class BooleanProviderValueGatherer {
|
||||
|
||||
private final Database database;
|
||||
private final DataProviders dataProviders;
|
||||
private final PluginLogger logger;
|
||||
|
||||
BooleanProviderValueGatherer(
|
||||
String pluginName, DataExtension extension,
|
||||
UUID serverUUID, Database database,
|
||||
DataProviders dataProviders,
|
||||
PluginLogger logger
|
||||
DataProviders dataProviders
|
||||
) {
|
||||
this.pluginName = pluginName;
|
||||
this.extension = extension;
|
||||
this.serverUUID = serverUUID;
|
||||
this.database = database;
|
||||
this.dataProviders = dataProviders;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
Conditions gatherBooleanDataOfPlayer(UUID playerUUID, String playerName) {
|
||||
@ -127,10 +124,7 @@ class BooleanProviderValueGatherer {
|
||||
boolean hidden = BooleanDataProvider.isHidden(booleanProvider);
|
||||
|
||||
MethodWrapper<Boolean> method = booleanProvider.getMethod();
|
||||
Boolean result = getMethodResult(
|
||||
methodCaller.apply(method),
|
||||
throwable -> pluginName + " has invalid implementation, method " + method.getMethodName() + " threw exception: " + throwable.toString()
|
||||
);
|
||||
Boolean result = getMethodResult(methodCaller.apply(method), method);
|
||||
if (result == null) {
|
||||
// Error during method call
|
||||
satisfied.add(booleanProvider); // Prevents further attempts to call this provider for this player.
|
||||
@ -155,13 +149,11 @@ class BooleanProviderValueGatherer {
|
||||
return satisfied;
|
||||
}
|
||||
|
||||
private <T> T getMethodResult(Callable<T> callable, Function<Throwable, String> errorMsg) {
|
||||
private <T> T getMethodResult(Callable<T> callable, MethodWrapper<T> method) {
|
||||
try {
|
||||
return callable.call();
|
||||
} catch (Exception | NoSuchFieldError | NoSuchMethodError e) {
|
||||
logger.warn(errorMsg.apply(e));
|
||||
return null;
|
||||
} catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) {
|
||||
throw new DataExtensionMethodCallException(e, pluginName, method);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.djrapitops.plan.extension.implementation.providers.gathering;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.DataExtensionMethodCallException;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.extension.DataExtension;
|
||||
@ -30,7 +31,6 @@ import com.djrapitops.plan.extension.implementation.storage.transactions.results
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.StorePlayerPercentageResultTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.StoreServerDoubleResultTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.StoreServerPercentageResultTransaction;
|
||||
import com.djrapitops.plugin.logging.console.PluginLogger;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
@ -51,20 +51,17 @@ class DoubleAndPercentageProviderValueGatherer {
|
||||
|
||||
private final Database database;
|
||||
private final DataProviders dataProviders;
|
||||
private final PluginLogger logger;
|
||||
|
||||
DoubleAndPercentageProviderValueGatherer(
|
||||
String pluginName, DataExtension extension,
|
||||
UUID serverUUID, Database database,
|
||||
DataProviders dataProviders,
|
||||
PluginLogger logger
|
||||
DataProviders dataProviders
|
||||
) {
|
||||
this.pluginName = pluginName;
|
||||
this.extension = extension;
|
||||
this.serverUUID = serverUUID;
|
||||
this.database = database;
|
||||
this.dataProviders = dataProviders;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
void gatherDoubleDataOfPlayer(UUID playerUUID, String playerName, Conditions conditions) {
|
||||
@ -105,10 +102,7 @@ class DoubleAndPercentageProviderValueGatherer {
|
||||
}
|
||||
|
||||
MethodWrapper<Double> method = doubleProvider.getMethod();
|
||||
Double result = getMethodResult(
|
||||
methodCaller.apply(method),
|
||||
throwable -> pluginName + " has invalid implementation, method " + method.getMethodName() + " threw exception: " + throwable.toString()
|
||||
);
|
||||
Double result = getMethodResult(methodCaller.apply(method), method);
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
@ -123,13 +117,11 @@ class DoubleAndPercentageProviderValueGatherer {
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T getMethodResult(Callable<T> callable, Function<Throwable, String> errorMsg) {
|
||||
private <T> T getMethodResult(Callable<T> callable, MethodWrapper<T> method) {
|
||||
try {
|
||||
return callable.call();
|
||||
} catch (Exception | NoSuchFieldError | NoSuchMethodError e) {
|
||||
logger.warn(errorMsg.apply(e));
|
||||
return null;
|
||||
} catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) {
|
||||
throw new DataExtensionMethodCallException(e, pluginName, method);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.djrapitops.plan.extension.implementation.providers.gathering;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.DataExtensionMethodCallException;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.extension.DataExtension;
|
||||
@ -29,7 +30,6 @@ import com.djrapitops.plan.extension.implementation.storage.transactions.StoreIc
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.providers.StoreNumberProviderTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.StorePlayerNumberResultTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.StoreServerNumberResultTransaction;
|
||||
import com.djrapitops.plugin.logging.console.PluginLogger;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
@ -50,20 +50,17 @@ class NumberProviderValueGatherer {
|
||||
|
||||
private final Database database;
|
||||
private final DataProviders dataProviders;
|
||||
private final PluginLogger logger;
|
||||
|
||||
NumberProviderValueGatherer(
|
||||
String pluginName, DataExtension extension,
|
||||
UUID serverUUID, Database database,
|
||||
DataProviders dataProviders,
|
||||
PluginLogger logger
|
||||
DataProviders dataProviders
|
||||
) {
|
||||
this.pluginName = pluginName;
|
||||
this.extension = extension;
|
||||
this.serverUUID = serverUUID;
|
||||
this.database = database;
|
||||
this.dataProviders = dataProviders;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
void gatherNumberDataOfPlayer(UUID playerUUID, String playerName, Conditions conditions) {
|
||||
@ -100,10 +97,7 @@ class NumberProviderValueGatherer {
|
||||
}
|
||||
|
||||
MethodWrapper<Long> method = numberProvider.getMethod();
|
||||
Long result = getMethodResult(
|
||||
methodCaller.apply(method),
|
||||
throwable -> pluginName + " has invalid implementation, method " + method.getMethodName() + " threw exception: " + throwable.toString()
|
||||
);
|
||||
Long result = getMethodResult(methodCaller.apply(method), method);
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
@ -115,12 +109,11 @@ class NumberProviderValueGatherer {
|
||||
database.executeTransaction(storeTransactionCreator.apply(method, result));
|
||||
}
|
||||
|
||||
private <T> T getMethodResult(Callable<T> callable, Function<Throwable, String> errorMsg) {
|
||||
private <T> T getMethodResult(Callable<T> callable, MethodWrapper<T> method) {
|
||||
try {
|
||||
return callable.call();
|
||||
} catch (Exception | NoSuchFieldError | NoSuchMethodError e) {
|
||||
logger.warn(errorMsg.apply(e));
|
||||
return null;
|
||||
} catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) {
|
||||
throw new DataExtensionMethodCallException(e, pluginName, method);
|
||||
}
|
||||
}
|
||||
}
|
@ -22,13 +22,14 @@ import com.djrapitops.plan.extension.DataExtension;
|
||||
import com.djrapitops.plan.extension.icon.Icon;
|
||||
import com.djrapitops.plan.extension.implementation.DataProviderExtractor;
|
||||
import com.djrapitops.plan.extension.implementation.TabInformation;
|
||||
import com.djrapitops.plan.extension.implementation.providers.DataProviders;
|
||||
import com.djrapitops.plan.extension.implementation.providers.MethodWrapper;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.StoreIconTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.StorePluginTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.StoreTabInformationTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.RemoveInvalidResultsTransaction;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plugin.logging.console.PluginLogger;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@ -43,43 +44,49 @@ public class ProviderValueGatherer {
|
||||
private final DataProviderExtractor extractor;
|
||||
private final DBSystem dbSystem;
|
||||
private final ServerInfo serverInfo;
|
||||
|
||||
private DataProviders dataProviders;
|
||||
private BooleanProviderValueGatherer booleanGatherer;
|
||||
private NumberProviderValueGatherer numberGatherer;
|
||||
private DoubleAndPercentageProviderValueGatherer doubleAndPercentageGatherer;
|
||||
private StringProviderValueGatherer stringGatherer;
|
||||
private TableProviderValueGatherer tableGatherer;
|
||||
|
||||
|
||||
public ProviderValueGatherer(
|
||||
DataExtension extension,
|
||||
DataProviderExtractor extractor,
|
||||
DBSystem dbSystem,
|
||||
ServerInfo serverInfo,
|
||||
PluginLogger logger
|
||||
ServerInfo serverInfo
|
||||
) {
|
||||
this.callEvents = extension.callExtensionMethodsOn();
|
||||
this.extractor = extractor;
|
||||
this.dbSystem = dbSystem;
|
||||
this.serverInfo = serverInfo;
|
||||
|
||||
String pluginName = extractor.getPluginName();
|
||||
UUID serverUUID = serverInfo.getServerUUID();
|
||||
Database database = dbSystem.getDatabase();
|
||||
dataProviders = extractor.getDataProviders();
|
||||
booleanGatherer = new BooleanProviderValueGatherer(
|
||||
extractor.getPluginName(), extension,
|
||||
serverInfo.getServerUUID(), dbSystem.getDatabase(),
|
||||
extractor.getDataProviders(), logger
|
||||
pluginName, extension, serverUUID, database, dataProviders
|
||||
);
|
||||
numberGatherer = new NumberProviderValueGatherer(
|
||||
extractor.getPluginName(), extension,
|
||||
serverInfo.getServerUUID(), dbSystem.getDatabase(),
|
||||
extractor.getDataProviders(), logger
|
||||
pluginName, extension, serverUUID, database, dataProviders
|
||||
);
|
||||
doubleAndPercentageGatherer = new DoubleAndPercentageProviderValueGatherer(
|
||||
extractor.getPluginName(), extension,
|
||||
serverInfo.getServerUUID(), dbSystem.getDatabase(),
|
||||
extractor.getDataProviders(), logger
|
||||
pluginName, extension, serverUUID, database, dataProviders
|
||||
);
|
||||
stringGatherer = new StringProviderValueGatherer(
|
||||
extractor.getPluginName(), extension,
|
||||
serverInfo.getServerUUID(), dbSystem.getDatabase(),
|
||||
extractor.getDataProviders(), logger
|
||||
pluginName, extension, serverUUID, database, dataProviders
|
||||
);
|
||||
tableGatherer = new TableProviderValueGatherer(
|
||||
pluginName, extension, serverUUID, database, dataProviders
|
||||
);
|
||||
}
|
||||
|
||||
public void disableMethodFromUse(MethodWrapper method) {
|
||||
dataProviders.removeProviderWithMethod(method);
|
||||
}
|
||||
|
||||
public boolean canCallEvent(CallEvents event) {
|
||||
@ -121,6 +128,7 @@ public class ProviderValueGatherer {
|
||||
numberGatherer.gatherNumberDataOfPlayer(playerUUID, playerName, conditions);
|
||||
doubleAndPercentageGatherer.gatherDoubleDataOfPlayer(playerUUID, playerName, conditions);
|
||||
stringGatherer.gatherStringDataOfPlayer(playerUUID, playerName, conditions);
|
||||
tableGatherer.gatherTableDataOfPlayer(playerUUID, playerName, conditions);
|
||||
}
|
||||
|
||||
public void updateValues() {
|
||||
@ -128,5 +136,6 @@ public class ProviderValueGatherer {
|
||||
numberGatherer.gatherNumberDataOfServer(conditions);
|
||||
doubleAndPercentageGatherer.gatherDoubleDataOfServer(conditions);
|
||||
stringGatherer.gatherStringDataOfServer(conditions);
|
||||
tableGatherer.gatherTableDataOfServer(conditions);
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.djrapitops.plan.extension.implementation.providers.gathering;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.DataExtensionMethodCallException;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.extension.DataExtension;
|
||||
@ -28,7 +29,6 @@ import com.djrapitops.plan.extension.implementation.storage.transactions.StoreIc
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.providers.StoreStringProviderTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.StorePlayerStringResultTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.StoreServerStringResultTransaction;
|
||||
import com.djrapitops.plugin.logging.console.PluginLogger;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Optional;
|
||||
@ -50,20 +50,17 @@ class StringProviderValueGatherer {
|
||||
|
||||
private final Database database;
|
||||
private final DataProviders dataProviders;
|
||||
private final PluginLogger logger;
|
||||
|
||||
StringProviderValueGatherer(
|
||||
String pluginName, DataExtension extension,
|
||||
UUID serverUUID, Database database,
|
||||
DataProviders dataProviders,
|
||||
PluginLogger logger
|
||||
DataProviders dataProviders
|
||||
) {
|
||||
this.pluginName = pluginName;
|
||||
this.extension = extension;
|
||||
this.serverUUID = serverUUID;
|
||||
this.database = database;
|
||||
this.dataProviders = dataProviders;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
void gatherStringDataOfPlayer(UUID playerUUID, String playerName, Conditions conditions) {
|
||||
@ -101,10 +98,7 @@ class StringProviderValueGatherer {
|
||||
}
|
||||
|
||||
MethodWrapper<String> method = stringProvider.getMethod();
|
||||
String result = getMethodResult(
|
||||
methodCaller.apply(method),
|
||||
throwable -> pluginName + " has invalid implementation, method " + method.getMethodName() + " threw exception: " + throwable.toString()
|
||||
);
|
||||
String result = getMethodResult(methodCaller.apply(method), method);
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
@ -116,12 +110,11 @@ class StringProviderValueGatherer {
|
||||
database.executeTransaction(storeTransactionCreator.apply(method, result));
|
||||
}
|
||||
|
||||
private <T> T getMethodResult(Callable<T> callable, Function<Throwable, String> errorMsg) {
|
||||
private <T> T getMethodResult(Callable<T> callable, MethodWrapper<String> method) {
|
||||
try {
|
||||
return callable.call();
|
||||
} catch (Exception | NoSuchFieldError | NoSuchMethodError e) {
|
||||
logger.warn(errorMsg.apply(e));
|
||||
return null;
|
||||
} catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) {
|
||||
throw new DataExtensionMethodCallException(e, pluginName, method);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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.extension.implementation.providers.gathering;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.DataExtensionMethodCallException;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.extension.DataExtension;
|
||||
import com.djrapitops.plan.extension.icon.Icon;
|
||||
import com.djrapitops.plan.extension.implementation.ProviderInformation;
|
||||
import com.djrapitops.plan.extension.implementation.providers.DataProvider;
|
||||
import com.djrapitops.plan.extension.implementation.providers.DataProviders;
|
||||
import com.djrapitops.plan.extension.implementation.providers.MethodWrapper;
|
||||
import com.djrapitops.plan.extension.implementation.providers.TableDataProvider;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.StoreIconTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.providers.StoreTableProviderTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.StorePlayerTableResultTransaction;
|
||||
import com.djrapitops.plan.extension.implementation.storage.transactions.results.StoreServerTableResultTransaction;
|
||||
import com.djrapitops.plan.extension.table.Table;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Gathers TableProvider method data.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
class TableProviderValueGatherer {
|
||||
|
||||
private final String pluginName;
|
||||
private final DataExtension extension;
|
||||
private final UUID serverUUID;
|
||||
|
||||
private final Database database;
|
||||
private final DataProviders dataProviders;
|
||||
|
||||
TableProviderValueGatherer(
|
||||
String pluginName, DataExtension extension,
|
||||
UUID serverUUID, Database database,
|
||||
DataProviders dataProviders
|
||||
) {
|
||||
this.pluginName = pluginName;
|
||||
this.extension = extension;
|
||||
this.serverUUID = serverUUID;
|
||||
this.database = database;
|
||||
this.dataProviders = dataProviders;
|
||||
}
|
||||
|
||||
void gatherTableDataOfPlayer(UUID playerUUID, String playerName, Conditions conditions) {
|
||||
// Method parameters abstracted away so that same method can be used for all parameter types
|
||||
// Same with Method result store transaction creation
|
||||
Function<MethodWrapper<Table>, Callable<Table>> methodCaller = method -> () -> method.callMethod(extension, playerUUID, playerName);
|
||||
BiFunction<MethodWrapper<Table>, Table, Transaction> storeTransactionCreator = (method, result) -> new StorePlayerTableResultTransaction(pluginName, serverUUID, method.getMethodName(), playerUUID, result);
|
||||
|
||||
for (DataProvider<Table> tableProvider : dataProviders.getPlayerMethodsByType(Table.class)) {
|
||||
gatherTableDataOfProvider(methodCaller, storeTransactionCreator, conditions, tableProvider);
|
||||
}
|
||||
}
|
||||
|
||||
void gatherTableDataOfServer(Conditions conditions) {
|
||||
// Method parameters abstracted away so that same method can be used for all parameter types
|
||||
// Same with Method result store transaction creation
|
||||
Function<MethodWrapper<Table>, Callable<Table>> methodCaller = method -> () -> method.callMethod(extension);
|
||||
BiFunction<MethodWrapper<Table>, Table, Transaction> storeTransactionCreator = (method, result) -> new StoreServerTableResultTransaction(pluginName, serverUUID, method.getMethodName(), result);
|
||||
|
||||
for (DataProvider<Table> tableProvider : dataProviders.getServerMethodsByType(Table.class)) {
|
||||
gatherTableDataOfProvider(methodCaller, storeTransactionCreator, conditions, tableProvider);
|
||||
}
|
||||
}
|
||||
|
||||
private void gatherTableDataOfProvider(
|
||||
Function<MethodWrapper<Table>, Callable<Table>> methodCaller,
|
||||
BiFunction<MethodWrapper<Table>, Table, Transaction> storeTransactionCreator,
|
||||
Conditions conditions,
|
||||
DataProvider<Table> tableProvider
|
||||
) {
|
||||
ProviderInformation providerInformation = tableProvider.getProviderInformation();
|
||||
Optional<String> condition = providerInformation.getCondition();
|
||||
if (condition.isPresent() && conditions.isNotFulfilled(condition.get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
MethodWrapper<Table> method = tableProvider.getMethod();
|
||||
Table result = getMethodResult(methodCaller.apply(method), method);
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Icon icon : result.getIcons()) {
|
||||
if (icon != null) {
|
||||
database.executeTransaction(new StoreIconTransaction(icon));
|
||||
}
|
||||
}
|
||||
database.executeTransaction(new StoreTableProviderTransaction(serverUUID, providerInformation, TableDataProvider.getTableColor(tableProvider), result));
|
||||
database.executeTransaction(storeTransactionCreator.apply(method, result));
|
||||
}
|
||||
|
||||
private <T> T getMethodResult(Callable<T> callable, MethodWrapper<T> method) {
|
||||
try {
|
||||
return callable.call();
|
||||
} catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) {
|
||||
throw new DataExtensionMethodCallException(e, pluginName, method);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -40,4 +40,8 @@ public class ExtensionDoubleData implements ExtensionData {
|
||||
public String getFormattedValue(Formatter<Double> formatter) {
|
||||
return formatter.apply(value);
|
||||
}
|
||||
|
||||
public double getRawValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
@ -47,4 +47,8 @@ public class ExtensionNumberData implements ExtensionData {
|
||||
public String getFormattedValue(Formatter<Long> formatter) {
|
||||
return formatter.apply(value);
|
||||
}
|
||||
|
||||
public long getRawValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
@ -36,7 +36,10 @@ public class ExtensionTabData implements Comparable<ExtensionTabData> {
|
||||
private final Map<String, ExtensionNumberData> numberData;
|
||||
private final Map<String, ExtensionStringData> stringData;
|
||||
|
||||
private final List<ExtensionTableData> tableData;
|
||||
|
||||
private List<String> order;
|
||||
private List<ExtensionDescriptive> descriptives;
|
||||
|
||||
// Table and Graph data will be added later.
|
||||
|
||||
@ -48,6 +51,9 @@ public class ExtensionTabData implements Comparable<ExtensionTabData> {
|
||||
percentageData = new HashMap<>();
|
||||
numberData = new HashMap<>();
|
||||
stringData = new HashMap<>();
|
||||
|
||||
tableData = new ArrayList<>();
|
||||
descriptives = new ArrayList<>();
|
||||
}
|
||||
|
||||
public TabInformation getTabInformation() {
|
||||
@ -78,6 +84,21 @@ public class ExtensionTabData implements Comparable<ExtensionTabData> {
|
||||
return Optional.ofNullable(stringData.get(providerName));
|
||||
}
|
||||
|
||||
public List<ExtensionTableData> getTableData() {
|
||||
return tableData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Descriptives for this tabs data.
|
||||
* <p>
|
||||
* Only available after the Tab has been built.
|
||||
*
|
||||
* @return List of {@link ExtensionDescriptive}s.
|
||||
*/
|
||||
public List<ExtensionDescriptive> getDescriptives() {
|
||||
return descriptives;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ExtensionTabData other) {
|
||||
return Integer.compare(this.tabInformation.getTabPriority(), other.tabInformation.getTabPriority()); // Lower is first
|
||||
@ -103,6 +124,23 @@ public class ExtensionTabData implements Comparable<ExtensionTabData> {
|
||||
this.percentageData.putAll(other.percentageData);
|
||||
this.numberData.putAll(other.numberData);
|
||||
this.stringData.putAll(other.stringData);
|
||||
|
||||
this.tableData.addAll(other.tableData);
|
||||
|
||||
createOrderingList();
|
||||
}
|
||||
|
||||
private void createOrderingList() {
|
||||
booleanData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add);
|
||||
doubleData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add);
|
||||
percentageData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add);
|
||||
numberData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add);
|
||||
stringData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add);
|
||||
|
||||
order = descriptives.stream().sorted()
|
||||
.map(ExtensionDescriptive::getName)
|
||||
.distinct()// Method names are usually different, but in case someone had same method name with different parameters.
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static class Factory {
|
||||
@ -138,22 +176,14 @@ public class ExtensionTabData implements Comparable<ExtensionTabData> {
|
||||
return this;
|
||||
}
|
||||
|
||||
private void createOrderingList() {
|
||||
List<ExtensionDescriptive> descriptives = new ArrayList<>();
|
||||
data.booleanData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add);
|
||||
data.doubleData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add);
|
||||
data.percentageData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add);
|
||||
data.numberData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add);
|
||||
data.stringData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add);
|
||||
|
||||
data.order = descriptives.stream().sorted()
|
||||
.map(ExtensionDescriptive::getName)
|
||||
.distinct()// Method names are usually different, but in case someone had same method name with different parameters.
|
||||
.collect(Collectors.toList());
|
||||
public Factory putTableData(ExtensionTableData extensionTableData) {
|
||||
data.tableData.add(extensionTableData);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ExtensionTabData build() {
|
||||
createOrderingList();
|
||||
data.createOrderingList();
|
||||
Collections.sort(data.tableData);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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.extension.implementation.results;
|
||||
|
||||
import com.djrapitops.plan.data.element.TableContainer;
|
||||
import com.djrapitops.plan.extension.icon.Color;
|
||||
import com.djrapitops.plan.extension.icon.Icon;
|
||||
import com.djrapitops.plan.extension.table.Table;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents table data from a single TableProvider.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ExtensionTableData implements Comparable<ExtensionTableData> {
|
||||
|
||||
private final String providerName;
|
||||
private final Table table;
|
||||
private final Color tableColor;
|
||||
|
||||
public ExtensionTableData(String providerName, Table table, Color tableColor) {
|
||||
this.providerName = providerName;
|
||||
this.table = table;
|
||||
this.tableColor = tableColor;
|
||||
}
|
||||
|
||||
public TableContainer getHtmlTable() {
|
||||
String[] columns = table.getColumns();
|
||||
Icon[] icons = table.getIcons();
|
||||
List<Object[]> rows = table.getRows();
|
||||
|
||||
String[] header = buildHeader(columns, icons);
|
||||
|
||||
TableContainer htmlTable = new TableContainer(header);
|
||||
if (rows.size() > 50) {
|
||||
htmlTable.useJqueryDataTables(); // Use a jQuery data table since there are a lot of rows.
|
||||
} else {
|
||||
String colorName = com.djrapitops.plan.utilities.html.icon.Color.getByName(tableColor.name()).orElse(com.djrapitops.plan.utilities.html.icon.Color.NONE).getHtmlClass()
|
||||
.replace("col-", ""); // TODO after PluginData deprecation, change this thing
|
||||
htmlTable.setColor(colorName);
|
||||
}
|
||||
|
||||
for (Object[] row : rows) {
|
||||
htmlTable.addRow(Arrays.stream(row).map(value -> value != null ? value.toString() : null).toArray(Serializable[]::new));
|
||||
}
|
||||
|
||||
return htmlTable;
|
||||
}
|
||||
|
||||
private String[] buildHeader(String[] columns, Icon[] icons) {
|
||||
ArrayList<String> header = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
String column = columns[i];
|
||||
if (column == null) {
|
||||
break;
|
||||
}
|
||||
header.add(com.djrapitops.plan.utilities.html.icon.Icon.fromExtensionIcon(icons[i]).toHtml() + ' ' + column);
|
||||
}
|
||||
|
||||
return header.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ExtensionTableData)) return false;
|
||||
ExtensionTableData that = (ExtensionTableData) o;
|
||||
return providerName.equals(that.providerName) &&
|
||||
tableColor == that.tableColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(providerName, tableColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ExtensionTableData other) {
|
||||
return String.CASE_INSENSITIVE_ORDER.compare(providerName, other.providerName);
|
||||
}
|
||||
|
||||
public boolean isWideTable() {
|
||||
return table.getMaxColumnSize() > 3;
|
||||
}
|
||||
}
|
@ -19,10 +19,7 @@ package com.djrapitops.plan.extension.implementation.results.player;
|
||||
import com.djrapitops.plan.extension.implementation.results.ExtensionInformation;
|
||||
import com.djrapitops.plan.extension.implementation.results.ExtensionTabData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Represents data of a single extension about a player.
|
||||
@ -104,6 +101,31 @@ public class ExtensionPlayerData implements Comparable<ExtensionPlayerData> {
|
||||
Collections.sort(data.tabs);
|
||||
return data;
|
||||
}
|
||||
|
||||
public Factory combine(Factory with) {
|
||||
if (with != null) {
|
||||
for (ExtensionTabData tab : with.build().getTabs()) {
|
||||
Optional<ExtensionTabData> found = getTab(tab.getTabInformation().getTabName());
|
||||
if (found.isPresent()) {
|
||||
found.get().combine(tab);
|
||||
} else {
|
||||
addTab(tab);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Optional<ExtensionTabData> getTab(String tabName) {
|
||||
for (ExtensionTabData tab : data.tabs) {
|
||||
if (tabName.equals(tab.getTabInformation().getTabName())) {
|
||||
return Optional.of(tab);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -150,8 +150,8 @@ public class ExtensionAggregateNumbersQuery implements Query<Map<Integer, Extens
|
||||
|
||||
private void extractAndPutDataTo(ExtensionTabData.Factory extensionTab, ExtensionDescriptive descriptive, ResultSet set) throws SQLException {
|
||||
FormatType formatType = FormatType.getByName(set.getString(ExtensionProviderTable.FORMAT_TYPE)).orElse(FormatType.NONE);
|
||||
extensionTab.putNumberData(new ExtensionNumberData(modifiedDescriptive(descriptive, "_avg", "Average "), formatType, set.getLong("average")));
|
||||
extensionTab.putNumberData(new ExtensionNumberData(modifiedDescriptive(descriptive, "_total", "Total "), formatType, set.getLong("total")));
|
||||
extensionTab.putNumberData(new ExtensionNumberData(modifiedDescriptive(descriptive, "_avg", "Average "), formatType, (long) set.getDouble("average")));
|
||||
extensionTab.putNumberData(new ExtensionNumberData(modifiedDescriptive(descriptive, "_total", "Total "), formatType, (long) set.getDouble("total")));
|
||||
}
|
||||
|
||||
private ExtensionDescriptive modifiedDescriptive(ExtensionDescriptive descriptive, String appendToName, String appendToText) {
|
||||
|
@ -68,9 +68,29 @@ public class ExtensionPlayerDataQuery implements Query<Map<UUID, List<ExtensionP
|
||||
Map<UUID, List<ExtensionInformation>> extensionsByServerUUID = db.query(ExtensionInformationQueries.allExtensions());
|
||||
Map<Integer, ExtensionPlayerData.Factory> extensionDataByPluginID = db.query(fetchIncompletePlayerDataByPluginID());
|
||||
|
||||
Map<Integer, ExtensionPlayerData.Factory> tableDataByPluginID = db.query(new ExtensionPlayerTablesQuery(playerUUID));
|
||||
combine(extensionDataByPluginID, tableDataByPluginID);
|
||||
|
||||
return flatMapByServerUUID(extensionsByServerUUID, extensionDataByPluginID);
|
||||
}
|
||||
|
||||
private void combine(
|
||||
Map<Integer, ExtensionPlayerData.Factory> extensionDataByPluginID,
|
||||
Map<Integer, ExtensionPlayerData.Factory> aggregates
|
||||
) {
|
||||
for (Map.Entry<Integer, ExtensionPlayerData.Factory> entry : aggregates.entrySet()) {
|
||||
Integer pluginID = entry.getKey();
|
||||
ExtensionPlayerData.Factory data = entry.getValue();
|
||||
|
||||
ExtensionPlayerData.Factory found = extensionDataByPluginID.get(pluginID);
|
||||
if (found == null) {
|
||||
extensionDataByPluginID.put(pluginID, data);
|
||||
} else {
|
||||
found.combine(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Map<UUID, List<ExtensionPlayerData>> flatMapByServerUUID(Map<UUID, List<ExtensionInformation>> extensionsByServerUUID, Map<Integer, ExtensionPlayerData.Factory> extensionDataByPluginID) {
|
||||
Map<UUID, List<ExtensionPlayerData>> extensionDataByServerUUID = new HashMap<>();
|
||||
|
||||
|
@ -0,0 +1,287 @@
|
||||
/*
|
||||
* 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.extension.implementation.storage.queries;
|
||||
|
||||
import com.djrapitops.plan.db.SQLDB;
|
||||
import com.djrapitops.plan.db.access.Query;
|
||||
import com.djrapitops.plan.db.access.QueryStatement;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionIconTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionPlayerTableValueTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionTabTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable;
|
||||
import com.djrapitops.plan.extension.ElementOrder;
|
||||
import com.djrapitops.plan.extension.icon.Color;
|
||||
import com.djrapitops.plan.extension.icon.Family;
|
||||
import com.djrapitops.plan.extension.icon.Icon;
|
||||
import com.djrapitops.plan.extension.implementation.TabInformation;
|
||||
import com.djrapitops.plan.extension.implementation.results.ExtensionTabData;
|
||||
import com.djrapitops.plan.extension.implementation.results.ExtensionTableData;
|
||||
import com.djrapitops.plan.extension.implementation.results.player.ExtensionPlayerData;
|
||||
import com.djrapitops.plan.extension.table.Table;
|
||||
import com.djrapitops.plan.extension.table.TableAccessor;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.*;
|
||||
|
||||
/**
|
||||
* Query player tables from tableprovider table.
|
||||
* <p>
|
||||
* Returns Map: PluginID - ExtensionPlayerData.Factory.
|
||||
* <p>
|
||||
* How it is done:
|
||||
* - TableProviders are queried and formed into Table.Factory objects sorted into a multi-map: PluginID - TableID - Table.Factory
|
||||
* - Table values are queried and merged into the above multimap
|
||||
* - Data query is sorted into a multi-map: PluginID - Tab Name - Tab Data
|
||||
* - (Tab Name can be empty.)
|
||||
* - Multi-map is sorted into ExtensionPlayerData objects by PluginID, one per ID
|
||||
* <p>
|
||||
* There are multiple data extraction methods to make extracting the value query easier.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ExtensionPlayerTablesQuery implements Query<Map<Integer, ExtensionPlayerData.Factory>> {
|
||||
|
||||
private final UUID playerUUID;
|
||||
|
||||
public ExtensionPlayerTablesQuery(UUID playerUUID) {
|
||||
this.playerUUID = playerUUID;
|
||||
}
|
||||
|
||||
private static Map<Integer, ExtensionPlayerData.Factory> flatMapByPluginID(Map<Integer, Map<String, ExtensionTabData.Factory>> tabDataByPluginID) {
|
||||
Map<Integer, ExtensionPlayerData.Factory> dataByPluginID = new HashMap<>();
|
||||
for (Map.Entry<Integer, Map<String, ExtensionTabData.Factory>> entry : tabDataByPluginID.entrySet()) {
|
||||
Integer pluginID = entry.getKey();
|
||||
ExtensionPlayerData.Factory data = dataByPluginID.getOrDefault(pluginID, new ExtensionPlayerData.Factory(pluginID));
|
||||
for (ExtensionTabData.Factory tabData : entry.getValue().values()) {
|
||||
data.addTab(tabData.build());
|
||||
}
|
||||
dataByPluginID.put(pluginID, data);
|
||||
}
|
||||
return dataByPluginID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, ExtensionPlayerData.Factory> executeQuery(SQLDB db) {
|
||||
Map<Integer, Map<Integer, Table.Factory>> tablesByPluginIDAndTableID = db.query(queryTableProviders());
|
||||
Map<Integer, Map<Integer, Table.Factory>> tablesWithValues = db.query(queryTableValues(tablesByPluginIDAndTableID));
|
||||
|
||||
Map<Integer, Map<String, ExtensionTabData.Factory>> tabDataByPluginID = mapToTabsByPluginID(tablesWithValues);
|
||||
return flatMapByPluginID(tabDataByPluginID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tablesByPluginIDAndTableID {@code <Plugin ID - <Table ID - Table.Factory>>}
|
||||
* @return {@code <Plugin ID - <Tab name - ExtensionTabData.Factory>}
|
||||
*/
|
||||
private Map<Integer, Map<String, ExtensionTabData.Factory>> mapToTabsByPluginID(Map<Integer, Map<Integer, Table.Factory>> tablesByPluginIDAndTableID) {
|
||||
Map<Integer, Map<String, ExtensionTabData.Factory>> byPluginID = new HashMap<>();
|
||||
|
||||
for (Map.Entry<Integer, Map<Integer, Table.Factory>> entry : tablesByPluginIDAndTableID.entrySet()) {
|
||||
Integer pluginID = entry.getKey();
|
||||
Map<String, ExtensionTabData.Factory> byTabName = byPluginID.getOrDefault(pluginID, new HashMap<>());
|
||||
for (Table.Factory table : entry.getValue().values()) {
|
||||
// Extra Table information
|
||||
String tableName = TableAccessor.getTableName(table);
|
||||
Color tableColor = TableAccessor.getColor(table);
|
||||
|
||||
// Extra tab information
|
||||
String tabName = TableAccessor.getTabName(table);
|
||||
int tabPriority = TableAccessor.getTabPriority(table);
|
||||
ElementOrder[] tabOrder = TableAccessor.getTabOrder(table);
|
||||
Icon tabIcon = TableAccessor.getTabIcon(table);
|
||||
|
||||
ExtensionTabData.Factory tab = byTabName.getOrDefault(tabName, new ExtensionTabData.Factory(new TabInformation(tabName, tabIcon, tabOrder, tabPriority)));
|
||||
tab.putTableData(new ExtensionTableData(
|
||||
tableName, table.build(), tableColor
|
||||
));
|
||||
byTabName.put(tabName, tab);
|
||||
}
|
||||
byPluginID.put(pluginID, byTabName);
|
||||
}
|
||||
|
||||
return byPluginID;
|
||||
}
|
||||
|
||||
// Map: <Plugin ID - <Table ID - Table.Factory>>
|
||||
private Query<Map<Integer, Map<Integer, Table.Factory>>> queryTableValues(Map<Integer, Map<Integer, Table.Factory>> tables) {
|
||||
String selectTableValues = SELECT +
|
||||
ExtensionTableProviderTable.PLUGIN_ID + ',' +
|
||||
ExtensionPlayerTableValueTable.TABLE_ID + ',' +
|
||||
ExtensionPlayerTableValueTable.VALUE_1 + ',' +
|
||||
ExtensionPlayerTableValueTable.VALUE_2 + ',' +
|
||||
ExtensionPlayerTableValueTable.VALUE_3 + ',' +
|
||||
ExtensionPlayerTableValueTable.VALUE_4 +
|
||||
FROM + ExtensionPlayerTableValueTable.TABLE_NAME +
|
||||
INNER_JOIN + ExtensionTableProviderTable.TABLE_NAME + " on " + ExtensionTableProviderTable.TABLE_NAME + '.' + ExtensionTableProviderTable.ID + '=' + ExtensionPlayerTableValueTable.TABLE_NAME + '.' + ExtensionPlayerTableValueTable.TABLE_ID +
|
||||
WHERE + ExtensionPlayerTableValueTable.USER_UUID + "=?";
|
||||
|
||||
return new QueryStatement<Map<Integer, Map<Integer, Table.Factory>>>(selectTableValues, 10000) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, playerUUID.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, Map<Integer, Table.Factory>> processResults(ResultSet set) throws SQLException {
|
||||
while (set.next()) {
|
||||
Table.Factory table = getTable(set);
|
||||
if (table == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Object[] row = extractTableRow(set);
|
||||
if (row.length > 0) {
|
||||
table.addRow(row);
|
||||
}
|
||||
}
|
||||
return tables;
|
||||
}
|
||||
|
||||
private Table.Factory getTable(ResultSet set) throws SQLException {
|
||||
int pluginID = set.getInt(ExtensionTableProviderTable.PLUGIN_ID);
|
||||
Map<Integer, Table.Factory> byTableID = tables.get(pluginID);
|
||||
if (byTableID == null) {
|
||||
return null;
|
||||
}
|
||||
int tableID = set.getInt(ExtensionPlayerTableValueTable.TABLE_ID);
|
||||
return byTableID.get(tableID);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Object[] extractTableRow(ResultSet set) throws SQLException {
|
||||
List<Object> row = new ArrayList<>();
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
String columnName = "col_" + i + "_value"; // See ExtensionPlayerTableValueTable.VALUE_1
|
||||
String value = set.getString(columnName);
|
||||
if (value == null) {
|
||||
return row.toArray(new Object[0]);
|
||||
}
|
||||
row.add(value);
|
||||
}
|
||||
return row.toArray(new Object[0]);
|
||||
}
|
||||
|
||||
// Map: <Plugin ID - <Table ID - Table.Factory>>
|
||||
private Query<Map<Integer, Map<Integer, Table.Factory>>> queryTableProviders() {
|
||||
String selectTables = SELECT +
|
||||
"p1." + ExtensionTableProviderTable.ID + " as table_id," +
|
||||
"p1." + ExtensionTableProviderTable.PLUGIN_ID + " as plugin_id," +
|
||||
"p1." + ExtensionTableProviderTable.PROVIDER_NAME + " as table_name," +
|
||||
"p1." + ExtensionTableProviderTable.COLOR + " as table_color," +
|
||||
ExtensionTableProviderTable.COL_1 + ',' +
|
||||
ExtensionTableProviderTable.COL_2 + ',' +
|
||||
ExtensionTableProviderTable.COL_3 + ',' +
|
||||
ExtensionTableProviderTable.COL_4 + ',' +
|
||||
"t1." + ExtensionTabTable.TAB_NAME + " as tab_name," +
|
||||
"t1." + ExtensionTabTable.TAB_PRIORITY + " as tab_priority," +
|
||||
"t1." + ExtensionTabTable.ELEMENT_ORDER + " as element_order," +
|
||||
"i1." + ExtensionIconTable.ICON_NAME + " as i1_name," +
|
||||
"i1." + ExtensionIconTable.FAMILY + " as i1_family," +
|
||||
"i1." + ExtensionIconTable.COLOR + " as i1_color," +
|
||||
"i2." + ExtensionIconTable.ICON_NAME + " as i2_name," +
|
||||
"i2." + ExtensionIconTable.FAMILY + " as i2_family," +
|
||||
"i2." + ExtensionIconTable.COLOR + " as i2_color," +
|
||||
"i3." + ExtensionIconTable.ICON_NAME + " as i3_name," +
|
||||
"i3." + ExtensionIconTable.FAMILY + " as i3_family," +
|
||||
"i3." + ExtensionIconTable.COLOR + " as i3_color," +
|
||||
"i4." + ExtensionIconTable.ICON_NAME + " as i4_name," +
|
||||
"i4." + ExtensionIconTable.FAMILY + " as i4_family," +
|
||||
"i4." + ExtensionIconTable.COLOR + " as i4_color," +
|
||||
"i6." + ExtensionIconTable.ICON_NAME + " as tab_icon_name," +
|
||||
"i6." + ExtensionIconTable.FAMILY + " as tab_icon_family," +
|
||||
"i6." + ExtensionIconTable.COLOR + " as tab_icon_color" +
|
||||
FROM + ExtensionTableProviderTable.TABLE_NAME + " p1" +
|
||||
INNER_JOIN + ExtensionPlayerTableValueTable.TABLE_NAME + " v1 on v1." + ExtensionPlayerTableValueTable.TABLE_ID + "=p1." + ExtensionTableProviderTable.ID +
|
||||
LEFT_JOIN + ExtensionTabTable.TABLE_NAME + " t1 on t1." + ExtensionTabTable.ID + "=p1." + ExtensionTableProviderTable.TAB_ID +
|
||||
LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_1_ID +
|
||||
LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i2 on i2." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_2_ID +
|
||||
LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i3 on i3." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_3_ID +
|
||||
LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i4 on i4." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_4_ID +
|
||||
LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i6 on i6." + ExtensionIconTable.ID + "=t1." + ExtensionTabTable.ICON_ID +
|
||||
WHERE + "v1." + ExtensionPlayerTableValueTable.USER_UUID + "=?";
|
||||
|
||||
return new QueryStatement<Map<Integer, Map<Integer, Table.Factory>>>(selectTables, 100) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, playerUUID.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, Map<Integer, Table.Factory>> processResults(ResultSet set) throws SQLException {
|
||||
Map<Integer, Map<Integer, Table.Factory>> byPluginID = new HashMap<>();
|
||||
|
||||
while (set.next()) {
|
||||
int pluginID = set.getInt("plugin_id");
|
||||
Map<Integer, Table.Factory> byTableID = byPluginID.getOrDefault(pluginID, new HashMap<>());
|
||||
|
||||
int tableID = set.getInt("table_id");
|
||||
Table.Factory table = Table.builder();
|
||||
|
||||
extractColumns(set, table);
|
||||
|
||||
TableAccessor.setColor(table, Color.getByName(set.getString("table_color")).orElse(Color.NONE));
|
||||
TableAccessor.setTableName(table, set.getString("table_name"));
|
||||
TableAccessor.setTabName(table, Optional.ofNullable(set.getString("tab_name")).orElse(""));
|
||||
TableAccessor.setTabPriority(table, Optional.of(set.getInt("tab_priority")).orElse(100));
|
||||
TableAccessor.setTabOrder(table, Optional.ofNullable(set.getString(ExtensionTabTable.ELEMENT_ORDER)).map(ElementOrder::deserialize).orElse(ElementOrder.values()));
|
||||
TableAccessor.setTabIcon(table, extractIcon(set, "tab_icon"));
|
||||
|
||||
byTableID.put(tableID, table);
|
||||
byPluginID.put(pluginID, byTableID);
|
||||
}
|
||||
|
||||
return byPluginID;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void extractColumns(ResultSet set, Table.Factory table) throws SQLException {
|
||||
String col1 = set.getString(ExtensionTableProviderTable.COL_1);
|
||||
if (col1 != null) {
|
||||
table.columnOne(col1, extractIcon(set, "i1"));
|
||||
}
|
||||
String col2 = set.getString(ExtensionTableProviderTable.COL_2);
|
||||
if (col2 != null) {
|
||||
table.columnTwo(col2, extractIcon(set, "i2"));
|
||||
}
|
||||
String col3 = set.getString(ExtensionTableProviderTable.COL_3);
|
||||
if (col3 != null) {
|
||||
table.columnThree(col3, extractIcon(set, "i3"));
|
||||
}
|
||||
String col4 = set.getString(ExtensionTableProviderTable.COL_4);
|
||||
if (col4 != null) {
|
||||
table.columnFour(col4, extractIcon(set, "i4"));
|
||||
}
|
||||
}
|
||||
|
||||
private Icon extractIcon(ResultSet set, String iconColumnName) throws SQLException {
|
||||
String iconName = set.getString(iconColumnName + "_name");
|
||||
if (iconName == null) {
|
||||
return null;
|
||||
}
|
||||
return new Icon(
|
||||
Family.getByName(set.getString(iconColumnName + "_family")).orElse(Family.SOLID),
|
||||
iconName,
|
||||
Color.getByName(set.getString(iconColumnName + "_color")).orElse(Color.NONE)
|
||||
);
|
||||
}
|
||||
}
|
@ -83,6 +83,7 @@ public class ExtensionServerDataQuery implements Query<List<ExtensionServerData>
|
||||
combine(extensionDataByPluginID, db.query(new ExtensionAggregateDoublesQuery(serverUUID)));
|
||||
combine(extensionDataByPluginID, db.query(new ExtensionAggregateNumbersQuery(serverUUID)));
|
||||
combine(extensionDataByPluginID, db.query(new ExtensionAggregatePercentagesQuery(serverUUID)));
|
||||
combine(extensionDataByPluginID, db.query(new ExtensionServerTablesQuery(serverUUID)));
|
||||
|
||||
return combineWithExtensionInfo(extensionsOfServer, extensionDataByPluginID);
|
||||
}
|
||||
|
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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.extension.implementation.storage.queries;
|
||||
|
||||
import com.djrapitops.plan.db.SQLDB;
|
||||
import com.djrapitops.plan.db.access.Query;
|
||||
import com.djrapitops.plan.db.access.QueryStatement;
|
||||
import com.djrapitops.plan.db.sql.tables.*;
|
||||
import com.djrapitops.plan.extension.FormatType;
|
||||
import com.djrapitops.plan.extension.icon.Color;
|
||||
import com.djrapitops.plan.extension.icon.Family;
|
||||
import com.djrapitops.plan.extension.icon.Icon;
|
||||
import com.djrapitops.plan.extension.implementation.results.*;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.*;
|
||||
|
||||
/**
|
||||
* Query Extension data of x most recent players on a server.
|
||||
* <p>
|
||||
* Returns Map: Player UUID - ExtensionTabData (container for provider based data)
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ExtensionServerPlayerDataTableQuery implements Query<Map<UUID, ExtensionTabData>> {
|
||||
|
||||
private final UUID serverUUID;
|
||||
private final int xMostRecentPlayers;
|
||||
|
||||
public ExtensionServerPlayerDataTableQuery(UUID serverUUID, int xMostRecentPlayers) {
|
||||
this.serverUUID = serverUUID;
|
||||
this.xMostRecentPlayers = xMostRecentPlayers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, ExtensionTabData> executeQuery(SQLDB db) {
|
||||
return db.query(fetchIncompletePlayerDataByPluginID());
|
||||
}
|
||||
|
||||
private Query<Map<UUID, ExtensionTabData>> fetchIncompletePlayerDataByPluginID() {
|
||||
String selectLimitedNumberOfPlayerUUIDsByLastSeenDate = SELECT +
|
||||
SessionsTable.TABLE_NAME + '.' + SessionsTable.USER_UUID +
|
||||
",MAX(" + SessionsTable.SESSION_END + ") as last_seen" +
|
||||
FROM + SessionsTable.TABLE_NAME +
|
||||
GROUP_BY + SessionsTable.USER_UUID +
|
||||
ORDER_BY + SessionsTable.SESSION_END + " DESC LIMIT ?";
|
||||
|
||||
String sql = SELECT +
|
||||
"v1." + ExtensionPlayerValueTable.USER_UUID + " as uuid," +
|
||||
"v1." + ExtensionPlayerValueTable.DOUBLE_VALUE + " as double_value," +
|
||||
"v1." + ExtensionPlayerValueTable.LONG_VALUE + " as long_value," +
|
||||
"v1." + ExtensionPlayerValueTable.STRING_VALUE + " as string_value," +
|
||||
"p1." + ExtensionProviderTable.PROVIDER_NAME + " as provider_name," +
|
||||
"p1." + ExtensionProviderTable.TEXT + " as text," +
|
||||
"p1." + ExtensionProviderTable.FORMAT_TYPE + " as format_type," +
|
||||
"p1." + ExtensionProviderTable.IS_PLAYER_NAME + " as is_player_name," +
|
||||
"i1." + ExtensionIconTable.ICON_NAME + " as provider_icon_name," +
|
||||
"i1." + ExtensionIconTable.FAMILY + " as provider_icon_family" +
|
||||
FROM + ExtensionPlayerValueTable.TABLE_NAME + " v1" +
|
||||
INNER_JOIN + '(' + selectLimitedNumberOfPlayerUUIDsByLastSeenDate + ") as last_seen_q on last_seen_q.uuid=v1." + ExtensionPlayerValueTable.USER_UUID +
|
||||
INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " p1 on p1." + ExtensionProviderTable.ID + "=v1." + ExtensionPlayerValueTable.PROVIDER_ID +
|
||||
INNER_JOIN + ExtensionPluginTable.TABLE_NAME + " e1 on e1." + ExtensionPluginTable.ID + "=p1." + ExtensionProviderTable.PLUGIN_ID +
|
||||
LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionProviderTable.ICON_ID +
|
||||
WHERE + "e1." + ExtensionPluginTable.SERVER_UUID + "=?" +
|
||||
AND + " v1." + ExtensionPlayerValueTable.BOOLEAN_VALUE + IS_NULL + // Don't select Boolean value rows
|
||||
AND + " v1." + ExtensionPlayerValueTable.PERCENTAGE_VALUE + IS_NULL + // Don't select Percentage value rows
|
||||
AND + " p1." + ExtensionProviderTable.IS_PLAYER_NAME + "=?";
|
||||
|
||||
return new QueryStatement<Map<UUID, ExtensionTabData>>(sql, 1000) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setInt(1, xMostRecentPlayers); // Limit to x most recently seen players
|
||||
statement.setString(2, serverUUID.toString());
|
||||
statement.setBoolean(3, false); // Don't select player_name String values
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, ExtensionTabData> processResults(ResultSet set) throws SQLException {
|
||||
return extractDataByPlayer(set);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Map<UUID, ExtensionTabData> extractDataByPlayer(ResultSet set) throws SQLException {
|
||||
Map<UUID, ExtensionTabData.Factory> dataByPlayer = new HashMap<>();
|
||||
|
||||
while (set.next()) {
|
||||
UUID playerUUID = UUID.fromString(set.getString("uuid"));
|
||||
ExtensionTabData.Factory data = dataByPlayer.getOrDefault(playerUUID, new ExtensionTabData.Factory(null));
|
||||
|
||||
ExtensionDescriptive extensionDescriptive = extractDescriptive(set);
|
||||
extractAndPutDataTo(data, extensionDescriptive, set);
|
||||
|
||||
dataByPlayer.put(playerUUID, data);
|
||||
}
|
||||
return dataByPlayer.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().build()));
|
||||
}
|
||||
|
||||
private void extractAndPutDataTo(ExtensionTabData.Factory extensionTab, ExtensionDescriptive descriptive, ResultSet set) throws SQLException {
|
||||
double doubleValue = set.getDouble(ExtensionPlayerValueTable.DOUBLE_VALUE);
|
||||
if (!set.wasNull()) {
|
||||
extensionTab.putDoubleData(new ExtensionDoubleData(descriptive, doubleValue));
|
||||
return;
|
||||
}
|
||||
|
||||
long numberValue = set.getLong(ExtensionPlayerValueTable.LONG_VALUE);
|
||||
if (!set.wasNull()) {
|
||||
FormatType formatType = FormatType.getByName(set.getString(ExtensionProviderTable.FORMAT_TYPE)).orElse(FormatType.NONE);
|
||||
extensionTab.putNumberData(new ExtensionNumberData(descriptive, formatType, numberValue));
|
||||
return;
|
||||
}
|
||||
|
||||
String stringValue = set.getString(ExtensionPlayerValueTable.STRING_VALUE);
|
||||
if (stringValue != null) {
|
||||
boolean isPlayerName = false;
|
||||
extensionTab.putStringData(new ExtensionStringData(descriptive, isPlayerName, stringValue));
|
||||
}
|
||||
}
|
||||
|
||||
private ExtensionDescriptive extractDescriptive(ResultSet set) throws SQLException {
|
||||
String name = set.getString("provider_name");
|
||||
String text = set.getString(ExtensionProviderTable.TEXT);
|
||||
|
||||
String iconName = set.getString("provider_icon_name");
|
||||
Family family = Family.getByName(set.getString("provider_icon_family")).orElse(Family.SOLID);
|
||||
Icon icon = new Icon(family, iconName, Color.NONE);
|
||||
|
||||
return new ExtensionDescriptive(name, text, null, icon, 0);
|
||||
}
|
||||
}
|
@ -0,0 +1,284 @@
|
||||
/*
|
||||
* 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.extension.implementation.storage.queries;
|
||||
|
||||
import com.djrapitops.plan.db.SQLDB;
|
||||
import com.djrapitops.plan.db.access.Query;
|
||||
import com.djrapitops.plan.db.access.QueryStatement;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionIconTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionServerTableValueTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionTabTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable;
|
||||
import com.djrapitops.plan.extension.ElementOrder;
|
||||
import com.djrapitops.plan.extension.icon.Color;
|
||||
import com.djrapitops.plan.extension.icon.Family;
|
||||
import com.djrapitops.plan.extension.icon.Icon;
|
||||
import com.djrapitops.plan.extension.implementation.TabInformation;
|
||||
import com.djrapitops.plan.extension.implementation.results.ExtensionTabData;
|
||||
import com.djrapitops.plan.extension.implementation.results.ExtensionTableData;
|
||||
import com.djrapitops.plan.extension.implementation.results.server.ExtensionServerData;
|
||||
import com.djrapitops.plan.extension.table.Table;
|
||||
import com.djrapitops.plan.extension.table.TableAccessor;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.*;
|
||||
|
||||
/**
|
||||
* Query server tables from tableprovider table.
|
||||
* <p>
|
||||
* Returns Map: PluginID - ExtensionServerData.Factory.
|
||||
* <p>
|
||||
* How it is done:
|
||||
* - TableProviders are queried and formed into Table.Factory objects sorted into a multi-map: PluginID - TableID - Table.Factory
|
||||
* - Table values are queried and merged into the above multimap
|
||||
* - Data query is sorted into a multi-map: PluginID - Tab Name - Tab Data
|
||||
* - (Tab Name can be empty.)
|
||||
* - Multi-map is sorted into ExtensionServerData objects by PluginID, one per ID
|
||||
* <p>
|
||||
* There are multiple data extraction methods to make extracting the value query easier.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ExtensionServerTablesQuery implements Query<Map<Integer, ExtensionServerData.Factory>> {
|
||||
|
||||
private final UUID serverUUID;
|
||||
|
||||
public ExtensionServerTablesQuery(UUID serverUUID) {
|
||||
this.serverUUID = serverUUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, ExtensionServerData.Factory> executeQuery(SQLDB db) {
|
||||
Map<Integer, Map<Integer, Table.Factory>> tablesByPluginIDAndTableID = db.query(queryTableProviders());
|
||||
Map<Integer, Map<Integer, Table.Factory>> tablesWithValues = db.query(queryTableValues(tablesByPluginIDAndTableID));
|
||||
|
||||
Map<Integer, Map<String, ExtensionTabData.Factory>> tabDataByPluginID = mapToTabsByPluginID(tablesWithValues);
|
||||
return ExtensionServerDataQuery.flatMapToServerData(tabDataByPluginID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tablesByPluginIDAndTableID {@code <Plugin ID - <Table ID - Table.Factory>>}
|
||||
* @return {@code <Plugin ID - <Tab name - ExtensionTabData.Factory>}
|
||||
*/
|
||||
private Map<Integer, Map<String, ExtensionTabData.Factory>> mapToTabsByPluginID(Map<Integer, Map<Integer, Table.Factory>> tablesByPluginIDAndTableID) {
|
||||
Map<Integer, Map<String, ExtensionTabData.Factory>> byPluginID = new HashMap<>();
|
||||
|
||||
for (Map.Entry<Integer, Map<Integer, Table.Factory>> entry : tablesByPluginIDAndTableID.entrySet()) {
|
||||
Integer pluginID = entry.getKey();
|
||||
Map<String, ExtensionTabData.Factory> byTabName = byPluginID.getOrDefault(pluginID, new HashMap<>());
|
||||
for (Table.Factory table : entry.getValue().values()) {
|
||||
// Extra Table information
|
||||
String tableName = TableAccessor.getTableName(table);
|
||||
Color tableColor = TableAccessor.getColor(table);
|
||||
|
||||
// Extra tab information
|
||||
String tabName = TableAccessor.getTabName(table);
|
||||
int tabPriority = TableAccessor.getTabPriority(table);
|
||||
ElementOrder[] tabOrder = TableAccessor.getTabOrder(table);
|
||||
Icon tabIcon = TableAccessor.getTabIcon(table);
|
||||
|
||||
ExtensionTabData.Factory tab = byTabName.getOrDefault(tabName, new ExtensionTabData.Factory(new TabInformation(tabName, tabIcon, tabOrder, tabPriority)));
|
||||
tab.putTableData(new ExtensionTableData(
|
||||
tableName, table.build(), tableColor
|
||||
));
|
||||
byTabName.put(tabName, tab);
|
||||
}
|
||||
byPluginID.put(pluginID, byTabName);
|
||||
}
|
||||
|
||||
return byPluginID;
|
||||
}
|
||||
|
||||
// Map: <Plugin ID - <Table ID - Table.Factory>>
|
||||
private Query<Map<Integer, Map<Integer, Table.Factory>>> queryTableValues(Map<Integer, Map<Integer, Table.Factory>> tables) {
|
||||
String selectTableValues = SELECT +
|
||||
ExtensionTableProviderTable.PLUGIN_ID + ',' +
|
||||
ExtensionServerTableValueTable.TABLE_ID + ',' +
|
||||
ExtensionServerTableValueTable.VALUE_1 + ',' +
|
||||
ExtensionServerTableValueTable.VALUE_2 + ',' +
|
||||
ExtensionServerTableValueTable.VALUE_3 + ',' +
|
||||
ExtensionServerTableValueTable.VALUE_4 + ',' +
|
||||
ExtensionServerTableValueTable.VALUE_5 +
|
||||
FROM + ExtensionServerTableValueTable.TABLE_NAME +
|
||||
INNER_JOIN + ExtensionTableProviderTable.TABLE_NAME + " on " + ExtensionTableProviderTable.TABLE_NAME + '.' + ExtensionTableProviderTable.ID + '=' + ExtensionServerTableValueTable.TABLE_NAME + '.' + ExtensionServerTableValueTable.TABLE_ID +
|
||||
WHERE + ExtensionServerTableValueTable.SERVER_UUID + "=?";
|
||||
|
||||
return new QueryStatement<Map<Integer, Map<Integer, Table.Factory>>>(selectTableValues, 10000) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, serverUUID.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, Map<Integer, Table.Factory>> processResults(ResultSet set) throws SQLException {
|
||||
while (set.next()) {
|
||||
Table.Factory table = getTable(set);
|
||||
if (table == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Object[] row = extractTableRow(set);
|
||||
if (row.length > 0) {
|
||||
table.addRow(row);
|
||||
}
|
||||
}
|
||||
return tables;
|
||||
}
|
||||
|
||||
private Table.Factory getTable(ResultSet set) throws SQLException {
|
||||
int pluginID = set.getInt(ExtensionTableProviderTable.PLUGIN_ID);
|
||||
Map<Integer, Table.Factory> byTableID = tables.get(pluginID);
|
||||
if (byTableID == null) {
|
||||
return null;
|
||||
}
|
||||
int tableID = set.getInt(ExtensionServerTableValueTable.TABLE_ID);
|
||||
return byTableID.get(tableID);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Object[] extractTableRow(ResultSet set) throws SQLException {
|
||||
List<Object> row = new ArrayList<>();
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
String columnName = "col_" + i + "_value"; // See ExtensionServerTableValueTable.VALUE_1
|
||||
String value = set.getString(columnName);
|
||||
if (value == null) {
|
||||
return row.toArray(new Object[0]);
|
||||
}
|
||||
row.add(value);
|
||||
}
|
||||
return row.toArray(new Object[0]);
|
||||
}
|
||||
|
||||
// Map: <Plugin ID - <Table ID - Table.Factory>>
|
||||
private Query<Map<Integer, Map<Integer, Table.Factory>>> queryTableProviders() {
|
||||
String selectTables = SELECT +
|
||||
"p1." + ExtensionTableProviderTable.ID + " as table_id," +
|
||||
"p1." + ExtensionTableProviderTable.PLUGIN_ID + " as plugin_id," +
|
||||
"p1." + ExtensionTableProviderTable.PROVIDER_NAME + " as table_name," +
|
||||
"p1." + ExtensionTableProviderTable.COLOR + " as table_color," +
|
||||
ExtensionTableProviderTable.COL_1 + ',' +
|
||||
ExtensionTableProviderTable.COL_2 + ',' +
|
||||
ExtensionTableProviderTable.COL_3 + ',' +
|
||||
ExtensionTableProviderTable.COL_4 + ',' +
|
||||
ExtensionTableProviderTable.COL_5 + ',' +
|
||||
"t1." + ExtensionTabTable.TAB_NAME + " as tab_name," +
|
||||
"t1." + ExtensionTabTable.TAB_PRIORITY + " as tab_priority," +
|
||||
"t1." + ExtensionTabTable.ELEMENT_ORDER + " as element_order," +
|
||||
"i1." + ExtensionIconTable.ICON_NAME + " as i1_name," +
|
||||
"i1." + ExtensionIconTable.FAMILY + " as i1_family," +
|
||||
"i1." + ExtensionIconTable.COLOR + " as i1_color," +
|
||||
"i2." + ExtensionIconTable.ICON_NAME + " as i2_name," +
|
||||
"i2." + ExtensionIconTable.FAMILY + " as i2_family," +
|
||||
"i2." + ExtensionIconTable.COLOR + " as i2_color," +
|
||||
"i3." + ExtensionIconTable.ICON_NAME + " as i3_name," +
|
||||
"i3." + ExtensionIconTable.FAMILY + " as i3_family," +
|
||||
"i3." + ExtensionIconTable.COLOR + " as i3_color," +
|
||||
"i4." + ExtensionIconTable.ICON_NAME + " as i4_name," +
|
||||
"i4." + ExtensionIconTable.FAMILY + " as i4_family," +
|
||||
"i4." + ExtensionIconTable.COLOR + " as i4_color," +
|
||||
"i5." + ExtensionIconTable.ICON_NAME + " as i5_name," +
|
||||
"i5." + ExtensionIconTable.FAMILY + " as i5_family," +
|
||||
"i5." + ExtensionIconTable.COLOR + " as i5_color," +
|
||||
"i6." + ExtensionIconTable.ICON_NAME + " as tab_icon_name," +
|
||||
"i6." + ExtensionIconTable.FAMILY + " as tab_icon_family," +
|
||||
"i6." + ExtensionIconTable.COLOR + " as tab_icon_color" +
|
||||
FROM + ExtensionTableProviderTable.TABLE_NAME + " p1" +
|
||||
INNER_JOIN + ExtensionServerTableValueTable.TABLE_NAME + " v1 on v1." + ExtensionServerTableValueTable.TABLE_ID + "=p1." + ExtensionTableProviderTable.ID +
|
||||
LEFT_JOIN + ExtensionTabTable.TABLE_NAME + " t1 on t1." + ExtensionTabTable.ID + "=p1." + ExtensionTableProviderTable.TAB_ID +
|
||||
LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_1_ID +
|
||||
LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i2 on i2." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_2_ID +
|
||||
LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i3 on i3." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_3_ID +
|
||||
LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i4 on i4." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_4_ID +
|
||||
LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i5 on i5." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_5_ID +
|
||||
LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i6 on i6." + ExtensionIconTable.ID + "=t1." + ExtensionTabTable.ICON_ID +
|
||||
WHERE + "v1." + ExtensionServerTableValueTable.SERVER_UUID + "=?";
|
||||
|
||||
return new QueryStatement<Map<Integer, Map<Integer, Table.Factory>>>(selectTables, 100) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, serverUUID.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, Map<Integer, Table.Factory>> processResults(ResultSet set) throws SQLException {
|
||||
Map<Integer, Map<Integer, Table.Factory>> byPluginID = new HashMap<>();
|
||||
|
||||
while (set.next()) {
|
||||
int pluginID = set.getInt("plugin_id");
|
||||
Map<Integer, Table.Factory> byTableID = byPluginID.getOrDefault(pluginID, new HashMap<>());
|
||||
|
||||
int tableID = set.getInt("table_id");
|
||||
Table.Factory table = Table.builder();
|
||||
|
||||
extractColumns(set, table);
|
||||
|
||||
TableAccessor.setColor(table, Color.getByName(set.getString("table_color")).orElse(Color.NONE));
|
||||
TableAccessor.setTableName(table, set.getString("table_name"));
|
||||
TableAccessor.setTabName(table, Optional.ofNullable(set.getString("tab_name")).orElse(""));
|
||||
TableAccessor.setTabPriority(table, Optional.of(set.getInt("tab_priority")).orElse(100));
|
||||
TableAccessor.setTabOrder(table, Optional.ofNullable(set.getString(ExtensionTabTable.ELEMENT_ORDER)).map(ElementOrder::deserialize).orElse(ElementOrder.values()));
|
||||
TableAccessor.setTabIcon(table, extractIcon(set, "tab_icon"));
|
||||
|
||||
byTableID.put(tableID, table);
|
||||
byPluginID.put(pluginID, byTableID);
|
||||
}
|
||||
|
||||
return byPluginID;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void extractColumns(ResultSet set, Table.Factory table) throws SQLException {
|
||||
String col1 = set.getString(ExtensionTableProviderTable.COL_1);
|
||||
if (col1 != null) {
|
||||
table.columnOne(col1, extractIcon(set, "i1"));
|
||||
}
|
||||
String col2 = set.getString(ExtensionTableProviderTable.COL_2);
|
||||
if (col2 != null) {
|
||||
table.columnTwo(col2, extractIcon(set, "i2"));
|
||||
}
|
||||
String col3 = set.getString(ExtensionTableProviderTable.COL_3);
|
||||
if (col3 != null) {
|
||||
table.columnThree(col3, extractIcon(set, "i3"));
|
||||
}
|
||||
String col4 = set.getString(ExtensionTableProviderTable.COL_4);
|
||||
if (col4 != null) {
|
||||
table.columnFour(col4, extractIcon(set, "i4"));
|
||||
}
|
||||
String col5 = set.getString(ExtensionTableProviderTable.COL_5);
|
||||
if (col5 != null) {
|
||||
table.columnFive(col5, extractIcon(set, "i5"));
|
||||
}
|
||||
}
|
||||
|
||||
private Icon extractIcon(ResultSet set, String iconColumnName) throws SQLException {
|
||||
String iconName = set.getString(iconColumnName + "_name");
|
||||
if (iconName == null) {
|
||||
return null;
|
||||
}
|
||||
return new Icon(
|
||||
Family.getByName(set.getString(iconColumnName + "_family")).orElse(Family.SOLID),
|
||||
iconName,
|
||||
Color.getByName(set.getString(iconColumnName + "_color")).orElse(Color.NONE)
|
||||
);
|
||||
}
|
||||
}
|
@ -68,14 +68,14 @@ public class StoreTabInformationTransaction extends Transaction {
|
||||
" SET " +
|
||||
ExtensionTabTable.TAB_PRIORITY + "=?," +
|
||||
ExtensionTabTable.ELEMENT_ORDER + "=?," +
|
||||
ExtensionTabTable.ICON_ID + "=" + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + "," +
|
||||
ExtensionTabTable.ICON_ID + "=" + ExtensionIconTable.STATEMENT_SELECT_ICON_ID +
|
||||
WHERE + ExtensionTabTable.PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID +
|
||||
AND + ExtensionTabTable.TAB_NAME + "=?";
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setInt(1, tabInformation.getTabPriority());
|
||||
statement.setString(2, tabInformation.getTabElementOrder().map(ElementOrder::serialize).orElse(null));
|
||||
statement.setString(2, ElementOrder.serialize(tabInformation.getTabElementOrder().orElse(ElementOrder.values())));
|
||||
ExtensionIconTable.set3IconValuesToStatement(statement, 3, tabInformation.getTabIcon());
|
||||
ExtensionPluginTable.set2PluginValuesToStatement(statement, 6, pluginName, serverUUID);
|
||||
statement.setString(8, tabInformation.getTabName());
|
||||
@ -88,14 +88,14 @@ public class StoreTabInformationTransaction extends Transaction {
|
||||
ExtensionTabTable.TAB_NAME + "," +
|
||||
ExtensionTabTable.ELEMENT_ORDER + "," +
|
||||
ExtensionTabTable.TAB_PRIORITY + "," +
|
||||
ExtensionTabTable.ICON_ID +
|
||||
ExtensionTabTable.ICON_ID + "," +
|
||||
ExtensionTabTable.PLUGIN_ID +
|
||||
") VALUES (?,?,?," + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + "," + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ")";
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, tabInformation.getTabName());
|
||||
statement.setString(2, tabInformation.getTabElementOrder().map(ElementOrder::serialize).orElse(null));
|
||||
statement.setString(2, ElementOrder.serialize(tabInformation.getTabElementOrder().orElse(ElementOrder.values())));
|
||||
statement.setInt(3, tabInformation.getTabPriority());
|
||||
ExtensionIconTable.set3IconValuesToStatement(statement, 4, tabInformation.getTabIcon());
|
||||
ExtensionPluginTable.set2PluginValuesToStatement(statement, 7, pluginName, serverUUID);
|
||||
|
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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.extension.implementation.storage.transactions.providers;
|
||||
|
||||
import com.djrapitops.plan.db.access.ExecStatement;
|
||||
import com.djrapitops.plan.db.access.Executable;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionIconTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionTabTable;
|
||||
import com.djrapitops.plan.extension.icon.Color;
|
||||
import com.djrapitops.plan.extension.icon.Icon;
|
||||
import com.djrapitops.plan.extension.implementation.ProviderInformation;
|
||||
import com.djrapitops.plan.extension.table.Table;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.AND;
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE;
|
||||
import static com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable.*;
|
||||
|
||||
/**
|
||||
* Transaction to store information about a {@link com.djrapitops.plan.extension.implementation.providers.TableDataProvider}.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class StoreTableProviderTransaction extends Transaction {
|
||||
|
||||
private final UUID serverUUID;
|
||||
private final ProviderInformation providerInformation;
|
||||
private final Color tableColor;
|
||||
private final Table table;
|
||||
|
||||
public StoreTableProviderTransaction(UUID serverUUID, ProviderInformation providerInformation, Color tableColor, Table table) {
|
||||
this.providerInformation = providerInformation;
|
||||
this.tableColor = tableColor;
|
||||
this.table = table;
|
||||
this.serverUUID = serverUUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performOperations() {
|
||||
execute(storeProvider());
|
||||
}
|
||||
|
||||
private Executable storeProvider() {
|
||||
return connection -> {
|
||||
if (!updateProvider().execute(connection)) {
|
||||
return insertProvider().execute(connection);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
private Executable updateProvider() {
|
||||
String[] columns = table.getColumns();
|
||||
Icon[] icons = table.getIcons();
|
||||
|
||||
String sql = "UPDATE " + TABLE_NAME + " SET " +
|
||||
COLOR + "=?," +
|
||||
COL_1 + "=?," +
|
||||
COL_2 + "=?," +
|
||||
COL_3 + "=?," +
|
||||
COL_4 + "=?," +
|
||||
COL_5 + "=?," +
|
||||
CONDITION + "=?," +
|
||||
TAB_ID + '=' + ExtensionTabTable.STATEMENT_SELECT_TAB_ID + ',' +
|
||||
ICON_1_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
|
||||
ICON_2_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
|
||||
ICON_3_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
|
||||
ICON_4_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
|
||||
ICON_5_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID +
|
||||
WHERE + PROVIDER_NAME + "=?" +
|
||||
AND + PLUGIN_ID + '=' + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID;
|
||||
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, tableColor.name());
|
||||
setStringOrNull(statement, 2, columns[0]);
|
||||
setStringOrNull(statement, 3, columns[1]);
|
||||
setStringOrNull(statement, 4, columns[2]);
|
||||
setStringOrNull(statement, 5, columns[3]);
|
||||
setStringOrNull(statement, 6, columns[4]);
|
||||
setStringOrNull(statement, 7, providerInformation.getCondition().orElse(null));
|
||||
ExtensionTabTable.set3TabValuesToStatement(statement, 8, providerInformation.getTab().orElse("No Tab"), providerInformation.getPluginName(), serverUUID);
|
||||
ExtensionIconTable.set3IconValuesToStatement(statement, 11, icons[0]);
|
||||
ExtensionIconTable.set3IconValuesToStatement(statement, 14, icons[1]);
|
||||
ExtensionIconTable.set3IconValuesToStatement(statement, 17, icons[2]);
|
||||
ExtensionIconTable.set3IconValuesToStatement(statement, 20, icons[3]);
|
||||
ExtensionIconTable.set3IconValuesToStatement(statement, 23, icons[4]);
|
||||
statement.setString(26, providerInformation.getName());
|
||||
ExtensionPluginTable.set2PluginValuesToStatement(statement, 27, providerInformation.getPluginName(), serverUUID);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Executable insertProvider() {
|
||||
String[] columns = table.getColumns();
|
||||
Icon[] icons = table.getIcons();
|
||||
|
||||
String sql = "INSERT INTO " + TABLE_NAME + '(' +
|
||||
PROVIDER_NAME + ',' +
|
||||
COLOR + ',' +
|
||||
COL_1 + ',' +
|
||||
COL_2 + ',' +
|
||||
COL_3 + ',' +
|
||||
COL_4 + ',' +
|
||||
COL_5 + ',' +
|
||||
CONDITION + ',' +
|
||||
TAB_ID + ',' +
|
||||
PLUGIN_ID + ',' +
|
||||
ICON_1_ID + ',' +
|
||||
ICON_2_ID + ',' +
|
||||
ICON_3_ID + ',' +
|
||||
ICON_4_ID + ',' +
|
||||
ICON_5_ID +
|
||||
") VALUES (?,?,?,?,?,?,?,?," +
|
||||
ExtensionTabTable.STATEMENT_SELECT_TAB_ID + ',' +
|
||||
ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ',' +
|
||||
ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
|
||||
ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
|
||||
ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
|
||||
ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
|
||||
ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ')';
|
||||
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, providerInformation.getName());
|
||||
statement.setString(2, tableColor.name());
|
||||
setStringOrNull(statement, 3, columns[0]);
|
||||
setStringOrNull(statement, 4, columns[1]);
|
||||
setStringOrNull(statement, 5, columns[2]);
|
||||
setStringOrNull(statement, 6, columns[3]);
|
||||
setStringOrNull(statement, 7, columns[4]);
|
||||
setStringOrNull(statement, 8, providerInformation.getCondition().orElse(null));
|
||||
ExtensionTabTable.set3TabValuesToStatement(statement, 9, providerInformation.getTab().orElse("No Tab"), providerInformation.getPluginName(), serverUUID);
|
||||
ExtensionPluginTable.set2PluginValuesToStatement(statement, 12, providerInformation.getPluginName(), serverUUID);
|
||||
ExtensionIconTable.set3IconValuesToStatement(statement, 14, icons[0]);
|
||||
ExtensionIconTable.set3IconValuesToStatement(statement, 17, icons[1]);
|
||||
ExtensionIconTable.set3IconValuesToStatement(statement, 20, icons[2]);
|
||||
ExtensionIconTable.set3IconValuesToStatement(statement, 23, icons[3]);
|
||||
ExtensionIconTable.set3IconValuesToStatement(statement, 26, icons[4]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void setStringOrNull(PreparedStatement statement, int index, String value) throws SQLException {
|
||||
if (value != null) {
|
||||
statement.setString(index, value);
|
||||
} else {
|
||||
statement.setNull(index, Types.VARCHAR);
|
||||
}
|
||||
}
|
||||
}
|
@ -19,9 +19,7 @@ package com.djrapitops.plan.extension.implementation.storage.transactions.result
|
||||
import com.djrapitops.plan.db.access.ExecStatement;
|
||||
import com.djrapitops.plan.db.access.Executable;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionPlayerValueTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable;
|
||||
import com.djrapitops.plan.db.sql.tables.*;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
@ -51,12 +49,17 @@ public class RemoveInvalidResultsTransaction extends Transaction {
|
||||
@Override
|
||||
protected void performOperations() {
|
||||
for (String invalidatedMethod : invalidatedMethods) {
|
||||
execute(deleteInvalidMethodResults(invalidatedMethod));
|
||||
execute(deleteInvalidPlayerMethodResults(invalidatedMethod));
|
||||
execute(deleteInvalidServerMethodResults(invalidatedMethod));
|
||||
execute(deleteInvalidMethodProvider(invalidatedMethod));
|
||||
|
||||
execute(deleteInvalidPlayerTableResults(invalidatedMethod));
|
||||
execute(deleteInvalidServerTableResults(invalidatedMethod));
|
||||
execute(deleteInvalidTableProvider(invalidatedMethod));
|
||||
}
|
||||
}
|
||||
|
||||
private Executable deleteInvalidMethodResults(String invalidMethod) {
|
||||
private Executable deleteInvalidPlayerMethodResults(String invalidMethod) {
|
||||
String sql = "DELETE FROM " + ExtensionPlayerValueTable.TABLE_NAME +
|
||||
WHERE + ExtensionPlayerValueTable.PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID;
|
||||
return new ExecStatement(sql) {
|
||||
@ -67,10 +70,56 @@ public class RemoveInvalidResultsTransaction extends Transaction {
|
||||
};
|
||||
}
|
||||
|
||||
private Executable deleteInvalidServerMethodResults(String invalidMethod) {
|
||||
String sql = "DELETE FROM " + ExtensionServerValueTable.TABLE_NAME +
|
||||
WHERE + ExtensionServerValueTable.PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID;
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
ExtensionProviderTable.set3PluginValuesToStatement(statement, 1, invalidMethod, pluginName, serverUUID);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Executable deleteInvalidPlayerTableResults(String invalidMethod) {
|
||||
String sql = "DELETE FROM " + ExtensionPlayerTableValueTable.TABLE_NAME +
|
||||
WHERE + ExtensionPlayerTableValueTable.TABLE_ID + "=" + ExtensionTableProviderTable.STATEMENT_SELECT_TABLE_ID;
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
ExtensionTableProviderTable.set3PluginValuesToStatement(statement, 1, invalidMethod, pluginName, serverUUID);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Executable deleteInvalidServerTableResults(String invalidMethod) {
|
||||
String sql = "DELETE FROM " + ExtensionServerTableValueTable.TABLE_NAME +
|
||||
WHERE + ExtensionServerTableValueTable.TABLE_ID + "=" + ExtensionTableProviderTable.STATEMENT_SELECT_TABLE_ID;
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
ExtensionTableProviderTable.set3PluginValuesToStatement(statement, 1, invalidMethod, pluginName, serverUUID);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Executable deleteInvalidMethodProvider(String invalidMethod) {
|
||||
String sql = "DELETE FROM " + ExtensionProviderTable.TABLE_NAME +
|
||||
WHERE + ExtensionProviderTable.PROVIDER_NAME + "=?" +
|
||||
AND + ExtensionProviderTable.PLUGIN_ID + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID;
|
||||
AND + ExtensionProviderTable.PLUGIN_ID + '=' + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID;
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, invalidMethod);
|
||||
ExtensionPluginTable.set2PluginValuesToStatement(statement, 2, pluginName, serverUUID);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Executable deleteInvalidTableProvider(String invalidMethod) {
|
||||
String sql = "DELETE FROM " + ExtensionTableProviderTable.TABLE_NAME +
|
||||
WHERE + ExtensionTableProviderTable.TABLE_NAME + "=?" +
|
||||
AND + ExtensionTableProviderTable.PLUGIN_ID + '=' + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID;
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
|
@ -20,8 +20,10 @@ import com.djrapitops.plan.db.DBType;
|
||||
import com.djrapitops.plan.db.access.ExecStatement;
|
||||
import com.djrapitops.plan.db.access.Executable;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionPlayerTableValueTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionPlayerValueTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
@ -39,37 +41,53 @@ import static com.djrapitops.plan.db.sql.parsing.Sql.*;
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class RemoveUnsatisfiedConditionalResultsTransaction extends Transaction {
|
||||
public class RemoveUnsatisfiedConditionalPlayerResultsTransaction extends Transaction {
|
||||
|
||||
private final String providerTable;
|
||||
private final String playerValueTable;
|
||||
private final String playerTableValueTable;
|
||||
private final String tableTable;
|
||||
|
||||
public RemoveUnsatisfiedConditionalPlayerResultsTransaction() {
|
||||
providerTable = ExtensionProviderTable.TABLE_NAME;
|
||||
playerValueTable = ExtensionPlayerValueTable.TABLE_NAME;
|
||||
tableTable = ExtensionTableProviderTable.TABLE_NAME;
|
||||
playerTableValueTable = ExtensionPlayerTableValueTable.TABLE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performOperations() {
|
||||
execute(deleteUnsatisfied());
|
||||
String selectSatisfiedConditions = getSatisfiedConditionsSQL();
|
||||
|
||||
execute(deleteUnsatisfiedValues(selectSatisfiedConditions));
|
||||
execute(deleteUnsatisfiedTableValues(selectSatisfiedConditions));
|
||||
}
|
||||
|
||||
private Executable deleteUnsatisfied() {
|
||||
private String getSatisfiedConditionsSQL() {
|
||||
String reversedCondition = dbType == DBType.SQLITE ? "'not_' || " + ExtensionProviderTable.PROVIDED_CONDITION : "CONCAT('not_'," + ExtensionProviderTable.PROVIDED_CONDITION + ')';
|
||||
|
||||
String providerTable = ExtensionProviderTable.TABLE_NAME;
|
||||
String playerValueTable = ExtensionPlayerValueTable.TABLE_NAME;
|
||||
|
||||
String selectSatisfiedPositiveConditions = SELECT +
|
||||
ExtensionProviderTable.PROVIDED_CONDITION + ',' +
|
||||
ExtensionPlayerValueTable.USER_UUID +
|
||||
ExtensionProviderTable.PLUGIN_ID + ',' +
|
||||
ExtensionPlayerTableValueTable.USER_UUID +
|
||||
FROM + providerTable +
|
||||
INNER_JOIN + playerValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionPlayerValueTable.PROVIDER_ID +
|
||||
WHERE + ExtensionPlayerValueTable.BOOLEAN_VALUE + "=?" +
|
||||
AND + ExtensionProviderTable.PROVIDED_CONDITION + IS_NOT_NULL;
|
||||
String selectSatisfiedNegativeConditions = SELECT +
|
||||
reversedCondition + " as " + ExtensionProviderTable.PROVIDED_CONDITION + ',' +
|
||||
ExtensionPlayerValueTable.USER_UUID +
|
||||
ExtensionProviderTable.PLUGIN_ID + ',' +
|
||||
ExtensionPlayerTableValueTable.USER_UUID +
|
||||
FROM + providerTable +
|
||||
INNER_JOIN + playerValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionPlayerValueTable.PROVIDER_ID +
|
||||
WHERE + ExtensionPlayerValueTable.BOOLEAN_VALUE + "=?" +
|
||||
AND + ExtensionProviderTable.PROVIDED_CONDITION + IS_NOT_NULL;
|
||||
|
||||
// Query contents: Set of provided_conditions
|
||||
String selectSatisfiedConditions = '(' + selectSatisfiedPositiveConditions + " UNION " + selectSatisfiedNegativeConditions + ") q1";
|
||||
return '(' + selectSatisfiedPositiveConditions + " UNION " + selectSatisfiedNegativeConditions + ") q1";
|
||||
}
|
||||
|
||||
private Executable deleteUnsatisfiedValues(String selectSatisfiedConditions) {
|
||||
// Query contents:
|
||||
// id | uuid | q1.uuid | condition | q1.provided_condition
|
||||
// -- | ---- | ------- | --------- | ---------------------
|
||||
@ -87,6 +105,8 @@ public class RemoveUnsatisfiedConditionalResultsTransaction extends Transaction
|
||||
"=q1." + ExtensionPlayerValueTable.USER_UUID +
|
||||
AND + ExtensionProviderTable.CONDITION +
|
||||
"=q1." + ExtensionProviderTable.PROVIDED_CONDITION +
|
||||
AND + providerTable + '.' + ExtensionProviderTable.PLUGIN_ID +
|
||||
"=q1." + ExtensionProviderTable.PLUGIN_ID +
|
||||
')' +
|
||||
WHERE + "q1." + ExtensionProviderTable.PROVIDED_CONDITION + IS_NULL + // Conditions that were not in the satisfied condition query
|
||||
AND + ExtensionProviderTable.CONDITION + IS_NOT_NULL; // Ignore values that don't need condition
|
||||
@ -105,4 +125,32 @@ public class RemoveUnsatisfiedConditionalResultsTransaction extends Transaction
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Executable deleteUnsatisfiedTableValues(String selectSatisfiedConditions) {
|
||||
String selectUnsatisfiedValueIDs = SELECT + ExtensionTableProviderTable.ID +
|
||||
FROM + tableTable +
|
||||
LEFT_JOIN + selectSatisfiedConditions + // Left join to preserve values that don't have their condition fulfilled
|
||||
" on (" +
|
||||
tableTable + '.' + ExtensionTableProviderTable.CONDITION +
|
||||
"=q1." + ExtensionProviderTable.PROVIDED_CONDITION +
|
||||
AND + tableTable + '.' + ExtensionTableProviderTable.PLUGIN_ID +
|
||||
"=q1." + ExtensionProviderTable.PLUGIN_ID +
|
||||
')' +
|
||||
WHERE + "q1." + ExtensionProviderTable.PROVIDED_CONDITION + IS_NULL + // Conditions that were not in the satisfied condition query
|
||||
AND + ExtensionProviderTable.CONDITION + IS_NOT_NULL; // Ignore values that don't need condition
|
||||
|
||||
// Nested query here is required because MySQL limits update statements with nested queries:
|
||||
// The nested query creates a temporary table that bypasses the same table query-update limit.
|
||||
// Note: MySQL versions 5.6.7+ might optimize this nested query away leading to an exception.
|
||||
String deleteValuesSQL = "DELETE FROM " + playerTableValueTable +
|
||||
WHERE + ExtensionPlayerTableValueTable.TABLE_ID + " IN (" + SELECT + ExtensionTableProviderTable.ID + FROM + '(' + selectUnsatisfiedValueIDs + ") as ids)";
|
||||
|
||||
return new ExecStatement(deleteValuesSQL) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setBoolean(1, true); // Select provided conditions with 'true' value
|
||||
statement.setBoolean(2, false); // Select negated conditions with 'false' value
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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.extension.implementation.storage.transactions.results;
|
||||
|
||||
import com.djrapitops.plan.db.DBType;
|
||||
import com.djrapitops.plan.db.access.ExecStatement;
|
||||
import com.djrapitops.plan.db.access.Executable;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionServerTableValueTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionServerValueTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.*;
|
||||
|
||||
/**
|
||||
* Transaction to remove older results that violate an updated condition value.
|
||||
* <p>
|
||||
* How it works:
|
||||
* - Select all fulfilled conditions for all servers (conditionName when true and not_conditionName when false)
|
||||
* - Left join with server value & provider tables when plugin_ids match, and when condition matches a condition in the
|
||||
* query above. (plugin_ids can be linked to servers)
|
||||
* - Filter the join query for values where the condition did not match any provided condition in the join (Is null)
|
||||
* - Delete all server values with IDs that are returned by the left join query after filtering
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class RemoveUnsatisfiedConditionalServerResultsTransaction extends Transaction {
|
||||
|
||||
private final String providerTable;
|
||||
private final String serverValueTable;
|
||||
private final String serverTableValueTable;
|
||||
private final String tableTable;
|
||||
|
||||
public RemoveUnsatisfiedConditionalServerResultsTransaction() {
|
||||
providerTable = ExtensionProviderTable.TABLE_NAME;
|
||||
serverValueTable = ExtensionServerValueTable.TABLE_NAME;
|
||||
tableTable = ExtensionTableProviderTable.TABLE_NAME;
|
||||
serverTableValueTable = ExtensionServerTableValueTable.TABLE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performOperations() {
|
||||
String selectSatisfiedConditions = getSatisfiedConditionsSQL();
|
||||
execute(deleteUnsatisfiedValues(selectSatisfiedConditions));
|
||||
execute(deleteUnsatisfiedTableValues(selectSatisfiedConditions));
|
||||
}
|
||||
|
||||
private Executable deleteUnsatisfiedValues(String selectSatisfiedConditions) {
|
||||
// Query contents:
|
||||
// id | provider_id | q1.provider_id | condition | q1.provided_condition
|
||||
// -- | ----------- | -------------- | --------- | ---------------------
|
||||
// 1 | ... | ... | A | A Satisfied condition
|
||||
// 2 | ... | ... | not_B | not_B Satisfied condition
|
||||
// 3 | ... | ... | NULL | NULL Satisfied condition
|
||||
// 4 | ... | ... | B | NULL Unsatisfied condition, filtered to these in WHERE clause.
|
||||
// 5 | ... | ... | not_C | NULL Unsatisfied condition
|
||||
String selectUnsatisfiedValueIDs = SELECT + serverValueTable + '.' + ExtensionServerValueTable.ID +
|
||||
FROM + providerTable +
|
||||
INNER_JOIN + serverValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionServerValueTable.PROVIDER_ID +
|
||||
LEFT_JOIN + selectSatisfiedConditions + // Left join to preserve values that don't have their condition fulfilled
|
||||
" on (" +
|
||||
ExtensionProviderTable.CONDITION + "=q1." + ExtensionProviderTable.PROVIDED_CONDITION +
|
||||
AND + providerTable + '.' + ExtensionProviderTable.PLUGIN_ID + "=q1." + ExtensionProviderTable.PLUGIN_ID +
|
||||
')' +
|
||||
WHERE + "q1." + ExtensionProviderTable.PROVIDED_CONDITION + IS_NULL + // Conditions that were not in the satisfied condition query
|
||||
AND + ExtensionProviderTable.CONDITION + IS_NOT_NULL; // Ignore values that don't need condition
|
||||
|
||||
// Nested query here is required because MySQL limits update statements with nested queries:
|
||||
// The nested query creates a temporary table that bypasses the same table query-update limit.
|
||||
// Note: MySQL versions 5.6.7+ might optimize this nested query away leading to an exception.
|
||||
String sql = "DELETE FROM " + serverValueTable +
|
||||
WHERE + ExtensionServerValueTable.ID + " IN (" + SELECT + ExtensionServerValueTable.ID + FROM + '(' + selectUnsatisfiedValueIDs + ") as ids)";
|
||||
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setBoolean(1, true); // Select provided conditions with 'true' value
|
||||
statement.setBoolean(2, false); // Select negated conditions with 'false' value
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private String getSatisfiedConditionsSQL() {
|
||||
String reversedCondition = dbType == DBType.SQLITE ? "'not_' || " + ExtensionProviderTable.PROVIDED_CONDITION : "CONCAT('not_'," + ExtensionProviderTable.PROVIDED_CONDITION + ')';
|
||||
|
||||
String selectSatisfiedPositiveConditions = SELECT +
|
||||
ExtensionProviderTable.PROVIDED_CONDITION + ',' +
|
||||
ExtensionProviderTable.PLUGIN_ID +
|
||||
FROM + providerTable +
|
||||
INNER_JOIN + serverValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionServerValueTable.PROVIDER_ID +
|
||||
WHERE + ExtensionServerValueTable.BOOLEAN_VALUE + "=?" +
|
||||
AND + ExtensionProviderTable.PROVIDED_CONDITION + IS_NOT_NULL;
|
||||
String selectSatisfiedNegativeConditions = SELECT +
|
||||
reversedCondition + " as " + ExtensionProviderTable.PROVIDED_CONDITION + ',' +
|
||||
ExtensionProviderTable.PLUGIN_ID +
|
||||
FROM + providerTable +
|
||||
INNER_JOIN + serverValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionServerValueTable.PROVIDER_ID +
|
||||
WHERE + ExtensionServerValueTable.BOOLEAN_VALUE + "=?" +
|
||||
AND + ExtensionProviderTable.PROVIDED_CONDITION + IS_NOT_NULL;
|
||||
|
||||
// Query contents: Set of provided_conditions
|
||||
return '(' + selectSatisfiedPositiveConditions + " UNION " + selectSatisfiedNegativeConditions + ") q1";
|
||||
}
|
||||
|
||||
private Executable deleteUnsatisfiedTableValues(String selectSatisfiedConditions) {
|
||||
String selectUnsatisfiedValueIDs = SELECT + ExtensionTableProviderTable.ID +
|
||||
FROM + tableTable +
|
||||
LEFT_JOIN + selectSatisfiedConditions + // Left join to preserve values that don't have their condition fulfilled
|
||||
" on (" +
|
||||
tableTable + '.' + ExtensionTableProviderTable.CONDITION +
|
||||
"=q1." + ExtensionProviderTable.PROVIDED_CONDITION +
|
||||
AND + tableTable + '.' + ExtensionTableProviderTable.PLUGIN_ID +
|
||||
"=q1." + ExtensionProviderTable.PLUGIN_ID +
|
||||
')' +
|
||||
WHERE + "q1." + ExtensionProviderTable.PROVIDED_CONDITION + IS_NULL + // Conditions that were not in the satisfied condition query
|
||||
AND + ExtensionProviderTable.CONDITION + IS_NOT_NULL; // Ignore values that don't need condition
|
||||
|
||||
// Nested query here is required because MySQL limits update statements with nested queries:
|
||||
// The nested query creates a temporary table that bypasses the same table query-update limit.
|
||||
// Note: MySQL versions 5.6.7+ might optimize this nested query away leading to an exception.
|
||||
String deleteValuesSQL = "DELETE FROM " + serverTableValueTable +
|
||||
WHERE + ExtensionServerTableValueTable.TABLE_ID + " IN (" + SELECT + ExtensionTableProviderTable.ID + FROM + '(' + selectUnsatisfiedValueIDs + ") as ids)";
|
||||
|
||||
return new ExecStatement(deleteValuesSQL) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setBoolean(1, true); // Select provided conditions with 'true' value
|
||||
statement.setBoolean(2, false); // Select negated conditions with 'false' value
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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.extension.implementation.storage.transactions.results;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.db.access.*;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable;
|
||||
import com.djrapitops.plan.extension.table.Table;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.*;
|
||||
import static com.djrapitops.plan.db.sql.tables.ExtensionPlayerTableValueTable.*;
|
||||
|
||||
/**
|
||||
* Transaction to store method result of a {@link com.djrapitops.plan.extension.implementation.providers.TableDataProvider}.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class StorePlayerTableResultTransaction extends Transaction {
|
||||
|
||||
private final String pluginName;
|
||||
private final UUID serverUUID;
|
||||
private final String providerName;
|
||||
private final UUID playerUUID;
|
||||
|
||||
private final Table table;
|
||||
|
||||
public StorePlayerTableResultTransaction(String pluginName, UUID serverUUID, String providerName, UUID playerUUID, Table table) {
|
||||
this.pluginName = pluginName;
|
||||
this.serverUUID = serverUUID;
|
||||
this.providerName = providerName;
|
||||
this.playerUUID = playerUUID;
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performOperations() {
|
||||
execute(storeValue());
|
||||
}
|
||||
|
||||
private Executable storeValue() {
|
||||
return connection -> {
|
||||
int maxColumnSize = table.getMaxColumnSize();
|
||||
if (maxColumnSize == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Integer tableID = query(tableID());
|
||||
deleteOldValues(tableID).execute(connection);
|
||||
insertNewValues(tableID).execute(connection);
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
private Executable deleteOldValues(int tableID) {
|
||||
String sql = "DELETE FROM " + TABLE_NAME +
|
||||
WHERE + TABLE_ID + "=?" +
|
||||
AND + USER_UUID + "=?";
|
||||
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setInt(1, tableID);
|
||||
statement.setString(2, playerUUID.toString());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Executable insertNewValues(int tableID) {
|
||||
String sql = "INSERT INTO " + TABLE_NAME + '(' +
|
||||
TABLE_ID + ',' +
|
||||
USER_UUID + ',' +
|
||||
VALUE_1 + ',' +
|
||||
VALUE_2 + ',' +
|
||||
VALUE_3 + ',' +
|
||||
VALUE_4 +
|
||||
") VALUES (?,?,?,?,?,?)";
|
||||
|
||||
return new ExecBatchStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
int maxColumnSize = Math.min(table.getMaxColumnSize(), 4); // Limit to maximum 4 columns, or how many column names there are.
|
||||
|
||||
for (Object[] row : table.getRows()) {
|
||||
statement.setInt(1, tableID);
|
||||
statement.setString(2, playerUUID.toString());
|
||||
for (int i = 0; i < maxColumnSize; i++) {
|
||||
Object value = row[i];
|
||||
setStringOrNull(statement, 3 + i, value != null ? value.toString() : null);
|
||||
}
|
||||
// Rest are set null if not 4 columns wide.
|
||||
for (int i = maxColumnSize; i < 4; i++) {
|
||||
statement.setNull(3 + i, Types.VARCHAR);
|
||||
}
|
||||
|
||||
statement.addBatch();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void setStringOrNull(PreparedStatement statement, int index, String value) throws SQLException {
|
||||
if (value != null) {
|
||||
statement.setString(index, value);
|
||||
} else {
|
||||
statement.setNull(index, Types.VARCHAR);
|
||||
}
|
||||
}
|
||||
|
||||
private Query<Integer> tableID() {
|
||||
String sql = SELECT + ExtensionTableProviderTable.ID +
|
||||
FROM + ExtensionTableProviderTable.TABLE_NAME +
|
||||
WHERE + ExtensionTableProviderTable.PROVIDER_NAME + "=?" +
|
||||
AND + ExtensionTableProviderTable.PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID +
|
||||
" LIMIT 1";
|
||||
return new QueryStatement<Integer>(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
ExtensionTableProviderTable.set3PluginValuesToStatement(statement, 1, providerName, pluginName, serverUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer processResults(ResultSet set) throws SQLException {
|
||||
if (set.next()) {
|
||||
int id = set.getInt(ExtensionTableProviderTable.ID);
|
||||
if (!set.wasNull()) {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
throw new DBOpException("Table Provider was not saved before storing results. Please report this issue. Extension method: " + pluginName + "#" + providerName);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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.extension.implementation.storage.transactions.results;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.db.access.*;
|
||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable;
|
||||
import com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable;
|
||||
import com.djrapitops.plan.extension.table.Table;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.*;
|
||||
import static com.djrapitops.plan.db.sql.tables.ExtensionServerTableValueTable.*;
|
||||
|
||||
/**
|
||||
* Transaction to store method result of a {@link com.djrapitops.plan.extension.implementation.providers.TableDataProvider}.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class StoreServerTableResultTransaction extends Transaction {
|
||||
|
||||
private final String pluginName;
|
||||
private final UUID serverUUID;
|
||||
private final String providerName;
|
||||
|
||||
private final Table table;
|
||||
|
||||
public StoreServerTableResultTransaction(String pluginName, UUID serverUUID, String providerName, Table table) {
|
||||
this.pluginName = pluginName;
|
||||
this.serverUUID = serverUUID;
|
||||
this.providerName = providerName;
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performOperations() {
|
||||
execute(storeValue());
|
||||
}
|
||||
|
||||
private Executable storeValue() {
|
||||
return connection -> {
|
||||
int maxColumnSize = table.getMaxColumnSize();
|
||||
if (maxColumnSize == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Integer tableID = query(tableID());
|
||||
deleteOldValues(tableID).execute(connection);
|
||||
insertNewValues(tableID).execute(connection);
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
private Executable deleteOldValues(int tableID) {
|
||||
String sql = "DELETE FROM " + TABLE_NAME +
|
||||
WHERE + TABLE_ID + "=?" +
|
||||
AND + SERVER_UUID + "=?";
|
||||
|
||||
return new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setInt(1, tableID);
|
||||
statement.setString(2, serverUUID.toString());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Executable insertNewValues(int tableID) {
|
||||
String sql = "INSERT INTO " + TABLE_NAME + '(' +
|
||||
TABLE_ID + ',' +
|
||||
SERVER_UUID + ',' +
|
||||
VALUE_1 + ',' +
|
||||
VALUE_2 + ',' +
|
||||
VALUE_3 + ',' +
|
||||
VALUE_4 + ',' +
|
||||
VALUE_5 +
|
||||
") VALUES (?,?,?,?,?,?, ?)";
|
||||
|
||||
return new ExecBatchStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
int maxColumnSize = Math.min(table.getMaxColumnSize(), 5); // Limit to maximum 5 columns, or how many column names there are.
|
||||
|
||||
for (Object[] row : table.getRows()) {
|
||||
statement.setInt(1, tableID);
|
||||
statement.setString(2, serverUUID.toString());
|
||||
for (int i = 0; i < maxColumnSize; i++) {
|
||||
Object value = row[i];
|
||||
setStringOrNull(statement, 3 + i, value != null ? value.toString() : null);
|
||||
}
|
||||
// Rest are set null if not 5 columns wide.
|
||||
for (int i = maxColumnSize; i < 5; i++) {
|
||||
statement.setNull(3 + i, Types.VARCHAR);
|
||||
}
|
||||
|
||||
statement.addBatch();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void setStringOrNull(PreparedStatement statement, int index, String value) throws SQLException {
|
||||
if (value != null) {
|
||||
statement.setString(index, value);
|
||||
} else {
|
||||
statement.setNull(index, Types.VARCHAR);
|
||||
}
|
||||
}
|
||||
|
||||
private Query<Integer> tableID() {
|
||||
String sql = SELECT + ExtensionTableProviderTable.ID +
|
||||
FROM + ExtensionTableProviderTable.TABLE_NAME +
|
||||
WHERE + ExtensionTableProviderTable.PROVIDER_NAME + "=?" +
|
||||
AND + ExtensionTableProviderTable.PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID +
|
||||
" LIMIT 1";
|
||||
return new QueryStatement<Integer>(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
ExtensionTableProviderTable.set3PluginValuesToStatement(statement, 1, providerName, pluginName, serverUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer processResults(ResultSet set) throws SQLException {
|
||||
if (set.next()) {
|
||||
int id = set.getInt(ExtensionTableProviderTable.ID);
|
||||
if (!set.wasNull()) {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
throw new DBOpException("Table Provider was not saved before storing results. Please report this issue. Extension method: " + pluginName + "#" + providerName);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.extension.table;
|
||||
|
||||
import com.djrapitops.plan.extension.ElementOrder;
|
||||
import com.djrapitops.plan.extension.icon.Color;
|
||||
import com.djrapitops.plan.extension.icon.Icon;
|
||||
|
||||
/**
|
||||
* Utility for accessing implementation variables inside Table.Factory object.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class TableAccessor {
|
||||
|
||||
private TableAccessor() {
|
||||
/* Static method class */
|
||||
}
|
||||
|
||||
public static Color getColor(Table.Factory factory) {
|
||||
return factory.color;
|
||||
}
|
||||
|
||||
public static void setColor(Table.Factory factory, Color color) {
|
||||
factory.color = color;
|
||||
}
|
||||
|
||||
public static String getTableName(Table.Factory factory) {
|
||||
return factory.tableName;
|
||||
}
|
||||
|
||||
public static void setTableName(Table.Factory factory, String tableName) {
|
||||
factory.tableName = tableName;
|
||||
}
|
||||
|
||||
public static String getTabName(Table.Factory factory) {
|
||||
return factory.tabName;
|
||||
}
|
||||
|
||||
public static void setTabName(Table.Factory factory, String tabName) {
|
||||
factory.tabName = tabName;
|
||||
}
|
||||
|
||||
public static int getTabPriority(Table.Factory factory) {
|
||||
return factory.tabPriority;
|
||||
}
|
||||
|
||||
public static void setTabPriority(Table.Factory factory, int tabPriority) {
|
||||
factory.tabPriority = tabPriority;
|
||||
}
|
||||
|
||||
public static ElementOrder[] getTabOrder(Table.Factory factory) {
|
||||
return factory.tabOrder;
|
||||
}
|
||||
|
||||
public static void setTabOrder(Table.Factory factory, ElementOrder[] tabOrder) {
|
||||
factory.tabOrder = tabOrder;
|
||||
}
|
||||
|
||||
public static Icon getTabIcon(Table.Factory factory) {
|
||||
return factory.tabIcon;
|
||||
}
|
||||
|
||||
public static void setTabIcon(Table.Factory factory, Icon tabIcon) {
|
||||
factory.tabIcon = tabIcon;
|
||||
}
|
||||
}
|
@ -126,11 +126,11 @@ public class PlanSystem implements SubSystem {
|
||||
localeSystem,
|
||||
versionCheckSystem,
|
||||
databaseSystem,
|
||||
importSystem,
|
||||
exportSystem,
|
||||
webServerSystem,
|
||||
processing,
|
||||
serverInfo,
|
||||
importSystem,
|
||||
exportSystem,
|
||||
infoSystem,
|
||||
cacheSystem,
|
||||
listenerSystem,
|
||||
|
@ -18,10 +18,10 @@ package com.djrapitops.plan.system.export;
|
||||
|
||||
import com.djrapitops.plan.system.SubSystem;
|
||||
import com.djrapitops.plan.system.info.connection.ConnectionSystem;
|
||||
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.plan.system.settings.paths.ExportSettings;
|
||||
import com.djrapitops.plugin.api.Check;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -35,6 +35,7 @@ import javax.inject.Singleton;
|
||||
public class ExportSystem implements SubSystem {
|
||||
|
||||
private final PlanConfig config;
|
||||
private final ServerInfo serverInfo;
|
||||
private final Processing processing;
|
||||
private final HtmlExport htmlExport;
|
||||
private final ConnectionSystem connectionSystem;
|
||||
@ -42,11 +43,13 @@ public class ExportSystem implements SubSystem {
|
||||
@Inject
|
||||
public ExportSystem(
|
||||
PlanConfig config,
|
||||
ServerInfo serverInfo,
|
||||
Processing processing,
|
||||
HtmlExport htmlExport,
|
||||
ConnectionSystem connectionSystem
|
||||
) {
|
||||
this.config = config;
|
||||
this.serverInfo = serverInfo;
|
||||
this.processing = processing;
|
||||
this.htmlExport = htmlExport;
|
||||
this.connectionSystem = connectionSystem;
|
||||
@ -54,7 +57,7 @@ public class ExportSystem implements SubSystem {
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
if (Check.isBukkitAvailable() && connectionSystem.isServerAvailable()) {
|
||||
if (serverInfo.getServer().isNotProxy() && connectionSystem.isServerAvailable()) {
|
||||
return;
|
||||
}
|
||||
if (config.isTrue(ExportSettings.JS_AND_CSS)) {
|
||||
@ -69,7 +72,10 @@ public class ExportSystem implements SubSystem {
|
||||
processing.submitNonCritical(htmlExport::exportAvailablePlayers);
|
||||
}
|
||||
if (config.isTrue(ExportSettings.SERVER_PAGE)) {
|
||||
processing.submitNonCritical(htmlExport::exportAvailableServerPages);
|
||||
processing.submitNonCritical(() -> {
|
||||
htmlExport.cacheNetworkPage();
|
||||
htmlExport.exportAvailableServerPages();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
package com.djrapitops.plan.system.export;
|
||||
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.api.exceptions.ParseException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.data.container.BaseUser;
|
||||
@ -32,9 +31,13 @@ import com.djrapitops.plan.system.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.system.settings.paths.ExportSettings;
|
||||
import com.djrapitops.plan.system.settings.theme.Theme;
|
||||
import com.djrapitops.plan.system.settings.theme.ThemeVal;
|
||||
import com.djrapitops.plan.system.webserver.cache.PageId;
|
||||
import com.djrapitops.plan.system.webserver.cache.ResponseCache;
|
||||
import com.djrapitops.plan.system.webserver.pages.json.JSONFactory;
|
||||
import com.djrapitops.plan.system.webserver.response.pages.NetworkPageResponse;
|
||||
import com.djrapitops.plan.utilities.html.pages.InspectPage;
|
||||
import com.djrapitops.plan.utilities.html.pages.NetworkPage;
|
||||
import com.djrapitops.plan.utilities.html.pages.PageFactory;
|
||||
import com.djrapitops.plugin.api.Check;
|
||||
import com.djrapitops.plugin.logging.L;
|
||||
import com.djrapitops.plugin.logging.error.ErrorHandler;
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
@ -55,7 +58,6 @@ import java.util.*;
|
||||
@Singleton
|
||||
public class HtmlExport extends SpecificExport {
|
||||
|
||||
private final PlanPlugin plugin;
|
||||
private final PlanConfig config;
|
||||
private final Theme theme;
|
||||
private final PlanFiles files;
|
||||
@ -66,18 +68,17 @@ public class HtmlExport extends SpecificExport {
|
||||
|
||||
@Inject
|
||||
public HtmlExport(
|
||||
PlanPlugin plugin,
|
||||
PlanFiles files,
|
||||
PlanConfig config,
|
||||
Theme theme,
|
||||
DBSystem dbSystem,
|
||||
PageFactory pageFactory,
|
||||
JSONFactory jsonFactory,
|
||||
ServerInfo serverInfo,
|
||||
ConnectionSystem connectionSystem,
|
||||
ErrorHandler errorHandler
|
||||
) {
|
||||
super(files, serverInfo);
|
||||
this.plugin = plugin;
|
||||
super(files, jsonFactory, serverInfo);
|
||||
this.config = config;
|
||||
this.theme = theme;
|
||||
this.files = files;
|
||||
@ -93,7 +94,7 @@ public class HtmlExport extends SpecificExport {
|
||||
}
|
||||
|
||||
public void exportServer(UUID serverUUID) {
|
||||
if (Check.isBukkitAvailable() && connectionSystem.isServerAvailable()) {
|
||||
if (serverInfo.getServer().isNotProxy() && connectionSystem.isServerAvailable()) {
|
||||
return;
|
||||
}
|
||||
dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverUUID))
|
||||
@ -122,7 +123,7 @@ public class HtmlExport extends SpecificExport {
|
||||
}
|
||||
|
||||
public void exportCachedPlayerPage(UUID playerUUID) {
|
||||
if (Check.isBukkitAvailable() && connectionSystem.isServerAvailable()) {
|
||||
if (serverInfo.getServer().isNotProxy() && connectionSystem.isServerAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -166,6 +167,35 @@ public class HtmlExport extends SpecificExport {
|
||||
}
|
||||
}
|
||||
|
||||
public void cacheNetworkPage() {
|
||||
if (serverInfo.getServer().isNotProxy()) {
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkPage networkPage = pageFactory.networkPage();
|
||||
ResponseCache.cacheResponse(PageId.SERVER.of(serverInfo.getServerUUID()), () -> {
|
||||
try {
|
||||
return new NetworkPageResponse(networkPage);
|
||||
} catch (ParseException e) {
|
||||
errorHandler.log(L.WARN, this.getClass(), e);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void exportNetworkPage() {
|
||||
if (serverInfo.getServer().isNotProxy()) {
|
||||
return;
|
||||
}
|
||||
|
||||
cacheNetworkPage();
|
||||
try {
|
||||
exportAvailableServerPage(serverInfo.getServerUUID(), serverInfo.getServer().getName());
|
||||
} catch (IOException e) {
|
||||
errorHandler.log(L.WARN, this.getClass(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void exportAvailableServerPages() {
|
||||
try {
|
||||
Map<UUID, String> serverNames = dbSystem.getDatabase().query(ServerQueries.fetchServerNames());
|
||||
@ -231,15 +261,11 @@ public class HtmlExport extends SpecificExport {
|
||||
|
||||
public void exportPlugins() {
|
||||
String[] resources = new String[]{
|
||||
"web/plugins/bootstrap/css/bootstrap.css",
|
||||
"web/plugins/node-waves/waves.css",
|
||||
"web/plugins/node-waves/waves.js",
|
||||
"web/plugins/animate-css/animate.css",
|
||||
"web/plugins/jquery-slimscroll/jquery.slimscroll.js",
|
||||
"web/plugins/jquery/jquery.min.js",
|
||||
"web/plugins/bootstrap/js/bootstrap.js",
|
||||
"web/plugins/jquery-datatable/skin/bootstrap/js/dataTables.bootstrap.js",
|
||||
"web/plugins/jquery-datatable/jquery.dataTables.js",
|
||||
"web/plugins/fullcalendar/fullcalendar.min.js",
|
||||
"web/plugins/fullcalendar/fullcalendar.min.css",
|
||||
"web/plugins/momentjs/moment.js",
|
||||
|
@ -24,6 +24,7 @@ import com.djrapitops.plan.system.info.server.Server;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.system.settings.paths.ExportSettings;
|
||||
import com.djrapitops.plan.system.webserver.pages.json.JSONFactory;
|
||||
import com.djrapitops.plan.system.webserver.response.ResponseFactory;
|
||||
import com.djrapitops.plugin.logging.L;
|
||||
import com.djrapitops.plugin.logging.error.ErrorHandler;
|
||||
@ -55,10 +56,11 @@ public class JSONExport extends SpecificExport {
|
||||
PlanConfig config,
|
||||
DBSystem dbSystem,
|
||||
ServerInfo serverInfo,
|
||||
JSONFactory jsonFactory,
|
||||
ResponseFactory responseFactory,
|
||||
ErrorHandler errorHandler
|
||||
) {
|
||||
super(files, serverInfo);
|
||||
super(files, jsonFactory, serverInfo);
|
||||
this.config = config;
|
||||
this.dbSystem = dbSystem;
|
||||
this.responseFactory = responseFactory;
|
||||
|
@ -20,8 +20,8 @@ import com.djrapitops.plan.system.file.PlanFiles;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.system.webserver.cache.PageId;
|
||||
import com.djrapitops.plan.system.webserver.cache.ResponseCache;
|
||||
import com.djrapitops.plan.system.webserver.pages.json.JSONFactory;
|
||||
import com.djrapitops.plan.system.webserver.response.Response;
|
||||
import com.djrapitops.plugin.api.Check;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -30,6 +30,7 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -41,17 +42,16 @@ import java.util.UUID;
|
||||
public abstract class SpecificExport {
|
||||
|
||||
private final PlanFiles files;
|
||||
private final ServerInfo serverInfo;
|
||||
private final JSONFactory jsonFactory; // Hacky, TODO export needs a rework
|
||||
protected final ServerInfo serverInfo;
|
||||
|
||||
private final boolean usingProxy;
|
||||
|
||||
protected SpecificExport(
|
||||
SpecificExport(
|
||||
PlanFiles files,
|
||||
ServerInfo serverInfo
|
||||
JSONFactory jsonFactory, ServerInfo serverInfo
|
||||
) {
|
||||
this.files = files;
|
||||
this.jsonFactory = jsonFactory;
|
||||
this.serverInfo = serverInfo;
|
||||
usingProxy = Check.isBungeeAvailable() || Check.isVelocityAvailable();
|
||||
}
|
||||
|
||||
protected File getFolder() {
|
||||
@ -78,19 +78,19 @@ public abstract class SpecificExport {
|
||||
Files.write(to.toPath(), lines, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
protected File getServerFolder() {
|
||||
File getServerFolder() {
|
||||
File server = new File(getFolder(), "server");
|
||||
server.mkdirs();
|
||||
return server;
|
||||
}
|
||||
|
||||
protected File getPlayerFolder() {
|
||||
File getPlayerFolder() {
|
||||
File player = new File(getFolder(), "player");
|
||||
player.mkdirs();
|
||||
return player;
|
||||
}
|
||||
|
||||
protected void exportPlayerPage(String playerName, String html) throws IOException {
|
||||
void exportPlayerPage(String playerName, String html) throws IOException {
|
||||
List<String> lines = Arrays.asList(html.replace("../", "../../").split("\n"));
|
||||
|
||||
File htmlLocation = new File(getPlayerFolder(), URLEncoder.encode(playerName, "UTF-8").replace(".", "%2E"));
|
||||
@ -100,7 +100,7 @@ public abstract class SpecificExport {
|
||||
export(exportFile, lines);
|
||||
}
|
||||
|
||||
protected void exportAvailablePlayerPage(UUID playerUUID, String name) throws IOException {
|
||||
void exportAvailablePlayerPage(UUID playerUUID, String name) throws IOException {
|
||||
Response response = ResponseCache.loadResponse(PageId.PLAYER.of(playerUUID));
|
||||
if (response == null) {
|
||||
return;
|
||||
@ -110,7 +110,7 @@ public abstract class SpecificExport {
|
||||
exportPlayerPage(name, html);
|
||||
}
|
||||
|
||||
protected void exportAvailableServerPage(UUID serverUUID, String serverName) throws IOException {
|
||||
void exportAvailableServerPage(UUID serverUUID, String serverName) throws IOException {
|
||||
|
||||
Response response = ResponseCache.loadResponse(PageId.SERVER.of(serverUUID));
|
||||
if (response == null) {
|
||||
@ -121,19 +121,23 @@ public abstract class SpecificExport {
|
||||
.replace("href=\"plugins/", "href=\"../plugins/")
|
||||
.replace("href=\"css/", "href=\"../css/")
|
||||
.replace("src=\"plugins/", "src=\"../plugins/")
|
||||
.replace("src=\"js/", "src=\"../js/");
|
||||
.replace("src=\"js/", "src=\"../js/")
|
||||
.replace("../json/players?serverName=" + serverName, "./players_table.json");
|
||||
|
||||
File htmlLocation;
|
||||
if (usingProxy) {
|
||||
if (serverInfo.getServer().isProxy()) {
|
||||
if (serverUUID.equals(serverInfo.getServerUUID())) {
|
||||
htmlLocation = new File(getFolder(), "network");
|
||||
} else {
|
||||
htmlLocation = new File(getServerFolder(), URLEncoder.encode(serverName, "UTF-8").replace(".", "%2E"));
|
||||
html = html.replace("../", "../../");
|
||||
exportPlayersTableJSON(htmlLocation, serverUUID);
|
||||
}
|
||||
} else {
|
||||
htmlLocation = getServerFolder();
|
||||
exportPlayersTableJSON(htmlLocation, serverUUID);
|
||||
}
|
||||
|
||||
htmlLocation.mkdirs();
|
||||
File exportFile = new File(htmlLocation, "index.html");
|
||||
|
||||
@ -141,4 +145,9 @@ public abstract class SpecificExport {
|
||||
|
||||
export(exportFile, lines);
|
||||
}
|
||||
|
||||
private void exportPlayersTableJSON(File htmlLocation, UUID serverUUID) throws IOException {
|
||||
File exportFile = new File(htmlLocation, "players_table.json");
|
||||
export(exportFile, Collections.singletonList(jsonFactory.serverPlayersTableJSON(serverUUID)));
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ import com.djrapitops.plan.system.info.request.InfoRequestFactory;
|
||||
import com.djrapitops.plan.system.info.server.Server;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.system.webserver.WebServer;
|
||||
import com.djrapitops.plugin.api.Check;
|
||||
import com.djrapitops.plugin.logging.console.PluginLogger;
|
||||
import dagger.Lazy;
|
||||
|
||||
@ -159,11 +158,8 @@ public abstract class InfoSystem implements SubSystem {
|
||||
* @throws WebException If fails.
|
||||
*/
|
||||
public void requestSetUp(String addressToRequestServer) throws WebException {
|
||||
if (Check.isBungeeAvailable()) {
|
||||
throw new BadRequestException("Method not available on Bungee.");
|
||||
}
|
||||
if (Check.isVelocityAvailable()) {
|
||||
throw new BadRequestException("Method not available on Velocity.");
|
||||
if (serverInfo.getServer().isProxy()) {
|
||||
throw new BadRequestException("Method not available on a Proxy server.");
|
||||
}
|
||||
Server bungee = new Server(-1, null, "Bungee", addressToRequestServer, -1);
|
||||
String addressOfThisServer = webServer.get().getAccessAddress();
|
||||
|
@ -21,6 +21,7 @@ import com.djrapitops.plan.api.exceptions.connection.WebException;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.system.info.request.InfoRequest;
|
||||
import com.djrapitops.plan.system.webserver.Request;
|
||||
import com.djrapitops.plan.system.webserver.RequestTarget;
|
||||
import com.djrapitops.plan.system.webserver.pages.PageHandler;
|
||||
import com.djrapitops.plan.system.webserver.response.Response;
|
||||
import com.djrapitops.plan.system.webserver.response.ResponseFactory;
|
||||
@ -30,7 +31,6 @@ import com.djrapitops.plugin.utilities.Verify;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PageHandler for /info/requestclassname pages.
|
||||
@ -62,7 +62,7 @@ public class InfoRequestPageHandler implements PageHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response getResponse(Request request, List<String> target) throws WebException {
|
||||
public Response getResponse(Request request, RequestTarget target) throws WebException {
|
||||
int responseCode = 200;
|
||||
|
||||
try {
|
||||
@ -85,7 +85,7 @@ public class InfoRequestPageHandler implements PageHandler {
|
||||
responseCode = getResponseCodeFor(e);
|
||||
throw e;
|
||||
} finally {
|
||||
connectionSystem.getConnectionLog().logConnectionFrom(request.getRemoteAddress(), request.getTarget(), responseCode);
|
||||
connectionSystem.getConnectionLog().logConnectionFrom(request.getRemoteAddress(), request.getTargetString(), responseCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,10 @@ public class CacheAnalysisPageRequest extends InfoRequestWithVariables implement
|
||||
}
|
||||
|
||||
if (config.get(ExportSettings.SERVER_PAGE)) {
|
||||
processing.submitNonCritical(() -> htmlExport.exportServer(serverUUID));
|
||||
processing.submitNonCritical(() -> {
|
||||
htmlExport.exportNetworkPage();
|
||||
htmlExport.exportServer(serverUUID);
|
||||
});
|
||||
}
|
||||
if (config.get(ExportSettings.SERVER_JSON)) {
|
||||
processing.submitNonCritical(() -> jsonExport.exportServerJSON(serverUUID));
|
||||
|
@ -22,9 +22,9 @@ import com.djrapitops.plan.api.exceptions.connection.GatewayException;
|
||||
import com.djrapitops.plan.api.exceptions.connection.WebException;
|
||||
import com.djrapitops.plan.system.info.connection.ConnectionSystem;
|
||||
import com.djrapitops.plan.system.info.server.Server;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.system.webserver.response.DefaultResponses;
|
||||
import com.djrapitops.plan.system.webserver.response.Response;
|
||||
import com.djrapitops.plugin.api.Check;
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
|
||||
import java.util.Map;
|
||||
@ -37,9 +37,11 @@ import java.util.UUID;
|
||||
*/
|
||||
public class CheckConnectionRequest extends InfoRequestWithVariables {
|
||||
|
||||
private final ServerInfo serverInfo;
|
||||
private final ConnectionSystem connectionSystem;
|
||||
|
||||
CheckConnectionRequest(String webServerAddress, ConnectionSystem connectionSystem) {
|
||||
CheckConnectionRequest(String webServerAddress, ServerInfo serverInfo, ConnectionSystem connectionSystem) {
|
||||
this.serverInfo = serverInfo;
|
||||
this.connectionSystem = connectionSystem;
|
||||
Verify.nullCheck(webServerAddress, () -> new IllegalArgumentException("webServerAddress can not be null."));
|
||||
|
||||
@ -47,7 +49,8 @@ public class CheckConnectionRequest extends InfoRequestWithVariables {
|
||||
variables.put("continue", "yes");
|
||||
}
|
||||
|
||||
CheckConnectionRequest(ConnectionSystem connectionSystem) {
|
||||
CheckConnectionRequest(ServerInfo serverInfo, ConnectionSystem connectionSystem) {
|
||||
this.serverInfo = serverInfo;
|
||||
this.connectionSystem = connectionSystem;
|
||||
}
|
||||
|
||||
@ -60,7 +63,7 @@ public class CheckConnectionRequest extends InfoRequestWithVariables {
|
||||
public Response handleRequest(Map<String, String> variables) throws WebException {
|
||||
// Available variables: sender, address
|
||||
|
||||
if (Check.isBungeeAvailable() || Check.isVelocityAvailable()) {
|
||||
if (serverInfo.getServer().isProxy()) {
|
||||
attemptConnection(variables);
|
||||
}
|
||||
|
||||
@ -82,7 +85,7 @@ public class CheckConnectionRequest extends InfoRequestWithVariables {
|
||||
Server bukkit = new Server(-1, serverUUID, "", address, -1);
|
||||
|
||||
try {
|
||||
connectionSystem.sendInfoRequest(new CheckConnectionRequest(connectionSystem), bukkit);
|
||||
connectionSystem.sendInfoRequest(new CheckConnectionRequest(serverInfo, connectionSystem), bukkit);
|
||||
} catch (ConnectionFailException e) {
|
||||
throw new GatewayException(e.getMessage());
|
||||
}
|
||||
|
@ -123,15 +123,15 @@ public class InfoRequestFactory {
|
||||
}
|
||||
|
||||
public SaveDBSettingsRequest saveDBSettingsRequest() {
|
||||
return new SaveDBSettingsRequest(plugin.get(), config.get(), logger.get(), runnableFactory.get());
|
||||
return new SaveDBSettingsRequest(plugin.get(), config.get(), serverInfo.get(), logger.get(), runnableFactory.get());
|
||||
}
|
||||
|
||||
public SetupRequest sendDBSettingsRequest(String addressOfThisServer) {
|
||||
return new SendDBSettingsRequest(addressOfThisServer, this, connectionSystem.get());
|
||||
return new SendDBSettingsRequest(addressOfThisServer, serverInfo.get(), this, connectionSystem.get());
|
||||
}
|
||||
|
||||
public CheckConnectionRequest checkConnectionRequest(String webAddress) {
|
||||
return new CheckConnectionRequest(webAddress, connectionSystem.get());
|
||||
return new CheckConnectionRequest(webAddress, serverInfo.get(), connectionSystem.get());
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@ -169,7 +169,7 @@ public class InfoRequestFactory {
|
||||
}
|
||||
|
||||
CheckConnectionRequest checkConnectionRequest() {
|
||||
return new CheckConnectionRequest(factory.connectionSystem.get());
|
||||
return new CheckConnectionRequest(factory.serverInfo.get(), factory.connectionSystem.get());
|
||||
}
|
||||
|
||||
GenerateRequest generateAnalysisPageRequest() {
|
||||
@ -204,6 +204,7 @@ public class InfoRequestFactory {
|
||||
return new SaveDBSettingsRequest(
|
||||
factory.plugin.get(),
|
||||
factory.config.get(),
|
||||
factory.serverInfo.get(),
|
||||
factory.logger.get(),
|
||||
factory.runnableFactory.get()
|
||||
);
|
||||
@ -211,6 +212,7 @@ public class InfoRequestFactory {
|
||||
|
||||
SetupRequest sendDBSettingsRequest() {
|
||||
return new SendDBSettingsRequest(
|
||||
factory.serverInfo.get(),
|
||||
factory,
|
||||
factory.connectionSystem.get()
|
||||
);
|
||||
|
@ -20,13 +20,13 @@ import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.api.exceptions.connection.BadRequestException;
|
||||
import com.djrapitops.plan.api.exceptions.connection.InternalErrorException;
|
||||
import com.djrapitops.plan.api.exceptions.connection.WebException;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.system.settings.paths.DatabaseSettings;
|
||||
import com.djrapitops.plan.system.settings.paths.PluginSettings;
|
||||
import com.djrapitops.plan.system.webserver.response.DefaultResponses;
|
||||
import com.djrapitops.plan.system.webserver.response.Response;
|
||||
import com.djrapitops.plan.system.webserver.response.errors.BadRequestResponse;
|
||||
import com.djrapitops.plugin.api.Check;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
import com.djrapitops.plugin.logging.console.PluginLogger;
|
||||
import com.djrapitops.plugin.task.AbsRunnable;
|
||||
@ -46,17 +46,19 @@ public class SaveDBSettingsRequest extends InfoRequestWithVariables implements S
|
||||
|
||||
private final PlanPlugin plugin;
|
||||
private final PlanConfig config;
|
||||
private final ServerInfo serverInfo;
|
||||
private final PluginLogger logger;
|
||||
private final RunnableFactory runnableFactory;
|
||||
|
||||
SaveDBSettingsRequest(
|
||||
PlanPlugin plugin,
|
||||
PlanConfig config,
|
||||
PluginLogger logger,
|
||||
ServerInfo serverInfo, PluginLogger logger,
|
||||
RunnableFactory runnableFactory
|
||||
) {
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
this.serverInfo = serverInfo;
|
||||
this.logger = logger;
|
||||
this.runnableFactory = runnableFactory;
|
||||
|
||||
@ -75,11 +77,8 @@ public class SaveDBSettingsRequest extends InfoRequestWithVariables implements S
|
||||
|
||||
@Override
|
||||
public Response handleRequest(Map<String, String> variables) throws WebException {
|
||||
if (Check.isBungeeAvailable()) {
|
||||
return new BadRequestResponse("Not supposed to be called on a Bungee server");
|
||||
}
|
||||
if (Check.isVelocityAvailable()) {
|
||||
return new BadRequestResponse("Not supposed to be called on a Velocity server");
|
||||
if (serverInfo.getServer().isProxy()) {
|
||||
return new BadRequestResponse("Not supposed to be called on a proxy server");
|
||||
}
|
||||
if (config.isFalse(PluginSettings.BUNGEE_COPY_CONFIG)) {
|
||||
return new BadRequestResponse("Bungee config settings overridden on this server.");
|
||||
|
@ -22,10 +22,10 @@ import com.djrapitops.plan.api.exceptions.connection.GatewayException;
|
||||
import com.djrapitops.plan.api.exceptions.connection.WebException;
|
||||
import com.djrapitops.plan.system.info.connection.ConnectionSystem;
|
||||
import com.djrapitops.plan.system.info.server.Server;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.system.webserver.response.DefaultResponses;
|
||||
import com.djrapitops.plan.system.webserver.response.Response;
|
||||
import com.djrapitops.plan.system.webserver.response.errors.BadRequestResponse;
|
||||
import com.djrapitops.plugin.api.Check;
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
|
||||
import java.net.SocketException;
|
||||
@ -39,20 +39,23 @@ import java.util.UUID;
|
||||
*/
|
||||
public class SendDBSettingsRequest extends InfoRequestWithVariables implements SetupRequest {
|
||||
|
||||
private final ServerInfo serverInfo;
|
||||
private final InfoRequestFactory infoRequestFactory;
|
||||
private final ConnectionSystem connectionSystem;
|
||||
|
||||
SendDBSettingsRequest(
|
||||
InfoRequestFactory infoRequestFactory, ConnectionSystem connectionSystem
|
||||
ServerInfo serverInfo, InfoRequestFactory infoRequestFactory, ConnectionSystem connectionSystem
|
||||
) {
|
||||
this.serverInfo = serverInfo;
|
||||
this.infoRequestFactory = infoRequestFactory;
|
||||
this.connectionSystem = connectionSystem;
|
||||
}
|
||||
|
||||
SendDBSettingsRequest(
|
||||
String webServerAddress,
|
||||
InfoRequestFactory infoRequestFactory, ConnectionSystem connectionSystem
|
||||
ServerInfo serverInfo, InfoRequestFactory infoRequestFactory, ConnectionSystem connectionSystem
|
||||
) {
|
||||
this.serverInfo = serverInfo;
|
||||
this.infoRequestFactory = infoRequestFactory;
|
||||
this.connectionSystem = connectionSystem;
|
||||
|
||||
@ -68,11 +71,8 @@ public class SendDBSettingsRequest extends InfoRequestWithVariables implements S
|
||||
@Override
|
||||
public Response handleRequest(Map<String, String> variables) throws WebException {
|
||||
// Available variables: sender, address
|
||||
if (Check.isBukkitAvailable()) {
|
||||
return new BadRequestResponse("Not supposed to be called on a Bukkit server");
|
||||
}
|
||||
if (Check.isSpongeAvailable()) {
|
||||
return new BadRequestResponse("Not supposed to be called on a Sponge server");
|
||||
if (serverInfo.getServer().isNotProxy()) {
|
||||
return new BadRequestResponse("Not supposed to be called on a non proxy server");
|
||||
}
|
||||
|
||||
String address = variables.get("address");
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user