Skip to content

Commit

Permalink
Handle disconnect events
Browse files Browse the repository at this point in the history
  • Loading branch information
codetheweb committed Jan 7, 2022
1 parent 5fc999c commit ee2b1e3
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 10 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ If the API responds with 401, the player is blocked from joining and the body of

Download a build from the [Releases page](https://github.com/Keweenaw-Kube/diorite/releases) and put it in the `mods/` directory.

After running the server with it installed for the first time, a config file will be created at `mods/diorite/config.yaml`. Fill in `endpoint` with the URL you want Diorite to call. There's an additional, optional property:
After running the server with it installed for the first time, a config file will be created at `mods/diorite/config.yaml`. Fill in `endpoint` with the URL you want Diorite to call. There's a few additional, optional properties:

```yml
# Will make request https://example.com?uuid=player-id&token=my-auth-token
endpoint: "https://example.com"
queryParams:
token: "my-auth-token"
# If true, will make call on player disconnect like https://example.com?uuid=player-id&state=disconnected
callOnDisconnect: false
```
### License
Expand Down
1 change: 1 addition & 0 deletions src/main/java/net/fabricmc/diorite/DioriteConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
public class DioriteConfig {
public String endpoint;
public HashMap<String, String> queryParams;
public boolean callOnDisconnect = false;

private static String getConfigFileLocation() {
File root = new File(DioriteMod.class.getProtectionDomain().getCodeSource().getLocation().getPath());
Expand Down
69 changes: 60 additions & 9 deletions src/main/java/net/fabricmc/diorite/DioriteMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,20 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.stream.Collectors;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.mojang.authlib.GameProfile;

import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerLoginNetworkHandler;

Expand All @@ -19,14 +27,21 @@
import net.fabricmc.fabric.api.networking.v1.PacketSender;
import net.fabricmc.fabric.api.networking.v1.ServerLoginNetworking;

import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.text.LiteralText;

public final class DioriteMod implements ModInitializer {
private DioriteConfig config;
private Executor scheduler = new ScheduledThreadPoolExecutor(1, new ThreadFactoryBuilder()
.setDaemon(true)
.setNameFormat("diorite-scheduler")
.build());

@Override
public void onInitialize() {
ServerLoginConnectionEvents.QUERY_START.register(this::onLoginStart);
ServerLoginConnectionEvents.QUERY_START.register(this::onPreLogin);

ServerPlayConnectionEvents.DISCONNECT.register(this::onDisconnect);

try {
this.config = DioriteConfig.loadConfig();
Expand All @@ -41,20 +56,19 @@ public void onInitialize() {
}
}

private void onLoginStart(ServerLoginNetworkHandler networkHandler, MinecraftServer server, PacketSender sender, ServerLoginNetworking.LoginSynchronizer synchronizer) {
private void onPreLogin(ServerLoginNetworkHandler networkHandler, MinecraftServer server, PacketSender sender, ServerLoginNetworking.LoginSynchronizer sync) {
GameProfile profile = ((ServerLoginNetworkHandlerAccessor) networkHandler).getProfile();
String playerUUID = PlayerEntity.getUuidFromProfile(profile).toString();

String playerUUID = profile.getId().toString();
sync.waitFor(CompletableFuture.runAsync(() -> onPreLoginAsync(networkHandler, playerUUID), this.scheduler));
}

private void onPreLoginAsync(ServerLoginNetworkHandler networkHandler, String playerUUID) {
// Decide here whether to allow connection or not by calling external HTTP API
try {
HashMap<String, String> queryParams = this.config.queryParams == null ? new HashMap<>() : new HashMap<String, String>(this.config.queryParams);

queryParams.put("uuid", playerUUID.replaceAll("-", ""));
HashMap queryParams = this.getQueryParams(playerUUID);

URL url = new URL(this.config.endpoint + '?' + DioriteUtil.getQueryParamsFrom(queryParams));

HttpURLConnection http = (HttpURLConnection) url.openConnection();
HttpURLConnection http = (HttpURLConnection) this.getURL(queryParams).openConnection();
http.setConnectTimeout(1000);
int statusCode = http.getResponseCode();

Expand All @@ -68,4 +82,41 @@ private void onLoginStart(ServerLoginNetworkHandler networkHandler, MinecraftSer
networkHandler.disconnect(new LiteralText("Whitelist API errored out."));
}
}

private void onDisconnect(ServerPlayNetworkHandler networkHandler, MinecraftServer server) {
String playerUUID = networkHandler.player.getUuidAsString();

if (this.config.callOnDisconnect) {
try {
HashMap queryParams = this.getQueryParams(playerUUID);

queryParams.put("state", "disconnected");

HttpURLConnection http = (HttpURLConnection) this.getURL(queryParams).openConnection();
http.setConnectTimeout(1000);
int statusCode = http.getResponseCode();

if (statusCode == 401) {
BufferedReader br = new BufferedReader(new InputStreamReader(http.getErrorStream()));
String msg = br.lines().collect(Collectors.joining());

networkHandler.disconnect(new LiteralText(msg));
}
} catch (IOException error) {
System.err.println("Whitelist API errored out.");
}
}
}

private HashMap<String, String> getQueryParams(String playerUUID) {
HashMap queryParams = this.config.queryParams == null ? new HashMap<>() : new HashMap<String, String>(this.config.queryParams);

queryParams.put("uuid", playerUUID.replaceAll("-", ""));

return queryParams;
}

private URL getURL(HashMap<String, String> queryParams) throws MalformedURLException {
return new URL(this.config.endpoint + '?' + DioriteUtil.getQueryParamsFrom(queryParams));
}
}

0 comments on commit ee2b1e3

Please sign in to comment.