mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-15 05:41:51 +08:00
Added database storage functionality for React data
This commit is contained in:
parent
d2e06711e6
commit
2a06c57c71
@ -220,6 +220,12 @@
|
||||
<version>LATEST</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.volmit</groupId>
|
||||
<artifactId>react</artifactId>
|
||||
<version>6.549</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
|
@ -0,0 +1,77 @@
|
||||
package com.djrapitops.pluginbridge.plan.react;
|
||||
|
||||
import com.djrapitops.plan.system.processing.Processing;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
import com.djrapitops.plugin.task.AbsRunnable;
|
||||
import com.volmit.react.React;
|
||||
import com.volmit.react.api.GraphSampleLine;
|
||||
import com.volmit.react.api.SampledType;
|
||||
import com.volmit.react.util.GMap;
|
||||
import com.volmit.react.util.M;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Task in charge of collecting data from React.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class DataCollectionTask extends AbsRunnable {
|
||||
|
||||
private static final SampledType[] STORED_TYPES = new SampledType[]{
|
||||
SampledType.ENT,
|
||||
SampledType.ENTLIV,
|
||||
SampledType.ENTDROP,
|
||||
SampledType.ENTTILE,
|
||||
|
||||
SampledType.TIU,
|
||||
SampledType.HOPPER_TICK_USAGE,
|
||||
SampledType.FLUID_TICK_USAGE,
|
||||
SampledType.REDSTONE_TICK_USAGE,
|
||||
|
||||
SampledType.TICK,
|
||||
SampledType.TILE_DROPTICK,
|
||||
SampledType.FLUID_TICK,
|
||||
SampledType.HOPPER_TICK,
|
||||
SampledType.ENTITY_DROPTICK,
|
||||
SampledType.REDSTONE_TICK,
|
||||
|
||||
SampledType.REACT_TASK_TIME
|
||||
};
|
||||
private final ReactDataTable table;
|
||||
private final Map<SampledType, List<ReactValue>> history;
|
||||
|
||||
public DataCollectionTask(ReactDataTable table) {
|
||||
super(DataCollectionTask.class.getSimpleName());
|
||||
this.table = table;
|
||||
history = new EnumMap<>(SampledType.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
GMap<SampledType, GraphSampleLine> samplers = React.instance.graphController.getG();
|
||||
|
||||
for (SampledType type : STORED_TYPES) {
|
||||
processType(samplers, type);
|
||||
}
|
||||
}
|
||||
|
||||
private void processType(GMap<SampledType, GraphSampleLine> samplers, SampledType type) {
|
||||
GMap<Long, Double> values = samplers.get(type).getPlotBoard().getBetween(M.ms() - 10000, M.ms());
|
||||
List<ReactValue> storedValues = history.getOrDefault(type, new ArrayList<>());
|
||||
values.entrySet().stream()
|
||||
.map(entry -> new ReactValue(type, entry.getKey(), entry.getValue()))
|
||||
.sorted()
|
||||
.forEachOrdered(storedValues::add);
|
||||
|
||||
if (storedValues.get(0).getDate() < System.currentTimeMillis() - TimeAmount.MINUTE.ms()) {
|
||||
Processing.submitNonCritical(new ValueStoringProcessor(table, type, storedValues));
|
||||
history.remove(type);
|
||||
} else {
|
||||
history.put(type, storedValues);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package com.djrapitops.pluginbridge.plan.react;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
||||
import com.djrapitops.plan.system.database.databases.sql.processing.ExecStatement;
|
||||
import com.djrapitops.plan.system.database.databases.sql.processing.QueryAllStatement;
|
||||
import com.djrapitops.plan.system.database.databases.sql.statements.Column;
|
||||
import com.djrapitops.plan.system.database.databases.sql.statements.Select;
|
||||
import com.djrapitops.plan.system.database.databases.sql.statements.Sql;
|
||||
import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser;
|
||||
import com.djrapitops.plan.system.database.databases.sql.tables.Table;
|
||||
import com.volmit.react.api.SampledType;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Database Table in charge of storing data from React.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ReactDataTable extends Table {
|
||||
|
||||
public static final String TABLE_NAME = "plan_react_data";
|
||||
|
||||
public ReactDataTable(SQLDB db) {
|
||||
super(TABLE_NAME, db);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTable() throws DBInitException {
|
||||
createTable(TableSqlParser.createTable(TABLE_NAME)
|
||||
.primaryKey(usingMySQL, Col.ID)
|
||||
.column(Col.DATE, Sql.LONG)
|
||||
.column(Col.SAMPLED_TYPE, Sql.varchar(30))
|
||||
.column(Col.MINUTE_AVERAGE, Sql.DOUBLE)
|
||||
.primaryKeyIDColumn(usingMySQL, Col.ID)
|
||||
.toString());
|
||||
}
|
||||
|
||||
public void addData(ReactValue value) throws SQLException {
|
||||
String sql = "INSERT INTO " + tableName + " (" +
|
||||
Col.SAMPLED_TYPE + ", " +
|
||||
Col.DATE + ", " +
|
||||
Col.MINUTE_AVERAGE +
|
||||
") VALUES (?, ?, ?)";
|
||||
|
||||
execute(new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, value.getType().name());
|
||||
statement.setLong(2, value.getDate());
|
||||
statement.setDouble(3, value.getDataValue());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Map<SampledType, List<ReactValue>> getAllData() throws SQLException {
|
||||
String sql = Select.all(tableName).toString();
|
||||
|
||||
return query(new QueryAllStatement<Map<SampledType, List<ReactValue>>>(sql, 50000) {
|
||||
@Override
|
||||
public Map<SampledType, List<ReactValue>> processResults(ResultSet set) throws SQLException {
|
||||
Map<SampledType, List<ReactValue>> results = new EnumMap<>(SampledType.class);
|
||||
while (set.next()) {
|
||||
try {
|
||||
SampledType type = SampledType.valueOf(set.getString(Col.SAMPLED_TYPE.get()));
|
||||
long date = set.getLong(Col.DATE.get());
|
||||
double average = set.getDouble(Col.MINUTE_AVERAGE.get());
|
||||
|
||||
ReactValue value = new ReactValue(type, date, average);
|
||||
|
||||
List<ReactValue> values = results.getOrDefault(type, new ArrayList<>());
|
||||
values.add(value);
|
||||
results.put(type, values);
|
||||
} catch (NoSuchFieldError ignore) {
|
||||
/* Ignored, field has been removed and is no longer supported */
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public enum Col implements Column {
|
||||
ID("id"),
|
||||
SAMPLED_TYPE("sampled_type"),
|
||||
DATE("date"),
|
||||
MINUTE_AVERAGE("minute_average");
|
||||
|
||||
private final String columnName;
|
||||
|
||||
Col(String columnName) {
|
||||
this.columnName = columnName;
|
||||
}
|
||||
|
||||
public String get() {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return columnName;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.djrapitops.pluginbridge.plan.react;
|
||||
|
||||
import com.djrapitops.plan.Plan;
|
||||
import com.djrapitops.plan.data.plugin.HookHandler;
|
||||
import com.djrapitops.pluginbridge.plan.Hook;
|
||||
|
||||
/**
|
||||
* Hook in charge for hooking into React.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ReactHook extends Hook {
|
||||
|
||||
public ReactHook(HookHandler hookHandler) {
|
||||
super("com.volmit.react.ReactPlugin", hookHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hook() throws NoClassDefFoundError {
|
||||
Plan plan = Plan.getInstance();
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.djrapitops.pluginbridge.plan.react;
|
||||
|
||||
import com.volmit.react.api.SampledType;
|
||||
|
||||
/**
|
||||
* Data container for React data points.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ReactValue implements Comparable<ReactValue> {
|
||||
|
||||
private final SampledType type;
|
||||
private final long date;
|
||||
private final double dataValue;
|
||||
|
||||
public ReactValue(SampledType type, long date, double dataValue) {
|
||||
this.type = type;
|
||||
this.date = date;
|
||||
this.dataValue = dataValue;
|
||||
}
|
||||
|
||||
public SampledType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public long getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public double getDataValue() {
|
||||
return dataValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ReactValue o) {
|
||||
return Long.compare(this.date, o.date);
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.djrapitops.pluginbridge.plan.react;
|
||||
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
import com.volmit.react.api.SampledType;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Processor in charge of turning values into single numbers.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ValueStoringProcessor implements Runnable {
|
||||
|
||||
private final ReactDataTable table;
|
||||
private final SampledType type;
|
||||
private final List<ReactValue> values;
|
||||
|
||||
public ValueStoringProcessor(ReactDataTable table, SampledType type, List<ReactValue> values) {
|
||||
this.table = table;
|
||||
this.type = type;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ReactValue average = avgValue(values);
|
||||
|
||||
if (average == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
table.addData(average);
|
||||
} catch (SQLException e) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private ReactValue avgValue(List<ReactValue> values) {
|
||||
if (values.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
long date = values.get(0).getDate();
|
||||
double average = values.stream().mapToDouble(ReactValue::getDataValue).average().orElse(0.0);
|
||||
|
||||
return new ReactValue(type, date, average);
|
||||
}
|
||||
}
|
@ -18,8 +18,6 @@ import us.myles.ViaVersion.api.ViaAPI;
|
||||
*/
|
||||
public class ViaVersionHook extends Hook {
|
||||
|
||||
private static PlayerVersionListener listener;
|
||||
|
||||
/**
|
||||
* Hooks the plugin and registers it's PluginData objects.
|
||||
* <p>
|
||||
|
Loading…
Reference in New Issue
Block a user