Skip to content

Commit

Permalink
Cache player names gotten from Mojang API
Browse files Browse the repository at this point in the history
  • Loading branch information
TechnicJelle committed Feb 17, 2024
1 parent da7e014 commit 2d2040f
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 4 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,6 @@ run/

# Minecraft server for testing
testserver/

# Player Name Caches
cachedPlayerNames.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public void onEnable() {
config = new PaperConfig(this);

Singletons.init(new PaperServer(this), getLogger(), config, new BlueMapMarkerHandler(), new BMApiStatus());
Singletons.getServer().startUp();

//all actual startup and shutdown logic moved to BlueMapAPI enable/disable methods, so `/bluemap reload` also reloads this plugin
BlueMapAPI.onEnable(onEnableListener);
Expand Down Expand Up @@ -74,6 +75,7 @@ public void onEnable() {
public void onDisable() {
BlueMapAPI.unregisterListener(onEnableListener);
BlueMapAPI.unregisterListener(onDisableListener);
Singletons.getServer().shutDown();
Singletons.getLogger().info("BlueMap Offline Player Markers plugin disabled!");
Singletons.cleanup();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,62 @@
package com.technicjelle.bluemapofflineplayermarkers.common;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.technicjelle.bluemapofflineplayermarkers.core.Singletons;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Path;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

public interface Server {
Gson _gson = new Gson();
Gson _gson = new GsonBuilder()
.setLenient()
// .setPrettyPrinting() //Disabled to discourage people from editing the file by hand
.enableComplexMapKeySerialization()
.create();

Map<UUID, String> _cachedPlayerNames = new HashMap<>();
String _cacheFileName = "cachedPlayerNames.json";

default void startUp() {
//load cached player names
Path cacheFolder = Singletons.getServer().getConfigFolder();
File cacheFile = new File(cacheFolder.toFile(), _cacheFileName);
if (cacheFile.exists()) {
try (InputStreamReader reader = new FileReader(cacheFile)) {
Map<UUID, String> map = _gson.fromJson(reader, new TypeToken<Map<UUID, String>>() {}.getType());
if (map != null) {
_cachedPlayerNames.putAll(map);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

default void shutDown() {
//save cached player names
Path cacheFolder = Singletons.getServer().getConfigFolder();
File cacheFile = new File(cacheFolder.toFile(), _cacheFileName);
try (Writer writer = new FileWriter(cacheFile)) {
_gson.toJson(_cachedPlayerNames, writer);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

boolean isPlayerOnline(UUID playerUUID);

Path getConfigFolder();

Path getPlayerDataFolder();

/**
Expand All @@ -29,15 +69,24 @@ public interface Server {

/**
* Requests the player's name from the Mojang API. May be slow.
*
* @throws IOException If there was an error with the connection.
*/
static String nameFromMojangAPI(UUID playerUUID) throws IOException {
String name = _cachedPlayerNames.get(playerUUID);
if (name != null) {
Singletons.getLogger().info("Requested player name from Mojang API, but returning from cache instead for " + playerUUID);
return name;
}
Singletons.getLogger().info("Requesting player name from Mojang API for " + playerUUID);
URL url = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + playerUUID);
URLConnection request = url.openConnection();
request.connect();

JsonObject response = _gson.fromJson(new InputStreamReader(request.getInputStream()), JsonObject.class);
return response.get("name").getAsString();
name = response.get("name").getAsString();
_cachedPlayerNames.put(playerUUID, name);
return name;
}

Optional<UUID> guessWorldUUID(Object object);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.destroystokyo.paper.profile.PlayerProfile;
import com.technicjelle.bluemapofflineplayermarkers.common.Server;
import com.technicjelle.bluemapofflineplayermarkers.core.Singletons;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
Expand All @@ -15,9 +16,11 @@
import java.util.UUID;

public class PaperServer implements Server {
final JavaPlugin plugin;
final org.bukkit.Server server;

public PaperServer(JavaPlugin plugin) {
this.plugin = plugin;
this.server = plugin.getServer();
}

Expand All @@ -27,6 +30,11 @@ public boolean isPlayerOnline(UUID playerUUID) {
return op.isOnline();
}

@Override
public Path getConfigFolder() {
return plugin.getDataFolder().toPath();
}

@Override
public Path getPlayerDataFolder() {
//I really don't like "getWorlds().get(0)" as a way to get the main world, but as far as I can tell there is no other way
Expand Down
2 changes: 2 additions & 0 deletions src/test/java/LoadOfflineMarkersTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
public class LoadOfflineMarkersTest {
@After
public void cleanup() {
Singletons.getServer().shutDown();
Singletons.cleanup();
}

Expand All @@ -19,6 +20,7 @@ public void extract_info_from_playerdata_files() {
new MockMarkerHandler(),
new MockBMApiStatus()
);
Singletons.getServer().startUp();
FileMarkerLoader.loadOfflineMarkers();
}
}
5 changes: 5 additions & 0 deletions src/test/java/mockery/MockServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public boolean isPlayerOnline(UUID playerUUID) {
return false;
}

@Override
public Path getConfigFolder() {
return getPlayerDataFolder();
}

@Override
public Path getPlayerDataFolder() {
Path path = Paths.get("").resolve("src/test/resources/" + playerDataFolderName);
Expand Down

0 comments on commit 2d2040f

Please sign in to comment.