Compare commits
22
Commits
standalone
...
v2.3.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9342f75317 | ||
|
|
f17bb4e414 | ||
|
|
5f347e538b | ||
|
|
b4fb8c69a9 | ||
|
|
95ebcf22a8 | ||
|
|
302da3c907 | ||
|
|
f8019debd0 | ||
|
|
ab317e76b3 | ||
|
|
15556be265 | ||
|
|
26958e35fe | ||
|
|
e905881238 | ||
|
|
fde7a941b6 | ||
|
|
9d24deabe9 | ||
|
|
c2f331e7ec | ||
|
|
705bddd062 | ||
|
|
826609db30 | ||
|
|
0eca96bd67 | ||
|
|
f767387840 | ||
|
|
8ae3c21a23 | ||
|
|
be1c056502 | ||
|
|
500142eb5b | ||
|
|
1e5876bc08 |
No files matched your search
+2
-1
@@ -11,7 +11,8 @@
|
||||
/build.xml
|
||||
|
||||
# maven
|
||||
/target
|
||||
/*/target/
|
||||
dependency-reduced-pom.xml
|
||||
|
||||
# vim
|
||||
.*.sw[a-p]
|
||||
|
||||
+1
-1
@@ -6,6 +6,6 @@ deploy:
|
||||
provider: releases
|
||||
api_key:
|
||||
secure: j8y4qeDOXAYjmf6WU6EbpUA6AKTz26yJ4zNb6oAuB4h9Y3PpBRjFjCIBL6jJQnMxZMLjdgk72/3uqS7+//jJ8/iiY/OJhO2L+2us8TJDcQhH5EI1USe/lcZKf60iJjmd9Q9pjh1eHNYhxr6kyNLnpa6fw5b/hIBT6CvNZAJV1qbhRpHwtzbgdlMFaHGnpX192vJNw7E3uuJuSwue5XNK2ybDp81oTrM0Q16JCq/UsQhGq4Ba3JffOhdBhpfg4EI2jJfe3vN8CFqojCYKNSp7eL6DPFPaV4x8Ly8cRIOZ5Zb60m5SyWAcagPKJuUq3ZOTHfeVTjkI9ymZMHe1pla2Mq6eitIBwZIGnonjyMxcTdkR9EJgq9jo+1PzdStR/NlGLakBiwPzk8Ov0DZ+iOwpYUkISUkMU0UgKWwoFoRu18CHtp+ALEsoYZhBQGlcShq+4EGv9VMNBYk9vN3KXNRMVGKqXd6O3T6shvSQgoUn/3mvksOTAuhS5J4U3woHecDrXwl/RfP2aqiHhX/S7p7yY4hVcHu8kiSYpNQMbay+rNd6HxFcRe/U9HOUt6kW8/yo1ROyCxs3ze+N6LtGDHspgzkFaay6I6wMHYNDnzzRP4MC3Zc73zxViXol6dGBk4Tawsm16VaI6b1uyWLBGKvuU23azkmMTHUmGFXl2/BTaYw=
|
||||
file: universal/target/nuvotifier-universal-2.3.2.2.jar
|
||||
file: universal/target/nuvotifier-universal-2.3.5.jar
|
||||
on:
|
||||
tags: true
|
||||
+1
-1
@@ -74,7 +74,7 @@ The message is JSON-encoded containing the following data:
|
||||
|
||||
A response is given after the vote has been received and parsed, but not yet processed.
|
||||
|
||||
For your convenience, the NuVotifier team has provided client libraries in [JavaScript](https://github.com/NuVotifier/votifier2-js) and [PHP](https://github.com/NuVotifier/votifier2-php). If you are stuck, these libraries may help you.
|
||||
For your convenience, the NuVotifier team has provided client libraries in [JavaScript](https://github.com/NuVotifier/votifier2-js), [PHP](https://github.com/NuVotifier/votifier2-php) and [Go](https://github.com/minecrafter/go-votifier). If you are stuck, these libraries may help you.
|
||||
|
||||
### Protocol v1 (deprecated)
|
||||
|
||||
|
||||
+4
-5
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>nuvotifier</artifactId>
|
||||
<groupId>com.vexsoftware</groupId>
|
||||
<version>2.3.2.2</version>
|
||||
<version>2.3.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -56,10 +56,9 @@
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.7.2-R0.1</version>
|
||||
<type>jar</type>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -190,88 +190,82 @@ public class NuVotifierBukkit extends JavaPlugin implements VoteHandler, Votifie
|
||||
|
||||
debug = cfg.getBoolean("debug", false);
|
||||
|
||||
boolean setUpPort = cfg.getBoolean("enableExternal", true); //Always default to running the external port
|
||||
// Load Votifier tokens.
|
||||
ConfigurationSection tokenSection = cfg.getConfigurationSection("tokens");
|
||||
|
||||
if (setUpPort) {
|
||||
// Load Votifier tokens.
|
||||
ConfigurationSection tokenSection = cfg.getConfigurationSection("tokens");
|
||||
|
||||
if (tokenSection != null) {
|
||||
Map<String, Object> websites = tokenSection.getValues(false);
|
||||
for (Map.Entry<String, Object> website : websites.entrySet()) {
|
||||
tokens.put(website.getKey(), KeyCreator.createKeyFrom(website.getValue().toString()));
|
||||
getLogger().info("Loaded token for website: " + website.getKey());
|
||||
}
|
||||
} else {
|
||||
String token = TokenUtil.newToken();
|
||||
tokenSection = cfg.createSection("tokens");
|
||||
tokenSection.set("default", token);
|
||||
tokens.put("default", KeyCreator.createKeyFrom(token));
|
||||
try {
|
||||
cfg.save(config);
|
||||
} catch (IOException e) {
|
||||
getLogger().log(Level.SEVERE,
|
||||
"Error generating Votifier token", e);
|
||||
gracefulExit();
|
||||
return;
|
||||
}
|
||||
getLogger().info("------------------------------------------------------------------------------");
|
||||
getLogger().info("No tokens were found in your configuration, so we've generated one for you.");
|
||||
getLogger().info("Your default Votifier token is " + token + ".");
|
||||
getLogger().info("You will need to provide this token when you submit your server to a voting");
|
||||
getLogger().info("list.");
|
||||
getLogger().info("------------------------------------------------------------------------------");
|
||||
if (tokenSection != null) {
|
||||
Map<String, Object> websites = tokenSection.getValues(false);
|
||||
for (Map.Entry<String, Object> website : websites.entrySet()) {
|
||||
tokens.put(website.getKey(), KeyCreator.createKeyFrom(website.getValue().toString()));
|
||||
getLogger().info("Loaded token for website: " + website.getKey());
|
||||
}
|
||||
|
||||
// Initialize the receiver.
|
||||
final String host = cfg.getString("host", hostAddr);
|
||||
final int port = cfg.getInt("port", 8192);
|
||||
if (debug)
|
||||
getLogger().info("DEBUG mode enabled!");
|
||||
|
||||
final boolean disablev1 = cfg.getBoolean("disable-v1-protocol");
|
||||
if (disablev1) {
|
||||
getLogger().info("------------------------------------------------------------------------------");
|
||||
getLogger().info("Votifier protocol v1 parsing has been disabled. Most voting websites do not");
|
||||
getLogger().info("currently support the modern Votifier protocol in NuVotifier.");
|
||||
getLogger().info("------------------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
serverGroup = new NioEventLoopGroup(1);
|
||||
|
||||
new ServerBootstrap()
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.group(serverGroup)
|
||||
.childHandler(new ChannelInitializer<NioSocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(NioSocketChannel channel) throws Exception {
|
||||
channel.attr(VotifierSession.KEY).set(new VotifierSession());
|
||||
channel.attr(VotifierPlugin.KEY).set(NuVotifierBukkit.this);
|
||||
channel.pipeline().addLast("greetingHandler", new VotifierGreetingHandler());
|
||||
channel.pipeline().addLast("protocolDifferentiator", new VotifierProtocolDifferentiator(false, !disablev1));
|
||||
channel.pipeline().addLast("voteHandler", new VoteInboundHandler(NuVotifierBukkit.this));
|
||||
}
|
||||
})
|
||||
.bind(host, port)
|
||||
.addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (future.isSuccess()) {
|
||||
serverChannel = future.channel();
|
||||
getLogger().info("Votifier enabled on socket "+serverChannel.localAddress()+".");
|
||||
} else {
|
||||
SocketAddress socketAddress = future.channel().localAddress();
|
||||
if (socketAddress == null) {
|
||||
socketAddress = new InetSocketAddress(host, port);
|
||||
}
|
||||
getLogger().log(Level.SEVERE, "Votifier was not able to bind to " + socketAddress, future.cause());
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
getLogger().info("You have enableExternal set to false in your config.yml. NuVotifier will NOT listen to votes coming in from an external voting list.");
|
||||
String token = TokenUtil.newToken();
|
||||
tokenSection = cfg.createSection("tokens");
|
||||
tokenSection.set("default", token);
|
||||
tokens.put("default", KeyCreator.createKeyFrom(token));
|
||||
try {
|
||||
cfg.save(config);
|
||||
} catch (IOException e) {
|
||||
getLogger().log(Level.SEVERE,
|
||||
"Error generating Votifier token", e);
|
||||
gracefulExit();
|
||||
return;
|
||||
}
|
||||
getLogger().info("------------------------------------------------------------------------------");
|
||||
getLogger().info("No tokens were found in your configuration, so we've generated one for you.");
|
||||
getLogger().info("Your default Votifier token is " + token + ".");
|
||||
getLogger().info("You will need to provide this token when you submit your server to a voting");
|
||||
getLogger().info("list.");
|
||||
getLogger().info("------------------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
// Initialize the receiver.
|
||||
final String host = cfg.getString("host", hostAddr);
|
||||
final int port = cfg.getInt("port", 8192);
|
||||
if (debug)
|
||||
getLogger().info("DEBUG mode enabled!");
|
||||
|
||||
final boolean disablev1 = cfg.getBoolean("disable-v1-protocol");
|
||||
if (disablev1) {
|
||||
getLogger().info("------------------------------------------------------------------------------");
|
||||
getLogger().info("Votifier protocol v1 parsing has been disabled. Most voting websites do not");
|
||||
getLogger().info("currently support the modern Votifier protocol in NuVotifier.");
|
||||
getLogger().info("------------------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
serverGroup = new NioEventLoopGroup(1);
|
||||
|
||||
new ServerBootstrap()
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.group(serverGroup)
|
||||
.childHandler(new ChannelInitializer<NioSocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(NioSocketChannel channel) throws Exception {
|
||||
channel.attr(VotifierSession.KEY).set(new VotifierSession());
|
||||
channel.attr(VotifierPlugin.KEY).set(NuVotifierBukkit.this);
|
||||
channel.pipeline().addLast("greetingHandler", new VotifierGreetingHandler());
|
||||
channel.pipeline().addLast("protocolDifferentiator", new VotifierProtocolDifferentiator(false, !disablev1));
|
||||
channel.pipeline().addLast("voteHandler", new VoteInboundHandler(NuVotifierBukkit.this));
|
||||
}
|
||||
})
|
||||
.bind(host, port)
|
||||
.addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (future.isSuccess()) {
|
||||
serverChannel = future.channel();
|
||||
getLogger().info("Votifier enabled on socket "+serverChannel.localAddress()+".");
|
||||
} else {
|
||||
SocketAddress socketAddress = future.channel().localAddress();
|
||||
if (socketAddress == null) {
|
||||
socketAddress = new InetSocketAddress(host, port);
|
||||
}
|
||||
getLogger().log(Level.SEVERE, "Votifier was not able to bind to " + socketAddress, future.cause());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ConfigurationSection forwardingConfig = cfg.getConfigurationSection("forwarding");
|
||||
if (forwardingConfig != null) {
|
||||
String method = forwardingConfig.getString("method", "none").toLowerCase(); //Default to lower case for case-insensitive searches
|
||||
@@ -342,12 +336,12 @@ public class NuVotifierBukkit extends JavaPlugin implements VoteHandler, Votifie
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVoteReceived(final Vote vote, VotifierSession.ProtocolVersion protocolVersion) throws Exception {
|
||||
public void onVoteReceived(Channel channel, final Vote vote, VotifierSession.ProtocolVersion protocolVersion) throws Exception {
|
||||
if (debug) {
|
||||
if (protocolVersion == VotifierSession.ProtocolVersion.ONE) {
|
||||
getLogger().info("Got a protocol v1 vote record -> " + vote);
|
||||
getLogger().info("Got a protocol v1 vote record from " + channel.remoteAddress() + " -> " + vote);
|
||||
} else {
|
||||
getLogger().info("Got a protocol v2 vote record -> " + vote);
|
||||
getLogger().info("Got a protocol v2 vote record from " + channel.remoteAddress() + " -> " + vote);
|
||||
}
|
||||
}
|
||||
Bukkit.getScheduler().runTask(this, new Runnable() {
|
||||
|
||||
@@ -9,10 +9,6 @@ port: 8192
|
||||
# This is useful when initially setting up NuVotifier to ensure votes are being delivered.
|
||||
debug: false
|
||||
|
||||
# Setting this value to false will turn off the votifier port listening for external votes. This is beneficial if the server
|
||||
# is only listening for votes coming from NuVotifier running on your BungeeCord.
|
||||
enableExternal: true
|
||||
|
||||
# Setting this option to true will disable handling of Protocol v1 packets. While the old protocol is not secure, this
|
||||
# option is currently not recommended as most voting sites only support the old protocol at present. However, if you are
|
||||
# using NuVotifier's proxy forwarding mechanism, enabling this option will increase your server's security.
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>nuvotifier</artifactId>
|
||||
<groupId>com.vexsoftware</groupId>
|
||||
<version>2.3.2.2</version>
|
||||
<version>2.3.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -321,12 +321,12 @@ public class NuVotifier extends Plugin implements VoteHandler, VotifierPlugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVoteReceived(final Vote vote, VotifierSession.ProtocolVersion protocolVersion) throws Exception {
|
||||
public void onVoteReceived(Channel channel, final Vote vote, VotifierSession.ProtocolVersion protocolVersion) throws Exception {
|
||||
if (debug) {
|
||||
if (protocolVersion == VotifierSession.ProtocolVersion.ONE) {
|
||||
getLogger().info("Got a protocol v1 vote record -> " + vote);
|
||||
getLogger().info("Got a protocol v1 vote record from " + channel.remoteAddress() + " -> " + vote);
|
||||
} else {
|
||||
getLogger().info("Got a protocol v2 vote record -> " + vote);
|
||||
getLogger().info("Got a protocol v2 vote record from " + channel.remoteAddress() + " -> " + vote);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
package com.vexsoftware.votifier.bungee.forwarding;
|
||||
|
||||
import com.vexsoftware.votifier.bungee.NuVotifier;
|
||||
import com.vexsoftware.votifier.bungee.forwarding.cache.FileVoteCache;
|
||||
import com.vexsoftware.votifier.bungee.forwarding.cache.VoteCache;
|
||||
import com.vexsoftware.votifier.model.Vote;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
||||
import net.md_5.bungee.api.event.ServerConnectedEvent;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public abstract class AbstractPluginMessagingForwardingSource implements ForwardingVoteSource {
|
||||
|
||||
public AbstractPluginMessagingForwardingSource(String channel, List<String> ignoredServers, NuVotifier nuVotifier, VoteCache cache) {
|
||||
ProxyServer.getInstance().registerChannel(channel);
|
||||
this.channel = channel;
|
||||
this.nuVotifier = nuVotifier;
|
||||
this.cache = cache;
|
||||
this.ignoredServers = ignoredServers;
|
||||
}
|
||||
|
||||
protected AbstractPluginMessagingForwardingSource(String channel, NuVotifier nuVotifier, VoteCache voteCache) {
|
||||
this(channel, null, nuVotifier, voteCache);
|
||||
}
|
||||
|
||||
protected final NuVotifier nuVotifier;
|
||||
protected final String channel;
|
||||
protected final VoteCache cache;
|
||||
protected final List<String> ignoredServers;
|
||||
|
||||
@Override
|
||||
public void forward(Vote v) {
|
||||
byte[] rawData = v.serialize().toString().getBytes(StandardCharsets.UTF_8);
|
||||
for (ServerInfo s : ProxyServer.getInstance().getServers().values()) {
|
||||
if (ignoredServers != null && ignoredServers.contains(s.getName())) continue;
|
||||
if (!forwardSpecific(s, rawData)) attemptToAddToCache(v, s.getName());
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean forwardSpecific(ServerInfo connection, Vote vote) {
|
||||
byte[] rawData = vote.serialize().toString().getBytes(StandardCharsets.UTF_8);
|
||||
return connection.sendData(channel, rawData, false);
|
||||
}
|
||||
|
||||
private boolean forwardSpecific(ServerInfo connection, byte[] data) {
|
||||
return connection.sendData(channel, data, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void halt() {
|
||||
ProxyServer.getInstance().unregisterChannel(channel);
|
||||
|
||||
if (cache != null && cache instanceof FileVoteCache) {
|
||||
try {
|
||||
((FileVoteCache) cache).halt();
|
||||
} catch (IOException e) {
|
||||
nuVotifier.getLogger().log(Level.SEVERE, "Unable to save cached votes, votes will be lost.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleServerConnected(final ServerConnectedEvent e) {
|
||||
if (cache == null) return;
|
||||
final String serverName = e.getServer().getInfo().getName();
|
||||
final Collection<Vote> cachedVotes = cache.evict(serverName);
|
||||
if (!cachedVotes.isEmpty()) {
|
||||
nuVotifier.getProxy().getScheduler().schedule(nuVotifier, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int evicted = 0;
|
||||
int unsuccessfulEvictions = 0;
|
||||
for (Vote v : cachedVotes) {
|
||||
if (forwardSpecific(e.getServer().getInfo(), v)) {
|
||||
evicted++;
|
||||
} else {
|
||||
// Re-add to cache to send later.
|
||||
cache.addToCache(v, serverName);
|
||||
unsuccessfulEvictions++;
|
||||
}
|
||||
}
|
||||
if (nuVotifier.isDebug()) {
|
||||
nuVotifier.getLogger().info("Successfully evicted " + evicted + " votes to server '" + serverName + "'.");
|
||||
if (unsuccessfulEvictions > 0) {
|
||||
nuVotifier.getLogger().info("Held " + unsuccessfulEvictions + " votes for server '" + serverName + "'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
protected void attemptToAddToCache(Vote v, String server) {
|
||||
if (cache != null) {
|
||||
cache.addToCache(v, server);
|
||||
if (nuVotifier.isDebug())
|
||||
nuVotifier.getLogger().info("Added to forwarding cache: " + v + " -> " + server);
|
||||
} else if (nuVotifier.isDebug())
|
||||
nuVotifier.getLogger().severe("Could not immediately send vote to backend, vote lost! " + v + " -> " + server);
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -8,16 +8,18 @@ import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
||||
import net.md_5.bungee.api.event.ServerConnectedEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
|
||||
/**
|
||||
* @author Joseph Hirschfeld
|
||||
* @date 12/31/2015
|
||||
*/
|
||||
public final class OnlineForwardPluginMessagingForwardingSource extends PluginMessagingForwardingSource {
|
||||
public final class OnlineForwardPluginMessagingForwardingSource extends AbstractPluginMessagingForwardingSource implements Listener {
|
||||
public OnlineForwardPluginMessagingForwardingSource(String channel, NuVotifier nuVotifier, VoteCache cache, String fallbackServer) {
|
||||
super(channel, nuVotifier, cache);
|
||||
this.fallbackServer = fallbackServer;
|
||||
ProxyServer.getInstance().getPluginManager().registerListener(nuVotifier, this);
|
||||
}
|
||||
|
||||
private final String fallbackServer;
|
||||
@@ -27,7 +29,7 @@ public final class OnlineForwardPluginMessagingForwardingSource extends PluginMe
|
||||
ProxiedPlayer p = ProxyServer.getInstance().getPlayer(v.getUsername());
|
||||
if (p == null || !forwardSpecific(p.getServer().getInfo(), v)) {
|
||||
ServerInfo serverInfo = ProxyServer.getInstance().getServers().get(fallbackServer);
|
||||
if (serverInfo == null || !forwardSpecific(serverInfo, v)) {
|
||||
if (serverInfo != null && !forwardSpecific(serverInfo, v)) {
|
||||
attemptToAddToCache(v, fallbackServer);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-93
@@ -1,75 +1,25 @@
|
||||
package com.vexsoftware.votifier.bungee.forwarding;
|
||||
|
||||
import com.vexsoftware.votifier.bungee.NuVotifier;
|
||||
import com.vexsoftware.votifier.bungee.forwarding.cache.FileVoteCache;
|
||||
import com.vexsoftware.votifier.bungee.forwarding.cache.VoteCache;
|
||||
import com.vexsoftware.votifier.model.Vote;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
||||
import net.md_5.bungee.api.event.ServerConnectedEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Created by Joe Hirschfeld on 10/20/2015.
|
||||
*/
|
||||
public class PluginMessagingForwardingSource implements ForwardingVoteSource, Listener {
|
||||
public class PluginMessagingForwardingSource extends AbstractPluginMessagingForwardingSource implements Listener {
|
||||
|
||||
public PluginMessagingForwardingSource(String channel, List<String> ignoredServers, NuVotifier nuVotifier, VoteCache cache) {
|
||||
ProxyServer.getInstance().registerChannel(channel);
|
||||
super(channel, ignoredServers, nuVotifier, cache);
|
||||
ProxyServer.getInstance().getPluginManager().registerListener(nuVotifier, this);
|
||||
this.channel = channel;
|
||||
this.nuVotifier = nuVotifier;
|
||||
this.cache = cache;
|
||||
this.ignoredServers = ignoredServers;
|
||||
}
|
||||
|
||||
protected PluginMessagingForwardingSource(String channel, NuVotifier nuVotifier, VoteCache voteCache) {
|
||||
this(channel, null, nuVotifier, voteCache);
|
||||
}
|
||||
|
||||
protected final NuVotifier nuVotifier;
|
||||
protected final String channel;
|
||||
protected final VoteCache cache;
|
||||
protected final List<String> ignoredServers;
|
||||
|
||||
@Override
|
||||
public void forward(Vote v) {
|
||||
byte[] rawData = v.serialize().toString().getBytes(StandardCharsets.UTF_8);
|
||||
for (ServerInfo s : ProxyServer.getInstance().getServers().values()) {
|
||||
if (ignoredServers != null && ignoredServers.contains(s.getName())) continue;
|
||||
if (!forwardSpecific(s, rawData)) attemptToAddToCache(v, s.getName());
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean forwardSpecific(ServerInfo connection, Vote vote) {
|
||||
byte[] rawData = vote.serialize().toString().getBytes(StandardCharsets.UTF_8);
|
||||
return connection.sendData(channel, rawData, false);
|
||||
}
|
||||
|
||||
private boolean forwardSpecific(ServerInfo connection, byte[] data) {
|
||||
return connection.sendData(channel, data, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void halt() {
|
||||
ProxyServer.getInstance().unregisterChannel(channel);
|
||||
|
||||
if (cache != null && cache instanceof FileVoteCache) {
|
||||
try {
|
||||
((FileVoteCache) cache).halt();
|
||||
} catch (IOException e) {
|
||||
nuVotifier.getLogger().log(Level.SEVERE, "Unable to save cached votes, votes will be lost.", e);
|
||||
}
|
||||
}
|
||||
super(channel, nuVotifier, voteCache);
|
||||
ProxyServer.getInstance().getPluginManager().registerListener(nuVotifier, this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@@ -81,43 +31,4 @@ public class PluginMessagingForwardingSource implements ForwardingVoteSource, Li
|
||||
public void onServerConnected(final ServerConnectedEvent e) { //Attempt to resend any votes that were previously cached.
|
||||
handleServerConnected(e);
|
||||
}
|
||||
|
||||
protected void handleServerConnected(final ServerConnectedEvent e) {
|
||||
if (cache == null) return;
|
||||
final String serverName = e.getServer().getInfo().getName();
|
||||
final Collection<Vote> cachedVotes = cache.evict(serverName);
|
||||
if (!cachedVotes.isEmpty()) {
|
||||
nuVotifier.getProxy().getScheduler().schedule(nuVotifier, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int evicted = 0;
|
||||
int unsuccessfulEvictions = 0;
|
||||
for (Vote v : cachedVotes) {
|
||||
if (forwardSpecific(e.getServer().getInfo(), v)) {
|
||||
evicted++;
|
||||
} else {
|
||||
// Re-add to cache to send later.
|
||||
cache.addToCache(v, serverName);
|
||||
unsuccessfulEvictions++;
|
||||
}
|
||||
}
|
||||
if (nuVotifier.isDebug()) {
|
||||
nuVotifier.getLogger().info("Successfully evicted " + evicted + " votes to server '" + serverName + "'.");
|
||||
if (unsuccessfulEvictions > 0) {
|
||||
nuVotifier.getLogger().info("Held " + unsuccessfulEvictions + " votes for server '" + serverName + "'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
protected void attemptToAddToCache(Vote v, String server) {
|
||||
if (cache != null) {
|
||||
cache.addToCache(v, server);
|
||||
if (nuVotifier.isDebug())
|
||||
nuVotifier.getLogger().info("Added to forwarding cache: " + v + " -> " + server);
|
||||
} else if (nuVotifier.isDebug())
|
||||
nuVotifier.getLogger().severe("Could not immediately send vote to backend, vote lost! " + v + " -> " + server);
|
||||
}
|
||||
}
|
||||
Vendored
+28
-28
@@ -7,15 +7,11 @@ import net.md_5.bungee.api.plugin.Plugin;
|
||||
import net.md_5.bungee.api.scheduler.ScheduledTask;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONTokener;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@@ -42,37 +38,41 @@ public class FileVoteCache extends MemoryVoteCache {
|
||||
}
|
||||
|
||||
private void load() throws IOException {
|
||||
if (cacheFile.exists()) {
|
||||
// Load the cache from disk
|
||||
JSONObject object = new JSONObject(Files.toString(cacheFile, StandardCharsets.UTF_8));
|
||||
// Load the cache from disk
|
||||
JSONObject object;
|
||||
try (BufferedReader reader = Files.newReader(cacheFile, StandardCharsets.UTF_8)) {
|
||||
object = new JSONObject(new JSONTokener(reader));
|
||||
} catch (FileNotFoundException e) {
|
||||
object = new JSONObject();
|
||||
}
|
||||
|
||||
// Deserialize all votes contained
|
||||
for (Object server : object.keySet()) {
|
||||
JSONArray voteArray = object.optJSONArray(((String) server));
|
||||
if (voteArray == null) continue;
|
||||
Set<Vote> votes = new LinkedHashSet<>(voteArray.length());
|
||||
for (int i = 0; i < voteArray.length(); i++) {
|
||||
votes.add(new Vote(voteArray.getJSONObject(i)));
|
||||
}
|
||||
voteCache.put(((String) server), votes);
|
||||
// Deserialize all votes contained
|
||||
for (Object server : object.keySet()) {
|
||||
JSONArray voteArray = object.getJSONArray(((String) server));
|
||||
List<Vote> votes = new ArrayList<>(voteArray.length());
|
||||
for (int i = 0; i < voteArray.length(); i++) {
|
||||
JSONObject voteObject = voteArray.getJSONObject(i);
|
||||
votes.add(new Vote(voteObject));
|
||||
}
|
||||
} else {
|
||||
cacheFile.createNewFile();
|
||||
voteCache.put(((String) server), votes);
|
||||
}
|
||||
}
|
||||
|
||||
public void save() throws IOException {
|
||||
cacheLock.lock();
|
||||
// Create a copy of the votes.
|
||||
JSONObject votesObject = new JSONObject();
|
||||
for (Map.Entry<String, Collection<Vote>> entry : voteCache.entrySet()) {
|
||||
JSONArray array = new JSONArray();
|
||||
for (Vote vote : entry.getValue()) {
|
||||
array.put(vote.serialize());
|
||||
try {
|
||||
// Create a copy of the votes.
|
||||
for (Map.Entry<String, Collection<Vote>> entry : voteCache.entrySet()) {
|
||||
JSONArray array = new JSONArray();
|
||||
for (Vote vote : entry.getValue()) {
|
||||
array.put(vote.serialize());
|
||||
}
|
||||
votesObject.put(entry.getKey(), array);
|
||||
}
|
||||
votesObject.put(entry.getKey(), array);
|
||||
} finally {
|
||||
cacheLock.unlock();
|
||||
}
|
||||
cacheLock.unlock();
|
||||
|
||||
try (BufferedWriter writer = Files.newWriter(cacheFile, StandardCharsets.UTF_8)) {
|
||||
votesObject.write(writer);
|
||||
|
||||
Vendored
+23
-12
@@ -1,5 +1,6 @@
|
||||
package com.vexsoftware.votifier.bungee.forwarding.cache;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.vexsoftware.votifier.model.Vote;
|
||||
|
||||
@@ -22,28 +23,38 @@ public class MemoryVoteCache implements VoteCache {
|
||||
@Override
|
||||
public Collection<String> getCachedServers() {
|
||||
cacheLock.lock();
|
||||
Set<String> servers = ImmutableSet.copyOf(voteCache.keySet());
|
||||
cacheLock.unlock();
|
||||
return servers;
|
||||
try {
|
||||
return ImmutableList.copyOf(voteCache.keySet());
|
||||
} finally {
|
||||
cacheLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToCache(Vote v, String server) {
|
||||
if (server == null) throw new NullPointerException();
|
||||
cacheLock.lock();
|
||||
Collection<Vote> voteCollection = voteCache.get(server);
|
||||
if (voteCollection == null) {
|
||||
voteCollection = new LinkedHashSet<>();
|
||||
voteCache.put(server, voteCollection);
|
||||
try {
|
||||
Collection<Vote> voteCollection = voteCache.get(server);
|
||||
if (voteCollection == null) {
|
||||
voteCollection = new ArrayList<>();
|
||||
voteCache.put(server, voteCollection);
|
||||
}
|
||||
voteCollection.add(v);
|
||||
} finally {
|
||||
cacheLock.unlock();
|
||||
}
|
||||
voteCollection.add(v);
|
||||
cacheLock.unlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Vote> evict(String server) {
|
||||
if (server == null) throw new NullPointerException();
|
||||
cacheLock.lock();
|
||||
Collection<Vote> fromCollection = voteCache.remove(server);
|
||||
cacheLock.unlock();
|
||||
return fromCollection != null ? ImmutableSet.copyOf(fromCollection) : ImmutableSet.<Vote>of();
|
||||
try {
|
||||
Collection<Vote> fromCollection = voteCache.remove(server);
|
||||
return fromCollection != null ? fromCollection : ImmutableList.<Vote>of();
|
||||
} finally {
|
||||
cacheLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>nuvotifier</artifactId>
|
||||
<groupId>com.vexsoftware</groupId>
|
||||
<version>2.3.2.2</version>
|
||||
<version>2.3.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.vexsoftware.votifier.net.VotifierSession;
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
public interface VoteHandler {
|
||||
void onVoteReceived(Vote vote, VotifierSession.ProtocolVersion protocolVersion) throws Exception;
|
||||
void onVoteReceived(Channel channel, Vote vote, VotifierSession.ProtocolVersion protocolVersion) throws Exception;
|
||||
|
||||
void onError(Channel channel, Throwable throwable);
|
||||
}
|
||||
@@ -19,7 +19,7 @@ public class VoteInboundHandler extends SimpleChannelInboundHandler<Vote> {
|
||||
protected void channelRead0(ChannelHandlerContext ctx, final Vote vote) throws Exception {
|
||||
VotifierSession session = ctx.channel().attr(VotifierSession.KEY).get();
|
||||
|
||||
handler.onVoteReceived(vote, session.getVersion());
|
||||
handler.onVoteReceived(ctx.channel(), vote, session.getVersion());
|
||||
|
||||
if (session.getVersion() == VotifierSession.ProtocolVersion.ONE) {
|
||||
ctx.close();
|
||||
|
||||
+2
-5
@@ -12,10 +12,7 @@ import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@@ -92,6 +89,6 @@ public class VotifierProtocol2Decoder extends MessageToMessageDecoder<String> {
|
||||
mac2.reset();
|
||||
byte[] realSig = mac2.doFinal(calculatedSig);
|
||||
|
||||
return Arrays.equals(clientSig, realSig);
|
||||
return MessageDigest.isEqual(clientSig, realSig);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ package com.vexsoftware.votifier.net.protocol.v1crypto;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
@@ -45,21 +46,18 @@ public class RSAIO {
|
||||
PrivateKey privateKey = keyPair.getPrivate();
|
||||
PublicKey publicKey = keyPair.getPublic();
|
||||
|
||||
// Store the public key.
|
||||
// Store the public and private keys.
|
||||
X509EncodedKeySpec publicSpec = new X509EncodedKeySpec(
|
||||
publicKey.getEncoded());
|
||||
FileOutputStream out = new FileOutputStream(directory + "/public.key");
|
||||
out.write(DatatypeConverter.printBase64Binary(publicSpec.getEncoded())
|
||||
.getBytes());
|
||||
out.close();
|
||||
|
||||
// Store the private key.
|
||||
PKCS8EncodedKeySpec privateSpec = new PKCS8EncodedKeySpec(
|
||||
privateKey.getEncoded());
|
||||
out = new FileOutputStream(directory + "/private.key");
|
||||
out.write(DatatypeConverter.printBase64Binary(privateSpec.getEncoded())
|
||||
.getBytes());
|
||||
out.close();
|
||||
try (FileOutputStream publicOut = new FileOutputStream(directory + "/public.key");
|
||||
FileOutputStream privateOut = new FileOutputStream(directory + "/private.key")) {
|
||||
publicOut.write(DatatypeConverter.printBase64Binary(publicSpec.getEncoded())
|
||||
.getBytes(StandardCharsets.UTF_8));
|
||||
privateOut.write(DatatypeConverter.printBase64Binary(privateSpec.getEncoded())
|
||||
.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,13 +73,13 @@ public class RSAIO {
|
||||
File publicKeyFile = new File(directory + "/public.key");
|
||||
byte[] encodedPublicKey = Files.readAllBytes(publicKeyFile.toPath());
|
||||
encodedPublicKey = DatatypeConverter.parseBase64Binary(new String(
|
||||
encodedPublicKey));
|
||||
encodedPublicKey, StandardCharsets.UTF_8));
|
||||
|
||||
// Read the private key file.
|
||||
File privateKeyFile = new File(directory + "/private.key");
|
||||
byte[] encodedPrivateKey = Files.readAllBytes(privateKeyFile.toPath());
|
||||
encodedPrivateKey = DatatypeConverter.parseBase64Binary(new String(
|
||||
encodedPrivateKey));
|
||||
encodedPrivateKey, StandardCharsets.UTF_8));
|
||||
|
||||
// Instantiate and return the key pair.
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
|
||||
+2
-2
@@ -74,11 +74,11 @@ public class StandaloneVotifierPlugin implements VotifierPlugin, VoteHandler {
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return "2.3.2.2";
|
||||
return "2.3.5";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVoteReceived(Vote vote, VotifierSession.ProtocolVersion protocolVersion) throws Exception {
|
||||
public void onVoteReceived(Channel channel, Vote vote, VotifierSession.ProtocolVersion protocolVersion) throws Exception {
|
||||
receiver.onVote(vote);
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -7,6 +7,7 @@ import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.security.Key;
|
||||
import java.security.KeyPair;
|
||||
import java.security.interfaces.RSAKey;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -27,6 +28,9 @@ public class VotifierServerBuilder {
|
||||
|
||||
public VotifierServerBuilder v1Key(KeyPair v1Key) {
|
||||
this.v1Key = Objects.requireNonNull(v1Key, "v1Key");
|
||||
if (!(v1Key.getPrivate() instanceof RSAKey)) {
|
||||
throw new IllegalArgumentException("Provided key is not an RSA key.");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<groupId>com.vexsoftware</groupId>
|
||||
<artifactId>nuvotifier</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>2.3.2.2</version>
|
||||
<version>2.3.5</version>
|
||||
<modules>
|
||||
<module>common</module>
|
||||
<module>bukkit</module>
|
||||
@@ -23,20 +23,17 @@
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>bukkit</id>
|
||||
<url>http://repo.bukkit.org/content/groups/public/</url>
|
||||
<id>spigotmc-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>minimumio-repo</id>
|
||||
<url>http://repo.minimum.io/content/repositories/releases/</url>
|
||||
<id>bintray-nuvotifier-maven</id>
|
||||
<name>nuvotifier-maven</name>
|
||||
<url>https://api.bintray.com/maven/nuvotifier/maven/NuVotifier/;publish=1</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>minimumio-repo-snapshots</id>
|
||||
<url>http://repo.minimum.io/content/repositories/snapshots/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<build>
|
||||
|
||||
+7
-2
@@ -5,12 +5,17 @@
|
||||
<parent>
|
||||
<artifactId>nuvotifier</artifactId>
|
||||
<groupId>com.vexsoftware</groupId>
|
||||
<version>2.3.2.2</version>
|
||||
<version>2.3.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>nuvotifier-sponge</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>sponge-maven-repo</id>
|
||||
@@ -50,7 +55,7 @@
|
||||
<dependency>
|
||||
<groupId>org.spongepowered</groupId>
|
||||
<artifactId>spongeapi</artifactId>
|
||||
<version>4.0.1</version>
|
||||
<version>5.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -53,7 +53,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@Plugin(id = "nuvotifier", name = "NuVotifier", version = "2.3.2.2")
|
||||
@Plugin(id = "nuvotifier", name = "NuVotifier", version = "2.3.5")
|
||||
public class VotifierPlugin implements VoteHandler, com.vexsoftware.votifier.VotifierPlugin, ForwardedVoteListener {
|
||||
private Logger logger;
|
||||
@Inject
|
||||
@@ -163,87 +163,81 @@ public class VotifierPlugin implements VoteHandler, com.vexsoftware.votifier.Vot
|
||||
|
||||
debug = node.getNode("debug").getBoolean(false);
|
||||
|
||||
boolean setUpPort = node.getNode("enableExternal").getBoolean(true); //Always default to running the external port
|
||||
// Load Votifier tokens.
|
||||
ConfigurationNode tokenSection = node.getNode("tokens");
|
||||
|
||||
if (setUpPort) {
|
||||
// Load Votifier tokens.
|
||||
ConfigurationNode tokenSection = node.getNode("tokens");
|
||||
|
||||
if (tokenSection.hasMapChildren()) {
|
||||
for (Map.Entry<Object, ? extends ConfigurationNode> entry : tokenSection.getChildrenMap().entrySet()) {
|
||||
if (entry.getKey() instanceof String) {
|
||||
tokens.put((String) entry.getKey(), KeyCreator.createKeyFrom(entry.getValue().getString()));
|
||||
logger.info("Loaded token for website: " + entry.getKey());
|
||||
}
|
||||
if (tokenSection.hasMapChildren()) {
|
||||
for (Map.Entry<Object, ? extends ConfigurationNode> entry : tokenSection.getChildrenMap().entrySet()) {
|
||||
if (entry.getKey() instanceof String) {
|
||||
tokens.put((String) entry.getKey(), KeyCreator.createKeyFrom(entry.getValue().getString()));
|
||||
logger.info("Loaded token for website: " + entry.getKey());
|
||||
}
|
||||
} else {
|
||||
String token = TokenUtil.newToken();
|
||||
tokenSection.setValue(ImmutableMap.of("default", token));
|
||||
tokens.put("default", KeyCreator.createKeyFrom(token));
|
||||
try {
|
||||
loader.save(node);
|
||||
} catch (IOException e) {
|
||||
logger.error("Error generating Votifier token", e);
|
||||
gracefulExit();
|
||||
return;
|
||||
}
|
||||
logger.info("------------------------------------------------------------------------------");
|
||||
logger.info("No tokens were found in your configuration, so we've generated one for you.");
|
||||
logger.info("Your default Votifier token is " + token + ".");
|
||||
logger.info("You will need to provide this token when you submit your server to a voting");
|
||||
logger.info("list.");
|
||||
logger.info("------------------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
// Initialize the receiver.
|
||||
final String host = node.getNode("host").getString(hostAddr);
|
||||
final int port = node.getNode("port").getInt(8192);
|
||||
if (debug)
|
||||
logger.info("DEBUG mode enabled!");
|
||||
|
||||
final boolean disablev1 = node.getNode("disable-v1-protocol").getBoolean(false);
|
||||
if (disablev1) {
|
||||
logger.info("------------------------------------------------------------------------------");
|
||||
logger.info("Votifier protocol v1 parsing has been disabled. Most voting websites do not");
|
||||
logger.info("currently support the modern Votifier protocol in NuVotifier.");
|
||||
logger.info("------------------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
serverGroup = new NioEventLoopGroup(1);
|
||||
|
||||
new ServerBootstrap()
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.group(serverGroup)
|
||||
.childHandler(new ChannelInitializer<NioSocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(NioSocketChannel channel) throws Exception {
|
||||
channel.attr(VotifierSession.KEY).set(new VotifierSession());
|
||||
channel.attr(com.vexsoftware.votifier.VotifierPlugin.KEY).set(VotifierPlugin.this);
|
||||
channel.pipeline().addLast("greetingHandler", new VotifierGreetingHandler());
|
||||
channel.pipeline().addLast("protocolDifferentiator", new VotifierProtocolDifferentiator(false, !disablev1));
|
||||
channel.pipeline().addLast("voteHandler", new VoteInboundHandler(VotifierPlugin.this));
|
||||
}
|
||||
})
|
||||
.bind(host, port)
|
||||
.addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (future.isSuccess()) {
|
||||
serverChannel = future.channel();
|
||||
logger.info("Votifier enabled on socket "+serverChannel.localAddress()+".");
|
||||
} else {
|
||||
SocketAddress socketAddress = future.channel().localAddress();
|
||||
if (socketAddress == null) {
|
||||
socketAddress = new InetSocketAddress(host, port);
|
||||
}
|
||||
logger.error("Votifier was not able to bind to " + socketAddress, future.cause());
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
logger.info("You have enableExternal set to false in your config.yml. NuVotifier will NOT listen to votes coming in from an external voting list.");
|
||||
String token = TokenUtil.newToken();
|
||||
tokenSection.setValue(ImmutableMap.of("default", token));
|
||||
tokens.put("default", KeyCreator.createKeyFrom(token));
|
||||
try {
|
||||
loader.save(node);
|
||||
} catch (IOException e) {
|
||||
logger.error("Error generating Votifier token", e);
|
||||
gracefulExit();
|
||||
return;
|
||||
}
|
||||
logger.info("------------------------------------------------------------------------------");
|
||||
logger.info("No tokens were found in your configuration, so we've generated one for you.");
|
||||
logger.info("Your default Votifier token is " + token + ".");
|
||||
logger.info("You will need to provide this token when you submit your server to a voting");
|
||||
logger.info("list.");
|
||||
logger.info("------------------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
// Initialize the receiver.
|
||||
final String host = node.getNode("host").getString(hostAddr);
|
||||
final int port = node.getNode("port").getInt(8192);
|
||||
if (debug)
|
||||
logger.info("DEBUG mode enabled!");
|
||||
|
||||
final boolean disablev1 = node.getNode("disable-v1-protocol").getBoolean(false);
|
||||
if (disablev1) {
|
||||
logger.info("------------------------------------------------------------------------------");
|
||||
logger.info("Votifier protocol v1 parsing has been disabled. Most voting websites do not");
|
||||
logger.info("currently support the modern Votifier protocol in NuVotifier.");
|
||||
logger.info("------------------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
serverGroup = new NioEventLoopGroup(1);
|
||||
|
||||
new ServerBootstrap()
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.group(serverGroup)
|
||||
.childHandler(new ChannelInitializer<NioSocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(NioSocketChannel channel) throws Exception {
|
||||
channel.attr(VotifierSession.KEY).set(new VotifierSession());
|
||||
channel.attr(com.vexsoftware.votifier.VotifierPlugin.KEY).set(VotifierPlugin.this);
|
||||
channel.pipeline().addLast("greetingHandler", new VotifierGreetingHandler());
|
||||
channel.pipeline().addLast("protocolDifferentiator", new VotifierProtocolDifferentiator(false, !disablev1));
|
||||
channel.pipeline().addLast("voteHandler", new VoteInboundHandler(VotifierPlugin.this));
|
||||
}
|
||||
})
|
||||
.bind(host, port)
|
||||
.addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (future.isSuccess()) {
|
||||
serverChannel = future.channel();
|
||||
logger.info("Votifier enabled on socket "+serverChannel.localAddress()+".");
|
||||
} else {
|
||||
SocketAddress socketAddress = future.channel().localAddress();
|
||||
if (socketAddress == null) {
|
||||
socketAddress = new InetSocketAddress(host, port);
|
||||
}
|
||||
logger.error("Votifier was not able to bind to " + socketAddress, future.cause());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ConfigurationNode forwardingConfig = node.getNode("forwarding");
|
||||
if (forwardingConfig != null) {
|
||||
String method = forwardingConfig.getNode("method").getString("none").toLowerCase(); //Default to lower case for case-insensitive searches
|
||||
@@ -340,12 +334,12 @@ public class VotifierPlugin implements VoteHandler, com.vexsoftware.votifier.Vot
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVoteReceived(final Vote vote, VotifierSession.ProtocolVersion protocolVersion) throws Exception {
|
||||
public void onVoteReceived(Channel channel, final Vote vote, VotifierSession.ProtocolVersion protocolVersion) throws Exception {
|
||||
if (debug) {
|
||||
if (protocolVersion == VotifierSession.ProtocolVersion.ONE) {
|
||||
logger.info("Got a protocol v1 vote record -> " + vote);
|
||||
logger.info("Got a protocol v1 vote record from " + channel.remoteAddress() + " -> " + vote);
|
||||
} else {
|
||||
logger.info("Got a protocol v2 vote record -> " + vote);
|
||||
logger.info("Got a protocol v2 vote record from " + channel.remoteAddress() + " -> " + vote);
|
||||
}
|
||||
}
|
||||
Sponge.getScheduler().createTaskBuilder()
|
||||
|
||||
@@ -9,10 +9,6 @@ port: 8192
|
||||
# This is useful when initially setting up NuVotifier to ensure votes are being delivered.
|
||||
debug: false
|
||||
|
||||
# Setting this value to false will turn off the votifier port listening for external votes. This is beneficial if the server
|
||||
# is only listening for votes coming from NuVotifier running on your BungeeCord.
|
||||
enableExternal: true
|
||||
|
||||
# Setting this option to true will disable handling of Protocol v1 packets. While the old protocol is not secure, this
|
||||
# option is currently not recommended as most voting sites only support the old protocol at present. However, if you are
|
||||
# using NuVotifier's proxy forwarding mechanism, enabling this option will increase your server's security.
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>nuvotifier</artifactId>
|
||||
<groupId>com.vexsoftware</groupId>
|
||||
<version>2.3.2.2</version>
|
||||
<version>2.3.5</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ networks.
|
||||
# Installation
|
||||
|
||||
The NuVotifier Universal jar (the default jar that is distributed on spigotmc.org) can be installed on Bukkit, BungeeCord,
|
||||
and Sponge servers as-is without modification.
|
||||
and Sponge servers as-is.
|
||||
|
||||
The Universal JAR can be downloaded off our [SpigotMC resource page](https://www.spigotmc.org/resources/nuvotifier.13449/).
|
||||
|
||||
@@ -18,7 +18,7 @@ the legacy protocol will be referred to v1. As of writing, most if not all vote
|
||||
|
||||
## Enabling the NuVotifier Server port
|
||||
|
||||
NuVotifier allows for the server port to be turned off when NuVotifier is only being used to forward votes. This is only
|
||||
NuVotifier allows for the server port to be turned off when NuVotifier is only receiving forwarded votes. This is only
|
||||
an option on Bukkit based servers, since it would not make logical sense for the port to be turned off on Bungee servers.
|
||||
|
||||
If you are receiving votes from a server list directly on the server in question (votes are not being forwarded through plugin
|
||||
@@ -28,10 +28,10 @@ be set to false.
|
||||
|
||||
## Port Configuration
|
||||
|
||||
One of NuVotifier's functions is acting as a vote server (receiver). The IP for NuVotifier to bind to is configured
|
||||
NuVotifier's main function is acting as a vote server (receiver). The IP for NuVotifier to bind to is configured
|
||||
by the `host` and `ip` configuration values within the config.yml files within the NuVotifier plugin folder.
|
||||
Most times, you will want this `host` value to be set to `0.0.0.0` or your server's ip. `0.0.0.0` will bind to all
|
||||
ip ports on your machine, while specifying a certain IP will only bind to that ip. If you don't know what to set this
|
||||
network addresses on your machine, while specifying a certain IP will only bind to that ip. If you don't know what to set this
|
||||
to, `0.0.0.0` is a safe bet. By default, NuVotifier listens on port 8192. This is the same as the default Votifier port.
|
||||
If you change this, you will have to remember this when setting up forwarding or server lists.
|
||||
|
||||
@@ -39,7 +39,7 @@ If you change this, you will have to remember this when setting up forwarding or
|
||||
|
||||
When first setting up NuVotifier, you will probably want debug mode to be enabled. This prints extra information to the
|
||||
console, ensuring that votes are being processed as they should. If you are experiencing an error, or having issues with
|
||||
votes being processed, you should first look to enable this. Debug mode can be turned on by setting `debug` in the config.yml
|
||||
votes being processed, you should first enable this. Debug mode can be turned on by setting `debug` in the config.yml
|
||||
to true.
|
||||
|
||||
## Tokens vs Public Key
|
||||
@@ -51,7 +51,7 @@ should be used. When setting up the `proxy` forwarding method, tokens should be
|
||||
Making a new token is as easy as adding another entry into `tokens` with the serviceName as the key and whatever string you want
|
||||
as the value. You can usually find the serviceName of a vote provider on their setup page if they use v2.
|
||||
|
||||
Unless a website specifies it, you should assume that the website is using v1, and you should enter your `rsa/public.key`.
|
||||
Unless a website specifies it, you should assume that the website is using v1, and you should use `rsa/public.key`.
|
||||
|
||||
## Forwarding
|
||||
|
||||
@@ -90,22 +90,22 @@ This is suitable for testing, but not for production system.
|
||||
|
||||
Votes can also be cached in a file located in the NuVotifier plugin folder. To enable this, you can set `cache` to file.
|
||||
If you want to change the file location from the default, you can set this under the `name` config under the `file` section.
|
||||
This caching method is suitable for most people.
|
||||
This caching method is suitable for most people. This is the default option.
|
||||
|
||||
##### No Caching
|
||||
|
||||
Caching can also be turned off. This is the default option. You can do this by setting `cache` to `none`. This is also not
|
||||
recommended, and is only suitable for a certain number of setups.
|
||||
Caching can also be turned off. You can do this by setting `cache` to `none`. This is also not recommended, and is only
|
||||
suitable for a certain number of setups.
|
||||
|
||||
### Proxy Based Forwarding
|
||||
|
||||
You can also forward votes using the proxy method. This will cause the BungeeCord to act as a voting websites, sending votes
|
||||
You can also forward votes using the proxy method. This will cause the BungeeCord to act like a voting website, sending votes
|
||||
to each server's NuVotifier port. To enable this method, you must set the `method` under `forwarding` to `proxy` in your
|
||||
BungeeCord config.yml. Within the server's config.yml, `forwarding` should be set to `none`.
|
||||
|
||||
For each server you wish to forward to, you must add each to your BungeeCord config.yml under the `proxy` section of `forwarding`.
|
||||
For each, you must specify the ip address (`address`), port (`port`) and token (`key`). Each backend Bukkit server should have
|
||||
1 default token under the `tokens` section. This is the token that should be used as the token for the `key` in that server's
|
||||
For each, you must specify the ip address (`address`), port (`port`) and token (`token`). Each backend Bukkit server should have
|
||||
1 default token under the `tokens` section. This is the token that should be used as the token for the `token` in that server's
|
||||
section within the `proxy` section. If the server is on the same server (same ip) as the BungeeCord server, you may
|
||||
use the `127.0.0.1` or `localhost` address, setting both the `proxy` forwarding address and Bukkit config.yml address to it.
|
||||
|
||||
@@ -122,7 +122,7 @@ and for Sponge [here](https://github.com/NuVotifier/NuVotifier/blob/master/spong
|
||||
|
||||
## Testing
|
||||
|
||||
There is a free resource for testing your NuVotifier setups at [ibj.io/v](https://ibj.io/v). If you are setting up your
|
||||
There is a free resource for testing your NuVotifier setups at [votifier.inaptbox.com](https://votifier.inaptbox.com). If you are setting up your
|
||||
network or server and want a server to get test votes on, you are more than welcome to use it.
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user