From 622a6ffa17e89f26f4019f16b7defd3031ff1632 Mon Sep 17 00:00:00 2001 From: Netherwhal Date: Sat, 10 Feb 2024 21:19:59 +0100 Subject: [PATCH] Add gh-actions (#3) --- .github/dependabot.yml | 12 + .github/workflows/build-and-publish.yml | 30 ++ Makefile | 5 - README.md | 6 +- build.gradle | 11 - gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 0 gradlew.bat | 184 +++++----- .../vexsoftware/votifier/ForwardServer.java | 21 -- .../vexsoftware/votifier/VotifierPlus.java | 313 ------------------ .../votifier/commands/CommandLoader.java | 130 -------- .../commands/CommandVotifierPlus.java | 49 --- .../commands/VotifierPlusTabCompleter.java | 50 --- .../vexsoftware/votifier/config/Config.java | 63 ---- .../vexsoftware/votifier/crypto/RSAIO.java | 124 ------- .../com/vexsoftware/votifier/model/Vote.java | 122 ------- .../votifier/model/VotifierEvent.java | 51 --- .../votifier/net/VoteReceiver.java | 266 --------------- .../simplyvotifier/SimplyVotifier.java | 234 +++++++++++++ .../simplyvotifier/config/Config.java | 39 +++ .../simplyvotifier}/crypto/RSA.java | 71 ++-- .../simplyvotifier/crypto/RSAIO.java | 119 +++++++ .../simplyvotifier}/crypto/RSAKeygen.java | 38 +-- .../simplyvotifier/model/Vote.java | 70 ++++ .../simplyvotifier/model/VotifierEvent.java | 40 +++ .../simplyvotifier/net/VoteReceiver.java | 224 +++++++++++++ src/main/resources/config.yml | 6 - src/main/resources/plugin.yml | 14 +- 28 files changed, 921 insertions(+), 1373 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/build-and-publish.yml mode change 100644 => 100755 gradlew delete mode 100644 src/main/java/com/vexsoftware/votifier/ForwardServer.java delete mode 100644 src/main/java/com/vexsoftware/votifier/VotifierPlus.java delete mode 100644 src/main/java/com/vexsoftware/votifier/commands/CommandLoader.java delete mode 100644 src/main/java/com/vexsoftware/votifier/commands/CommandVotifierPlus.java delete mode 100644 src/main/java/com/vexsoftware/votifier/commands/VotifierPlusTabCompleter.java delete mode 100644 src/main/java/com/vexsoftware/votifier/config/Config.java delete mode 100644 src/main/java/com/vexsoftware/votifier/crypto/RSAIO.java delete mode 100644 src/main/java/com/vexsoftware/votifier/model/Vote.java delete mode 100644 src/main/java/com/vexsoftware/votifier/model/VotifierEvent.java delete mode 100644 src/main/java/com/vexsoftware/votifier/net/VoteReceiver.java create mode 100644 src/main/java/net/simplyvanilla/simplyvotifier/SimplyVotifier.java create mode 100644 src/main/java/net/simplyvanilla/simplyvotifier/config/Config.java rename src/main/java/{com/vexsoftware/votifier => net/simplyvanilla/simplyvotifier}/crypto/RSA.java (50%) create mode 100644 src/main/java/net/simplyvanilla/simplyvotifier/crypto/RSAIO.java rename src/main/java/{com/vexsoftware/votifier => net/simplyvanilla/simplyvotifier}/crypto/RSAKeygen.java (63%) create mode 100644 src/main/java/net/simplyvanilla/simplyvotifier/model/Vote.java create mode 100644 src/main/java/net/simplyvanilla/simplyvotifier/model/VotifierEvent.java create mode 100644 src/main/java/net/simplyvanilla/simplyvotifier/net/VoteReceiver.java diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..def5ba5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + + - package-ecosystem: "gradle" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml new file mode 100644 index 0000000..2e2bc29 --- /dev/null +++ b/.github/workflows/build-and-publish.yml @@ -0,0 +1,30 @@ +name: Build and Publish + +on: + push: + branches: + - main + tags: + - '*' + pull_request: + branches: + - main + +env: + TERM: xterm-256color + +jobs: + build-and-publish: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Build jar + run: make + + - name: Release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + files: build/libs/*.jar diff --git a/Makefile b/Makefile index 15ffb50..3e32137 100644 --- a/Makefile +++ b/Makefile @@ -10,11 +10,6 @@ build: ./gradlew build -.PHONY: coveralls -coveralls: - ./gradlew jacocoTestReport coveralls - - .PHONY: wrapper wrapper: ./gradlew wrapper diff --git a/README.md b/README.md index a3011f0..ad70a71 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ -# VotifierPlus -Fork of votifier +# SimplyVotifier + +SimplyVotifier is a simple and easy to use Votifier listener plugin for PaperMC/Folia servers, originally forked from +[VotifierPlus](https://github.com/BenCodez/VotifierPlus) by BenCodez. diff --git a/build.gradle b/build.gradle index 1cfd81c..51830e7 100644 --- a/build.gradle +++ b/build.gradle @@ -25,15 +25,9 @@ repositories { maven { url 'https://repo.papermc.io/repository/maven-public/' } - maven { - url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' - } maven { url 'https://nexus.bencodez.com/repository/maven-public/' } - maven { - url 'https://oss.sonatype.org/content/repositories/snapshots' - } maven { url 'https://nexuslite.gcnt.net/repos/other/' } @@ -56,11 +50,6 @@ processResources { shadowJar { archiveClassifier.set('') relocate 'com.bencodez.advancedcore', 'net.simplyvanilla.dependency.advancedcore' - relocate 'net.pl3x.bukkit.chatapi', 'net.simplyvanilla.dependency.chatapi' - relocate 'me.mrten.mysqlapi', 'net.simplyvanilla.dependency.mysqlapi' - relocate 'com.zaxxer.HikariCP', 'net.simplyvanilla.dependency.hikaricp' - relocate 'com.zaxxer.hikari', 'net.simplyvanilla.dependency.hikari' - relocate 'org.bstats', 'net.simplyvanilla.dependency.bstats' minimize { dependencies { exclude('com.google') diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1af9e09..a80b22c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/gradlew.bat b/gradlew.bat index 93e3f59..7101f8e 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,92 +1,92 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/com/vexsoftware/votifier/ForwardServer.java b/src/main/java/com/vexsoftware/votifier/ForwardServer.java deleted file mode 100644 index 71d9563..0000000 --- a/src/main/java/com/vexsoftware/votifier/ForwardServer.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.vexsoftware.votifier; - -import lombok.Getter; - -public class ForwardServer { - @Getter - private String host; - @Getter - private int port; - @Getter - private String key; - @Getter - private boolean enabled; - - public ForwardServer(boolean enabled, String host, int port, String key) { - this.enabled = enabled; - this.host = host; - this.port = port; - this.key = key; - } -} diff --git a/src/main/java/com/vexsoftware/votifier/VotifierPlus.java b/src/main/java/com/vexsoftware/votifier/VotifierPlus.java deleted file mode 100644 index fe5b805..0000000 --- a/src/main/java/com/vexsoftware/votifier/VotifierPlus.java +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (C) 2012 Vex Software LLC - * This file is part of Votifier. - * - * Votifier is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Votifier is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Votifier. If not, see . - */ - -package com.vexsoftware.votifier; - -import com.bencodez.advancedcore.folialib.FoliaLib; -import java.io.File; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.URL; -import java.security.CodeSource; -import java.security.KeyPair; -import java.util.ArrayList; -import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.TimeUnit; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import org.bukkit.Bukkit; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; - -import com.bencodez.advancedcore.AdvancedCorePlugin; -import com.bencodez.advancedcore.api.command.CommandHandler; -import com.bencodez.advancedcore.api.metrics.BStatsMetrics; -import com.bencodez.advancedcore.api.updater.Updater; -import com.vexsoftware.votifier.commands.CommandLoader; -import com.vexsoftware.votifier.commands.CommandVotifierPlus; -import com.vexsoftware.votifier.commands.VotifierPlusTabCompleter; -import com.vexsoftware.votifier.config.Config; -import com.vexsoftware.votifier.crypto.RSAIO; -import com.vexsoftware.votifier.crypto.RSAKeygen; -import com.vexsoftware.votifier.model.Vote; -import com.vexsoftware.votifier.model.VotifierEvent; -import com.vexsoftware.votifier.net.VoteReceiver; - -import lombok.Getter; -import lombok.Setter; - -/** - * The main Votifier plugin class. - * - * @author Blake Beaupain - * @author Kramer Campbell - */ -public class VotifierPlus extends AdvancedCorePlugin { - - /** The Votifier instance. */ - private static VotifierPlus instance; - - @Getter - private FoliaLib foliaLib; - - public Config config; - - @Getter - @Setter - private Updater updater; - - /** The vote receiver. */ - private VoteReceiver voteReceiver; - - /** The RSA key pair. */ - @Setter - private KeyPair keyPair; - - @Getter - private ArrayList commands = new ArrayList(); - - @Override - public void onPostLoad() { - this.foliaLib = new FoliaLib(this); - - getCommand("votifierplus").setExecutor(new CommandVotifierPlus(this)); - getCommand("votifierplus").setTabCompleter(new VotifierPlusTabCompleter()); - CommandLoader.getInstance().loadCommands(); - - File rsaDirectory = new File(getDataFolder() + "/rsa"); - - /* - * Create RSA directory and keys if it does not exist; otherwise, read keys. - */ - try { - if (!rsaDirectory.exists()) { - rsaDirectory.mkdir(); - keyPair = RSAKeygen.generate(2048); - RSAIO.save(rsaDirectory, keyPair); - } else { - keyPair = RSAIO.load(rsaDirectory); - } - } catch (Exception ex) { - getLogger().severe("Error reading configuration file or RSA keys"); - gracefulExit(); - return; - } - - loadVoteReceiver(); - - metrics(); - } - - private void loadVoteReceiver() { - try { - voteReceiver = new VoteReceiver(config.getHost(), config.getPort()) { - - @Override - public void logWarning(String warn) { - getLogger().warning(warn); - } - - @Override - public void logSevere(String msg) { - getLogger().severe(msg); - } - - @Override - public void log(String msg) { - getLogger().info(msg); - } - - @Override - public String getVersion() { - return getDescription().getVersion(); - } - - @Override - public Set getServers() { - return config.getServers(); - } - - @Override - public ForwardServer getServerData(String s) { - ConfigurationSection d = config.getForwardingConfiguration(s); - return new ForwardServer(d.getBoolean("Enabled"), d.getString("Host", ""), d.getInt("Port"), - d.getString("Key", "")); - } - - @Override - public KeyPair getKeyPair() { - return instance.getKeyPair(); - } - - @Override - public void debug(Exception e) { - instance.debug(e); - } - - @Override - public void debug(String debug) { - instance.debug(debug); - } - - @Override - public void callEvent(Vote vote) { - foliaLib.getImpl().runAsync(new Runnable() { - public void run() { - Bukkit.getServer().getPluginManager().callEvent(new VotifierEvent(vote)); - } - }); - } - }; - voteReceiver.start(); - - getLogger().info("Votifier enabled."); - } catch (Exception ex) { - gracefulExit(); - return; - } - } - - @Override - public void onDisable() { - // Interrupt the vote receiver. - if (voteReceiver != null) { - voteReceiver.shutdown(); - } - getLogger().info("Votifier disabled."); - } - - private void gracefulExit() { - getLogger().severe("Votifier did not initialize properly!"); - } - - /** - * Gets the instance. - * - * @return The instance - */ - public static VotifierPlus getInstance() { - return instance; - } - - /** - * Gets the vote receiver. - * - * @return The vote receiver - */ - public VoteReceiver getVoteReceiver() { - return voteReceiver; - } - - /** - * Gets the keyPair. - * - * @return The keyPair - */ - public KeyPair getKeyPair() { - return keyPair; - } - - @Override - public void onPreLoad() { - instance = this; - - config = new Config(this); - config.setup(); - - if (config.isJustCreated()) { - int openPort = 8192; - try { - ServerSocket s = new ServerSocket(); - s.bind(new InetSocketAddress("0.0.0.0", 0)); - openPort = s.getLocalPort(); - s.close(); - } catch (Exception e) { - - } - try { - // First time run - do some initialization. - getLogger().info("Configuring Votifier for the first time..."); - config.getData().set("port", openPort); - config.saveData(); - - /* - * Remind hosted server admins to be sure they have the right port number. - */ - getLogger().info("------------------------------------------------------------------------------"); - getLogger().info("Assigning Votifier to listen on an open port " + openPort - + ". If you are hosting server on a"); - getLogger().info("shared server please check with your hosting provider to verify that this port"); - getLogger().info("is available for your use. Chances are that your hosting provider will assign"); - getLogger().info("a different port, which you need to specify in config.yml"); - getLogger().info("------------------------------------------------------------------------------"); - - } catch (Exception ex) { - getLogger().severe("Error creating configuration file"); - debug(ex); - } - } - config.loadValues(); - - updateAdvancedCoreHook(); - } - - private void metrics() { - BStatsMetrics metrics = new BStatsMetrics(this, 5807); - metrics.addCustomChart(new BStatsMetrics.SimplePie("Forwarding", new Callable() { - - @Override - public String call() throws Exception { - int amount = 0; - for (String server : config.getServers()) { - if (config.getForwardingConfiguration(server).getBoolean("Enabled")) { - amount++; - } - } - return "" + amount; - } - })); - } - - @Override - public void onUnLoad() { - - } - - @Override - public void reload() { - config.reloadData(); - updateAdvancedCoreHook(); - voteReceiver.shutdown(); - loadVoteReceiver(); - } - - @SuppressWarnings("deprecation") - public void updateAdvancedCoreHook() { - setConfigData(config.getData()); - setLoadRewards(false); - setLoadServerData(false); - setLoadUserData(false); - setLoadGeyserAPI(false); - setLoadLuckPerms(false); - } - -} diff --git a/src/main/java/com/vexsoftware/votifier/commands/CommandLoader.java b/src/main/java/com/vexsoftware/votifier/commands/CommandLoader.java deleted file mode 100644 index 30e4e9b..0000000 --- a/src/main/java/com/vexsoftware/votifier/commands/CommandLoader.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.vexsoftware.votifier.commands; - -import java.io.File; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketAddress; -import java.security.PublicKey; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; - -import org.bukkit.command.CommandSender; - -import com.bencodez.advancedcore.api.command.CommandHandler; -import com.vexsoftware.votifier.VotifierPlus; -import com.vexsoftware.votifier.crypto.RSAIO; -import com.vexsoftware.votifier.crypto.RSAKeygen; - -import net.md_5.bungee.api.ChatColor; -import net.md_5.bungee.api.chat.TextComponent; - -// TODO: Auto-generated Javadoc -/** - * The Class CommandLoader. - */ -public class CommandLoader { - - private static CommandLoader instance = new CommandLoader(); - private VotifierPlus plugin = VotifierPlus.getInstance(); - - public static CommandLoader getInstance() { - return instance; - } - - public ArrayList helpText(CommandSender sender) { - ArrayList msg = new ArrayList(); - HashMap unsorted = new HashMap(); - - boolean requirePerms = false; - ChatColor hoverColor = ChatColor.AQUA; - for (CommandHandler cmdHandle : plugin.getCommands()) { - if (!requirePerms || cmdHandle.hasPerm(sender)) { - unsorted.put(cmdHandle.getHelpLineCommand("/votifierplus"), - cmdHandle.getHelpLine("/votifierplus", "&6%Command% - &6%HelpMessage%", hoverColor)); - } - } - ArrayList unsortedList = new ArrayList(); - unsortedList.addAll(unsorted.keySet()); - Collections.sort(unsortedList, String.CASE_INSENSITIVE_ORDER); - for (String cmd : unsortedList) { - msg.add(unsorted.get(cmd)); - } - - return msg; - } - - public void loadCommands() { - plugin.getCommands() - .add(new CommandHandler(plugin, new String[] { "Help" }, "VotifierPlus.Help", "Open help page") { - - @Override - public void execute(CommandSender sender, String[] args) { - sendMessageJson(sender, helpText(sender)); - } - }); - plugin.getCommands() - .add(new CommandHandler(plugin, new String[] { "Reload" }, "VotifierPlus.Reload", "Reload the plugin") { - - @Override - public void execute(CommandSender sender, String[] args) { - plugin.reload(); - sendMessage(sender, "&cVotifierPlus " + plugin.getVersion() + " reloaded"); - } - }); - - plugin.getCommands().add(new CommandHandler(plugin, new String[] { "GenerateKeys" }, - "VotifierPlus.GenerateKeys", "Regenerate votifier keys", true, true) { - - @Override - public void execute(CommandSender sender, String[] args) { - File rsaDirectory = new File(plugin.getDataFolder() + File.separator + "rsa"); - - try { - for (File file : rsaDirectory.listFiles()) { - if (!file.isDirectory()) { - file.delete(); - } - } - rsaDirectory.mkdir(); - plugin.setKeyPair(RSAKeygen.generate(2048)); - RSAIO.save(rsaDirectory, plugin.getKeyPair()); - } catch (Exception ex) { - sendMessage(sender, "&cFailed to create keys"); - return; - } - sendMessage(sender, "&cNew keys generated"); - } - }); - - plugin.getCommands().add(new CommandHandler(plugin, new String[] { "Test", "(player)", "(Text)" }, - "VotifierPlus.Test", "Test votifier connection") { - - @Override - public void execute(CommandSender sender, String[] args) { - try { - PublicKey publicKey = plugin.getKeyPair().getPublic(); - String serverIP = plugin.config.getHost(); - int serverPort = plugin.config.getPort(); - if (serverIP.length() != 0) { - String VoteString = "VOTE\n" + args[2] + "\n" + args[1] + "\n" + "Address" + "\n" + "TestVote" - + "\n"; - - SocketAddress sockAddr = new InetSocketAddress(serverIP, serverPort); - Socket socket1 = new Socket(); - socket1.connect(sockAddr, 1000); - OutputStream socketOutputStream = socket1.getOutputStream(); - socketOutputStream.write(plugin.getVoteReceiver().encrypt(VoteString.getBytes(), publicKey)); - socketOutputStream.close(); - socket1.close(); - } - } catch (Exception e) { - e.printStackTrace(); - } - sendMessage(sender, "&cCheck console for test results"); - - } - }); - } -} diff --git a/src/main/java/com/vexsoftware/votifier/commands/CommandVotifierPlus.java b/src/main/java/com/vexsoftware/votifier/commands/CommandVotifierPlus.java deleted file mode 100644 index 2ad7123..0000000 --- a/src/main/java/com/vexsoftware/votifier/commands/CommandVotifierPlus.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.vexsoftware.votifier.commands; - -import org.bukkit.ChatColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; - -import com.bencodez.advancedcore.api.command.CommandHandler; -import com.vexsoftware.votifier.VotifierPlus; - -// TODO: Auto-generated Javadoc -/** - * The Class CommandVotifierPlus. - */ -public class CommandVotifierPlus implements CommandExecutor { - /** The plugin. */ - private VotifierPlus plugin; - - /** - * Instantiates a new command vote. - * - * @param plugin - * the plugin - */ - public CommandVotifierPlus(VotifierPlus plugin) { - this.plugin = plugin; - } - - /* - * (non-Javadoc) - * @see org.bukkit.command.CommandExecutor#onCommand(org.bukkit.command. - * CommandSender , org.bukkit.command.Command, java.lang.String, - * java.lang.String[]) - */ - @Override - public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { - - for (CommandHandler commandHandler : plugin.getCommands()) { - if (commandHandler.runCommand(sender, args)) { - return true; - } - } - - // invalid command - sender.sendMessage(ChatColor.RED + "No valid arguments, see /votifierplus help!"); - return true; - } - -} diff --git a/src/main/java/com/vexsoftware/votifier/commands/VotifierPlusTabCompleter.java b/src/main/java/com/vexsoftware/votifier/commands/VotifierPlusTabCompleter.java deleted file mode 100644 index 01f824b..0000000 --- a/src/main/java/com/vexsoftware/votifier/commands/VotifierPlusTabCompleter.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.vexsoftware.votifier.commands; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; - -import com.bencodez.advancedcore.api.command.TabCompleteHandler; -import com.bencodez.advancedcore.api.messages.StringParser; -import com.vexsoftware.votifier.VotifierPlus; - -// TODO: Auto-generated Javadoc -/** - * The Class VoteTabCompleter. - */ -public class VotifierPlusTabCompleter implements TabCompleter { - - /* - * (non-Javadoc) - * @see org.bukkit.command.TabCompleter#onTabComplete(org.bukkit.command. - * CommandSender, org.bukkit.command.Command, java.lang.String, - * java.lang.String[]) - */ - @Override - public List onTabComplete(CommandSender sender, Command cmd, String alias, String[] args) { - - ArrayList tab = new ArrayList(); - - Set cmds = new HashSet(); - - cmds.addAll(TabCompleteHandler.getInstance().getTabCompleteOptions(VotifierPlus.getInstance().getCommands(), - sender, args, args.length - 1)); - - for (String str : cmds) { - if (StringParser.getInstance().startsWithIgnoreCase(str, args[args.length - 1])) { - tab.add(str); - } - } - - Collections.sort(tab, String.CASE_INSENSITIVE_ORDER); - - return tab; - } - -} diff --git a/src/main/java/com/vexsoftware/votifier/config/Config.java b/src/main/java/com/vexsoftware/votifier/config/Config.java deleted file mode 100644 index f7c57ee..0000000 --- a/src/main/java/com/vexsoftware/votifier/config/Config.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.vexsoftware.votifier.config; - -import java.io.File; -import java.util.HashSet; -import java.util.Set; - -import org.bukkit.configuration.ConfigurationSection; - -import com.bencodez.advancedcore.api.yml.YMLFile; -import com.bencodez.advancedcore.api.yml.annotation.AnnotationHandler; -import com.bencodez.advancedcore.api.yml.annotation.ConfigDataBoolean; -import com.bencodez.advancedcore.api.yml.annotation.ConfigDataInt; -import com.bencodez.advancedcore.api.yml.annotation.ConfigDataKeys; -import com.bencodez.advancedcore.api.yml.annotation.ConfigDataString; -import com.vexsoftware.votifier.VotifierPlus; - -import lombok.Getter; -import lombok.Setter; - -public class Config extends YMLFile { - - public Config(VotifierPlus plugin) { - super(plugin, new File(VotifierPlus.getInstance().getDataFolder(), "config.yml")); - } - - public void loadValues() { - new AnnotationHandler().load(getData(), this); - } - - @Override - public void onFileCreation() { - VotifierPlus.getInstance().saveResource("config.yml", true); - } - - @ConfigDataString(path = "host") - @Getter - @Setter - private String host = "0.0.0.0"; - - @ConfigDataInt(path = "port") - @Getter - @Setter - private int port = 8192; - - @ConfigDataBoolean(path = "debug") - @Getter - @Setter - private boolean debug = false; - - @ConfigDataKeys(path = "Forwarding") - @Getter - @Setter - private Set servers = new HashSet(); - - @ConfigDataBoolean(path = "DisableUpdateChecking") - @Getter - private boolean disableUpdateChecking = false; - - public ConfigurationSection getForwardingConfiguration(String s) { - return getData().getConfigurationSection("Forwarding." + s); - } - -} diff --git a/src/main/java/com/vexsoftware/votifier/crypto/RSAIO.java b/src/main/java/com/vexsoftware/votifier/crypto/RSAIO.java deleted file mode 100644 index fff6dd1..0000000 --- a/src/main/java/com/vexsoftware/votifier/crypto/RSAIO.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2011 Vex Software LLC - * This file is part of Votifier. - * - * Votifier is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Votifier is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Votifier. If not, see . - */ - -package com.vexsoftware.votifier.crypto; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; -import java.util.Base64; - -/** - * Static utility methods for saving and loading RSA key pairs. - * - * @author Blake Beaupain - */ -public class RSAIO { - - /** - * Saves the key pair to the disk. - * - * @param directory - * The directory to save to - * @param keyPair - * The key pair to save - * @throws Exception - * If an error occurs - */ - public static void save(File directory, KeyPair keyPair) throws Exception { - PrivateKey privateKey = keyPair.getPrivate(); - PublicKey publicKey = keyPair.getPublic(); - - // Store the public key. - X509EncodedKeySpec publicSpec = new X509EncodedKeySpec(publicKey.getEncoded()); - FileOutputStream out = null; - try { - out = new FileOutputStream(directory + "/public.key"); - out.write(Base64.getEncoder().encodeToString(publicSpec.getEncoded()).getBytes()); - } catch (Exception e) { - e.printStackTrace(); - } finally { - if (out != null) { - out.close(); - } - } - // out.close(); - - // Store the private key. - PKCS8EncodedKeySpec privateSpec = new PKCS8EncodedKeySpec(privateKey.getEncoded()); - try { - out = new FileOutputStream(directory + "/private.key"); - out.write(Base64.getEncoder().encodeToString(privateSpec.getEncoded()).getBytes()); - } catch (Exception e) { - e.printStackTrace(); - } finally { - if (out != null) { - out.close(); - } - } - } - - /** - * Loads an RSA key pair from a directory. The directory must have the files - * "public.key" and "private.key". - * - * @param directory - * The directory to load from - * @return The key pair - * @throws Exception - * If an error occurs - */ - public static KeyPair load(File directory) throws Exception { - // Read the public key file. - File publicKeyFile = new File(directory + "/public.key"); - byte[] encodedPublicKey = null; - try (FileInputStream in = new FileInputStream(publicKeyFile)) { - encodedPublicKey = new byte[(int) publicKeyFile.length()]; - in.read(encodedPublicKey); - encodedPublicKey = Base64.getDecoder().decode(encodedPublicKey); - } catch (Exception e) { - e.printStackTrace(); - } - - // Read the private key file. - File privateKeyFile = new File(directory + "/private.key"); - byte[] encodedPrivateKey = null; - try (FileInputStream in = new FileInputStream(privateKeyFile)) { - encodedPrivateKey = new byte[(int) privateKeyFile.length()]; - in.read(encodedPrivateKey); - encodedPrivateKey = Base64.getDecoder().decode(encodedPrivateKey); - } catch (Exception e) { - e.printStackTrace(); - } - - // Instantiate and return the key pair. - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedPublicKey); - PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); - PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey); - PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec); - return new KeyPair(publicKey, privateKey); - } - -} diff --git a/src/main/java/com/vexsoftware/votifier/model/Vote.java b/src/main/java/com/vexsoftware/votifier/model/Vote.java deleted file mode 100644 index c8ef4b0..0000000 --- a/src/main/java/com/vexsoftware/votifier/model/Vote.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2011 Vex Software LLC - * This file is part of Votifier. - * - * Votifier is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Votifier is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Votifier. If not, see . - */ - -package com.vexsoftware.votifier.model; - -/** - * A model for a vote. - * - * @author Blake Beaupain - */ -public class Vote { - - /** The name of the vote service. */ - private String serviceName; - - /** The username of the voter. */ - private String username; - - /** The address of the voter. */ - private String address; - - /** The date and time of the vote. */ - private String timeStamp; - - @Override - public String toString() { - return "Vote (from:" + serviceName + " username:" + username - + " address:" + address + " timeStamp:" + timeStamp + ")"; - } - - /** - * Sets the serviceName. - * - * @param serviceName - * The new serviceName - */ - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - /** - * Gets the serviceName. - * - * @return The serviceName - */ - public String getServiceName() { - return serviceName; - } - - /** - * Sets the username. - * - * @param username - * The new username - */ - public void setUsername(String username) { - this.username = username.length() <= 16 ? username : username.substring(0, 16); - } - - /** - * Gets the username. - * - * @return The username - */ - public String getUsername() { - return username; - } - - /** - * Sets the address. - * - * @param address - * The new address - */ - public void setAddress(String address) { - this.address = address; - } - - /** - * Gets the address. - * - * @return The address - */ - public String getAddress() { - return address; - } - - /** - * Sets the time stamp. - * - * @param timeStamp - * The new time stamp - */ - public void setTimeStamp(String timeStamp) { - this.timeStamp = timeStamp; - } - - /** - * Gets the time stamp. - * - * @return The time stamp - */ - public String getTimeStamp() { - return timeStamp; - } - -} diff --git a/src/main/java/com/vexsoftware/votifier/model/VotifierEvent.java b/src/main/java/com/vexsoftware/votifier/model/VotifierEvent.java deleted file mode 100644 index 0e8cbc7..0000000 --- a/src/main/java/com/vexsoftware/votifier/model/VotifierEvent.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.vexsoftware.votifier.model; - -import org.bukkit.event.*; - -/** - * {@code VotifierEvent} is a custom Bukkit event class that is sent - * synchronously to CraftBukkit's main thread allowing other plugins to listener - * for votes. - * - * @author frelling - * - */ -public class VotifierEvent extends Event { - /** - * Event listener handler list. - */ - private static final HandlerList handlers = new HandlerList(); - - /** - * Encapsulated vote record. - */ - private Vote vote; - - /** - * Constructs a vote event that encapsulated the given vote record. - * - * @param vote - * vote record - */ - public VotifierEvent(final Vote vote) { - this.vote = vote; - } - - /** - * Return the encapsulated vote record. - * - * @return vote record - */ - public Vote getVote() { - return vote; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } -} diff --git a/src/main/java/com/vexsoftware/votifier/net/VoteReceiver.java b/src/main/java/com/vexsoftware/votifier/net/VoteReceiver.java deleted file mode 100644 index 305d5fc..0000000 --- a/src/main/java/com/vexsoftware/votifier/net/VoteReceiver.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2012 Vex Software LLC - * This file is part of Votifier. - * - * Votifier is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Votifier is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Votifier. If not, see . - */ - -package com.vexsoftware.votifier.net; - -import java.io.BufferedWriter; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketAddress; -import java.net.SocketException; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.PublicKey; -import java.security.spec.X509EncodedKeySpec; -import java.util.Base64; -import java.util.Set; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; - -import com.vexsoftware.votifier.ForwardServer; -import com.vexsoftware.votifier.crypto.RSA; -import com.vexsoftware.votifier.model.Vote; - -/** - * The vote receiving server. - * - * @author Blake Beaupain - * @author Kramer Campbell - */ -public abstract class VoteReceiver extends Thread { - - /** The host to listen on. */ - private final String host; - - /** The port to listen on. */ - private final int port; - - /** The server socket. */ - private ServerSocket server; - - /** The running flag. */ - private boolean running = true; - - /** - * Instantiates a new vote receiver - * - * @param host - * The host to listen on - * @param port - * The port to listen on - * @throws Exception - * exception - */ - public VoteReceiver(String host, int port) throws Exception { - super("Votifier I/O"); - this.host = host; - this.port = port; - - setPriority(Thread.MIN_PRIORITY); - - initialize(); - } - - private void initialize() throws Exception { - try { - server = new ServerSocket(); - server.bind(new InetSocketAddress(host, port)); - debug(server.getInetAddress().getHostAddress() + ":" + server.getLocalPort()); - } catch (Exception ex) { - logSevere("Error initializing vote receiver. Please verify that the configured"); - logSevere("IP address and port are not already in use. This is a common problem"); - logSevere("with hosting services and, if so, you should check with your hosting provider."); - ex.printStackTrace(); - throw new Exception(ex); - } - } - - public abstract void logWarning(String warn); - - public abstract void logSevere(String msg); - - public abstract void log(String msg); - - public abstract void debug(String debug); - - public abstract String getVersion(); - - /** - * Shuts the vote receiver down cleanly. - */ - public void shutdown() { - running = false; - if (server == null) - return; - try { - server.close(); - } catch (Exception ex) { - logWarning("Unable to shut down vote receiver cleanly."); - } - } - - public abstract Set getServers(); - - public abstract KeyPair getKeyPair(); - - @Override - public void run() { - - // Main loop. - while (running) { - try (Socket socket = server.accept()) { - socket.setSoTimeout(5000); // Don't hang on slow connections. - BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); - InputStream in = socket.getInputStream(); - - // Send them our version. - writer.write("VOTIFIERPLUS " + getVersion()); - writer.newLine(); - writer.flush(); - - // Read the 256 byte block. - byte[] block = new byte[256]; - in.read(block, 0, block.length); - - // Decrypt the block. - block = RSA.decrypt(block, getKeyPair().getPrivate()); - int position = 0; - - // Perform the opcode check. - String opcode = readString(block, position); - position += opcode.length() + 1; - if (!opcode.equals("VOTE")) { - // Something went wrong in RSA. - throw new Exception("Unable to decode RSA"); - } - - // Parse the block. - String serviceName = readString(block, position); - position += serviceName.length() + 1; - String username = readString(block, position); - position += username.length() + 1; - String address = readString(block, position); - position += address.length() + 1; - String timeStamp = readString(block, position); - position += timeStamp.length() + 1; - - // Create the vote. - final Vote vote = new Vote(); - vote.setServiceName(serviceName); - vote.setUsername(username); - vote.setAddress(address); - vote.setTimeStamp(timeStamp); - - if (timeStamp.equalsIgnoreCase("TestVote")) { - log("Test vote received"); - } - - debug("Received vote record -> " + vote); - - for (String server : getServers()) { - ForwardServer forwardServer = getServerData(server); - if (forwardServer.isEnabled()) { - debug("Sending vote to " + server); - - byte[] encodedPublicKey = Base64.getDecoder().decode(forwardServer.getKey()); - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedPublicKey); - PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); - String serverIP = forwardServer.getHost(); - int serverPort = forwardServer.getPort(); - if (serverIP.length() != 0) { - try { - String VoteString = "VOTE\n" + vote.getServiceName() + "\n" + vote.getUsername() + "\n" - + vote.getAddress() + "\n" + vote.getTimeStamp() + "\n"; - - SocketAddress sockAddr = new InetSocketAddress(serverIP, serverPort); - Socket socket1 = new Socket(); - socket1.connect(sockAddr, 1000); - OutputStream socketOutputStream = socket1.getOutputStream(); - socketOutputStream.write(encrypt(VoteString.getBytes(), publicKey)); - socketOutputStream.close(); - socket1.close(); - - } catch (Exception e) { - log("Failed to send vote to " + server + "(" + serverIP + ":" + serverPort + "): " - + vote.toString() + ", ignore this if server is offline. Enable debug to see the stacktrace"); - debug(e); - } - } - - } - } - - // Call event in a synchronized fashion to ensure that the - // custom event runs in the - // the main server thread, not this one. - callEvent(vote); - - // Clean up. - writer.close(); - in.close(); - socket.close(); - } catch (SocketException ex) { - logWarning("Protocol error. Ignoring packet - " + ex.getLocalizedMessage()); - debug(ex); - } catch (BadPaddingException ex) { - logWarning("Unable to decrypt vote record. Make sure that that your public key"); - logWarning("matches the one you gave the server list."); - debug(ex); - } catch (Exception ex) { - logWarning("Exception caught while receiving a vote notification"); - debug(ex); - } - } - - } - - public abstract ForwardServer getServerData(String s); - - public abstract void debug(Exception e); - - public abstract void callEvent(Vote e); - - public byte[] encrypt(byte[] data, PublicKey key) throws Exception { - Cipher cipher = Cipher.getInstance("RSA"); - cipher.init(Cipher.ENCRYPT_MODE, key); - return cipher.doFinal(data); - } - - /** - * Reads a string from a block of data. - * - * @param data - * The data to read from - * @return The string - */ - private String readString(byte[] data, int offset) { - StringBuilder builder = new StringBuilder(); - for (int i = offset; i < data.length; i++) { - if (data[i] == '\n') - break; // Delimiter reached. - builder.append((char) data[i]); - } - return builder.toString(); - } -} diff --git a/src/main/java/net/simplyvanilla/simplyvotifier/SimplyVotifier.java b/src/main/java/net/simplyvanilla/simplyvotifier/SimplyVotifier.java new file mode 100644 index 0000000..ee3183d --- /dev/null +++ b/src/main/java/net/simplyvanilla/simplyvotifier/SimplyVotifier.java @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2012 Vex Software LLC + * This file is part of Votifier. + * + * Votifier is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Votifier is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Votifier. If not, see . + */ + +package net.simplyvanilla.simplyvotifier; + +import com.bencodez.advancedcore.AdvancedCorePlugin; +import com.bencodez.advancedcore.folialib.FoliaLib; +import lombok.Getter; +import lombok.Setter; +import net.simplyvanilla.simplyvotifier.config.Config; +import net.simplyvanilla.simplyvotifier.crypto.RSAIO; +import net.simplyvanilla.simplyvotifier.crypto.RSAKeygen; +import net.simplyvanilla.simplyvotifier.model.Vote; +import net.simplyvanilla.simplyvotifier.model.VotifierEvent; +import net.simplyvanilla.simplyvotifier.net.VoteReceiver; +import org.bukkit.Bukkit; + +import java.io.File; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.security.KeyPair; + +/** + * The main Votifier plugin class. + * + * @author Blake Beaupain + * @author Kramer Campbell + */ +public class SimplyVotifier extends AdvancedCorePlugin { + + /** + * The Votifier instance. + */ + @Getter + private static SimplyVotifier instance; + + @Getter + private FoliaLib foliaLib; + + public Config config; + + /** + * The vote receiver. + */ + @Getter + private VoteReceiver voteReceiver; + + /** + * The RSA key pair. + */ + @Getter + @Setter + private KeyPair keyPair; + + + @Override + public void onPostLoad() { + this.foliaLib = new FoliaLib(this); + + File rsaDirectory = new File(getDataFolder() + "/rsa"); + + /* + * Create RSA directory and keys if it does not exist; otherwise, read keys. + */ + try { + if (!rsaDirectory.exists()) { + rsaDirectory.mkdir(); + keyPair = RSAKeygen.generate(2048); + RSAIO.save(rsaDirectory, keyPair); + } else { + keyPair = RSAIO.load(rsaDirectory); + } + } catch (Exception ex) { + getLogger().severe("Error reading configuration file or RSA keys"); + gracefulExit(); + return; + } + + loadVoteReceiver(); + } + + private void loadVoteReceiver() { + try { + voteReceiver = new VoteReceiver(config.getHost(), config.getPort()) { + + @Override + public void logWarning(String warn) { + getLogger().warning(warn); + } + + @Override + public void logSevere(String msg) { + getLogger().severe(msg); + } + + @Override + public void log(String msg) { + getLogger().info(msg); + } + + @Override + public String getVersion() { + return getDescription().getVersion(); + } + + @Override + public KeyPair getKeyPair() { + return instance.getKeyPair(); + } + + @Override + public void debug(Exception e) { + instance.debug(e); + } + + @Override + public void debug(String debug) { + instance.debug(debug); + } + + @Override + public void callEvent(Vote vote) { + foliaLib.getImpl().runAsync(new Runnable() { + public void run() { + Bukkit.getServer().getPluginManager().callEvent(new VotifierEvent(vote)); + } + }); + } + }; + voteReceiver.start(); + + getLogger().info("Votifier enabled."); + } catch (Exception ex) { + gracefulExit(); + return; + } + } + + @Override + public void onDisable() { + // Interrupt the vote receiver. + if (voteReceiver != null) { + voteReceiver.shutdown(); + } + getLogger().info("Votifier disabled."); + } + + private void gracefulExit() { + getLogger().severe("Votifier did not initialize properly!"); + } + + @Override + public void onPreLoad() { + instance = this; + + config = new Config(this); + config.setup(); + + if (config.isJustCreated()) { + int openPort = 8192; + try { + ServerSocket s = new ServerSocket(); + s.bind(new InetSocketAddress("0.0.0.0", 0)); + openPort = s.getLocalPort(); + s.close(); + } catch (Exception e) { + + } + try { + // First time run - do some initialization. + getLogger().info("Configuring Votifier for the first time..."); + config.getData().set("port", openPort); + config.saveData(); + + /* + * Remind hosted server admins to be sure they have the right port number. + */ + getLogger().info("------------------------------------------------------------------------------"); + getLogger().info("Assigning Votifier to listen on an open port " + openPort + + ". If you are hosting server on a"); + getLogger().info("shared server please check with your hosting provider to verify that this port"); + getLogger().info("is available for your use. Chances are that your hosting provider will assign"); + getLogger().info("a different port, which you need to specify in config.yml"); + getLogger().info("------------------------------------------------------------------------------"); + + } catch (Exception ex) { + getLogger().severe("Error creating configuration file"); + debug(ex); + } + } + config.loadValues(); + + updateAdvancedCoreHook(); + } + + @Override + public void onUnLoad() { + + } + + @Override + public void reload() { + config.reloadData(); + updateAdvancedCoreHook(); + voteReceiver.shutdown(); + loadVoteReceiver(); + } + + @SuppressWarnings("deprecation") + public void updateAdvancedCoreHook() { + setConfigData(config.getData()); + setLoadRewards(false); + setLoadServerData(false); + setLoadUserData(false); + setLoadGeyserAPI(false); + setLoadLuckPerms(false); + } + +} diff --git a/src/main/java/net/simplyvanilla/simplyvotifier/config/Config.java b/src/main/java/net/simplyvanilla/simplyvotifier/config/Config.java new file mode 100644 index 0000000..6476708 --- /dev/null +++ b/src/main/java/net/simplyvanilla/simplyvotifier/config/Config.java @@ -0,0 +1,39 @@ +package net.simplyvanilla.simplyvotifier.config; + +import com.bencodez.advancedcore.api.yml.YMLFile; +import com.bencodez.advancedcore.api.yml.annotation.AnnotationHandler; +import com.bencodez.advancedcore.api.yml.annotation.ConfigDataBoolean; +import com.bencodez.advancedcore.api.yml.annotation.ConfigDataInt; +import com.bencodez.advancedcore.api.yml.annotation.ConfigDataString; +import lombok.Getter; +import lombok.Setter; +import net.simplyvanilla.simplyvotifier.SimplyVotifier; + +import java.io.File; + +@Setter +@Getter +public class Config extends YMLFile { + + public Config(SimplyVotifier plugin) { + super(plugin, new File(SimplyVotifier.getInstance().getDataFolder(), "config.yml")); + } + + public void loadValues() { + new AnnotationHandler().load(getData(), this); + } + + @Override + public void onFileCreation() { + SimplyVotifier.getInstance().saveResource("config.yml", true); + } + + @ConfigDataString(path = "host") + private String host = "0.0.0.0"; + + @ConfigDataInt(path = "port") + private int port = 8192; + + @ConfigDataBoolean(path = "debug") + private boolean debug = false; +} diff --git a/src/main/java/com/vexsoftware/votifier/crypto/RSA.java b/src/main/java/net/simplyvanilla/simplyvotifier/crypto/RSA.java similarity index 50% rename from src/main/java/com/vexsoftware/votifier/crypto/RSA.java rename to src/main/java/net/simplyvanilla/simplyvotifier/crypto/RSA.java index 41df187..5765c08 100644 --- a/src/main/java/com/vexsoftware/votifier/crypto/RSA.java +++ b/src/main/java/net/simplyvanilla/simplyvotifier/crypto/RSA.java @@ -1,68 +1,61 @@ /* * Copyright (C) 2011 Vex Software LLC * This file is part of Votifier. - * + * * Votifier is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Votifier is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Votifier. If not, see . */ -package com.vexsoftware.votifier.crypto; +package net.simplyvanilla.simplyvotifier.crypto; +import javax.crypto.Cipher; import java.security.PrivateKey; import java.security.PublicKey; -import javax.crypto.Cipher; - /** * Static RSA utility methods for encrypting and decrypting blocks of * information. - * + * * @author Blake Beaupain */ public class RSA { - /** - * Encrypts a block of data. - * - * @param data - * The data to encrypt - * @param key - * The key to encrypt with - * @return The encrypted data - * @throws Exception - * If an error occurs - */ - public static byte[] encrypt(byte[] data, PublicKey key) throws Exception { - Cipher cipher = Cipher.getInstance("RSA"); - cipher.init(Cipher.ENCRYPT_MODE, key); - return cipher.doFinal(data); - } + /** + * Encrypts a block of data. + * + * @param data The data to encrypt + * @param key The key to encrypt with + * @return The encrypted data + * @throws Exception If an error occurs + */ + public static byte[] encrypt(byte[] data, PublicKey key) throws Exception { + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, key); + return cipher.doFinal(data); + } - /** - * Decrypts a block of data. - * - * @param data - * The data to decrypt - * @param key - * The key to decrypt with - * @return The decrypted data - * @throws Exception - * If an error occurs - */ - public static byte[] decrypt(byte[] data, PrivateKey key) throws Exception { - Cipher cipher = Cipher.getInstance("RSA"); - cipher.init(Cipher.DECRYPT_MODE, key); - return cipher.doFinal(data); - } + /** + * Decrypts a block of data. + * + * @param data The data to decrypt + * @param key The key to decrypt with + * @return The decrypted data + * @throws Exception If an error occurs + */ + public static byte[] decrypt(byte[] data, PrivateKey key) throws Exception { + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, key); + return cipher.doFinal(data); + } } diff --git a/src/main/java/net/simplyvanilla/simplyvotifier/crypto/RSAIO.java b/src/main/java/net/simplyvanilla/simplyvotifier/crypto/RSAIO.java new file mode 100644 index 0000000..e3e8385 --- /dev/null +++ b/src/main/java/net/simplyvanilla/simplyvotifier/crypto/RSAIO.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2011 Vex Software LLC + * This file is part of Votifier. + * + * Votifier is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Votifier is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Votifier. If not, see . + */ + +package net.simplyvanilla.simplyvotifier.crypto; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +/** + * Static utility methods for saving and loading RSA key pairs. + * + * @author Blake Beaupain + */ +public class RSAIO { + + /** + * Saves the key pair to the disk. + * + * @param directory The directory to save to + * @param keyPair The key pair to save + * @throws Exception If an error occurs + */ + public static void save(File directory, KeyPair keyPair) throws Exception { + PrivateKey privateKey = keyPair.getPrivate(); + PublicKey publicKey = keyPair.getPublic(); + + // Store the public key. + X509EncodedKeySpec publicSpec = new X509EncodedKeySpec(publicKey.getEncoded()); + FileOutputStream out = null; + try { + out = new FileOutputStream(directory + "/public.key"); + out.write(Base64.getEncoder().encodeToString(publicSpec.getEncoded()).getBytes()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (out != null) { + out.close(); + } + } + // out.close(); + + // Store the private key. + PKCS8EncodedKeySpec privateSpec = new PKCS8EncodedKeySpec(privateKey.getEncoded()); + try { + out = new FileOutputStream(directory + "/private.key"); + out.write(Base64.getEncoder().encodeToString(privateSpec.getEncoded()).getBytes()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (out != null) { + out.close(); + } + } + } + + /** + * Loads an RSA key pair from a directory. The directory must have the files + * "public.key" and "private.key". + * + * @param directory The directory to load from + * @return The key pair + * @throws Exception If an error occurs + */ + public static KeyPair load(File directory) throws Exception { + // Read the public key file. + File publicKeyFile = new File(directory + "/public.key"); + byte[] encodedPublicKey = null; + try (FileInputStream in = new FileInputStream(publicKeyFile)) { + encodedPublicKey = new byte[(int) publicKeyFile.length()]; + in.read(encodedPublicKey); + encodedPublicKey = Base64.getDecoder().decode(encodedPublicKey); + } catch (Exception e) { + e.printStackTrace(); + } + + // Read the private key file. + File privateKeyFile = new File(directory + "/private.key"); + byte[] encodedPrivateKey = null; + try (FileInputStream in = new FileInputStream(privateKeyFile)) { + encodedPrivateKey = new byte[(int) privateKeyFile.length()]; + in.read(encodedPrivateKey); + encodedPrivateKey = Base64.getDecoder().decode(encodedPrivateKey); + } catch (Exception e) { + e.printStackTrace(); + } + + // Instantiate and return the key pair. + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedPublicKey); + PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); + PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey); + PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec); + return new KeyPair(publicKey, privateKey); + } + +} diff --git a/src/main/java/com/vexsoftware/votifier/crypto/RSAKeygen.java b/src/main/java/net/simplyvanilla/simplyvotifier/crypto/RSAKeygen.java similarity index 63% rename from src/main/java/com/vexsoftware/votifier/crypto/RSAKeygen.java rename to src/main/java/net/simplyvanilla/simplyvotifier/crypto/RSAKeygen.java index 93c6cdf..a89373c 100644 --- a/src/main/java/com/vexsoftware/votifier/crypto/RSAKeygen.java +++ b/src/main/java/net/simplyvanilla/simplyvotifier/crypto/RSAKeygen.java @@ -1,22 +1,22 @@ /* * Copyright (C) 2011 Vex Software LLC * This file is part of Votifier. - * + * * Votifier is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Votifier is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Votifier. If not, see . */ -package com.vexsoftware.votifier.crypto; +package net.simplyvanilla.simplyvotifier.crypto; import java.security.KeyPair; import java.security.KeyPairGenerator; @@ -24,25 +24,23 @@ /** * An RSA key pair generator. - * + * * @author Blake Beaupain */ public abstract class RSAKeygen { - /** - * Generates an RSA key pair. - * - * @param bits - * The amount of bits - * @return The key pair - * @throws Exception - * exception - */ - public static KeyPair generate(int bits) throws Exception { - KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA"); - RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(bits, RSAKeyGenParameterSpec.F4); - keygen.initialize(spec); - return keygen.generateKeyPair(); - } + /** + * Generates an RSA key pair. + * + * @param bits The amount of bits + * @return The key pair + * @throws Exception exception + */ + public static KeyPair generate(int bits) throws Exception { + KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA"); + RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(bits, RSAKeyGenParameterSpec.F4); + keygen.initialize(spec); + return keygen.generateKeyPair(); + } } diff --git a/src/main/java/net/simplyvanilla/simplyvotifier/model/Vote.java b/src/main/java/net/simplyvanilla/simplyvotifier/model/Vote.java new file mode 100644 index 0000000..a8b6268 --- /dev/null +++ b/src/main/java/net/simplyvanilla/simplyvotifier/model/Vote.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2011 Vex Software LLC + * This file is part of Votifier. + * + * Votifier is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Votifier is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Votifier. If not, see . + */ + +package net.simplyvanilla.simplyvotifier.model; + +import lombok.Getter; +import lombok.Setter; + +/** + * A model for a vote. + * + * @author Blake Beaupain + */ +@Getter +public class Vote { + + /** + * The name of the vote service. + */ + @Setter + private String serviceName; + + /** + * The username of the voter. + */ + private String username; + + /** + * The address of the voter. + */ + @Setter + private String address; + + /** + * The date and time of the vote. + */ + @Setter + private String timeStamp; + + @Override + public String toString() { + return "Vote (from:" + serviceName + " username:" + username + + " address:" + address + " timeStamp:" + timeStamp + ")"; + } + + /** + * Sets the username. + * + * @param username The new username + */ + public void setUsername(String username) { + this.username = username.length() <= 16 ? username : username.substring(0, 16); + } + +} diff --git a/src/main/java/net/simplyvanilla/simplyvotifier/model/VotifierEvent.java b/src/main/java/net/simplyvanilla/simplyvotifier/model/VotifierEvent.java new file mode 100644 index 0000000..2984ff9 --- /dev/null +++ b/src/main/java/net/simplyvanilla/simplyvotifier/model/VotifierEvent.java @@ -0,0 +1,40 @@ +package net.simplyvanilla.simplyvotifier.model; + +import lombok.Getter; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * {@code VotifierEvent} is a custom Bukkit event class that is sent + * synchronously to CraftBukkit's main thread allowing other plugins to listener + * for votes. + * + * @author frelling + */ +@Getter +public class VotifierEvent extends Event { + /** + * Event listener handler list. + */ + private static final HandlerList handlers = new HandlerList(); + + /** + * Encapsulated vote record. + */ + private Vote vote; + + /** + * Constructs a vote event that encapsulated the given vote record. + * + * @param vote vote record + */ + public VotifierEvent(final Vote vote) { + this.vote = vote; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + +} diff --git a/src/main/java/net/simplyvanilla/simplyvotifier/net/VoteReceiver.java b/src/main/java/net/simplyvanilla/simplyvotifier/net/VoteReceiver.java new file mode 100644 index 0000000..ff5f6ec --- /dev/null +++ b/src/main/java/net/simplyvanilla/simplyvotifier/net/VoteReceiver.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2012 Vex Software LLC + * This file is part of Votifier. + * + * Votifier is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Votifier is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Votifier. If not, see . + */ + +package net.simplyvanilla.simplyvotifier.net; + +import net.simplyvanilla.simplyvotifier.crypto.RSA; +import net.simplyvanilla.simplyvotifier.model.Vote; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import java.io.BufferedWriter; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; +import java.security.KeyPair; +import java.security.PublicKey; + +/** + * The vote receiving server. + * + * @author Blake Beaupain + * @author Kramer Campbell + */ +public abstract class VoteReceiver extends Thread { + + /** + * The host to listen on. + */ + private final String host; + + /** + * The port to listen on. + */ + private final int port; + + /** + * The server socket. + */ + private ServerSocket server; + + /** + * The running flag. + */ + private boolean running = true; + + /** + * Instantiates a new vote receiver + * + * @param host The host to listen on + * @param port The port to listen on + * @throws Exception exception + */ + public VoteReceiver(String host, int port) throws Exception { + super("Votifier I/O"); + this.host = host; + this.port = port; + + setPriority(Thread.MIN_PRIORITY); + + initialize(); + } + + private void initialize() throws Exception { + try { + server = new ServerSocket(); + server.bind(new InetSocketAddress(host, port)); + debug(server.getInetAddress().getHostAddress() + ":" + server.getLocalPort()); + } catch (Exception ex) { + logSevere("Error initializing vote receiver. Please verify that the configured"); + logSevere("IP address and port are not already in use. This is a common problem"); + logSevere("with hosting services and, if so, you should check with your hosting provider."); + ex.printStackTrace(); + throw new Exception(ex); + } + } + + public abstract void logWarning(String warn); + + public abstract void logSevere(String msg); + + public abstract void log(String msg); + + public abstract void debug(String debug); + + public abstract String getVersion(); + + /** + * Shuts the vote receiver down cleanly. + */ + public void shutdown() { + running = false; + if (server == null) + return; + try { + server.close(); + } catch (Exception ex) { + logWarning("Unable to shut down vote receiver cleanly."); + } + } + + public abstract KeyPair getKeyPair(); + + @Override + public void run() { + + // Main loop. + while (running) { + try (Socket socket = server.accept()) { + socket.setSoTimeout(5000); // Don't hang on slow connections. + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); + InputStream in = socket.getInputStream(); + + // Send them our version. + writer.write("SIMPLYVOTIFIER " + getVersion()); + writer.newLine(); + writer.flush(); + + // Read the 256 byte block. + byte[] block = new byte[256]; + in.read(block, 0, block.length); + + // Decrypt the block. + block = RSA.decrypt(block, getKeyPair().getPrivate()); + int position = 0; + + // Perform the opcode check. + String opcode = readString(block, position); + position += opcode.length() + 1; + if (!opcode.equals("VOTE")) { + // Something went wrong in RSA. + throw new Exception("Unable to decode RSA"); + } + + // Parse the block. + String serviceName = readString(block, position); + position += serviceName.length() + 1; + String username = readString(block, position); + position += username.length() + 1; + String address = readString(block, position); + position += address.length() + 1; + String timeStamp = readString(block, position); + position += timeStamp.length() + 1; + + // Create the vote. + final Vote vote = new Vote(); + vote.setServiceName(serviceName); + vote.setUsername(username); + vote.setAddress(address); + vote.setTimeStamp(timeStamp); + + if (timeStamp.equalsIgnoreCase("TestVote")) { + log("Test vote received"); + } + + debug("Received vote record -> " + vote); + + // Call event in a synchronized fashion to ensure that the + // custom event runs in the + // the main server thread, not this one. + callEvent(vote); + + // Clean up. + writer.close(); + in.close(); + socket.close(); + } catch (SocketException ex) { + logWarning("Protocol error. Ignoring packet - " + ex.getLocalizedMessage()); + debug(ex); + } catch (BadPaddingException ex) { + logWarning("Unable to decrypt vote record. Make sure that that your public key"); + logWarning("matches the one you gave the server list."); + debug(ex); + } catch (Exception ex) { + logWarning("Exception caught while receiving a vote notification"); + debug(ex); + } + } + + } + + public abstract void debug(Exception e); + + public abstract void callEvent(Vote e); + + public byte[] encrypt(byte[] data, PublicKey key) throws Exception { + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, key); + return cipher.doFinal(data); + } + + /** + * Reads a string from a block of data. + * + * @param data The data to read from + * @return The string + */ + private String readString(byte[] data, int offset) { + StringBuilder builder = new StringBuilder(); + for (int i = offset; i < data.length; i++) { + if (data[i] == '\n') + break; // Delimiter reached. + builder.append((char) data[i]); + } + return builder.toString(); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index aa9ff19..2e22435 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -5,9 +5,3 @@ DebugLevel: NONE host: 0.0.0.0 port: 8192 -Forwarding: - server1: - Enabled: false - Host: '' - Port: 8193 - Key: '' \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index fff12a7..8ad4c73 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,11 +1,9 @@ +main: net.simplyvanilla.simplyvotifier.SimplyVotifier name: SimplyVotifier -main: com.vexsoftware.votifier.VotifierPlus -version: @version@ description: A plugin that gets notified when votes are made for the server on toplists. -author: BenCodez -api-version: 1.13 -softdepend: [SuperVanish, PremiumVanish] +version: @version@ +api-version: 1.19 + +author: Simply Vanilla +website: https://github.com/SimplyVanilla/SimplyChat folia-supported: true -commands: - votifierplus: - description: main command