Definitive configuration paste system

This commit is contained in:
Jaime Martinez Rincon 2017-08-09 03:17:09 +02:00
parent d2032cfe82
commit 3a3aa2b348
16 changed files with 154 additions and 111 deletions

View File

@ -1,7 +1,7 @@
# PlayerBalancer
[Spigot Resource](https://www.spigotmc.org/resources/10788/)
[![Build Status](https://travis-ci.com/jaime29010/PlayerBalancer.svg?token=2yUi9WpA9QzSbJx9eTmy&branch=master)](https://travis-ci.com/jaime29010/LobbyBalancer)
[![Build Status](https://travis-ci.com/jaime29010/PlayerBalancer.svg?token=2yUi9WpA9QzSbJx9eTmy&branch=master)](https://travis-ci.com/jaime29010/PlayerBalancer)
### Things to do:
- [x] Get dummy sections able to have already registered servers on other sections
@ -9,9 +9,9 @@
- [ ] Add support for wildcards, contains, equalsIgnoreCase and regex at the same time
- [x] Add tooltip when you hover over a server in /section info
- [ ] Stop using inventivetalent's deprecated bungee-update
- [ ] Create a LobbyBalancer spigot addon that adds connector signs and placeholders
- [ ] Create a spigot addon that adds connector signs and placeholders
- [ ] Separate the types of connections in classes instead of being in ConnectionIntent
- [ ] Make the plugin API not be so dependent on a instance of LobbyBalancer
- [ ] Make the plugin API not be so dependent on a instance of PlayerBalancer
- [ ] Separate connection providers in classes instead of being hardcoded in an enum
- [ ] Make the feature `marker-descs` work per section
- [ ] Add a identifier to get the servers of a section (auto complete)

23
pom.xml
View File

@ -88,19 +88,18 @@
<artifactId>configme</artifactId>
<version>0.4</version>
<scope>compile</scope>
<exclusions>
<!-- This is already shaded in BungeeCord -->
<exclusion>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.3.6</version>
</dependency>
<!-- TODO Ditch this dependency, move to ConfigMe -->
<!-- TODO This is shading commons lang3 -->
<dependency>
<groupId>me.jaimemartz</groupId>
<artifactId>faucet-bungee</artifactId>
@ -116,7 +115,7 @@
<scope>compile</scope>
</dependency>
<!-- TODO Replace with our own alternative to "RedisBunge" (maybe) -->
<!-- TODO Replace with our own alternative to "RedisBungee" (maybe) -->
<dependency>
<groupId>com.imaginarycode.minecraft</groupId>
<artifactId>RedisBungee</artifactId>

View File

@ -109,7 +109,7 @@ public class PlayerBalancer extends Plugin {
getProxy().getPluginManager().registerListener(this, new PlayerDisconnectListener(this));
getProxy().registerChannel("LobbyBalancer");
getProxy().registerChannel("PlayerBalancer");
if (ConfigEntries.RECONNECT_KICK_ENABLED.get()) {
kickListener = new ServerKickListener(this);

View File

@ -1,7 +1,7 @@
package com.jaimemartz.playerbalancer.commands;
import com.jaimemartz.playerbalancer.manager.PasteHelper;
import com.jaimemartz.playerbalancer.PlayerBalancer;
import com.jaimemartz.playerbalancer.manager.PasteHelper;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.ComponentBuilder;
@ -21,9 +21,9 @@ public class MainCommand extends Command {
if (args.length != 0) {
switch (args[0].toLowerCase()) {
case "paste": {
if (sender.hasPermission("lobbybalancer.admin")) {
PasteHelper.PLUGIN.send(plugin, sender, "Plugin config paste link: {response}");
PasteHelper.BUNGEE.send(plugin, sender, "Bungee config paste link (IPs stripped): {response}");
if (sender.hasPermission("playerbalancer.admin")) {
PasteHelper.PLUGIN.send(plugin, sender);
PasteHelper.BUNGEE.send(plugin, sender);
} else {
sender.sendMessage(new ComponentBuilder("You do not have permission to execute this command!").color(ChatColor.RED).create());
}
@ -31,7 +31,7 @@ public class MainCommand extends Command {
}
case "reload": {
if (sender.hasPermission("lobbybalancer.admin")) {
if (sender.hasPermission("playerbalancer.admin")) {
sender.sendMessage(new ComponentBuilder("Reloading the configuration, this may take a while...").color(ChatColor.GREEN).create());
if (plugin.reloadPlugin()) {
sender.sendMessage(new ComponentBuilder("The plugin has successfully reloaded").color(ChatColor.GREEN).create());
@ -50,7 +50,7 @@ public class MainCommand extends Command {
}
} else {
sender.sendMessage(new ComponentBuilder(StringUtils.repeat('-', 53)).strikethrough(true).color(ChatColor.GRAY).create());
sender.sendMessage(new ComponentBuilder("LobbyBalancer " + plugin.getDescription().getVersion()).color(ChatColor.GRAY).create());
sender.sendMessage(new ComponentBuilder("PlayerBalancer " + plugin.getDescription().getVersion()).color(ChatColor.GRAY).create());
sender.sendMessage(new ComponentBuilder("Available commands:").color(ChatColor.GRAY).create());
sender.sendMessage(new ComponentBuilder("/balancer").color(ChatColor.AQUA).append(" - ").color(ChatColor.GRAY).append("Shows you this message").color(ChatColor.RED).create());
sender.sendMessage(new ComponentBuilder("/balancer paste").color(ChatColor.AQUA).append(" - ").color(ChatColor.GRAY).append("Creates a paste with the important files").color(ChatColor.RED).create());

View File

@ -11,14 +11,11 @@ import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Command;
import org.apache.commons.lang3.StringUtils;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class ManageCommand extends Command {
private final PlayerBalancer plugin;
@ -30,7 +27,7 @@ public class ManageCommand extends Command {
@Override
public void execute(CommandSender sender, String[] args) {
if (sender.hasPermission("lobbybalancer.admin")) {
if (sender.hasPermission("playerbalancer.admin")) {
if (args.length != 0) {
switch (args[0].toLowerCase()) {
case "connect": {

View File

@ -1,9 +1,9 @@
package com.jaimemartz.playerbalancer.connection;
import com.jaimemartz.playerbalancer.manager.PlayerLocker;
import com.jaimemartz.playerbalancer.ping.ServerStatus;
import com.jaimemartz.playerbalancer.PlayerBalancer;
import com.jaimemartz.playerbalancer.configuration.ConfigEntries;
import com.jaimemartz.playerbalancer.manager.PlayerLocker;
import com.jaimemartz.playerbalancer.ping.ServerStatus;
import com.jaimemartz.playerbalancer.section.ServerSection;
import com.jaimemartz.playerbalancer.utils.MessageUtils;
import net.md_5.bungee.api.config.ServerInfo;

View File

@ -1,8 +1,8 @@
package com.jaimemartz.playerbalancer.listener;
import com.jaimemartz.playerbalancer.connection.ServerAssignRegistry;
import com.jaimemartz.playerbalancer.PlayerBalancer;
import com.jaimemartz.playerbalancer.configuration.ConfigEntries;
import com.jaimemartz.playerbalancer.connection.ServerAssignRegistry;
import com.jaimemartz.playerbalancer.manager.PlayerLocker;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.PlayerDisconnectEvent;

View File

@ -82,7 +82,7 @@ public class PluginMessageListener implements Listener {
e.printStackTrace();
}
sender.sendData("LobbyBalancer", stream.toByteArray());
sender.sendData("PlayerBalancer", stream.toByteArray());
break;
}

View File

@ -1,10 +1,10 @@
package com.jaimemartz.playerbalancer.listener;
import com.jaimemartz.playerbalancer.PlayerBalancer;
import com.jaimemartz.playerbalancer.configuration.ConfigEntries;
import com.jaimemartz.playerbalancer.connection.ConnectionIntent;
import com.jaimemartz.playerbalancer.connection.ServerAssignRegistry;
import com.jaimemartz.playerbalancer.manager.PlayerLocker;
import com.jaimemartz.playerbalancer.PlayerBalancer;
import com.jaimemartz.playerbalancer.configuration.ConfigEntries;
import com.jaimemartz.playerbalancer.section.ServerSection;
import com.jaimemartz.playerbalancer.utils.MessageUtils;
import net.md_5.bungee.api.config.ServerInfo;

View File

@ -3,30 +3,35 @@ package com.jaimemartz.playerbalancer.manager;
import com.google.common.io.CharStreams;
import com.jaimemartz.playerbalancer.PlayerBalancer;
import com.jaimemartz.playerbalancer.utils.GuestPaste;
import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.scheduler.ScheduledTask;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
public enum PasteHelper {
PLUGIN {
PLUGIN((sender, url) -> {
if (sender instanceof ProxiedPlayer) {
sender.sendMessage(new ComponentBuilder("Click me for the plugin configuration")
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, url.toString()))
.color(ChatColor.GREEN)
.create()
);
} else {
sender.sendMessage(new ComponentBuilder("Plugin configuration link: " + url.toString()).create());
}
}) {
@Override
public String paste(PlayerBalancer plugin) throws Exception {
public URL paste(PlayerBalancer plugin) throws Exception {
File file = new File(plugin.getDataFolder(), "config.yml");
if (!file.exists()) {
return "File does not exist";
}
try (FileInputStream stream = new FileInputStream(file)) {
try (InputStreamReader reader = new InputStreamReader(stream, "UTF-8")) {
String content = CharStreams.toString(reader);
@ -47,18 +52,24 @@ public enum PasteHelper {
}
}
},
BUNGEE {
BUNGEE((sender, url) -> {
if (sender instanceof ProxiedPlayer) {
sender.sendMessage(new ComponentBuilder("Click me for the BungeeCord configuration")
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, url.toString()))
.color(ChatColor.GREEN)
.create()
);
} else {
sender.sendMessage(new ComponentBuilder("BungeeCord configuration link: " + url.toString()).create());
}
}) {
@Override
public String paste(PlayerBalancer plugin) throws Exception {
public URL paste(PlayerBalancer plugin) throws Exception {
File file = new File("config.yml");
if (!file.exists()) {
return "File does not exist";
}
try (FileInputStream stream = new FileInputStream(file)) {
try (InputStreamReader reader = new InputStreamReader(stream, "UTF-8")) {
String content = CharStreams.toString(reader);
content = content.replaceAll("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}", "X.X.X.X");
content = content.replaceAll("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}", "?.?.?.?");
GuestPaste paste = new GuestPaste("e3ff18d8fb001a3ece08ae0d7d4a87bd", content);
paste.setName("{name} ({version}) Configuration"
@ -76,24 +87,43 @@ public enum PasteHelper {
}
};
//Cached link of the paste
private String response;
private URL url;
private ScheduledTask task = null;
public void send(PlayerBalancer plugin, CommandSender sender, String message) {
try {
sender.sendMessage(new ComponentBuilder(message.replace("{response}", response == null ? response = paste(plugin) : response)).color(ChatColor.GREEN).create());
private final BiConsumer<CommandSender, URL> consumer;
PasteHelper(BiConsumer<CommandSender, URL> consumer) {
this.consumer = consumer;
}
if (task != null) {
plugin.getProxy().getScheduler().cancel(task);
public void send(PlayerBalancer plugin, CommandSender sender) {
if (url == null) {
try {
url = paste(plugin);
if (task != null) {
task.cancel();
}
task = plugin.getProxy().getScheduler().schedule(plugin, () -> {
url = null;
}, 5, TimeUnit.MINUTES);
} catch (GuestPaste.PasteException e) {
sender.sendMessage(new ComponentBuilder("An pastebin exception occurred: " + e.getMessage())
.color(ChatColor.RED)
.create()
);
e.printStackTrace();
} catch (Exception e) {
sender.sendMessage(new ComponentBuilder("An internal error occurred while attempting to perform this command")
.color(ChatColor.RED)
.create()
);
e.printStackTrace();
}
}
task = plugin.getProxy().getScheduler().schedule(plugin, () -> response = null, 5, TimeUnit.MINUTES);
} catch (Exception e) {
sender.sendMessage(new ComponentBuilder("An internal error occurred while attempting to perform this command").color(ChatColor.RED).create());
e.printStackTrace();
if (url != null) {
consumer.accept(sender, url);
}
}
public abstract String paste(PlayerBalancer plugin) throws Exception;
public abstract URL paste(PlayerBalancer plugin) throws Exception;
}

View File

@ -1,8 +1,8 @@
package com.jaimemartz.playerbalancer.ping;
import com.jaimemartz.playerbalancer.configuration.ConfigEntries;
import lombok.Getter;
import lombok.Setter;
import com.jaimemartz.playerbalancer.configuration.ConfigEntries;
import net.md_5.bungee.api.config.ServerInfo;
public final class ServerStatus {

View File

@ -1,9 +1,9 @@
package com.jaimemartz.playerbalancer.section;
import com.jaimemartz.playerbalancer.PlayerBalancer;
import com.jaimemartz.playerbalancer.configuration.ConfigEntries;
import com.jaimemartz.playerbalancer.connection.ConnectionIntent;
import com.jaimemartz.playerbalancer.utils.MessageUtils;
import com.jaimemartz.playerbalancer.PlayerBalancer;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.ComponentBuilder;

View File

@ -1,15 +1,14 @@
package com.jaimemartz.playerbalancer.section;
import lombok.Getter;
import lombok.Setter;
import com.jaimemartz.playerbalancer.PlayerBalancer;
import com.jaimemartz.playerbalancer.configuration.ConfigEntries;
import lombok.Getter;
import lombok.Setter;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.connection.Server;
import net.md_5.bungee.api.scheduler.ScheduledTask;
import net.md_5.bungee.config.Configuration;
import org.apache.commons.lang3.Validate;
import java.util.HashMap;
import java.util.Map;

View File

@ -2,12 +2,12 @@ package com.jaimemartz.playerbalancer.section;
import com.google.gson.annotations.Expose;
import com.jaimemartz.playerbalancer.PlayerBalancer;
import com.jaimemartz.playerbalancer.connection.ProviderType;
import com.jaimemartz.playerbalancer.utils.AlphanumComparator;
import com.jaimemartz.playerbalancer.utils.FixedAdapter;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import com.jaimemartz.playerbalancer.connection.ProviderType;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.config.Configuration;

View File

@ -2,19 +2,15 @@ package com.jaimemartz.playerbalancer.utils;
import lombok.Data;
import lombok.Getter;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.AbstractMap.SimpleEntry;
import java.util.LinkedList;
import java.util.List;
@ -33,35 +29,71 @@ public class GuestPaste {
this.code = code;
}
public String paste() throws Exception {
HttpPost request = new HttpPost("https://pastebin.com/api/api_post.php");
public URL paste() throws Exception {
URL url = new URL("https://pastebin.com/api/api_post.php");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
List<BasicNameValuePair> params = new LinkedList<>();
params.add(new BasicNameValuePair("api_dev_key", key));
params.add(new BasicNameValuePair("api_option", "paste"));
params.add(new BasicNameValuePair("api_paste_code", code));
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
List<SimpleEntry<String, String>> params = new LinkedList<>();
params.add(new SimpleEntry<>("api_dev_key", key));
params.add(new SimpleEntry<>("api_option", "paste"));
params.add(new SimpleEntry<>("api_paste_code", code));
if (name != null) {
params.add(new BasicNameValuePair("api_paste_name", name));
params.add(new SimpleEntry<>("api_paste_name", name));
}
if (format != null) {
params.add(new BasicNameValuePair("api_paste_format", format));
params.add(new SimpleEntry<>("api_paste_format", format));
}
if (expiration != null) {
params.add(new BasicNameValuePair("api_paste_expire_date", expiration.getValue()));
params.add(new SimpleEntry<>("api_paste_expire_date", expiration.getValue()));
}
if (exposure != null) {
params.add(new BasicNameValuePair("api_paste_private", String.valueOf(exposure.getValue())));
params.add(new SimpleEntry<>("api_paste_private", String.valueOf(exposure.getValue())));
}
HttpEntity entity = new UrlEncodedFormEntity(params, Consts.UTF_8);
request.setEntity(entity);
StringBuilder output = new StringBuilder();
for (SimpleEntry<String, String> entry : params) {
if (output.length() > 0)
output.append('&');
Response response = new Response();
return client.execute(request, response);
output.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
output.append('=');
output.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
con.setDoOutput(true);
try (DataOutputStream dos = new DataOutputStream(con.getOutputStream())) {
dos.writeBytes(output.toString());
dos.flush();
}
int status = con.getResponseCode();
if (status >= 200 && status < 300) {
try (InputStreamReader isr = new InputStreamReader(con.getInputStream())) {
try (BufferedReader br = new BufferedReader(isr)) {
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = br.readLine()) != null) {
response.append(inputLine);
}
try {
return new URL(response.toString());
} catch (MalformedURLException e) {
throw new PasteException("Pastebin error: " + response.toString());
}
}
}
} else {
throw new PasteException("Unexpected response code " + status);
}
}
public enum Expiration {
@ -94,22 +126,9 @@ public class GuestPaste {
}
}
public static class Response implements ResponseHandler<String> {
@Override
public String handleResponse(HttpResponse response) throws IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 && status < 300) {
HttpEntity entity = response.getEntity();
try {
return entity != null ? EntityUtils.toString(entity) : "";
} catch (ParseException | IOException e) {
return "Error : " + e.getMessage();
}
} else {
return "Unexpected response status: " + status;
}
public class PasteException extends Exception {
public PasteException(String response) {
super(response);
}
}
private static final HttpClient client = HttpClients.createDefault();
}

View File

@ -1,4 +1,3 @@
import com.jaimemartz.playerbalancer.utils.GuestPaste;
import org.junit.Test;
public class GeneralTest {