From 6c0da9e167d3aa7be893957982f167411faeddf4 Mon Sep 17 00:00:00 2001
From: Risto Lahtela <24460436+AuroraLS3@users.noreply.github.com>
Date: Sun, 21 Nov 2021 20:10:27 +0200
Subject: [PATCH] Added some data pipelines, not in use yet
---
.../bukkit/BukkitEventPipelineModule.java | 93 ++++++++++++++
.../java/com/djrapitops/plan/DataService.java | 18 ++-
.../java/com/djrapitops/plan/DataSvc.java | 21 +++-
.../exceptions/MissingPipelineException.java | 24 ++++
.../gathering/cache/JoinAddressCache.java | 59 +++++++++
.../plan/gathering/cache/SessionCache.java | 5 +
.../plan/gathering/domain/ActiveSession.java | 4 +-
.../plan/gathering/domain/PlayerMetadata.java | 114 ++++++++++++++++++
.../gathering/domain/event/JoinAddress.java | 36 ++++++
.../plan/gathering/domain/event/MobKill.java | 89 ++++++++++++++
.../gathering/domain/event/PlayerJoin.java | 78 ++++++------
.../gathering/domain/event/PlayerLeave.java | 91 ++++++++++++++
.../plan/modules/DataPipelineModule.java | 57 ++++++++-
.../events/SessionEndTransaction.java | 6 +
14 files changed, 651 insertions(+), 44 deletions(-)
create mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitEventPipelineModule.java
create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/exceptions/MissingPipelineException.java
create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/gathering/cache/JoinAddressCache.java
create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/PlayerMetadata.java
create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/JoinAddress.java
create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/MobKill.java
create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/PlayerLeave.java
diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitEventPipelineModule.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitEventPipelineModule.java
new file mode 100644
index 000000000..12759ff40
--- /dev/null
+++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitEventPipelineModule.java
@@ -0,0 +1,93 @@
+/*
+ * 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 .
+ */
+package com.djrapitops.plan.modules.bukkit;
+
+import com.djrapitops.plan.DataService;
+import com.djrapitops.plan.exceptions.MissingPipelineException;
+import com.djrapitops.plan.gathering.cache.JoinAddressCache;
+import com.djrapitops.plan.gathering.domain.PlayerMetadata;
+import com.djrapitops.plan.gathering.domain.event.JoinAddress;
+import com.djrapitops.plan.gathering.domain.event.PlayerJoin;
+import com.djrapitops.plan.gathering.domain.event.PlayerLeave;
+import com.djrapitops.plan.identification.ServerUUID;
+import dagger.Module;
+import dagger.Provides;
+import dagger.multibindings.IntoSet;
+import org.bukkit.GameMode;
+import org.bukkit.entity.Player;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+
+import javax.inject.Singleton;
+import java.net.InetSocketAddress;
+import java.util.Optional;
+import java.util.UUID;
+
+@Module
+public class BukkitEventPipelineModule {
+
+ @Provides
+ @Singleton
+ @IntoSet
+ DataService.Pipeline metadata(JoinAddressCache joinAddressCache) {
+ return service -> service
+ .registerMapper(UUID.class, Player.class, PlayerMetadata.class,
+ player -> getPlayerMetadata(player, service, joinAddressCache));
+ }
+
+ private PlayerMetadata getPlayerMetadata(Player player, DataService service, JoinAddressCache joinAddressCache) {
+ return PlayerMetadata.builder()
+ .playerName(player.getName())
+ .displayName(player.getDisplayName())
+ .world(player.getWorld().getName())
+ .gameMode(Optional.ofNullable(player.getGameMode()).map(GameMode::name).orElse(null))
+ .ipAddress(Optional.ofNullable(player.getAddress()).map(InetSocketAddress::getAddress).orElse(null))
+ .joinAddress(service.pullWithoutId(JoinAddress.class).map(JoinAddress::getAddress).orElse(null))
+ .build();
+ }
+
+ @Provides
+ @Singleton
+ @IntoSet
+ DataService.Pipeline events() {
+ return service -> service
+ .registerDataServiceMapper(UUID.class, PlayerJoinEvent.class, PlayerJoin.class, this::mapToPlayerJoin)
+ .registerDataServiceMapper(UUID.class, PlayerQuitEvent.class, PlayerLeave.class, this::mapToPlayerLeave);
+ }
+
+ private PlayerJoin mapToPlayerJoin(DataService service, PlayerJoinEvent event) {
+ UUID playerUUID = event.getPlayer().getUniqueId();
+ Optional metadata = service.map(playerUUID, event.getPlayer(), PlayerMetadata.class);
+ return PlayerJoin.builder()
+ .playerUUID(playerUUID)
+ .serverUUID(service.pullWithoutId(ServerUUID.class).orElseThrow(MissingPipelineException::new))
+ .playerMetadata(metadata.orElseThrow(MissingPipelineException::new))
+ .time(System.currentTimeMillis())
+ .build();
+ }
+
+ private PlayerLeave mapToPlayerLeave(DataService service, PlayerQuitEvent event) {
+ UUID playerUUID = event.getPlayer().getUniqueId();
+ Optional metadata = service.map(playerUUID, event.getPlayer(), PlayerMetadata.class);
+ return PlayerLeave.builder()
+ .playerUUID(playerUUID)
+ .serverUUID(service.pullWithoutId(ServerUUID.class).orElseThrow(MissingPipelineException::new))
+ .playerMetadata(metadata.orElseThrow(MissingPipelineException::new))
+ .time(System.currentTimeMillis())
+ .build();
+ }
+}
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/DataService.java b/Plan/common/src/main/java/com/djrapitops/plan/DataService.java
index d0f94875f..997579ec3 100644
--- a/Plan/common/src/main/java/com/djrapitops/plan/DataService.java
+++ b/Plan/common/src/main/java/com/djrapitops/plan/DataService.java
@@ -34,11 +34,19 @@ public interface DataService {
void push(K identifier, T value, Class type);
+ default DataService registerOptionalMapper(Class identifierType, Class from, Class to, BiFunction> mapper) {
+ return registerMapper(identifierType, from, to, (id, value) -> mapper.apply(id, value).orElse(null));
+ }
+
DataService registerMapper(Class identifierType, Class from, Class to, BiFunction mapper);
DataService registerMapper(Class identifierType, Class from, Class to, Function mapper);
- DataService registerMapper(Class fromIdentifier, Class from, Class toIdentifier, Class to, TriConsumer> mapper);
+ default DataService registerDataServiceMapper(Class identifierType, Class from, Class to, BiFunction mapper) {
+ return registerMapper(identifierType, from, to, value -> mapper.apply(this, value));
+ }
+
+ DataService registerMapper(Class fromIdentifier, Class from, Class toIdentifier, Class to, TriConsumer> mapper);
DataService registerSink(Class identifierType, Class type, BiConsumer consumer);
@@ -46,16 +54,22 @@ public interface DataService {
Optional pull(Class type, K identifier);
- Optional pull(Class type);
+ Optional pullWithoutId(Class type);
DataService registerPullSource(Class identifierType, Class type, Function source);
+ default DataService registerOptionalPullSource(Class identifierType, Class type, Function> source) {
+ return registerPullSource(identifierType, type, id -> source.apply(id).orElse(null));
+ }
+
DataService registerDatabasePullSource(Class identifierType, Class type, Function> source);
DataService registerPullSource(Class type, Supplier source);
DataService registerDatabasePullSource(Class type, Supplier> source);
+ Optional map(K identifier, A value, Class toType);
+
interface Pipeline {
void register(DataService service);
}
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/DataSvc.java b/Plan/common/src/main/java/com/djrapitops/plan/DataSvc.java
index 916d2b62b..16b921a57 100644
--- a/Plan/common/src/main/java/com/djrapitops/plan/DataSvc.java
+++ b/Plan/common/src/main/java/com/djrapitops/plan/DataSvc.java
@@ -62,11 +62,22 @@ public class DataSvc implements DataService {
}
for (Mapper mapper : mappers.get(classPair)) {
- Class convertingTo = mapper.typeB;
- push(identifier, mapper.func.apply(identifier, value), convertingTo);
+ push(identifier, mapper.func.apply(identifier, value), mapper.typeB);
}
}
+ @Override
+ public Optional map(K identifier, A value, Class toType) {
+ ClassPair classPair = new ClassPair<>((Class) identifier.getClass(), (Class) value.getClass());
+
+ List candidates = this.mappers.get(classPair);
+ return candidates
+ .stream()
+ .filter(mapper -> Objects.equals(mapper.typeB, toType))
+ .findAny()
+ .map(mapper -> toType.cast(mapper.func.apply(identifier, value)));
+ }
+
@Override
public DataService registerMapper(Class identifierType, Class from, Class to, BiFunction mapper) {
ClassPair classPair = new ClassPair<>(identifierType, from);
@@ -80,8 +91,8 @@ public class DataSvc implements DataService {
}
@Override
- public DataService registerMapper(Class fromIdentifier, Class from, Class toIdentifier, Class to, TriConsumer> mapper) {
- ClassPair classPair = new ClassPair<>(fromIdentifier, from);
+ public DataService registerMapper(Class fromIdentifier, Class from, Class toIdentifier, Class to, TriConsumer> mapper) {
+ ClassPair classPair = new ClassPair<>(fromIdentifier, from);
sinks.putOne(classPair, (id, value) -> mapper.accept(fromIdentifier.cast(id), from.cast(value), this::push));
return this;
}
@@ -107,7 +118,7 @@ public class DataSvc implements DataService {
}
@Override
- public Optional pull(Class type) {
+ public Optional pullWithoutId(Class type) {
return Optional.ofNullable(noIdentifierPullSources.get(type))
.map(Supplier::get)
.map(type::cast);
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/exceptions/MissingPipelineException.java b/Plan/common/src/main/java/com/djrapitops/plan/exceptions/MissingPipelineException.java
new file mode 100644
index 000000000..9f3728b10
--- /dev/null
+++ b/Plan/common/src/main/java/com/djrapitops/plan/exceptions/MissingPipelineException.java
@@ -0,0 +1,24 @@
+/*
+ * 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 .
+ */
+package com.djrapitops.plan.exceptions;
+
+public class MissingPipelineException extends IllegalStateException {
+
+ public MissingPipelineException() {
+ super("A data service pipeline is missing!");
+ }
+}
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/cache/JoinAddressCache.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/cache/JoinAddressCache.java
new file mode 100644
index 000000000..e5b74b27d
--- /dev/null
+++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/cache/JoinAddressCache.java
@@ -0,0 +1,59 @@
+/*
+ * 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 .
+ */
+package com.djrapitops.plan.gathering.cache;
+
+import com.djrapitops.plan.gathering.domain.event.JoinAddress;
+import com.djrapitops.plan.gathering.domain.event.PlayerLeave;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+
+@Singleton
+public class JoinAddressCache {
+
+ private final Map joinAddresses;
+
+ @Inject
+ public JoinAddressCache() {
+ joinAddresses = new HashMap<>();
+ }
+
+ public void put(UUID playerUUID, JoinAddress joinAddress) {
+ put(playerUUID, joinAddress.getAddress());
+ }
+
+ public void put(UUID playerUUID, String joinAddress) {
+ joinAddresses.put(playerUUID, joinAddress);
+ }
+
+ public Optional get(UUID playerUUID) {
+ return Optional.ofNullable(joinAddresses.get(playerUUID))
+ .map(JoinAddress::new);
+ }
+
+ public void remove(UUID playerUUID, PlayerLeave leave) {
+ remove(playerUUID);
+ }
+
+ public void remove(UUID playerUUID) {
+ joinAddresses.remove(playerUUID);
+ }
+}
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/cache/SessionCache.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/cache/SessionCache.java
index d9afef3a2..600d90ca1 100644
--- a/Plan/common/src/main/java/com/djrapitops/plan/gathering/cache/SessionCache.java
+++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/cache/SessionCache.java
@@ -18,6 +18,7 @@ package com.djrapitops.plan.gathering.cache;
import com.djrapitops.plan.gathering.domain.ActiveSession;
import com.djrapitops.plan.gathering.domain.FinishedSession;
+import com.djrapitops.plan.gathering.domain.event.PlayerLeave;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -97,6 +98,10 @@ public class SessionCache {
return Optional.of(activeSession.toFinishedSession(time));
}
+ public Optional endSession(UUID playerUUID, PlayerLeave leave) {
+ return endSession(playerUUID, leave.getTime());
+ }
+
public Optional endSession(UUID playerUUID, long time) {
return endSession(playerUUID, time, ACTIVE_SESSIONS.get(playerUUID));
}
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/ActiveSession.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/ActiveSession.java
index fc3fa4485..c45c3ec29 100644
--- a/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/ActiveSession.java
+++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/ActiveSession.java
@@ -46,7 +46,9 @@ public class ActiveSession {
}
public static ActiveSession fromPlayerJoin(PlayerJoin join) {
- return new ActiveSession(join.getPlayerUUID(), join.getServerUUID(), join.getTime(), join.getWorld(), join.getGameMode());
+ return new ActiveSession(join.getPlayerUUID(), join.getServerUUID(), join.getTime(),
+ join.getPlayerMetadata().getWorld().orElse("Unspecified"),
+ join.getPlayerMetadata().getGameMode().orElse("Unknown"));
}
public FinishedSession toFinishedSessionFromStillActive() {
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/PlayerMetadata.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/PlayerMetadata.java
new file mode 100644
index 000000000..5a68173f0
--- /dev/null
+++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/PlayerMetadata.java
@@ -0,0 +1,114 @@
+/*
+ * 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 .
+ */
+package com.djrapitops.plan.gathering.domain;
+
+import java.net.InetAddress;
+import java.util.Optional;
+
+public class PlayerMetadata {
+
+ private final String playerName;
+ private final String displayName;
+
+ private final String joinAddress;
+ private final InetAddress ipAddress;
+
+ private final String world;
+ private final String gameMode;
+
+ public PlayerMetadata(String playerName, String displayName, String joinAddress, InetAddress ipAddress, String world, String gameMode) {
+ this.playerName = playerName;
+ this.displayName = displayName;
+ this.joinAddress = joinAddress;
+ this.ipAddress = ipAddress;
+ this.world = world;
+ this.gameMode = gameMode;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public String getPlayerName() {
+ return playerName;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public Optional getJoinAddress() {
+ return Optional.ofNullable(joinAddress);
+ }
+
+ public Optional getIpAddress() {
+ return Optional.ofNullable(ipAddress);
+ }
+
+ public Optional getWorld() {
+ return Optional.ofNullable(world);
+ }
+
+ public Optional getGameMode() {
+ return Optional.ofNullable(gameMode);
+ }
+
+ public static final class Builder {
+ private String playerName;
+ private String displayName;
+ private String joinAddress;
+ private InetAddress ipAddress;
+ private String world;
+ private String gameMode;
+
+ private Builder() {}
+
+ public static Builder aPlayerMetadata() {return new Builder();}
+
+ public Builder playerName(String playerName) {
+ this.playerName = playerName;
+ return this;
+ }
+
+ public Builder displayName(String displayName) {
+ this.displayName = displayName;
+ return this;
+ }
+
+ public Builder joinAddress(String joinAddress) {
+ this.joinAddress = joinAddress;
+ return this;
+ }
+
+ public Builder ipAddress(InetAddress ipAddress) {
+ this.ipAddress = ipAddress;
+ return this;
+ }
+
+ public Builder world(String world) {
+ this.world = world;
+ return this;
+ }
+
+ public Builder gameMode(String gameMode) {
+ this.gameMode = gameMode;
+ return this;
+ }
+
+ public PlayerMetadata build() {return new PlayerMetadata(playerName, displayName, joinAddress, ipAddress, world, gameMode);}
+ }
+}
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/JoinAddress.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/JoinAddress.java
new file mode 100644
index 000000000..15f5509b6
--- /dev/null
+++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/JoinAddress.java
@@ -0,0 +1,36 @@
+/*
+ * 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 .
+ */
+package com.djrapitops.plan.gathering.domain.event;
+
+public class JoinAddress {
+ private final String address;
+
+ public JoinAddress(String address) {
+ this.address = address;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ @Override
+ public String toString() {
+ return "JoinAddress{" +
+ "address='" + address + '\'' +
+ '}';
+ }
+}
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/MobKill.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/MobKill.java
new file mode 100644
index 000000000..7ebe21f6f
--- /dev/null
+++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/MobKill.java
@@ -0,0 +1,89 @@
+/*
+ * 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 .
+ */
+package com.djrapitops.plan.gathering.domain.event;
+
+import com.djrapitops.plan.gathering.domain.PlayerMetadata;
+
+import java.util.UUID;
+
+public class MobKill {
+ private final UUID playerUUID;
+ private final PlayerMetadata playerMetadata;
+ private final String mobType;
+ private final long time;
+
+ public MobKill(UUID playerUUID, PlayerMetadata playerMetadata, String mobType, long time) {
+ this.playerUUID = playerUUID;
+ this.playerMetadata = playerMetadata;
+ this.mobType = mobType;
+ this.time = time;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public UUID getPlayerUUID() {
+ return playerUUID;
+ }
+
+ public PlayerMetadata getPlayerMetadata() {
+ return playerMetadata;
+ }
+
+ public String getMobType() {
+ return mobType;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+
+ public static final class Builder {
+ private UUID playerUUID;
+ private PlayerMetadata playerMetadata;
+ private String mobType;
+ private long time;
+
+ private Builder() {}
+
+ public static Builder aMobKill() {return new Builder();}
+
+ public Builder playerUUID(UUID playerUUID) {
+ this.playerUUID = playerUUID;
+ return this;
+ }
+
+ public Builder playerMetadata(PlayerMetadata playerMetadata) {
+ this.playerMetadata = playerMetadata;
+ return this;
+ }
+
+ public Builder mobType(String mobType) {
+ this.mobType = mobType;
+ return this;
+ }
+
+ public Builder time(long time) {
+ this.time = time;
+ return this;
+ }
+
+ public MobKill build() {return new MobKill(playerUUID, playerMetadata, mobType, time);}
+ }
+}
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/PlayerJoin.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/PlayerJoin.java
index f86e37b9a..ecfa4bee6 100644
--- a/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/PlayerJoin.java
+++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/PlayerJoin.java
@@ -16,68 +16,76 @@
*/
package com.djrapitops.plan.gathering.domain.event;
+import com.djrapitops.plan.gathering.domain.PlayerMetadata;
import com.djrapitops.plan.identification.ServerUUID;
-import java.net.InetAddress;
import java.util.UUID;
public class PlayerJoin {
private final UUID playerUUID;
- private final String playerName;
- private final String displayName;
- private final InetAddress ipAddress;
-
private final ServerUUID serverUUID;
- private final String world;
- private final String gameMode;
+ private final PlayerMetadata playerMetadata;
private final long time;
- public PlayerJoin(
- UUID playerUUID, String playerName, String displayName, InetAddress ipAddress,
- ServerUUID serverUUID, String world, String gameMode,
- long time
- ) {
+ public PlayerJoin(UUID playerUUID, ServerUUID serverUUID, PlayerMetadata playerMetadata, long time) {
this.playerUUID = playerUUID;
- this.playerName = playerName;
- this.displayName = displayName;
- this.ipAddress = ipAddress;
this.serverUUID = serverUUID;
- this.world = world;
- this.gameMode = gameMode;
+ this.playerMetadata = playerMetadata;
this.time = time;
}
+ public static Builder builder() {
+ return new Builder();
+ }
+
public UUID getPlayerUUID() {
return playerUUID;
}
- public String getPlayerName() {
- return playerName;
- }
-
- public String getDisplayName() {
- return displayName;
- }
-
- public InetAddress getIpAddress() {
- return ipAddress;
- }
-
public ServerUUID getServerUUID() {
return serverUUID;
}
- public String getWorld() {
- return world;
- }
-
- public String getGameMode() {
- return gameMode;
+ public PlayerMetadata getPlayerMetadata() {
+ return playerMetadata;
}
public long getTime() {
return time;
}
+
+ public static final class Builder {
+ private UUID playerUUID;
+ private ServerUUID serverUUID;
+ private PlayerMetadata playerMetadata;
+ private long time;
+
+ private Builder() {}
+
+ public static Builder aPlayerJoin() {return new Builder();}
+
+ public Builder playerUUID(UUID playerUUID) {
+ this.playerUUID = playerUUID;
+ return this;
+ }
+
+ public Builder serverUUID(ServerUUID serverUUID) {
+ this.serverUUID = serverUUID;
+ return this;
+ }
+
+ public Builder playerMetadata(PlayerMetadata playerMetadata) {
+ this.playerMetadata = playerMetadata;
+ return this;
+ }
+
+ public Builder time(long time) {
+ this.time = time;
+ return this;
+ }
+
+ public PlayerJoin build() {return new PlayerJoin(playerUUID, serverUUID, playerMetadata, time);}
+ }
}
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/PlayerLeave.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/PlayerLeave.java
new file mode 100644
index 000000000..afa570e36
--- /dev/null
+++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/domain/event/PlayerLeave.java
@@ -0,0 +1,91 @@
+/*
+ * 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 .
+ */
+package com.djrapitops.plan.gathering.domain.event;
+
+import com.djrapitops.plan.gathering.domain.PlayerMetadata;
+import com.djrapitops.plan.identification.ServerUUID;
+
+import java.util.UUID;
+
+public class PlayerLeave {
+
+ private final UUID playerUUID;
+ private final ServerUUID serverUUID;
+ private final PlayerMetadata playerMetadata;
+
+ private final long time;
+
+ public PlayerLeave(UUID playerUUID, ServerUUID serverUUID, PlayerMetadata playerMetadata, long time) {
+ this.playerUUID = playerUUID;
+ this.serverUUID = serverUUID;
+ this.playerMetadata = playerMetadata;
+ this.time = time;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public UUID getPlayerUUID() {
+ return playerUUID;
+ }
+
+ public ServerUUID getServerUUID() {
+ return serverUUID;
+ }
+
+ public PlayerMetadata getPlayerMetadata() {
+ return playerMetadata;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ public static final class Builder {
+ private UUID playerUUID;
+ private ServerUUID serverUUID;
+ private PlayerMetadata playerMetadata;
+ private long time;
+
+ private Builder() {}
+
+ public static Builder aPlayerLeave() {return new Builder();}
+
+ public Builder playerUUID(UUID playerUUID) {
+ this.playerUUID = playerUUID;
+ return this;
+ }
+
+ public Builder serverUUID(ServerUUID serverUUID) {
+ this.serverUUID = serverUUID;
+ return this;
+ }
+
+ public Builder playerMetadata(PlayerMetadata playerMetadata) {
+ this.playerMetadata = playerMetadata;
+ return this;
+ }
+
+ public Builder time(long time) {
+ this.time = time;
+ return this;
+ }
+
+ public PlayerLeave build() {return new PlayerLeave(playerUUID, serverUUID, playerMetadata, time);}
+ }
+}
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/modules/DataPipelineModule.java b/Plan/common/src/main/java/com/djrapitops/plan/modules/DataPipelineModule.java
index 92ed1062a..82d8587fc 100644
--- a/Plan/common/src/main/java/com/djrapitops/plan/modules/DataPipelineModule.java
+++ b/Plan/common/src/main/java/com/djrapitops/plan/modules/DataPipelineModule.java
@@ -17,9 +17,14 @@
package com.djrapitops.plan.modules;
import com.djrapitops.plan.DataService;
+import com.djrapitops.plan.gathering.cache.JoinAddressCache;
import com.djrapitops.plan.gathering.cache.SessionCache;
-import com.djrapitops.plan.gathering.domain.ActiveSession;
+import com.djrapitops.plan.gathering.domain.*;
+import com.djrapitops.plan.gathering.domain.event.JoinAddress;
+import com.djrapitops.plan.gathering.domain.event.MobKill;
import com.djrapitops.plan.gathering.domain.event.PlayerJoin;
+import com.djrapitops.plan.gathering.domain.event.PlayerLeave;
+import com.djrapitops.plan.storage.database.transactions.events.SessionEndTransaction;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoSet;
@@ -39,4 +44,54 @@ public class DataPipelineModule {
.registerSink(UUID.class, ActiveSession.class, sessionCache::cacheSession);
}
+ @Provides
+ @Singleton
+ @IntoSet
+ DataService.Pipeline joinAddress(JoinAddressCache joinAddressCache) {
+ return service -> service
+ .registerSink(UUID.class, JoinAddress.class, joinAddressCache::put)
+ .registerOptionalPullSource(UUID.class, JoinAddress.class, joinAddressCache::get)
+ .registerSink(UUID.class, PlayerLeave.class, joinAddressCache::remove);
+ }
+
+ @Provides
+ @Singleton
+ @IntoSet
+ DataService.Pipeline duringSession() {
+ return service -> service
+ .registerOptionalPullSource(UUID.class, ActiveSession.class, SessionCache::getCachedSession)
+ .registerOptionalPullSource(UUID.class, WorldTimes.class, uuid ->
+ service.pull(ActiveSession.class, uuid)
+ .map(ActiveSession::getExtraData)
+ .flatMap(extra -> extra.get(WorldTimes.class)))
+ .registerOptionalPullSource(UUID.class, MobKillCounter.class, uuid ->
+ service.pull(ActiveSession.class, uuid)
+ .map(ActiveSession::getExtraData)
+ .flatMap(extra -> extra.get(MobKillCounter.class)))
+ .registerOptionalPullSource(UUID.class, DeathCounter.class, uuid ->
+ service.pull(ActiveSession.class, uuid)
+ .map(ActiveSession::getExtraData)
+ .flatMap(extra -> extra.get(DeathCounter.class)))
+ .registerOptionalPullSource(UUID.class, PlayerKills.class, uuid ->
+ service.pull(ActiveSession.class, uuid)
+ .map(ActiveSession::getExtraData)
+ .flatMap(extra -> extra.get(PlayerKills.class)))
+ .registerSink(UUID.class, MobKill.class, (uuid, kill) -> {
+ service.pull(MobKillCounter.class, uuid).ifPresent(Counter::add);
+ })
+ .registerSink(UUID.class, PlayerKill.class, (uuid, kill) -> {
+ service.pull(PlayerKills.class, kill.getKiller().getUuid()).ifPresent(playerKills -> playerKills.add(kill));
+ service.pull(DeathCounter.class, kill.getVictim().getUuid()).ifPresent(Counter::add);
+ });
+ }
+
+ @Provides
+ @Singleton
+ @IntoSet
+ DataService.Pipeline playerLeaveToSession(SessionCache sessionCache) {
+ return service -> service
+ .registerOptionalMapper(UUID.class, PlayerLeave.class, FinishedSession.class, sessionCache::endSession)
+ .registerDatabaseSink(UUID.class, FinishedSession.class, SessionEndTransaction::new);
+ }
+
}
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/events/SessionEndTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/events/SessionEndTransaction.java
index ab80cc47e..62d81253d 100644
--- a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/events/SessionEndTransaction.java
+++ b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/events/SessionEndTransaction.java
@@ -20,6 +20,8 @@ import com.djrapitops.plan.gathering.domain.FinishedSession;
import com.djrapitops.plan.storage.database.queries.DataStoreQueries;
import com.djrapitops.plan.storage.database.transactions.Transaction;
+import java.util.UUID;
+
/**
* Transaction for storing a session after a session has ended.
*
@@ -29,6 +31,10 @@ public class SessionEndTransaction extends Transaction {
private final FinishedSession session;
+ public SessionEndTransaction(UUID playerUUID, FinishedSession session) {
+ this(session);
+ }
+
public SessionEndTransaction(FinishedSession session) {
this.session = session;
}