Initial commit

This commit is contained in:
Mark Vainomaa 2016-08-27 16:18:28 +03:00
commit 1b16a1d67e
29 changed files with 1374 additions and 0 deletions

21
.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
# ---> Java
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# IntelliJ IDEA
*.iml
.idea/
# Maven
target/
dependency-reduced-pom.xml

40
Bannerparser/pom.xml Normal file
View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>utils</artifactId>
<groupId>eu.mikroskeem</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bannerparser</artifactId>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.10.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations-java5</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,33 @@
package eu.mikroskeem.utils.bannerparser;
public class IntegerFromString {
public static String valueOf(int value){
for (IntegerFromStringEnum anEnum : IntegerFromStringEnum.values()) {
if(value == anEnum.getValue()){
return anEnum.toString();
}
}
return null;
}
private enum IntegerFromStringEnum {
ONE(1),
TWO(2),
THREE(3),
FOUR(4),
FIVE(5),
SIX(6),
SEVEN(7),
EIGHT(8),
NINE(9),
ZERO(0);
private int value;
IntegerFromStringEnum(int value) {
this.value = value;
}
public int getValue(){
return value;
}
}
}

View File

@ -0,0 +1,21 @@
package eu.mikroskeem.utils.bannerparser;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.LinkedHashMap;
import java.util.Map;
public class ParseQuery {
public static Map<String, String> splitQuery(URL url) throws UnsupportedEncodingException {
Map<String, String> query_pairs = new LinkedHashMap<>();
String query = url.getQuery();
String[] pairs = query.split("&");
for (String pair : pairs) {
int idx = pair.indexOf("=");
query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
}
return query_pairs;
}
}

View File

@ -0,0 +1,10 @@
package eu.mikroskeem.utils.bannerparser.parsers;
import org.bukkit.block.banner.Pattern;
import java.net.URL;
import java.util.ArrayList;
public interface Parser {
ArrayList<Pattern> fromUrl(URL url);
}

View File

@ -0,0 +1,29 @@
package eu.mikroskeem.utils.bannerparser.parsers;
import eu.mikroskeem.utils.bannerparser.parsers.needcoolshoes.NeedCoolShoesParser;
import eu.mikroskeem.utils.bannerparser.parsers.planetminecraft.PlanetMinecraftParser;
import org.bukkit.block.banner.Pattern;
import java.net.URL;
import java.util.ArrayList;
public class Parsers {
public static Parser getParser(URL url){
String host = url.getHost();
if(host.contains("planetminecraft.com")){
return new PlanetMinecraftParser();
} else if (host.contains("needcoolshoes.com")){
return new NeedCoolShoesParser();
}
return null;
}
public static ArrayList<Pattern> parse(URL url){
Parser parser = getParser(url);
if(parser != null){
return parser.fromUrl(url);
} else {
return null;
}
}
}

View File

@ -0,0 +1,38 @@
package eu.mikroskeem.utils.bannerparser.parsers.needcoolshoes;
import org.bukkit.DyeColor;
import static org.bukkit.DyeColor.*;
class ColorParser {
static DyeColor valueOf(String a){
return ColorEnum.valueOf(a).getColor();
}
@SuppressWarnings("unused")
private enum ColorEnum {
a(BLACK),
b(RED),
c(GREEN),
d(BROWN),
e(BLUE),
f(PURPLE),
g(CYAN),
h(SILVER),
i(GRAY),
j(PINK),
k(LIME),
l(YELLOW),
m(LIGHT_BLUE),
n(MAGENTA),
o(ORANGE),
p(WHITE);
private DyeColor color;
ColorEnum(DyeColor color) {
this.color = color;
}
public DyeColor getColor() {
return color;
}
}
}

View File

@ -0,0 +1,47 @@
package eu.mikroskeem.utils.bannerparser.parsers.needcoolshoes;
import eu.mikroskeem.utils.bannerparser.parsers.Parser;
import org.bukkit.DyeColor;
import org.bukkit.block.banner.Pattern;
import org.bukkit.block.banner.PatternType;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class NeedCoolShoesParser implements Parser {
/*
* See http://www.needcoolshoes.com/banner
*/
public ArrayList<Pattern> fromUrl(URL url){
try {
String bannerData = url.getQuery().split("\\?=")[0].substring(1);
return parse(bannerData);
} catch (ArrayIndexOutOfBoundsException e){
return null;
}
}
private ArrayList<Pattern> parse(String whole){
ArrayList<Pattern> patterns = new ArrayList<>();
List<String> propertyList = Arrays.asList(whole.split("(?<=\\G..)"));
propertyList.forEach(property->{
DyeColor color = parseColor(property.charAt(0));
PatternType patternType = parsePattern(property.charAt(1));
patterns.add(new Pattern(color, patternType));
});
return patterns;
}
private PatternType parsePattern(char part){
String partStr = String.valueOf(part);
return PatternParser.valueOf(partStr);
}
private DyeColor parseColor(char part){
String partStr = String.valueOf(part);
return ColorParser.valueOf(partStr);
}
}

View File

@ -0,0 +1,73 @@
package eu.mikroskeem.utils.bannerparser.parsers.needcoolshoes;
import org.bukkit.block.banner.PatternType;
import static org.bukkit.block.banner.PatternType.*;
class PatternParser {
static PatternType valueOf(String a) {
return PatternEnum.valueOf(a).getPattern();
}
@SuppressWarnings("unused")
private enum PatternEnum {
a(BASE),
e(BRICKS),
j(CROSS),
z(STRAIGHT_CROSS),
p(GRADIENT),
K(GRADIENT_UP),
q(HALF_HORIZONTAL_MIRROR),
L(HALF_VERTICAL),
H(HALF_VERTICAL_MIRROR),
M(HALF_HORIZONTAL),
E(STRIPE_TOP),
f(STRIPE_BOTTOM),
s(STRIPE_LEFT),
y(STRIPE_RIGHT),
r(DIAGONAL_LEFT),
J(DIAGONAL_RIGHT_MIRROR),
I(DIAGONAL_LEFT_MIRROR),
x(DIAGONAL_RIGHT),
m(STRIPE_DOWNLEFT),
n(STRIPE_DOWNRIGHT),
l(STRIPE_MIDDLE),
w(STRIPE_CENTER),
C(SQUARE_TOP_LEFT),
b(SQUARE_BOTTOM_LEFT),
D(SQUARE_TOP_RIGHT),
d(SQUARE_BOTTOM_RIGHT),
F(TRIANGLE_TOP),
g(TRIANGLE_BOTTOM),
v(RHOMBUS_MIDDLE),
t(CIRCLE_MIDDLE),
h(TRIANGLES_BOTTOM),
G(TRIANGLES_TOP),
B(STRIPE_SMALL),
c(BORDER),
i(CURLY_BORDER),
o(FLOWER),
k(CREEPER),
A(SKULL),
u(MOJANG);
private PatternType type;
PatternEnum(PatternType type) {
this.type = type;
}
public PatternType getPattern() {
return type;
}
}
}

View File

@ -0,0 +1,46 @@
package eu.mikroskeem.utils.bannerparser.parsers.planetminecraft;
import eu.mikroskeem.utils.bannerparser.IntegerFromString;
import org.bukkit.DyeColor;
import static org.bukkit.DyeColor.*;
class ColorParser {
static DyeColor valueOf(String a){
try {
/* Test for integer value first */
String name = IntegerFromString.valueOf(Integer.valueOf(a));
return ColorEnum.valueOf(name).getColor();
} catch (NumberFormatException e){
/* Return by string identifier */
return ColorEnum.valueOf(a).getColor();
}
}
@SuppressWarnings("unused")
private enum ColorEnum {
g(WHITE),
EIGHT(SILVER),
NINE(GRAY),
ONE(BLACK),
c(YELLOW),
f(ORANGE),
TWO(RED),
FOUR(BROWN),
b(LIME),
THREE(GREEN),
d(LIGHT_BLUE),
SEVEN(CYAN),
FIVE(BLUE),
a(PINK),
e(MAGENTA),
SIX(PURPLE);
private DyeColor color;
ColorEnum(DyeColor color) {
this.color = color;
}
public DyeColor getColor() {
return color;
}
}
}

View File

@ -0,0 +1,76 @@
package eu.mikroskeem.utils.bannerparser.parsers.planetminecraft;
import eu.mikroskeem.utils.bannerparser.IntegerFromString;
import org.bukkit.block.banner.PatternType;
import static org.bukkit.block.banner.PatternType.*;
class PatternParser {
static PatternType valueOf(String a) {
try {
/* Test for integer value first */
String name = IntegerFromString.valueOf(Integer.valueOf(a));
return PatternEnum.valueOf(name).getPattern();
} catch (NumberFormatException e){
/* Return by string identifier */
return PatternEnum.valueOf(a).getPattern();
}
}
@SuppressWarnings("unused")
private enum PatternEnum {
o(STRIPE_BOTTOM),
v(STRIPE_TOP),
s(STRIPE_LEFT),
u(STRIPE_RIGHT),
t(STRIPE_MIDDLE),
p(STRIPE_CENTER),
r(STRIPE_DOWNRIGHT),
q(STRIPE_DOWNLEFT),
SEVEN(CROSS),
i(STRIPE_SMALL),
n(STRAIGHT_CROSS),
a(DIAGONAL_RIGHT_MIRROR),
NINE(DIAGONAL_LEFT),
A(DIAGONAL_LEFT_MIRROR),
B(DIAGONAL_RIGHT),
e(HALF_VERTICAL),
E(HALF_VERTICAL_MIRROR),
d(HALF_HORIZONTAL),
D(HALF_HORIZONTAL_MIRROR),
j(SQUARE_BOTTOM_LEFT),
k(SQUARE_BOTTOM_RIGHT),
l(SQUARE_TOP_LEFT),
m(SQUARE_TOP_RIGHT),
y(TRIANGLE_BOTTOM),
z(TRIANGLE_TOP),
w(TRIANGLES_BOTTOM),
x(TRIANGLES_TOP),
FIVE(CIRCLE_MIDDLE),
g(RHOMBUS_MIDDLE),
THREE(BORDER),
EIGHT(CURLY_BORDER),
FOUR(BRICKS),
SIX(CREEPER),
h(SKULL),
b(FLOWER),
f(MOJANG),
c(GRADIENT),
C(GRADIENT_UP);
private PatternType type;
PatternEnum(PatternType type) {
this.type = type;
}
public PatternType getPattern() {
return type;
}
}
}

View File

@ -0,0 +1,51 @@
package eu.mikroskeem.utils.bannerparser.parsers.planetminecraft;
import eu.mikroskeem.utils.bannerparser.parsers.Parser;
import eu.mikroskeem.utils.bannerparser.ParseQuery;
import org.bukkit.DyeColor;
import org.bukkit.block.banner.Pattern;
import org.bukkit.block.banner.PatternType;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class PlanetMinecraftParser implements Parser {
/*
* See http://www.planetminecraft.com/banner/
*/
public ArrayList<Pattern> fromUrl(URL url){
try {
String bannerData = ParseQuery.splitQuery(url).getOrDefault("b", "");
return parse(bannerData);
} catch (UnsupportedEncodingException e){
return null;
}
}
private ArrayList<Pattern> parse(String whole){
ArrayList<Pattern> patterns = new ArrayList<>();
/* Get base color */
patterns.add(new Pattern(parseColor(whole.charAt(0)), PatternType.BASE));
/* Iterate over all others */
List<String> propertyList = Arrays.asList(whole.substring(1).split("(?<=\\G..)"));
propertyList.forEach(property->{
DyeColor color = parseColor(property.charAt(0));
PatternType patternType = parsePattern(property.charAt(1));
patterns.add(new Pattern(color, patternType));
});
return patterns;
}
private PatternType parsePattern(char part){
String partStr = String.valueOf(part);
return PatternParser.valueOf(partStr);
}
private DyeColor parseColor(char part){
String partStr = String.valueOf(part);
return ColorParser.valueOf(partStr);
}
}

View File

@ -0,0 +1,80 @@
package eu.mikroskeem.utils.test.bannerparser;
import eu.mikroskeem.utils.bannerparser.parsers.Parsers;
import eu.mikroskeem.utils.bannerparser.parsers.needcoolshoes.NeedCoolShoesParser;
import eu.mikroskeem.utils.bannerparser.parsers.planetminecraft.PlanetMinecraftParser;
import org.bukkit.DyeColor;
import org.bukkit.block.banner.Pattern;
import org.bukkit.block.banner.PatternType;
import org.junit.Assert;
import org.junit.Test;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
public class ParserTest {
@Test
public void testParserSelector() throws MalformedURLException {
URL url = new URL("http://www.planetminecraft.com/banner/?b=g2feC");
URL url1 = new URL("http://www.needcoolshoes.com/banner?=pabunK");
URL url2 = new URL("http://example.com");
Assert.assertEquals(Parsers.getParser(url).getClass(), PlanetMinecraftParser.class);
Assert.assertEquals(Parsers.getParser(url1).getClass(), NeedCoolShoesParser.class);
Assert.assertNull(Parsers.getParser(url2));
}
@Test
public void testPMCParser() throws MalformedURLException {
URL url = new URL("http://www.planetminecraft.com/banner/?b=g1Aca");
ArrayList<Pattern> matchPattern = new ArrayList<Pattern>(){{
add(new Pattern(DyeColor.WHITE, PatternType.BASE));
add(new Pattern(DyeColor.BLACK, PatternType.DIAGONAL_LEFT_MIRROR));
add(new Pattern(DyeColor.YELLOW, PatternType.DIAGONAL_RIGHT_MIRROR));
}};
ArrayList<Pattern> parsed = Parsers.parse(url);
for (int i = 0; i < parsed.size(); i++) {
Assert.assertEquals(matchPattern.get(i), parsed.get(i));
}
}
@Test
public void testNCSParser() throws MalformedURLException {
URL url = new URL("http://www.needcoolshoes.com/banner?=paaIlJ");
ArrayList<Pattern> matchPattern = new ArrayList<Pattern>(){{
add(new Pattern(DyeColor.WHITE, PatternType.BASE));
add(new Pattern(DyeColor.BLACK, PatternType.DIAGONAL_LEFT_MIRROR));
add(new Pattern(DyeColor.YELLOW, PatternType.DIAGONAL_RIGHT_MIRROR));
}};
ArrayList<Pattern> parsed = Parsers.parse(url);
for (int i = 0; i < parsed.size(); i++) {
Assert.assertEquals(matchPattern.get(i), parsed.get(i));
}
}
@Test
public void testDiagonals() throws MalformedURLException {
URL url = new URL("http://www.planetminecraft.com/banner/?b=gcAbBda29");
URL url1 = new URL("http://www.needcoolshoes.com/banner?=palIkxmJbr");
ArrayList<Pattern> matchPattern = new ArrayList<Pattern>(){{
add(new Pattern(DyeColor.WHITE, PatternType.BASE));
add(new Pattern(DyeColor.YELLOW, PatternType.DIAGONAL_LEFT_MIRROR));
add(new Pattern(DyeColor.LIME, PatternType.DIAGONAL_RIGHT));
add(new Pattern(DyeColor.LIGHT_BLUE, PatternType.DIAGONAL_RIGHT_MIRROR));
add(new Pattern(DyeColor.RED, PatternType.DIAGONAL_LEFT));
}};
ArrayList<Pattern> parsed = Parsers.parse(url);
for (int i = 0; i < parsed.size(); i++) {
Assert.assertTrue(parsed.get(i).equals(matchPattern.get(i)));
}
ArrayList<Pattern> parsed1 = Parsers.parse(url1);
for (int i = 0; i < parsed1.size(); i++) {
Assert.assertTrue(parsed1.get(i).equals(matchPattern.get(i)));
}
}
}

76
EtcdConnector/pom.xml Normal file
View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>utils</artifactId>
<groupId>eu.mikroskeem</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>etcdconnector</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/maven/**</exclude>
</excludes>
</filter>
</filters>
<relocations>
<relocation>
<pattern>io.netty</pattern>
<shadedPattern>eu.mikroskeem.utils.etcdconnector.deps.io.netty</shadedPattern>
<excludes>
<exclude>io.netty.*</exclude>
</excludes>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations-java5</artifactId>
<version>RELEASE</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<!-- Etcd -->
<dependency>
<groupId>org.mousio</groupId>
<artifactId>etcd4j</artifactId>
<version>2.12.0</version>
</dependency>
<!-- Serialization -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.7</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,30 @@
package eu.mikroskeem.utils.etcdconnector;
import mousio.client.retry.RetryOnce;
import mousio.etcd4j.EtcdClient;
import java.io.IOException;
import java.net.URI;
public class EtcdConnector extends EtcdConnectorBase {
/**
* Sets up EtcdConnector against
* Etcd server with no encryption
*
* @param etcdUrls url(s) where to connect to
*/
public EtcdConnector(URI... etcdUrls) throws IOException {
super();
/* Initialize client */
initClient(etcdUrls);
/* Test client */
testEtcd();
}
@Override void initClient(URI... urls){
etcdClient = new EtcdClient(urls);
etcdClient.setRetryHandler(new RetryOnce(5000));
}
}

View File

@ -0,0 +1,206 @@
package eu.mikroskeem.utils.etcdconnector;
import com.google.gson.Gson;
import mousio.etcd4j.EtcdClient;
import mousio.etcd4j.responses.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeoutException;
abstract class EtcdConnectorBase {
final Logger logger;
EtcdClient etcdClient;
EtcdConnectorBase() throws IOException {
/* Set up logger */
logger = LoggerFactory.getLogger("EtcdConnector");
}
/**
* Initializes EtcdClient object
*/
abstract void initClient(URI... urls);
/**
* Tests if Etcd connection is working
*
* @throws IOException if connection doesn't work
*/
void testEtcd() throws IOException {
/* Test client */
try {
logger.debug("Testing Etcd connection...");
EtcdVersionResponse ver = etcdClient.version();
logger.debug("Etcd server version: {}", ver.getServer());
} catch (NullPointerException e){
throw new IOException("Etcd connection test failed!");
}
logger.debug("Etcd is working!");
}
/**
* Closes Etcd4j client
*
* @throws IOException Thrown by Etcd4j
*/
public void close() throws IOException {
if(this.etcdClient != null){
this.etcdClient.close();
}
}
/**
* Gets etcd key value
*
* @param path Key path
* @return Key value
*/
@Nullable
public String getKey(@NotNull String path){
logger.debug("getKey: {}", path);
try {
EtcdKeysResponse response = etcdClient.get(path).send().get();
/* Parse object */
String rawResp = response.getNode().getValue();
if(rawResp != null){
return new Gson().fromJson(rawResp, String.class);
}
return null;
} catch(EtcdException e){
if(!e.isErrorCode(EtcdErrorCode.KeyNotFound)) {
e.printStackTrace();
}
} catch(IOException|EtcdAuthenticationException |TimeoutException e){
e.printStackTrace();
}
return null;
}
/**
* Gets etcd key value and sets default,
* if key isn't defined
*
* @param path Key path
* @param defaultValue Value to set if key is nonexistent
* @return Key value
*/
@Nullable
public String getKey(@NotNull String path, @NotNull String defaultValue){
logger.debug("getKey: {}, {}", path, defaultValue);
try {
EtcdKeysResponse response = etcdClient.get(path).send().get();
/* Parse object */
String rawResp = response.getNode().getValue();
if(rawResp != null){
return new Gson().fromJson(rawResp, String.class);
}
return null;
} catch(EtcdException e){
if(e.isErrorCode(EtcdErrorCode.KeyNotFound)){
/* Put default value to there then */
putKey(path, defaultValue);
return defaultValue;
} else e.printStackTrace();
} catch(IOException|EtcdAuthenticationException|TimeoutException e){
e.printStackTrace();
}
return null;
}
/**
* Gets etcd directory contents and returns it as
* List of String
*
* @param path directory path
* @return directory contents
*/
@Nullable
public List<String> getDir(@NotNull String path){
logger.debug("getDir: {}", path);
List<String> ret = new ArrayList<>();
try {
EtcdKeysResponse response = etcdClient.getDir(path).send().get();
response.getNode().getNodes().forEach(etcdNode -> ret.add((new File(etcdNode.getKey())).getName()));
return ret;
} catch(EtcdException e){
if(!(e.isErrorCode(EtcdErrorCode.KeyNotFound))){
e.printStackTrace();
}
return null;
} catch(IOException|EtcdAuthenticationException|TimeoutException e){
e.printStackTrace();
}
return null;
}
/**
* Sets etcd key value
*
* @param path key path
* @param value key value
* @return whether write succeeded or not
*/
public boolean putKey(@NotNull String path, @NotNull String value){
logger.debug("putKey: {}, {}", path, value);
try {
/* Serialize value */
EtcdKeysResponse response = etcdClient.put(path, new Gson().toJson(value)).send().get();
response.getNode().getValue();
return true;
} catch(Exception e) {
e.printStackTrace();
}
return false;
}
/**
* Sets etcd key value with TTL
*
* @param path key path
* @param value key value
* @param ttl key ttl (seconds)
* @return whether write succeeded or not
*/
public boolean putKey(@NotNull String path, @NotNull String value, @NotNull int ttl){
logger.debug("putKey: {}, {}, {}", path, value, ttl);
try {
EtcdKeysResponse response = etcdClient.put(path, new Gson().toJson(value)).ttl(ttl).send().get();
response.getNode().getValue();
return true;
} catch(Exception e) {
e.printStackTrace();
}
return false;
}
/**
* Deletes etcd key
* @param path key path
* @return whether delete succeeded or not
*/
public boolean deleteKey(@NotNull String path){
logger.debug("deleteKey: {}", path);
try {
EtcdKeysResponse response = etcdClient.delete(path).send().get();
response.getNode().getValue();
return true;
} catch(EtcdException e){
if(!(e.isErrorCode(EtcdErrorCode.KeyNotFound))){
e.printStackTrace();
}
} catch(Exception e){
e.printStackTrace();
}
return false;
}
}

33
Itemutils/pom.xml Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>utils</artifactId>
<groupId>eu.mikroskeem</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>itemutils</artifactId>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.10.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations-java5</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,35 @@
package eu.mikroskeem.utils.itemutils;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.block.Banner;
import org.bukkit.block.banner.Pattern;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
public class Shield {
/**
* Set Minecraft shield design
*
* @param shieldStack Shield itemstack to apply design on
* @param patternList Banner design patterns
*/
public static void setShieldDesign(@NotNull ItemStack shieldStack, @Nullable ArrayList<Pattern> patternList){
Validate.isTrue(shieldStack.getType().equals(Material.SHIELD), "Item must be a shield");
ItemMeta shieldMeta = shieldStack.getItemMeta();
BlockStateMeta shieldbMeta = (BlockStateMeta)shieldMeta;
Banner banner = (Banner)shieldbMeta.getBlockState();
banner.setPatterns(patternList);
banner.update(); // TODO: find out if it is needed
shieldbMeta.setBlockState(banner);
shieldStack.setItemMeta(shieldMeta);
}
}

32
Paste/pom.xml Normal file
View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>utils</artifactId>
<groupId>eu.mikroskeem</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>paste</artifactId>
<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160212</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations-java5</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,7 @@
package eu.mikroskeem.utils.paste;
import java.io.IOException;
public interface IPaste {
String paste(String content) throws IOException;
}

View File

@ -0,0 +1,43 @@
package eu.mikroskeem.utils.paste;
import eu.mikroskeem.utils.paste.providers.Hastebin;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
*
* @author Mark
*/
public class Paste {
private final IPaste pasteProvider;
public Paste(){
/* Currently only supported provider */
this.pasteProvider = new Hastebin();
}
/**
* Format exception into proper string
*
* @param e Exception to format
* @return Exception as string
*/
public static String formatException(Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
return sw.toString();
}
/**
* Paste stacktrace to pastebin
*
* @param e Exception to paste
* @return Paste url
*/
public String pasteException(Exception e) throws IOException {
return pasteProvider.paste(formatException(e));
}
}

View File

@ -0,0 +1,39 @@
package eu.mikroskeem.utils.paste.providers;
import eu.mikroskeem.utils.paste.IPaste;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class Hastebin implements IPaste {
@Nullable
public String paste(@NotNull String content) throws IOException {
HttpURLConnection connection = null;
try {
URL url = new URL("https://paste.nightsnack.cf/documents");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(content);
wr.flush();
wr.close();
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
return String.format("https://paste.nightsnack.cf/raw/%s", new JSONObject(rd.readLine()).get("key"));
} catch (MalformedURLException e) {
return null;
} finally {
if (connection == null) { return null; }
connection.disconnect();
}
}
}

View File

@ -0,0 +1,29 @@
package eu.mikroskeem.utils.test.paste;
import eu.mikroskeem.utils.paste.Paste;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
public class PasteTest {
@Test
public void testExceptionPaste(){
Paste paste = new Paste();
try {
throw new RuntimeException("Fake exception");
} catch (RuntimeException e){
String url;
try {
url = paste.pasteException(e);
} catch (IOException ioex){
/* Test paste server down? */
Assert.fail("Paste server seems to be down, unable to test");
return;
}
Assert.assertNotNull(url);
System.out.println("Example paste:");
System.out.println(url);
}
}
}

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# Utils
Various utils

26
Reflect/pom.xml Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>utils</artifactId>
<groupId>eu.mikroskeem</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>reflect</artifactId>
<dependencies>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations-java5</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,124 @@
package eu.mikroskeem.utils.reflect;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Reflection utils
*
* @author Mark
*/
public class Reflect {
/**
* Find class by name
*
* @param clazz Class to search
* @return Class or null
*/
@Nullable
public static Class<?> getClass(@NotNull String clazz){
try {
return Class.forName(clazz);
} catch (ClassNotFoundException e){
return null;
}
}
/**
* Return whether class exists or not
*
* @param clazz Class to search
* @return Whether class existed or not
*/
public static boolean classExists(@NotNull String clazz){
return getClass(clazz) != null;
}
/**
* Get declared class method (public,protected,private)
*
* @param clazz Class to reflect
* @param method Method to search
* @param arguments Method arguments
* @return Method or null
*/
@Nullable
public static Method getMethod(@NotNull Class<?> clazz, @NotNull String method, Class<?>... arguments){
try {
Method m = clazz.getDeclaredMethod(method, arguments);
m.setAccessible(true);
return m;
} catch (NoSuchMethodException e){
return null;
}
}
/**
* Invoke method and get result
*
* @param method Method to invoke
* @param instance Instance where given method resides (null if static)
* @param args Method arguments
* @return Method result or null
*/
@Nullable
public static Object invokeMethod(@NotNull Method method, @Nullable Object instance, @Nullable Object... args){
try {
return method.invoke(instance, args);
} catch (IllegalAccessException|InvocationTargetException e){
return null;
}
}
/**
* Get declared class field (public,protected,private)
*
* @param clazz Class to reflect
* @param field Field to search
* @return Field or null
*/
@Nullable
public static Field getField(@NotNull Class<?> clazz, @NotNull String field){
try {
Field f = clazz.getDeclaredField(field);
f.setAccessible(true);
return f;
} catch (NoSuchFieldException e){
return null;
}
}
/**
* Read field
*
* @param field Field to read
* @param instance Instance where to read (null if static)
* @return Field contents or null;
*/
@Nullable
public static Object readField(@NotNull Field field, @Nullable Object instance){
try {
return field.get(instance);
} catch (IllegalAccessException e){
return null;
}
}
/**
* Write field
*
* @param field Field to write
* @param instance Instance where field resides (null if static)
* @param value Field new contents
*/
public static void writeField(@NotNull Field field, @Nullable Object instance, @Nullable Object value){
try {
field.set(instance, value);
} catch (IllegalAccessException e){}
}
}

View File

@ -0,0 +1,6 @@
package eu.mikroskeem.utils.test.reflect;
public class ReflectionTestClass {
public static String FOOBAR = "nope";
public static String BAZFED = "yeah";
}

View File

@ -0,0 +1,65 @@
package eu.mikroskeem.utils.test.reflect;
import eu.mikroskeem.utils.reflect.Reflect;
import org.junit.Assert;
import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestReflect {
@Test
public void testGetClass(){
Assert.assertEquals(Reflect.getClass("java.lang.String"), String.class);
Assert.assertNotEquals(Reflect.getClass("java.lang.Integer"), String.class);
}
@Test
public void testClassFind(){
Assert.assertTrue(Reflect.classExists("java.lang.String"));
Assert.assertFalse(Reflect.classExists("foo.bar.baz.xyz"));
}
@Test
public void testGetMethod(){
Class reflectClass = Reflect.getClass("eu.mikroskeem.utils.reflect.Reflect");
Method method = Reflect.getMethod(reflectClass, "getClass", String.class);
Assert.assertNotNull(method);
Method invalidMethod = Reflect.getMethod(reflectClass, "getClass", Integer.class);
Assert.assertNull(invalidMethod);
}
@Test
public void testInvokeMethod(){
Class reflectClass = Reflect.getClass("eu.mikroskeem.utils.reflect.Reflect");
Method method = Reflect.getMethod(reflectClass, "getClass", String.class);
Class<?> resultClazz = (Class)Reflect.invokeMethod(method, null, "java.lang.String");
Assert.assertEquals(resultClazz, String.class);
}
@Test
public void testGetField(){
Class reflectTestClass = Reflect.getClass("eu.mikroskeem.utils.test.reflect.ReflectionTestClass");
Field foobarField = Reflect.getField(reflectTestClass, "FOOBAR");
Assert.assertNotNull(foobarField);
Field invalidField = Reflect.getField(reflectTestClass, "ROOMAZ");
Assert.assertNull(invalidField);
}
@Test
public void testReadField(){
Class reflectTestClass = Reflect.getClass("eu.mikroskeem.utils.test.reflect.ReflectionTestClass");
Field foobarField = Reflect.getField(reflectTestClass, "FOOBAR");
String value = (String)Reflect.readField(foobarField, null);
Assert.assertEquals(value, "nope");
}
@Test
public void testWriteField(){
Class reflectTestClass = Reflect.getClass("eu.mikroskeem.utils.test.reflect.ReflectionTestClass");
Field bazfed = Reflect.getField(reflectTestClass, "BAZFED");
Reflect.writeField(bazfed, null, "no yeah man :(");
String value = (String)Reflect.readField(bazfed, null);
Assert.assertEquals(value, "no yeah man :(");
}
}

55
pom.xml Normal file
View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>eu.mikroskeem</groupId>
<artifactId>utils</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>Reflect</module>
<module>Bannerparser</module>
<module>EtcdConnector</module>
<module>Paste</module>
<module>Itemutils</module>
</modules>
<!-- Properties -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<build.builder>${env.USER}</build.builder>
<build.number>${env.BUILD_NUMBER}</build.number>
</properties>
<!-- Default environment variables -->
<profiles>
<profile>
<id>Manual build</id>
<activation>
<property>
<name>!env.BUILD_NUMBER</name>
</property>
</activation>
<properties>
<env.BUILD_NUMBER>Manual:${maven.build.timestamp}</env.BUILD_NUMBER>
</properties>
</profile>
</profiles>
<build>
<defaultGoal>clean compile test package</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>