Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed retrieving data by Discord Name #4

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<<<<<<< HEAD

# An API to expose player information for Janet (or other discord bots).

Expand Down Expand Up @@ -131,3 +132,6 @@ Note, the plugin will not run unless you change the secret. This is explained ab
# Legal Mumbo Jumbo
The idea and base code for this project came from [TristanSMPAPI](https://github.com/twisttaan/TristanSMPAPI).
It has been extensively added to by myself with much technical help from the developers of [DiscordSRV](https://github.com/DiscordSRV/DiscordSRV/)
=======
A remake of BoredManCodes' SMP-API to fit my needs.
>>>>>>> 5b19083 (file add)
12 changes: 11 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<<<<<<< HEAD
<groupId>net.boredman</groupId>
<artifactId>SMP-API</artifactId>
<version>2.0.3</version>
=======
<groupId>quest.safecloud</groupId>
<artifactId>SMP-API</artifactId>
<version>1.0</version>
>>>>>>> 5b19083 (file add)
<packaging>jar</packaging>

<name>SMP-Api</name>
Expand All @@ -16,7 +22,11 @@
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<<<<<<< HEAD
<url>https://boredman.net</url>
=======
<url>https://safecloud.quest</url>
>>>>>>> 5b19083 (file add)

<build>
<plugins>
Expand Down Expand Up @@ -89,7 +99,7 @@
<dependency>
<groupId>com.discordsrv</groupId>
<artifactId>discordsrv</artifactId>
<version>1.21.1</version>
<version>1.27.0</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/net/boredman/api.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,4 @@ public void start() {
}

public static Express express = new Express();


}
11 changes: 2 additions & 9 deletions src/main/java/net/boredman/routes/DiscordRoute.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,23 @@ public DiscordRoute(Express app) {
API.getPlugin(API.class).getLogger().info("A request was made to access " +
req.getParams().get("username") + "'s Discord data");
}
if (!secret.equals(req.getHeader("secret").get(0))) {
if (secret!= null &&!secret.equals(req.getHeader("secret").get(0))) {
obj.put("error", true);
obj.put("message", "You are not authorised to access this resource");
res.send(obj.toJSONString());
API.getPlugin(API.class).getLogger().warning("A request to access Discord info from " + req.getIp() +
" was rejected as they did not pass the correct secret in the header");
return;
} else {
if (discordId == null) {
obj.put("error", true);
obj.put("message", "Player not linked to discord");
res.send(obj.toJSONString());
return;
} else {
User user = DiscordUtil.getJda().getUserById(discordId);
if (user == null) {
obj.put("error", true);
obj.put("message", "Couldn't find Discord User by ID. Maybe they left the server?");
res.send(obj.toJSONString());
return;
} else {
obj.put("error", false);
obj.put("username", username);
Expand All @@ -58,7 +55,6 @@ public DiscordRoute(Express app) {
obj.put("discordTag", user.getAsTag());
obj.put("discordName", user.getName());
res.send(obj.toJSONString());
return;
}
}
}
Expand All @@ -74,7 +70,7 @@ public DiscordRoute(Express app) {
API.getPlugin(API.class).getLogger().info("A request was made to access " +
req.getParams().get("id") + "'s Discord data");
}
if (!secret.equals(req.getHeader("secret").get(0))) {
if (secret!= null &&!secret.equals(req.getHeader("secret").get(0))) {
obj.put("error", true);
obj.put("message", "You are not authorised to access this resource");
res.send(obj.toJSONString());
Expand All @@ -85,14 +81,12 @@ public DiscordRoute(Express app) {
obj.put("error", true);
obj.put("message", "Player not linked to discord");
res.send(obj.toJSONString());
return;
} else {
User user = DiscordUtil.getJda().getUserById(discordId);
if (user == null) {
obj.put("error", true);
obj.put("message", "Couldn't find Discord User by ID. Maybe they left the server?");
res.send(obj.toJSONString());
return;
} else {
obj.put("error", false);
obj.put("username", username);
Expand All @@ -101,7 +95,6 @@ public DiscordRoute(Express app) {
obj.put("discordTag", user.getAsTag());
obj.put("discordName", user.getName());
res.send(obj.toJSONString());
return;
}
}
}
Expand Down
49 changes: 49 additions & 0 deletions src/main/java/quest/safecloud/API.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package quest.safecloud;

import express.Express;
import github.scarsz.discordsrv.objects.managers.AccountLinkManager;
import quest.safecloud.events.QuitEvent;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;


public class API extends JavaPlugin implements Listener {
private static API plugin;
final FileConfiguration config = getConfig();

public static Express getApp() {
return express;
}

@Override
public void onEnable() {
config.addDefault("port", 25567);
config.addDefault("secret", "CHANGE THIS!");
config.addDefault("debug", false);
config.options().copyDefaults(true);
saveConfig();
start();
plugin = this;
if (config.getString("secret").equals("CHANGE THIS!")) {
getLogger().warning("--------------------------------------------");
getLogger().severe("You MUST change the secret in the config.yml for this plugin to work. " +
"This prevents exposing player IP addresses to the world");
getLogger().warning("--------------------------------------------");
this.getPluginLoader().disablePlugin(this);
}
this.getServer().getPluginManager().registerEvents(new QuitEvent(), this);
}

@Override
public void onDisable() {
}

public void start() {
getLogger().info("Starting API on port " + config.getInt("port"));
new ReqHandler(express);
getLogger().info("API Started");
}

public static Express express = new Express();
}
16 changes: 16 additions & 0 deletions src/main/java/quest/safecloud/ReqHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package quest.safecloud;

import express.Express;
import quest.safecloud.routes.DiscordRoute;
import quest.safecloud.routes.PlayersRoute;

public class ReqHandler {

public ReqHandler(Express app) {
int port = API.getPlugin(API.class).getConfig().getInt("port");
new PlayersRoute(app);
new DiscordRoute(app);
app.get("/", (req, res) -> res.send("Error 418: The server refuses to brew coffee because it is, permanently, a teapot.\n" +
"For more information: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/418")).listen(port);
}
}
78 changes: 78 additions & 0 deletions src/main/java/quest/safecloud/events/QuitEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package quest.safecloud.events;

import quest.safecloud.API;
import org.bukkit.Statistic;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.json.simple.JSONObject;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static org.bukkit.Bukkit.getPlayer;

public class QuitEvent implements Listener {
@EventHandler
public void playerQuitEvent(PlayerQuitEvent event) throws IOException {
boolean debug = API.getPlugin(API.class).getConfig().getBoolean("debug");
if (debug) {
System.out.println(event.getPlayer().getName().toString() + " left the server, saving their player data.");
}
File dir = new File(API.class.getProtectionDomain().getCodeSource().getLocation().getPath().replaceAll("%20", " "));
File plugins = new File(dir.getParentFile().getPath());
String playerDataFolder = plugins + "\\SMP-API\\playerdata\\";
if (!Files.exists(Path.of(playerDataFolder))) {
Files.createDirectory(Path.of(playerDataFolder));
}
String filename = playerDataFolder + event.getPlayer().getName() + ".json";
String username = event.getPlayer().getName();
JSONObject obj = new JSONObject();
Player player = getPlayer(username);
String bed;
String[] arrOfBed;
String location;
String[] arrOfLocation;
String address;
String[] arrOfAddress;
try {
obj.put((Object) "username", (Object) player.getName());
obj.put((Object) "uuid", (Object) player.getUniqueId().toString());
obj.put((Object) "health", (Object) String.valueOf(player.getHealth()));
obj.put((Object) "food", (Object) String.valueOf(player.getFoodLevel()));
obj.put((Object) "world", (Object) player.getWorld().getName());
obj.put((Object) "experience", (Object) String.valueOf(player.getExp()));
obj.put((Object) "level", (Object) String.valueOf(player.getLevel()));
obj.put((Object) "deaths", (Object) String.valueOf(player.getStatistic(Statistic.DEATHS)));
obj.put((Object) "kills", (Object) String.valueOf(player.getStatistic(Statistic.MOB_KILLS)));
obj.put((Object) "jumps", (Object) String.valueOf(player.getStatistic(Statistic.JUMP)));
obj.put((Object) "gamemode", (Object) player.getGameMode().toString());
if (player.getBedSpawnLocation() != null) {
bed = player.getBedSpawnLocation().toString();
arrOfBed = bed.split(",");
obj.put((Object) "bed", (Object) (arrOfBed[1] + "," + arrOfBed[2] + "," + arrOfBed[3]));
}
obj.put((Object) "time", (Object) String.valueOf(player.getStatistic(Statistic.PLAY_ONE_MINUTE) / 20));
obj.put((Object) "death", (Object) String.valueOf(player.getStatistic(Statistic.TIME_SINCE_DEATH) / 20));
address = String.valueOf(player.getAddress()).replace("/", "");
arrOfAddress = address.split(":");
obj.put((Object) "address", (Object) arrOfAddress[0]);
obj.put((Object) "lastJoined", (Object) System.currentTimeMillis());
obj.put((Object) "online", (Object) false);
location = player.getLocation().toString();
arrOfLocation = location.split(",");
obj.put((Object) "location", (Object) (arrOfLocation[1] + "," + arrOfLocation[2] + "," + arrOfLocation[3]));
Files.write(Paths.get(filename), obj.toJSONString().getBytes());
if (debug) {
API.getPlugin(API.class).getLogger().info("Saved " + event.getPlayer().getName() + "'s player data");
}
} catch (Exception e) {
API.getPlugin(API.class).getLogger().severe("Ran into an error trying to save player data");
API.getPlugin(API.class).getLogger().severe(String.valueOf(e));
}
}
}
108 changes: 108 additions & 0 deletions src/main/java/quest/safecloud/routes/DiscordRoute.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package quest.safecloud.routes;

import express.Express;
import github.scarsz.discordsrv.dependencies.jda.api.entities.User;
import github.scarsz.discordsrv.util.DiscordUtil;
import quest.safecloud.API;
import org.bukkit.OfflinePlayer;
import org.json.simple.JSONObject;

import java.util.UUID;

import static github.scarsz.discordsrv.DiscordSRV.getPlugin;
import static org.bukkit.Bukkit.getOfflinePlayer;


@SuppressWarnings("unchecked")
public class DiscordRoute {
public DiscordRoute(Express app) {

// Read config
boolean debug = API.getPlugin(API.class).getConfig().getBoolean("debug");
String secret = API.getPlugin(API.class).getConfig().getString("secret");

if (secret == null) {
API.getPlugin(API.class).getLogger().warning("Secret not set in config.yml. This is a security risk.");
return;
}

// Lookup Discord via username
app.get("/minecraft/name/:username", (req, res) -> {
final String username = req.getParams().get("username");
final OfflinePlayer player = getOfflinePlayer(username);
final String discordId = getPlugin().getAccountLinkManager().getDiscordId(player.getUniqueId());
final JSONObject obj = new JSONObject();
if (debug) {
API.getPlugin(API.class).getLogger().info("A request was made to access " +
req.getParams().get("username") + "'s Discord data");
}
if (!secret.equals(req.getHeader("secret").get(0))) {
obj.put("error", true);
obj.put("message", "You are not authorised to access this resource");
res.send(obj.toJSONString());
API.getPlugin(API.class).getLogger().warning("A request to access Discord info from " + req.getIp() +
" was rejected as they did not pass the correct secret in the header");
} else {
if (discordId == null) {
obj.put("error", true);
obj.put("message", "Player not linked to discord");
} else {
User user = DiscordUtil.getJda().getUserById(discordId);
if (user == null) {
obj.put("error", true);
obj.put("message", "Couldn't find Discord User by ID. Maybe they left the server?");
} else {
obj.put("error", false);
obj.put("username", username);
obj.put("uuid", player.getUniqueId().toString());
obj.put("discordId", discordId);
obj.put("discordTag", user.getAsTag());
obj.put("discordName", user.getName());
}
}
res.send(obj.toJSONString());
}
});

// Lookup Discord via ID
app.get("/discord/id/:id", (req, res) -> {
final String discordId = req.getParams().get("id");
final UUID playerUUID = getPlugin().getAccountLinkManager().getUuid(discordId);
final JSONObject obj = new JSONObject();
if (debug) {
API.getPlugin(API.class).getLogger().info("A request was made to access " +
req.getParams().get("id") + "'s Discord data");
}
if (!secret.equals(req.getHeader("secret").get(0))) {
obj.put("error", true);
obj.put("message", "You are not authorised to access this resource");
res.send(obj.toJSONString());
API.getPlugin(API.class).getLogger().warning("A request to access Discord info from " + req.getIp() +
" was rejected as they did not pass the correct secret in the header");
} else {
if (playerUUID == null) {
obj.put("error", true);
obj.put("message", "Player not linked to discord");
res.send(obj.toJSONString());
} else {
User user = DiscordUtil.getJda().getUserById(discordId);
if (user == null) {
obj.put("error", true);
obj.put("message", "Couldn't find Discord User by ID. Maybe they left the server?");
res.send(obj.toJSONString());
} else {
OfflinePlayer player = getOfflinePlayer(playerUUID);
obj.put("error", false);
obj.put("username", player.getName());
obj.put("uuid", player.getUniqueId().toString());
obj.put("discordId", discordId);
obj.put("discordTag", user.getAsTag());
obj.put("discordName", user.getName());
res.send(obj.toJSONString());
}
}
}
});

}
}
Loading