Skip to content

Commit 985ebfb

Browse files
committed
Add PLAYERS_ONLINE datapoint
1 parent 51dac0a commit 985ebfb

9 files changed

Lines changed: 126 additions & 4 deletions

File tree

Plan/common/src/main/java/com/djrapitops/plan/delivery/domain/auth/WebPermission.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ public enum WebPermission implements Supplier<String>, Lang {
158158
DATA_NETWORK_PLAYTIME_PER_PLAYER_AVERAGE("See Average playtime per player datapoint of network"),
159159
DATA_SERVER_PLAYERS_ONLINE_PEAK("See Player online peak -datapoint of servers"),
160160
DATA_NETWORK_PLAYERS_ONLINE_PEAK("See Player online peak -datapoint of network"),
161+
DATA_SERVER_PLAYERS_ONLINE("See Players online -datapoint of servers"),
162+
DATA_NETWORK_PLAYERS_ONLINE("See Players online -datapoint of network"),
161163
DATA_PLAYER_MOB_KILLS("See Mob kills datapoint of players"),
162164
DATA_SERVER_MOB_KILLS("See Mob kills datapoint of servers"),
163165
DATA_NETWORK_MOB_KILLS("See Mob kills datapoint of network"),

Plan/common/src/main/java/com/djrapitops/plan/delivery/export/NetworkPageExporter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ public void exportJSON(Path toDirectory, ServerUUID serverUUID) throws IOExcepti
150150
datapointType + DatapointType.NEW_PLAYERS + afterMillis + TimeUnit.DAYS.toMillis(7),
151151
datapointType + DatapointType.NEW_PLAYERS + afterMillis + TimeUnit.DAYS.toMillis(1),
152152
datapointType + DatapointType.REGULAR_PLAYERS,
153+
datapointType + DatapointType.PLAYERS_ONLINE,
153154
datapointType + DatapointType.PLAYERS_ONLINE_PEAK + afterMillis + TimeUnit.DAYS.toMillis(2),
154155
datapointType + DatapointType.PLAYERS_ONLINE_PEAK,
155156
datapointType + DatapointType.SESSION_COUNT,

Plan/common/src/main/java/com/djrapitops/plan/delivery/export/ServerPageExporter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ public void exportJSON(Path toDirectory, ServerUUID serverUUID) throws IOExcepti
159159
datapointType + DatapointType.REGULAR_PLAYERS + server,
160160
datapointType + DatapointType.PLAYERS_ONLINE_PEAK + afterMillis + TimeUnit.DAYS.toMillis(2) + server,
161161
datapointType + DatapointType.PLAYERS_ONLINE_PEAK + server,
162+
datapointType + DatapointType.PLAYERS_ONLINE + server,
162163
datapointType + DatapointType.SESSION_COUNT + server,
163164
datapointType + DatapointType.SESSION_COUNT + after + server,
164165
datapointType + DatapointType.PLAYTIME_PER_PLAYER_AVERAGE + server,

Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/json/datapoint/DatapointType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public enum DatapointType {
4444
SESSION_LENGTH_AVERAGE(SessionLengthAverage.class, DatapointCacheKey.SESSION),
4545
PLAYTIME_PER_PLAYER_AVERAGE(PlaytimePerPlayerAverage.class, DatapointCacheKey.SESSION),
4646
PLAYERS_ONLINE_PEAK(PlayersOnlinePeak.class, DatapointCacheKey.TPS),
47+
PLAYERS_ONLINE(PlayersOnline.class, DatapointCacheKey.TPS),
4748
MOB_KILLS(MobKills.class, DatapointCacheKey.SESSION),
4849
PLAYER_KILLS(PlayerKills.class, DatapointCacheKey.SESSION),
4950
DEATHS(Deaths.class, DatapointCacheKey.SESSION);

Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/json/datapoint/types/DatapointModule.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ public interface DatapointModule {
9292
@IntoSet
9393
Datapoint<?> bindPlayerOnlinePeak(PlayersOnlinePeak playersOnlinePeak);
9494

95+
@Binds
96+
@IntoSet
97+
Datapoint<?> bindPlayersOnline(PlayersOnline playersOnline);
98+
9599
@Binds
96100
@IntoSet
97101
Datapoint<?> bindMobKills(MobKills mobKills);
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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.delivery.rendering.json.datapoint.types;
18+
19+
import com.djrapitops.plan.delivery.domain.auth.WebPermission;
20+
import com.djrapitops.plan.delivery.domain.datatransfer.GenericFilter;
21+
import com.djrapitops.plan.delivery.rendering.json.datapoint.Datapoint;
22+
import com.djrapitops.plan.delivery.rendering.json.datapoint.DatapointType;
23+
import com.djrapitops.plan.delivery.web.resolver.exception.BadRequestException;
24+
import com.djrapitops.plan.gathering.ServerSensor;
25+
import com.djrapitops.plan.gathering.domain.TPS;
26+
import com.djrapitops.plan.identification.ServerInfo;
27+
import com.djrapitops.plan.identification.ServerUUID;
28+
import com.djrapitops.plan.storage.database.DBSystem;
29+
import com.djrapitops.plan.storage.database.queries.objects.TPSQueries;
30+
31+
import javax.inject.Inject;
32+
import javax.inject.Singleton;
33+
import java.util.List;
34+
import java.util.Optional;
35+
import java.util.concurrent.TimeUnit;
36+
37+
/**
38+
* Datapoint for looking up current Players online count.
39+
*
40+
* @author AuroraLS3
41+
*/
42+
@Singleton
43+
public class PlayersOnline implements Datapoint<Integer> {
44+
45+
private final DBSystem dbSystem;
46+
private final ServerInfo serverInfo;
47+
private final ServerSensor<?> serverSensor;
48+
49+
@Inject
50+
public PlayersOnline(DBSystem dbSystem, ServerInfo serverInfo, ServerSensor<?> serverSensor) {
51+
this.dbSystem = dbSystem;
52+
this.serverInfo = serverInfo;
53+
this.serverSensor = serverSensor;
54+
}
55+
56+
@Override
57+
public Optional<Integer> getValue(GenericFilter filter) {
58+
if (filter.getPlayerUUID().isPresent()) {
59+
throw new BadRequestException("PLAYERS_ONLINE does not support player parameter");
60+
}
61+
62+
List<ServerUUID> serverUUIDs = filter.getServerUUIDs();
63+
if (serverUUIDs.isEmpty()) {
64+
return Optional.of(serverSensor.getOnlinePlayerCount());
65+
}
66+
67+
if (serverUUIDs.size() == 1) {
68+
ServerUUID serverUUID = serverUUIDs.get(0);
69+
if (serverUUID.equals(serverInfo.getServerUUID())) {
70+
return Optional.of(serverSensor.getOnlinePlayerCount());
71+
}
72+
return Optional.of(dbSystem.getDatabase().query(TPSQueries.fetchLatestTPSEntryForServer(serverUUID))
73+
.filter(tps -> tps.getDate() > System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2))
74+
.map(TPS::getPlayers)
75+
.orElse(0)
76+
);
77+
}
78+
79+
// Multiple servers: sum of latest online counts
80+
int total = 0;
81+
for (ServerUUID serverUUID : serverUUIDs) {
82+
if (serverUUID.equals(serverInfo.getServerUUID())) {
83+
total += serverSensor.getOnlinePlayerCount();
84+
} else {
85+
total += dbSystem.getDatabase().query(TPSQueries.fetchLatestTPSEntryForServer(serverUUID))
86+
.filter(tps -> tps.getDate() > System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2))
87+
.map(TPS::getPlayers).orElse(0);
88+
}
89+
}
90+
return Optional.of(total);
91+
}
92+
93+
@Override
94+
public WebPermission getPermission(GenericFilter filter) {
95+
if (filter.getPlayerUUID().isPresent()) {
96+
return WebPermission.DATA_PLAYER;
97+
} else if (!filter.getServerUUIDs().isEmpty()) {
98+
return WebPermission.DATA_SERVER_PLAYERS_ONLINE;
99+
} else {
100+
return WebPermission.DATA_NETWORK_PLAYERS_ONLINE;
101+
}
102+
}
103+
104+
@Override
105+
public DatapointType getType() {
106+
return DatapointType.PLAYERS_ONLINE;
107+
}
108+
}

Plan/common/src/test/java/com/djrapitops/plan/delivery/webserver/AccessControlTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,9 @@ static Stream<Arguments> testCases() {
219219
Arguments.of("/v1/datapoint?type=PLAYERS_ONLINE_PEAK", WebPermission.DATA_NETWORK_PLAYERS_ONLINE_PEAK, 200, 403),
220220
Arguments.of("/v1/datapoint?type=PLAYERS_ONLINE_PEAK&server=" + TestConstants.SERVER_UUID_STRING, WebPermission.DATA_SERVER_PLAYERS_ONLINE_PEAK, 200, 403),
221221
Arguments.of("/v1/datapoint?type=PLAYERS_ONLINE_PEAK&player=" + TestConstants.PLAYER_ONE_UUID_STRING, WebPermission.DATA_PLAYER, 400, 403),
222+
Arguments.of("/v1/datapoint?type=PLAYERS_ONLINE", WebPermission.DATA_NETWORK_PLAYERS_ONLINE, 200, 403),
223+
Arguments.of("/v1/datapoint?type=PLAYERS_ONLINE&server=" + TestConstants.SERVER_UUID_STRING, WebPermission.DATA_SERVER_PLAYERS_ONLINE, 200, 403),
224+
Arguments.of("/v1/datapoint?type=PLAYERS_ONLINE&player=" + TestConstants.PLAYER_ONE_UUID_STRING, WebPermission.DATA_PLAYER, 400, 403),
222225
Arguments.of("/v1/datapoint?type=REGULAR_PLAYERS", WebPermission.DATA_NETWORK_REGULAR_PLAYERS, 200, 403),
223226
Arguments.of("/v1/datapoint?type=REGULAR_PLAYERS&server=" + TestConstants.SERVER_UUID_STRING, WebPermission.DATA_SERVER_REGULAR_PLAYERS, 200, 403),
224227
Arguments.of("/v1/datapoint?type=REGULAR_PLAYERS&player=" + TestConstants.PLAYER_ONE_UUID_STRING, WebPermission.DATA_PLAYER, 400, 403),

Plan/react/dashboard/src/components/cards/server/values/ServerAsNumbersCard.jsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {useTranslation} from "react-i18next";
22
import {Card} from "react-bootstrap";
33
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
44
import {faBookOpen, faChartLine, faCrosshairs, faSkull, faUser, faUsers} from "@fortawesome/free-solid-svg-icons";
5-
import Datapoint from "../../../datapoint/Datapoint.tsx";
65
import {faCalendarCheck, faClock} from "@fortawesome/free-regular-svg-icons";
76
import React from "react";
87
import {CardLoader} from "../../../navigation/Loader.tsx";
@@ -45,9 +44,10 @@ const ServerAsNumbersCard = ({data}) => {
4544
color={'players-regular'} icon={faUsers}
4645
dataType={DatapointType.REGULAR_PLAYERS}
4746
filter={filter} bold/>
48-
<Datapoint name={t('html.label.playersOnline')}
49-
color={'players-online'} icon={faUser}
50-
value={data.online_players} bold/>
47+
<QueryDatapoint name={t('html.label.playersOnline')}
48+
color={'players-online'} icon={faUser}
49+
dataType={DatapointType.PLAYERS_ONLINE}
50+
filter={filter} bold/>
5151
<hr/>
5252
<QueryDatapoint
5353
name={t('html.label.lastPeak')}

Plan/react/dashboard/src/dataHooks/model/datapoint/Datapoint.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export enum DatapointType {
2020
UNIQUE_PLAYERS = "UNIQUE_PLAYERS",
2121
NEW_PLAYERS = "NEW_PLAYERS",
2222
REGULAR_PLAYERS = "REGULAR_PLAYERS",
23+
PLAYERS_ONLINE = "PLAYERS_ONLINE",
2324
PLAYERS_ONLINE_PEAK = "PLAYERS_ONLINE_PEAK",
2425
SESSION_COUNT = "SESSION_COUNT",
2526
SESSION_LENGTH_AVERAGE = "SESSION_LENGTH_AVERAGE",
@@ -37,6 +38,7 @@ export type DatapointTypeMap = {
3738
UNIQUE_PLAYERS: number;
3839
NEW_PLAYERS: number;
3940
REGULAR_PLAYERS: number;
41+
PLAYERS_ONLINE: number;
4042
SESSION_COUNT: number;
4143
SESSION_LENGTH_AVERAGE: number;
4244
PLAYTIME_PER_PLAYER_AVERAGE: number;

0 commit comments

Comments
 (0)