Compare commits

...
20 Commits
Author SHA1 Message Date
Tux 9355d6015f fix #7 2016-03-24 15:50:06 -04:00
Tux 700db6dca0 Add standalone server support 2016-03-22 21:41:04 -04:00
Tux f61ba7a6ad fix depend 2016-03-08 08:09:16 -05:00
Tux fe7e8cef41 SpongeAPI 4.x 2016-03-08 08:07:22 -05:00
Tux 7cda39ad12 fix travis 2016-03-05 03:24:37 -05:00
Tux b377a53de4 Fix vote detection 2016-03-05 01:15:57 -05:00
Tux 9a306365b8 2.3.2.2 2016-03-05 00:50:39 -05:00
Tux f74cdbe648 Read and drain the full vote buffer 2016-02-28 21:37:06 -05:00
Tux 6a51c1c106 Don't accept > 16 character usernames in v2 2016-02-28 00:09:31 -05:00
Tux 36195be292 Repermit long usernames since some voting sites still insist on sending them
Votifier v2 votes will not accept them, however.
2016-02-28 00:08:26 -05:00
Tux 893fe93ab6 Document hmacEqual() 2016-01-29 21:46:37 -05:00
Tux 90e844b082 formatting tweak 2016-01-29 21:43:03 -05:00
Joseph Hirschfeld 886b60b2de Only send info when in debug mode 2016-01-29 13:40:15 -05:00
Joseph Hirschfeld 30d8e9884c Use 'token' instead of 'key' to avoid confusion between v1 public keys and v2 tokens. 2016-01-29 01:36:03 -05:00
Joseph Hirschfeld 7e05b0752b Add actual link to usage document 2016-01-28 22:38:35 -05:00
Joseph Hirschfeld e124c371b3 Add build notification icon 2016-01-28 22:37:01 -05:00
Joseph Hirschfeld 4af4ae1006 Add additional logging when the votifier port is opened 2016-01-28 22:31:07 -05:00
Tux b63c4a7c68 Make v1 validation a bit smarter in an attempt to accept votes from brain-damaged libraries 2016-01-28 21:26:32 -05:00
Tux 3cf4741cbb Whoops 2016-01-24 23:59:51 -05:00
Tux bb6c311e2f Can only compile with 1.8 because Sponge requires 1.8 2016-01-24 22:09:31 -05:00
25 changed files with 256 additions and 61 deletions

No files matched your search

+1 -3
View File
@@ -1,13 +1,11 @@
sudo: false
language: java
jdk:
- openjdk7
- oraclejdk7
- oraclejdk8
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.jar
file: universal/target/nuvotifier-universal-2.3.2.2.jar
on:
tags: true
+3 -1
View File
@@ -2,6 +2,8 @@
NuVotifier is a Bukkit plugin whose purpose is to be notified (aka *votified*) when a vote is made on a Minecraft server top list for the server. NuVotifier creates a *lightweight* server that waits for connections by Minecraft server lists and uses a simple protocol to get the required information. NuVotifier is *secure*, and makes sure that all vote notifications are delivered by authentic top lists.
[![Build Status](https://travis-ci.org/NuVotifier/NuVotifier.svg?branch=master)](https://travis-ci.org/NuVotifier/NuVotifier)
## Why fork Votifier?
Votifier has lagged in activity, has severe security flaws in its protocol, and is vulnerable to denial of service attacks.
@@ -27,7 +29,7 @@ NuVotifier configures itself the first time it is run. If you have an existing V
If you want to customize NuVotifier, simply the edit `./plugins/(Nu)Votifier/config.yml` file.
An in-depth configuration guide is located in `usage.md` of this repository.
An in-depth configuration guide is located in the [usage](https://github.com/NuVotifier/NuVotifier/blob/master/usage.md) document.
### Tokens
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>nuvotifier</artifactId>
<groupId>com.vexsoftware</groupId>
<version>2.3.2</version>
<version>2.3.2.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -258,7 +258,7 @@ public class NuVotifierBukkit extends JavaPlugin implements VoteHandler, Votifie
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
serverChannel = future.channel();
getLogger().info("Votifier enabled.");
getLogger().info("Votifier enabled on socket "+serverChannel.localAddress()+".");
} else {
SocketAddress socketAddress = future.channel().localAddress();
if (socketAddress == null) {
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>nuvotifier</artifactId>
<groupId>com.vexsoftware</groupId>
<version>2.3.2</version>
<version>2.3.2.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -221,7 +221,7 @@ public class NuVotifier extends Plugin implements VoteHandler, VotifierPlugin {
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
serverChannel = future.channel();
getLogger().info("Votifier enabled.");
getLogger().info("Votifier enabled on socket "+serverChannel.localAddress()+".");
} else {
SocketAddress socketAddress = future.channel().localAddress();
if (socketAddress == null) {
@@ -293,7 +293,8 @@ public class NuVotifier extends Plugin implements VoteHandler, VotifierPlugin {
continue;
}
ProxyForwardingVoteSource.BackendServer server = new ProxyForwardingVoteSource.BackendServer(s,
new InetSocketAddress(address, section.getShort("port")), KeyCreator.createKeyFrom(section.getString("key")));
new InetSocketAddress(address, section.getShort("port")),
KeyCreator.createKeyFrom(section.getString("token",section.getString("key"))));
serverList.add(server);
}
@@ -76,7 +76,7 @@ public class ProxyForwardingVoteSource implements ForwardingVoteSource {
public void onFailure(Throwable error) {
handleFailure(server, v, error, tries);
}
}));
}, plugin));
}
})
.connect(server.address)
@@ -1,5 +1,6 @@
package com.vexsoftware.votifier.bungee.forwarding.proxy.client;
import com.vexsoftware.votifier.bungee.NuVotifier;
import com.vexsoftware.votifier.model.Vote;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
@@ -8,10 +9,12 @@ import io.netty.handler.codec.CorruptedFrameException;
public class VotifierProtocol2HandshakeHandler extends SimpleChannelInboundHandler<String> {
private final Vote toSend;
private final VotifierResponseHandler responseHandler;
private final NuVotifier nuVotifier;
public VotifierProtocol2HandshakeHandler(Vote toSend, VotifierResponseHandler responseHandler) {
public VotifierProtocol2HandshakeHandler(Vote toSend, VotifierResponseHandler responseHandler, NuVotifier nuVotifier) {
this.toSend = toSend;
this.responseHandler = responseHandler;
this.nuVotifier = nuVotifier;
}
@Override
@@ -22,7 +25,9 @@ public class VotifierProtocol2HandshakeHandler extends SimpleChannelInboundHandl
}
VoteRequest request = new VoteRequest(handshakeContents[2], toSend);
System.out.println(request);
if (nuVotifier.isDebug()) {
nuVotifier.getLogger().info("Sent request: " + request.toString());
}
ctx.writeAndFlush(request);
ctx.pipeline().addLast(new VotifierProtocol2ResponseHandler(responseHandler));
ctx.pipeline().remove(this);
@@ -58,8 +58,8 @@ forwarding:
Hub:
address: 127.0.0.1
port: 8193
key: MyKeyHere
token: MyKeyHere
Hub2:
address: 127.0.0.1
port: 8194
key: AnotherKeyHere
token: AnotherKeyHere
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>nuvotifier</artifactId>
<groupId>com.vexsoftware</groupId>
<version>2.3.2</version>
<version>2.3.2.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -52,9 +52,6 @@ public class Vote {
}
public Vote(String serviceName, String username, String address, String timeStamp) {
if (username.length() > 16) {
throw new IllegalArgumentException("Username is too long.");
}
this.serviceName = serviceName;
this.username = username;
this.address = address;
@@ -105,9 +102,6 @@ public class Vote {
*/
@Deprecated
public void setUsername(String username) {
if (username.length() > 16) {
throw new IllegalArgumentException("Username is too long.");
}
this.username = username;
}
@@ -17,10 +17,14 @@ import java.util.List;
public class VotifierProtocol1Decoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buf, List<Object> list) throws Exception {
byte[] block = new byte[256];
if (buf.readableBytes() < 256) {
return;
}
byte[] block = new byte[buf.readableBytes()];
buf.getBytes(0, block);
// "Drain" the whole buffer
buf.readerIndex(buf.capacity());
buf.readerIndex(buf.readableBytes());
VotifierPlugin plugin = ctx.channel().attr(VotifierPlugin.KEY).get();
@@ -63,6 +63,10 @@ public class VotifierProtocol2Decoder extends MessageToMessageDecoder<String> {
UUID.fromString(votePayload.getString("uuid"));
}
if (votePayload.getString("username").length() > 16) {
throw new CorruptedFrameException("Username too long");
}
// Create the vote.
Vote vote = new Vote(votePayload);
list.add(vote);
@@ -75,15 +79,18 @@ public class VotifierProtocol2Decoder extends MessageToMessageDecoder<String> {
// This randomizes the byte order to make timing attacks more difficult.
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(key);
byte[] messageCalc = mac.doFinal(message);
byte[] calculatedSig = mac.doFinal(message);
Mac mac2 = Mac.getInstance("HmacSHA256");
// Generate a random key for use in comparison
byte[] randomKey = new byte[32];
RANDOM.nextBytes(randomKey);
// Then generate two HMACs for the different signatures found
Mac mac2 = Mac.getInstance("HmacSHA256");
mac2.init(new SecretKeySpec(randomKey, "HmacSHA256"));
byte[] clientSig = mac2.doFinal(sig);
mac2.reset();
byte[] realSig = mac2.doFinal(messageCalc);
byte[] realSig = mac2.doFinal(calculatedSig);
return Arrays.equals(clientSig, realSig);
}
@@ -29,12 +29,10 @@ public class VotifierProtocolDifferentiator extends ByteToMessageDecoder {
protected void decode(ChannelHandlerContext ctx, ByteBuf buf, List<Object> list) throws Exception {
// Determine the number of bytes that are available.
int readable = buf.readableBytes();
buf.retain(); // TODO: Is this needed?
if (readable < 2) {
// Some retarded voting sites (PMC?) seem to send empty buffers for no good reason.
// TODO: How can we handle this?
throw new CorruptedFrameException("Frame is too short");
return;
}
short readMagic = buf.readShort();
@@ -46,6 +44,8 @@ public class VotifierProtocolDifferentiator extends ByteToMessageDecoder {
if (readMagic == PROTOCOL_2_MAGIC) {
// Short 0x733A + Message = Protocol v2 Vote
session.setVersion(VotifierSession.ProtocolVersion.TWO);
if (!testMode) {
ctx.pipeline().addAfter("protocolDifferentiator", "protocol2LengthDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 2, 0, 4));
ctx.pipeline().addAfter("protocol2LengthDecoder", "protocol2StringDecoder", new StringDecoder(StandardCharsets.UTF_8));
@@ -53,17 +53,16 @@ public class VotifierProtocolDifferentiator extends ByteToMessageDecoder {
ctx.pipeline().addAfter("protocol2VoteDecoder", "protocol2StringEncoder", new StringEncoder(StandardCharsets.UTF_8));
ctx.pipeline().remove(this);
}
session.setVersion(VotifierSession.ProtocolVersion.TWO);
} else {
if (!allowv1) {
throw new CorruptedFrameException("This server only accepts well-formed Votifier v2 packets.");
}
// Probably Protocol v1 Vote Message
session.setVersion(VotifierSession.ProtocolVersion.ONE);
if (!testMode) {
ctx.pipeline().addAfter("protocolDifferentiator", "protocol1Handler", new VotifierProtocol1Decoder());
ctx.pipeline().remove(this);
}
session.setVersion(VotifierSession.ProtocolVersion.ONE);
}
}
}
@@ -0,0 +1,89 @@
package com.vexsoftware.votifier.util.standalone;
import com.vexsoftware.votifier.VoteHandler;
import com.vexsoftware.votifier.VotifierPlugin;
import com.vexsoftware.votifier.model.Vote;
import com.vexsoftware.votifier.net.VotifierSession;
import com.vexsoftware.votifier.net.protocol.VoteInboundHandler;
import com.vexsoftware.votifier.net.protocol.VotifierGreetingHandler;
import com.vexsoftware.votifier.net.protocol.VotifierProtocolDifferentiator;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.net.InetSocketAddress;
import java.security.Key;
import java.security.KeyPair;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class StandaloneVotifierPlugin implements VotifierPlugin, VoteHandler {
private final Map<String, Key> tokens;
private final VoteReceiver receiver;
private final KeyPair v1Key;
private final InetSocketAddress bind;
private NioEventLoopGroup group;
public StandaloneVotifierPlugin(Map<String, Key> tokens, VoteReceiver receiver, KeyPair v1Key, InetSocketAddress bind) {
this.receiver = receiver;
this.bind = bind;
this.tokens = Collections.unmodifiableMap(new HashMap<>(tokens));
this.v1Key = v1Key;
}
public Throwable start() throws Throwable {
group = new NioEventLoopGroup(2);
ChannelFuture future = new ServerBootstrap()
.channel(NioServerSocketChannel.class)
.group(group)
.childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel channel) throws Exception {
channel.attr(VotifierSession.KEY).set(new VotifierSession());
channel.attr(VotifierPlugin.KEY).set(StandaloneVotifierPlugin.this);
channel.pipeline().addLast("greetingHandler", new VotifierGreetingHandler());
channel.pipeline().addLast("protocolDifferentiator", new VotifierProtocolDifferentiator(false, v1Key != null));
channel.pipeline().addLast("voteHandler", new VoteInboundHandler(StandaloneVotifierPlugin.this));
}
})
.bind(bind)
.syncUninterruptibly();
if (!future.isSuccess()) {
return future.cause();
} else {
return null;
}
}
@Override
public Map<String, Key> getTokens() {
return tokens;
}
@Override
public KeyPair getProtocolV1Key() {
return v1Key;
}
@Override
public String getVersion() {
return "2.3.2.2";
}
@Override
public void onVoteReceived(Vote vote, VotifierSession.ProtocolVersion protocolVersion) throws Exception {
receiver.onVote(vote);
}
@Override
public void onError(Channel channel, Throwable throwable) {
receiver.onException(throwable);
}
}
@@ -0,0 +1,8 @@
package com.vexsoftware.votifier.util.standalone;
import com.vexsoftware.votifier.model.Vote;
public interface VoteReceiver {
void onVote(Vote vote) throws Exception;
void onException(Throwable throwable);
}
@@ -0,0 +1,53 @@
package com.vexsoftware.votifier.util.standalone;
import com.vexsoftware.votifier.net.protocol.v1crypto.RSAIO;
import com.vexsoftware.votifier.util.KeyCreator;
import java.io.File;
import java.net.InetSocketAddress;
import java.security.Key;
import java.security.KeyPair;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class VotifierServerBuilder {
private final Map<String, Key> keyMap = new HashMap<>();
private KeyPair v1Key;
private InetSocketAddress bind;
private VoteReceiver receiver;
public VotifierServerBuilder addToken(String service, String token) {
Objects.requireNonNull(service, "service");
Objects.requireNonNull(token, "key");
keyMap.put(service, KeyCreator.createKeyFrom(token));
return this;
}
public VotifierServerBuilder v1Key(KeyPair v1Key) {
this.v1Key = Objects.requireNonNull(v1Key, "v1Key");
return this;
}
public VotifierServerBuilder v1KeyFolder(File file) throws Exception {
this.v1Key = RSAIO.load(Objects.requireNonNull(file, "file"));
return this;
}
public VotifierServerBuilder bind(InetSocketAddress bind) {
this.bind = Objects.requireNonNull(bind, "bind");
return this;
}
public VotifierServerBuilder receiver(VoteReceiver receiver) {
this.receiver = Objects.requireNonNull(receiver, "receiver");
return this;
}
public StandaloneVotifierPlugin create() {
Objects.requireNonNull(bind, "need an address to bind to");
Objects.requireNonNull(receiver, "need a receiver for votes");
return new StandaloneVotifierPlugin(keyMap, receiver, v1Key, bind);
}
}
@@ -0,0 +1,31 @@
package com.vexsoftware.votifier.net.protocol;
import com.vexsoftware.votifier.model.Vote;
import com.vexsoftware.votifier.net.protocol.v1crypto.RSA;
import java.nio.charset.StandardCharsets;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.List;
public class VoteUtil {
public static byte[] encodePOJOv1(Vote vote) throws Exception {
return encodePOJOv1(vote, TestVotifierPlugin.getI().getProtocolV1Key().getPublic());
}
public static byte[] encodePOJOv1(Vote vote, PublicKey key) throws Exception {
List<String> ordered = new ArrayList<>();
ordered.add("VOTE");
ordered.add(vote.getServiceName());
ordered.add(vote.getUsername());
ordered.add(vote.getAddress());
ordered.add(vote.getTimeStamp());
StringBuilder builder = new StringBuilder();
for (String s : ordered) {
builder.append(s).append('\n'); // naive join needed!
}
return RSA.encrypt(builder.toString().getBytes(StandardCharsets.UTF_8), key);
}
}
@@ -29,16 +29,12 @@ public class VotifierProtocol1DecoderTest {
@Test
public void testSuccessfulDecode() throws Exception {
// Encode a test vote.
String voteString = "VOTE\nTest\ntest\ntest\ntest\n";
// For reference, this is the same vote as a POJO:
Vote votePojo = new Vote("Test", "test", "test", "test");
// Send the vote
EmbeddedChannel channel = createChannel();
byte[] encrypted = RSA.encrypt(voteString.getBytes(StandardCharsets.UTF_8), TestVotifierPlugin.getI().getProtocolV1Key().getPublic());
byte[] encrypted = VoteUtil.encodePOJOv1(votePojo);
ByteBuf encryptedByteBuf = Unpooled.wrappedBuffer(encrypted);
assertTrue(channel.writeInbound(encryptedByteBuf));
@@ -81,8 +77,7 @@ public class VotifierProtocol1DecoderTest {
// Send the bad vote
EmbeddedChannel channel = createChannel();
String voteString = "VOTE\nTest\ntest\ntest\ntest\n";
byte[] encrypted = RSA.encrypt(voteString.getBytes(StandardCharsets.UTF_8), badPublicKey);
byte[] encrypted = VoteUtil.encodePOJOv1(new Vote("Test", "test", "test", "test"), badPublicKey);
ByteBuf encryptedByteBuf = Unpooled.wrappedBuffer(encrypted);
try {
@@ -1,5 +1,6 @@
package com.vexsoftware.votifier.net.protocol;
import com.vexsoftware.votifier.model.Vote;
import com.vexsoftware.votifier.net.VotifierSession;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
@@ -62,21 +63,6 @@ public class VotifierProtocolDifferentiatorTest {
channel.close();
}
@Test(expected = DecoderException.class)
public void failOnSmallBufferTest() {
EmbeddedChannel channel = new EmbeddedChannel(new VotifierProtocolDifferentiator(true, false));
ByteBuf buf = Unpooled.buffer(1);
buf.writeByte(0);
try {
channel.writeInbound(buf);
} finally {
buf.release();
channel.close();
}
}
@Test(expected = DecoderException.class)
public void failOnBadPacketTest() {
EmbeddedChannel channel = new EmbeddedChannel(new VotifierProtocolDifferentiator(true, false));
@@ -93,4 +79,22 @@ public class VotifierProtocolDifferentiatorTest {
channel.close();
}
}
@Test
public void tryIdentifyRealVotev1() throws Exception {
EmbeddedChannel channel = new EmbeddedChannel(new VotifierProtocolDifferentiator(true, true));
VotifierSession session = new VotifierSession();
channel.attr(VotifierSession.KEY).set(session);
Vote votePojo = new Vote("Test", "test", "test", "test");
byte[] encrypted = VoteUtil.encodePOJOv1(votePojo);
ByteBuf encryptedByteBuf = Unpooled.wrappedBuffer(encrypted);
channel.writeInbound(encryptedByteBuf);
assertEquals(VotifierSession.ProtocolVersion.ONE, session.getVersion());
encryptedByteBuf.release();
channel.close();
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
<groupId>com.vexsoftware</groupId>
<artifactId>nuvotifier</artifactId>
<packaging>pom</packaging>
<version>2.3.2</version>
<version>2.3.2.2</version>
<modules>
<module>common</module>
<module>bukkit</module>
+2 -2
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>nuvotifier</artifactId>
<groupId>com.vexsoftware</groupId>
<version>2.3.2</version>
<version>2.3.2.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -50,7 +50,7 @@
<dependency>
<groupId>org.spongepowered</groupId>
<artifactId>spongeapi</artifactId>
<version>3.0.0</version>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
@@ -34,6 +34,7 @@ import org.spongepowered.api.Sponge;
import org.spongepowered.api.config.ConfigDir;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.cause.Cause;
import org.spongepowered.api.event.cause.NamedCause;
import org.spongepowered.api.event.game.state.GameStartedServerEvent;
import org.spongepowered.api.event.game.state.GameStoppingServerEvent;
import org.spongepowered.api.plugin.Plugin;
@@ -52,7 +53,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@Plugin(id = "nuvotifier", name = "NuVotifier", version = "2.3.2")
@Plugin(id = "nuvotifier", name = "NuVotifier", version = "2.3.2.2")
public class VotifierPlugin implements VoteHandler, com.vexsoftware.votifier.VotifierPlugin, ForwardedVoteListener {
private Logger logger;
@Inject
@@ -229,7 +230,7 @@ public class VotifierPlugin implements VoteHandler, com.vexsoftware.votifier.Vot
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
serverChannel = future.channel();
logger.info("Votifier enabled.");
logger.info("Votifier enabled on socket "+serverChannel.localAddress()+".");
} else {
SocketAddress socketAddress = future.channel().localAddress();
if (socketAddress == null) {
@@ -351,7 +352,7 @@ public class VotifierPlugin implements VoteHandler, com.vexsoftware.votifier.Vot
.execute(new Runnable() {
@Override
public void run() {
VotifierEvent event = new VotifierEvent(vote, Cause.of(VotifierPlugin.this));
VotifierEvent event = new VotifierEvent(vote, Cause.of(NamedCause.of("Vote", vote)));
Sponge.getEventManager().post(event);
}
})
@@ -377,7 +378,7 @@ public class VotifierPlugin implements VoteHandler, com.vexsoftware.votifier.Vot
.execute(new Runnable() {
@Override
public void run() {
VotifierEvent event = new VotifierEvent(v, Cause.of(VotifierPlugin.this));
VotifierEvent event = new VotifierEvent(v, Cause.of(NamedCause.of("ForwardedVote", v)));
Sponge.getEventManager().post(event);
}
})
@@ -21,4 +21,8 @@ public class VotifierEvent extends AbstractEvent {
public Cause getCause() {
return cause;
}
public Vote getVote() {
return vote;
}
}
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>nuvotifier</artifactId>
<groupId>com.vexsoftware</groupId>
<version>2.3.2</version>
<version>2.3.2.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>