Skip to content

Commit 2579ece

Browse files
committed
Refactor HTTP client and remove OkHttp dependency
1 parent 3ce3876 commit 2579ece

File tree

18 files changed

+267
-245
lines changed

18 files changed

+267
-245
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# AzLink
22

3-
[![Tests](https://img.shields.io/github/workflow/status/Azuriom/AzLink/Java%20CI?style=flat-square)](https://github.com/Azuriom/AzLink/actions)
4-
[![Language grade](https://img.shields.io/lgtm/grade/java/github/Azuriom/AzLink?label=code%20quality&logo=lgtm&logoWidth=18&style=flat-square)](https://lgtm.com/projects/g/Azuriom/AzLink/context:java)
3+
[![Tests](https://img.shields.io/github/actions/workflow/status/Azuriom/AzLink/build.yml?branch=master&style=flat-square)](https://github.com/Azuriom/AzLink/actions/workflows/build.yml)
54
[![Chat](https://img.shields.io/discord/625774284823986183?color=5865f2&label=Discord&logo=discord&logoColor=fff&style=flat-square)](https://azuriom.com/discord)
65

76
AzLink is a plugin to link a Minecraft server or proxy with [Azuriom](https://azuriom.com/).
@@ -11,11 +10,12 @@ This plugin currently supports the following platforms:
1110
* [BungeeCord](https://github.com/SpigotMC/BungeeCord)
1211
* [Sponge](https://www.spongepowered.org/)
1312
* [Velocity](https://velocitypowered.com/)
14-
* [Nukkit](https://nukkitx.com/)
13+
* [Nukkit](https://cloudburstmc.org/articles/)
1514

1615
## Setup
1716

1817
### Installation
18+
1919
The plugin works with the same .jar for all the platforms, except Bukkit/Spigot 1.7.10 which requires the legacy version of the plugin.
2020

2121
You just need to download the plugin, add it to the `plugins` folder of your server, and restart your server.

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
allprojects {
22
group 'com.azuriom'
3-
version '1.1.2'
3+
version '1.2.0'
44
}
55

66
subprojects {

bukkit/src/main/java/com/azuriom/azlink/bukkit/integrations/AuthMeIntegration.java

+15-26
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@
1010
import fr.xephi.authme.security.crypts.EncryptionMethod;
1111
import fr.xephi.authme.security.crypts.HashedPassword;
1212
import org.bukkit.entity.Player;
13-
import org.bukkit.event.Event;
1413
import org.bukkit.event.EventHandler;
1514
import org.bukkit.event.EventPriority;
1615
import org.bukkit.event.Listener;
1716

18-
import java.io.IOException;
1917
import java.lang.reflect.Field;
2018
import java.net.InetAddress;
2119
import java.net.InetSocketAddress;
@@ -55,13 +53,14 @@ public void onPasswordEncryption(PasswordEncryptionEvent event) {
5553
public void onEmailChanged(EmailChangedEvent event) {
5654
Player player = event.getPlayer();
5755

58-
runAsync(event, () -> {
59-
try {
60-
this.plugin.getPlugin().getHttpClient().updateEmail(player.getUniqueId(), event.getNewEmail());
61-
} catch (IOException e) {
62-
this.plugin.getLoggerAdapter().error("Unable to update email for " + player.getName(), e);
63-
}
64-
});
56+
this.plugin.getPlugin()
57+
.getHttpClient()
58+
.updateEmail(player.getUniqueId(), event.getNewEmail())
59+
.exceptionally(ex -> {
60+
this.plugin.getLoggerAdapter().error("Unable to update email for " + player.getName(), ex);
61+
62+
return null;
63+
});
6564
}
6665

6766
@EventHandler
@@ -80,24 +79,14 @@ public void onRegister(RegisterEvent event) {
8079
return;
8180
}
8281

83-
runAsync(event, () -> {
84-
try {
85-
this.plugin.getPlugin()
86-
.getHttpClient()
87-
.registerUser(player.getName(), email, player.getUniqueId(), password, ip);
88-
} catch (IOException e) {
89-
this.plugin.getLoggerAdapter().error("Unable to register " + player.getName(), e);
90-
}
91-
});
92-
}
93-
94-
private void runAsync(Event event, Runnable runnable) {
95-
if (event.isAsynchronous()) {
96-
runnable.run();
97-
return;
98-
}
82+
this.plugin.getPlugin()
83+
.getHttpClient()
84+
.registerUser(player.getName(), email, player.getUniqueId(), password, ip)
85+
.exceptionally(ex -> {
86+
this.plugin.getLoggerAdapter().error("Unable to register " + player.getName(), ex);
9987

100-
this.plugin.getSchedulerAdapter().executeAsync(runnable);
88+
return null;
89+
});
10190
}
10291

10392
public class ForwardingEncryptionMethod implements EncryptionMethod {

bungee/src/main/java/com/azuriom/azlink/bungee/BungeeSchedulerAdapter.java

+13
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44
import com.azuriom.azlink.common.scheduler.SchedulerAdapter;
55
import net.md_5.bungee.api.scheduler.ScheduledTask;
66

7+
import java.util.concurrent.Executor;
78
import java.util.concurrent.TimeUnit;
89

910
public class BungeeSchedulerAdapter implements SchedulerAdapter {
1011

12+
private final Executor executor = this::executeAsync;
13+
1114
private final AzLinkBungeePlugin plugin;
1215

1316
public BungeeSchedulerAdapter(AzLinkBungeePlugin plugin) {
@@ -24,6 +27,16 @@ public void executeAsync(Runnable runnable) {
2427
this.plugin.getProxy().getScheduler().runAsync(this.plugin, runnable);
2528
}
2629

30+
@Override
31+
public Executor syncExecutor() {
32+
return this.executor;
33+
}
34+
35+
@Override
36+
public Executor asyncExecutor() {
37+
return this.executor;
38+
}
39+
2740
@Override
2841
public CancellableTask executeAsyncLater(Runnable runnable, long delay, TimeUnit unit) {
2942
ScheduledTask task = this.plugin.getProxy()

common/build.gradle

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
dependencies {
2-
implementation 'com.squareup.okhttp3:okhttp:3.14.9'
3-
42
compileOnly 'org.slf4j:slf4j-api:1.7.36'
53
compileOnly 'com.google.code.gson:gson:2.9.1'
6-
compileOnly 'io.netty:netty-all:4.1.25.Final'
4+
compileOnly 'io.netty:netty-all:4.1.42.Final'
75

86
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0'
97
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.0'

common/src/main/java/com/azuriom/azlink/common/AzLinkPlugin.java

+26-25
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.time.temporal.ChronoUnit;
3232
import java.util.List;
3333
import java.util.Optional;
34+
import java.util.concurrent.CompletableFuture;
3435
import java.util.concurrent.TimeUnit;
3536
import java.util.stream.Collectors;
3637

@@ -71,10 +72,16 @@ public void init() {
7172

7273
this.httpServer = createHttpServer();
7374

74-
LocalDateTime start = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES).plusMinutes(1);
75-
long startDelay = Duration.between(LocalDateTime.now(), start).plusMillis(500).toMillis(); // Add 0.5s to ensure we are not in the previous hour
75+
// Add a random start delay to prevent important load on shared web hosts
76+
// caused by many servers sending request at the same time
77+
LocalDateTime start = LocalDateTime.now()
78+
.truncatedTo(ChronoUnit.MINUTES)
79+
.plusMinutes(1)
80+
.plusSeconds(1 + (long) (Math.random() * 30));
81+
long startDelay = Duration.between(LocalDateTime.now(), start).toMillis();
82+
long repeatDelay = TimeUnit.MINUTES.toMillis(1);
7683

77-
getScheduler().executeAsyncRepeating(this.fetcherTask, startDelay, TimeUnit.MINUTES.toMillis(1), TimeUnit.MILLISECONDS);
84+
getScheduler().executeAsyncRepeating(this.fetcherTask, startDelay, repeatDelay, TimeUnit.MILLISECONDS);
7885

7986
if (!this.config.isValid()) {
8087
getLogger().warn("Invalid configuration, please use '/azlink' to setup the plugin.");
@@ -91,15 +98,13 @@ public void init() {
9198
getScheduler().executeAsync(updateChecker::checkUpdates);
9299
}
93100

94-
getScheduler().executeAsync(() -> {
95-
try {
96-
this.httpClient.verifyStatus();
101+
this.httpClient.verifyStatus()
102+
.thenRun(() -> getLogger().info("Successfully connected to " + this.config.getSiteUrl()))
103+
.exceptionally(ex -> {
104+
getLogger().warn("Unable to verify the website connection: " + ex.getMessage());
97105

98-
getLogger().info("Successfully connected to " + this.config.getSiteUrl());
99-
} catch (IOException e) {
100-
getLogger().warn("Unable to verify the website connection: " + e.getMessage() + " - " + e.getClass().getName());
101-
}
102-
});
106+
return null;
107+
});
103108
}
104109

105110
public void restartHttpServer() {
@@ -127,10 +132,6 @@ public void shutdown() {
127132
}
128133
}
129134

130-
public void setConfig(PluginConfig config) {
131-
this.config = config;
132-
}
133-
134135
public void saveConfig() throws IOException {
135136
if (!Files.isDirectory(this.platform.getDataDirectory())) {
136137
Files.createDirectories(this.platform.getDataDirectory());
@@ -161,8 +162,8 @@ public ServerData getServerData(boolean fullData) {
161162
return new ServerData(platformData, version, players, max, system, world, fullData);
162163
}
163164

164-
public void fetchNow() {
165-
getScheduler().executeAsync(this.fetcherTask);
165+
public CompletableFuture<Void> fetch() {
166+
return this.fetcherTask.fetch();
166167
}
167168

168169
public LoggerAdapter getLogger() {
@@ -189,14 +190,6 @@ public HttpServer getHttpServer() {
189190
return this.httpServer;
190191
}
191192

192-
public static Gson getGson() {
193-
return GSON;
194-
}
195-
196-
public static Gson getGsonPrettyPrint() {
197-
return GSON_PRETTY_PRINT;
198-
}
199-
200193
public Optional<UserInfo> getUser(String name) {
201194
return this.fetcherTask.getUser(name);
202195
}
@@ -217,4 +210,12 @@ private double getCpuUsage() {
217210
}
218211
return -1;
219212
}
213+
214+
public static Gson getGson() {
215+
return GSON;
216+
}
217+
218+
public static Gson getGsonPrettyPrint() {
219+
return GSON_PRETTY_PRINT;
220+
}
220221
}

common/src/main/java/com/azuriom/azlink/common/command/AzLinkCommand.java

+30-28
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.util.Arrays;
77
import java.util.Collections;
88
import java.util.List;
9+
import java.util.concurrent.CompletableFuture;
910
import java.util.stream.Collectors;
1011

1112
public class AzLinkCommand {
@@ -42,13 +43,18 @@ public void execute(CommandSender sender, String[] args) {
4243
}
4344

4445
if (args[0].equalsIgnoreCase("status")) {
45-
plugin.getScheduler().executeAsync(() -> showStatus(sender));
46+
showStatus(sender);
4647
return;
4748
}
4849

4950
if (args[0].equalsIgnoreCase("fetch")) {
50-
this.plugin.fetchNow();
51-
sender.sendMessage("&6Data has been fetched successfully.");
51+
this.plugin.fetch()
52+
.thenRun(() -> sender.sendMessage("&6Data has been fetched successfully."))
53+
.exceptionally(ex -> {
54+
sender.sendMessage("&cUnable to fetch data: " + ex.getMessage());
55+
56+
return null;
57+
});
5258
return;
5359
}
5460

@@ -79,7 +85,8 @@ public void execute(CommandSender sender, String[] args) {
7985

8086
sender.sendMessage("&aHTTP server started on port " + port);
8187
} catch (Exception e) {
82-
sender.sendMessage("&cAn error occurred while starting the HTTP server: " + e.getMessage() + " - " + e.getClass().getName());
88+
String info = e.getMessage() + " - " + e.getClass().getName();
89+
sender.sendMessage("&cAn error occurred while starting the HTTP server: " + info);
8390
this.plugin.getLogger().error("Error while starting the HTTP server", e);
8491
return;
8592
}
@@ -123,43 +130,38 @@ private void setup(CommandSender sender, String url, String key) {
123130
url = url.substring(0, url.length() - 1);
124131
}
125132

133+
if (startsWithIgnoreCase(url, "http:")) {
134+
sender.sendMessage("&6You should use https to improve security!");
135+
}
136+
126137
this.plugin.getConfig().setSiteKey(key);
127138
this.plugin.getConfig().setSiteUrl(url);
128139

129-
if (showStatus(sender)) {
130-
if (startsWithIgnoreCase(url, "http://")) {
131-
sender.sendMessage("&6You should use https to improve security.");
132-
}
133-
134-
saveConfig(sender);
135-
136-
this.plugin.restartHttpServer();
137-
}
140+
showStatus(sender)
141+
.thenRun(() -> saveConfig(sender))
142+
.thenRun(this.plugin::restartHttpServer);
138143
}
139144

140145
private void saveConfig(CommandSender sender) {
141146
try {
142147
this.plugin.saveConfig();
143148
} catch (IOException e) {
144-
sender.sendMessage("&cAn error occurred while saving config: " + e.getMessage() + " - " + e.getClass().getName());
149+
String info = e.getMessage() + " - " + e.getClass().getName();
150+
sender.sendMessage("&cAn error occurred while saving config: " + info);
145151
this.plugin.getLogger().error("Error while saving config", e);
146152
}
147153
}
148154

149-
private boolean showStatus(CommandSender sender) {
150-
try {
151-
this.plugin.getHttpClient().verifyStatus();
152-
153-
sender.sendMessage("&aLinked to the website successfully.");
154-
155-
this.plugin.fetchNow();
156-
157-
return true;
158-
} catch (Exception e) {
159-
sender.sendMessage("&cUnable to connect to the website: " + e.getMessage() + " - " + e.getClass().getName());
160-
161-
return false;
162-
}
155+
private CompletableFuture<Void> showStatus(CommandSender sender) {
156+
return this.plugin.getHttpClient()
157+
.verifyStatus()
158+
.thenRun(() -> sender.sendMessage("&aLinked to the website successfully."))
159+
.thenRun(this.plugin::fetch)
160+
.whenComplete((v, ex) -> {
161+
if (ex != null) {
162+
sender.sendMessage("&cUnable to connect to the website: " + ex.getMessage());
163+
}
164+
});
163165
}
164166

165167
private static boolean startsWithIgnoreCase(String string, String prefix) {

0 commit comments

Comments
 (0)