Skip to content

Commit 8fe1805

Browse files
committed
Add support for PLAYER_PERIODICAL update in DataExtensions
Affects issues: - #4410
1 parent 9c663ea commit 8fe1805

11 files changed

Lines changed: 654 additions & 482 deletions

File tree

Plan/api/src/main/java/com/djrapitops/plan/extension/CallEvents.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ public enum CallEvents {
3737
* Method calls are asynchronous.
3838
*/
3939
PLAYER_JOIN,
40+
/**
41+
* This event represents call to player methods while player is online.
42+
* <p>
43+
* The call is made periodically from an async task.
44+
*/
45+
PLAYER_PERIODICAL,
4046
/**
4147
* This event represents a call to player methods on a Player Leave event.
4248
* <p>

Plan/common/src/main/java/com/djrapitops/plan/extension/ExtensionServerDataUpdater.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public void run() {
5353

5454
@Override
5555
public void register(RunnableFactory runnableFactory) {
56-
long period = TimeAmount.toTicks(config.get(TimeSettings.EXTENSION_DATA_REFRESH_PERIOD), TimeUnit.MILLISECONDS);
56+
long period = TimeAmount.toTicks(config.get(TimeSettings.EXTENSION_SERVER_DATA_REFRESH_PERIOD), TimeUnit.MILLISECONDS);
5757
long delay = TimeAmount.toTicks(30, TimeUnit.SECONDS);
5858
runnableFactory.create(this).runTaskTimerAsynchronously(delay, period);
5959
}

Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/Parameters.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ public UUID getPlayerUUID() {
9090
return playerUUID;
9191
}
9292

93+
public String getPlayerName() {
94+
return playerName;
95+
}
96+
9397
@Override
9498
public Object usingOn(DataExtension extension, Method method) throws InvocationTargetException, IllegalAccessException {
9599
Class<?> parameterType = method.getParameterTypes()[0];
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* This file is part of Player Analytics (Plan).
3+
*
4+
* Plan is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Lesser General Public License v3 as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* Plan is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public License
15+
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
package com.djrapitops.plan.gathering;
18+
19+
import com.djrapitops.plan.TaskSystem;
20+
import com.djrapitops.plan.utilities.java.Lists;
21+
22+
import javax.inject.Singleton;
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.UUID;
26+
import java.util.concurrent.ConcurrentHashMap;
27+
28+
/**
29+
* Holds reference to all player specific gathering tasks that should be cancelled on player logout.
30+
*
31+
* @author AuroraLS3
32+
*/
33+
@Singleton
34+
public class PlayerGatheringTasks {
35+
36+
private final Map<UUID, List<TaskSystem.Task>> tasks;
37+
38+
public PlayerGatheringTasks() {
39+
tasks = new ConcurrentHashMap<>();
40+
}
41+
42+
public void register(UUID playerUUID, TaskSystem.Task task) {
43+
tasks.computeIfAbsent(playerUUID, Lists::create).add(task);
44+
}
45+
46+
public void unregister(UUID playerUUID) {
47+
List<TaskSystem.Task> registered = tasks.get(playerUUID);
48+
tasks.remove(playerUUID);
49+
if (registered != null) {
50+
registered.forEach(TaskSystem.Task::cancel);
51+
registered.clear();
52+
}
53+
}
54+
}

Plan/common/src/main/java/com/djrapitops/plan/gathering/events/PlayerJoinEventConsumer.java

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.djrapitops.plan.delivery.export.Exporter;
2323
import com.djrapitops.plan.extension.CallEvents;
2424
import com.djrapitops.plan.extension.ExtensionSvc;
25+
import com.djrapitops.plan.extension.implementation.providers.Parameters;
2526
import com.djrapitops.plan.gathering.JoinAddressValidator;
2627
import com.djrapitops.plan.gathering.cache.NicknameCache;
2728
import com.djrapitops.plan.gathering.cache.SessionCache;
@@ -30,6 +31,7 @@
3031
import com.djrapitops.plan.gathering.domain.event.JoinAddress;
3132
import com.djrapitops.plan.gathering.domain.event.PlayerJoin;
3233
import com.djrapitops.plan.gathering.geolocation.GeolocationCache;
34+
import com.djrapitops.plan.gathering.timed.PlayerExtensionDataUpdateTask;
3335
import com.djrapitops.plan.identification.ServerUUID;
3436
import com.djrapitops.plan.processing.Processing;
3537
import com.djrapitops.plan.settings.config.PlanConfig;
@@ -59,6 +61,7 @@ public class PlayerJoinEventConsumer {
5961

6062
private final ExtensionSvc extensionService;
6163
private final Exporter exporter;
64+
private final PlayerExtensionDataUpdateTask.Factory playerExtensionUpdateTaskFactory;
6265

6366
@Inject
6467
public PlayerJoinEventConsumer(
@@ -69,7 +72,8 @@ public PlayerJoinEventConsumer(
6972
SessionCache sessionCache,
7073
NicknameCache nicknameCache,
7174
ExtensionSvc extensionService,
72-
Exporter exporter
75+
Exporter exporter,
76+
PlayerExtensionDataUpdateTask.Factory playerExtensionUpdateTaskFactory
7377
) {
7478
this.processing = processing;
7579
this.config = config;
@@ -80,6 +84,16 @@ public PlayerJoinEventConsumer(
8084
this.nicknameCache = nicknameCache;
8185
this.extensionService = extensionService;
8286
this.exporter = exporter;
87+
this.playerExtensionUpdateTaskFactory = playerExtensionUpdateTaskFactory;
88+
}
89+
90+
private static long getRegisterDate(PlayerJoin join) {
91+
long registerDate = join.getPlayer().getRegisterDate().orElseGet(join::getTime);
92+
// Correct incorrect register dates https://github.com/plan-player-analytics/Plan/issues/2934
93+
if (registerDate < System.currentTimeMillis() / 1000) {
94+
registerDate = registerDate * 1000;
95+
}
96+
return registerDate;
8397
}
8498

8599
public void onJoinGameServer(PlayerJoin join) {
@@ -95,10 +109,15 @@ public void onJoinGameServer(PlayerJoin join) {
95109
storeNickname(join);
96110
updatePlayerDataExtensionValues(join);
97111
updateExport(join);
112+
registerExtensionUpdateTask(join);
98113
}, processing.getCriticalExecutor());
99114
});
100115
}
101116

117+
private void registerExtensionUpdateTask(PlayerJoin join) {
118+
playerExtensionUpdateTaskFactory.register(Parameters.player(join.getServer().getUuid(), join.getPlayerUUID(), join.getPlayer().getName()));
119+
}
120+
102121
public void onJoinProxyServer(PlayerJoin join) {
103122
cacheActiveSession(join);
104123
processing.submitCritical(() -> storeProxyPlayer(join)
@@ -133,15 +152,6 @@ private void storeWorldInformation(PlayerJoin join) {
133152
.ifPresent(dbSystem.getDatabase()::executeTransaction);
134153
}
135154

136-
private static long getRegisterDate(PlayerJoin join) {
137-
long registerDate = join.getPlayer().getRegisterDate().orElseGet(join::getTime);
138-
// Correct incorrect register dates https://github.com/plan-player-analytics/Plan/issues/2934
139-
if (registerDate < System.currentTimeMillis() / 1000) {
140-
registerDate = registerDate * 1000;
141-
}
142-
return registerDate;
143-
}
144-
145155
private CompletableFuture<?> storeGamePlayer(PlayerJoin join) {
146156
long registerDate = getRegisterDate(join);
147157
String joinAddress = join.getPlayer().getJoinAddress()

Plan/common/src/main/java/com/djrapitops/plan/gathering/events/PlayerLeaveEventConsumer.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.djrapitops.plan.delivery.export.Exporter;
2020
import com.djrapitops.plan.extension.CallEvents;
2121
import com.djrapitops.plan.extension.ExtensionSvc;
22+
import com.djrapitops.plan.gathering.PlayerGatheringTasks;
2223
import com.djrapitops.plan.gathering.cache.JoinAddressCache;
2324
import com.djrapitops.plan.gathering.cache.NicknameCache;
2425
import com.djrapitops.plan.gathering.cache.SessionCache;
@@ -50,9 +51,10 @@ public class PlayerLeaveEventConsumer {
5051

5152
private final ExtensionSvc extensionService;
5253
private final Exporter exporter;
54+
private final PlayerGatheringTasks playerGatheringTasks;
5355

5456
@Inject
55-
public PlayerLeaveEventConsumer(Processing processing, PlanConfig config, DBSystem dbSystem, JoinAddressCache joinAddressCache, NicknameCache nicknameCache, SessionCache sessionCache, ExtensionSvc extensionService, Exporter exporter) {
57+
public PlayerLeaveEventConsumer(Processing processing, PlanConfig config, DBSystem dbSystem, JoinAddressCache joinAddressCache, NicknameCache nicknameCache, SessionCache sessionCache, ExtensionSvc extensionService, Exporter exporter, PlayerGatheringTasks playerGatheringTasks) {
5658
this.processing = processing;
5759
this.config = config;
5860
this.dbSystem = dbSystem;
@@ -61,6 +63,7 @@ public PlayerLeaveEventConsumer(Processing processing, PlanConfig config, DBSyst
6163
this.sessionCache = sessionCache;
6264
this.extensionService = extensionService;
6365
this.exporter = exporter;
66+
this.playerGatheringTasks = playerGatheringTasks;
6467
}
6568

6669
public void beforeLeave(PlayerLeave leave) {
@@ -121,5 +124,6 @@ private void cleanFromCache(PlayerLeave leave) {
121124
UUID playerUUID = leave.getPlayerUUID();
122125
nicknameCache.removeDisplayName(playerUUID);
123126
joinAddressCache.remove(playerUUID);
127+
playerGatheringTasks.unregister(playerUUID);
124128
}
125129
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* This file is part of Player Analytics (Plan).
3+
*
4+
* Plan is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Lesser General Public License v3 as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* Plan is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public License
15+
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
package com.djrapitops.plan.gathering.timed;
18+
19+
import com.djrapitops.plan.TaskSystem;
20+
import com.djrapitops.plan.extension.CallEvents;
21+
import com.djrapitops.plan.extension.ExtensionSvc;
22+
import com.djrapitops.plan.extension.implementation.providers.Parameters;
23+
import com.djrapitops.plan.gathering.PlayerGatheringTasks;
24+
import com.djrapitops.plan.settings.config.PlanConfig;
25+
import com.djrapitops.plan.settings.config.paths.TimeSettings;
26+
import net.playeranalytics.plugin.scheduling.RunnableFactory;
27+
28+
import javax.inject.Inject;
29+
import javax.inject.Singleton;
30+
import java.util.concurrent.TimeUnit;
31+
32+
/**
33+
* Updates player values periodically.
34+
*
35+
* @author AuroraLS3
36+
*/
37+
public class PlayerExtensionDataUpdateTask extends TaskSystem.Task {
38+
39+
private final PlanConfig config;
40+
private final PlayerGatheringTasks playerGatheringTasks;
41+
private final ExtensionSvc extensionService;
42+
private final Parameters.PlayerParameters parameters;
43+
44+
public PlayerExtensionDataUpdateTask(PlanConfig config, PlayerGatheringTasks playerGatheringTasks, ExtensionSvc extensionService, Parameters.PlayerParameters parameters) {
45+
this.config = config;
46+
this.playerGatheringTasks = playerGatheringTasks;
47+
this.extensionService = extensionService;
48+
this.parameters = parameters;
49+
}
50+
51+
@Override
52+
public void register(RunnableFactory runnableFactory) {
53+
Long refreshPeriod = config.get(TimeSettings.EXTENSION_PLAYER_DATA_REFRESH_PERIOD);
54+
runnableFactory.create(this)
55+
.runTaskTimerAsynchronously(refreshPeriod, refreshPeriod, TimeUnit.MILLISECONDS);
56+
playerGatheringTasks.register(parameters.getPlayerUUID(), this);
57+
}
58+
59+
@Override
60+
public void run() {
61+
extensionService.updatePlayerValues(parameters.getPlayerUUID(), parameters.getPlayerName(), CallEvents.PLAYER_PERIODICAL);
62+
}
63+
64+
@Singleton
65+
public static class Factory {
66+
private final PlanConfig config;
67+
private final PlayerGatheringTasks playerGatheringTasks;
68+
private final RunnableFactory runnableFactory;
69+
private final ExtensionSvc extensionService;
70+
71+
@Inject
72+
public Factory(PlanConfig config, PlayerGatheringTasks playerGatheringTasks, RunnableFactory runnableFactory, ExtensionSvc extensionService) {
73+
this.config = config;
74+
this.playerGatheringTasks = playerGatheringTasks;
75+
this.runnableFactory = runnableFactory;
76+
this.extensionService = extensionService;
77+
}
78+
79+
public void register(Parameters playerParameters) {
80+
new PlayerExtensionDataUpdateTask(config, playerGatheringTasks, extensionService, (Parameters.PlayerParameters) playerParameters)
81+
.register(runnableFactory);
82+
}
83+
}
84+
85+
}

Plan/common/src/main/java/com/djrapitops/plan/settings/config/changes/ConfigUpdater.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ ConfigChange[] configEnhancementPatch() {
180180

181181
new ConfigChange.Moved("Data_gathering.Preserve_join_address_case", "Data_gathering.Join_addresses.Preserve_case"),
182182
new ConfigChange.Moved("Data_gathering.Preserve_invalid_join_addresses", "Data_gathering.Join_addresses.Preserve_invalid"),
183+
184+
new ConfigChange.Moved("Time.Periodic_tasks.Extension_data_refresh_every", "Time.Periodic_tasks.Extension_server_data_refresh_every")
183185
};
184186
}
185187

Plan/common/src/main/java/com/djrapitops/plan/settings/config/paths/TimeSettings.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ public class TimeSettings {
3535
public static final Setting<Long> DELETE_TPS_DATA_AFTER = new TimeSetting("Time.Thresholds.Remove_time_series_data_after");
3636
public static final Setting<Long> DELETE_PING_DATA_AFTER = new TimeSetting("Time.Thresholds.Remove_ping_data_after");
3737
public static final Setting<Long> DELETE_EXTENSION_DATA_AFTER = new TimeSetting("Time.Thresholds.Remove_disabled_extension_data_after");
38-
public static final Setting<Long> EXTENSION_DATA_REFRESH_PERIOD = new TimeSetting("Time.Periodic_tasks.Extension_data_refresh_every");
38+
public static final Setting<Long> EXTENSION_SERVER_DATA_REFRESH_PERIOD = new TimeSetting("Time.Periodic_tasks.Extension_server_data_refresh_every");
39+
public static final Setting<Long> EXTENSION_PLAYER_DATA_REFRESH_PERIOD = new TimeSetting("Time.Periodic_tasks.Extension_player_data_refresh_every");
3940
public static final Setting<Long> CLEAN_DATABASE_PERIOD = new TimeSetting("Time.Periodic_tasks.Clean_Database_every");
4041
public static final Setting<Long> CONFIG_UPDATE_INTERVAL = new TimeSetting("Time.Periodic_tasks.Check_DB_for_server_config_files_every");
4142

0 commit comments

Comments
 (0)