Merge branch 'server' of https://github.com/TotalFreedomMC/TotalFreedomMod into server
This commit is contained in:
commit
7b3a4babd1
62
pom.xml
62
pom.xml
|
@ -5,7 +5,7 @@
|
|||
|
||||
<groupId>me.totalfreedom</groupId>
|
||||
<artifactId>TotalFreedomMod</artifactId>
|
||||
<version>2020.10</version>
|
||||
<version>2020.11</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
|
@ -114,20 +114,25 @@
|
|||
<id>ess-repo</id>
|
||||
<url>https://ci.ender.zone/plugin/repository/everything/</url>
|
||||
</repository>
|
||||
|
||||
<repository>
|
||||
<id>telesphoreo-repo</id>
|
||||
<url>https://telesphoreo.me/repo/maven/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.12</version>
|
||||
<version>1.18.16</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.7</version>
|
||||
<version>2.8.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -141,35 +146,49 @@
|
|||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.14</version>
|
||||
<version>1.15</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>me.telesphoreo</groupId>
|
||||
<artifactId>mojangson</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>1.7</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.16.2-R0.1-SNAPSHOT</version>
|
||||
<version>1.16.3-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.TotalFreedom</groupId>
|
||||
<groupId>com.github.TotalFreedomMC</groupId>
|
||||
<artifactId>BukkitTelnet</artifactId>
|
||||
<version>4.5-pre1</version>
|
||||
<version>541e9fdb84</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.TFPatches</groupId>
|
||||
<groupId>com.github.TotalFreedomMC</groupId>
|
||||
<artifactId>TF-LibsDisguises</artifactId>
|
||||
<version>0cfa32159a</version>
|
||||
<version>48f01cf2fe</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sk89q.worldedit</groupId>
|
||||
<artifactId>worldedit-bukkit</artifactId>
|
||||
<version>7.1.0</version>
|
||||
<version>7.2.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -197,7 +216,7 @@
|
|||
<dependency>
|
||||
<groupId>com.sk89q.worldguard</groupId>
|
||||
<artifactId>worldguard-bukkit</artifactId>
|
||||
<version>7.0.3</version>
|
||||
<version>7.0.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -232,19 +251,21 @@
|
|||
<dependency>
|
||||
<groupId>org.reflections</groupId>
|
||||
<artifactId>reflections</artifactId>
|
||||
<version>0.9.11</version>
|
||||
<version>0.9.12</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javassist</groupId>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.12.1.GA</version>
|
||||
<version>3.27.0-GA</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.TFPatches</groupId>
|
||||
<groupId>com.github.TotalFreedomMC</groupId>
|
||||
<artifactId>TFGuilds</artifactId>
|
||||
<version>ad93b9ed00</version>
|
||||
<version>db036fb187</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -252,6 +273,7 @@
|
|||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -419,6 +441,10 @@
|
|||
<pattern>io.papermc.lib</pattern>
|
||||
<shadedPattern>me.totalfreedom.totalfreedommod.paperlib</shadedPattern> <!-- Replace this -->
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>me.totalfreedom.totalfreedommod</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<artifactSet>
|
||||
<includes>
|
||||
|
@ -426,9 +452,11 @@
|
|||
<include>org.apache.commons:commons-lang3</include>
|
||||
<include>commons-codec:commons-codec</include>
|
||||
<include>org.reflections:reflections</include>
|
||||
<include>javassist:javassist</include>
|
||||
<include>org.javassist:javassist</include>
|
||||
<include>me.rayzr522:jsonmessage</include>
|
||||
<include>io.papermc:paperlib</include>
|
||||
<include>me.telesphoreo:mojangson</include>
|
||||
<include>org.bstats:bstats-bukkit</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
</configuration>
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
package ca.momothereal.mojangson;
|
||||
|
||||
import ca.momothereal.mojangson.ex.MojangsonParseException;
|
||||
import ca.momothereal.mojangson.value.MojangsonString;
|
||||
import ca.momothereal.mojangson.value.MojangsonValue;
|
||||
|
||||
public class MojangsonFinder
|
||||
{
|
||||
|
||||
/**
|
||||
* Automatically detects the appropriate MojangsonValue from the given value.
|
||||
*
|
||||
* @param value The value to parse
|
||||
* @return The resulting MojangsonValue. If the type couldn't be found, it falls back to MojangsonString
|
||||
* @throws MojangsonParseException if the given value could not be parsed
|
||||
*/
|
||||
public static MojangsonValue readFromValue(String value) throws MojangsonParseException
|
||||
{
|
||||
MojangsonValue val = new MojangsonString();
|
||||
val.read(value);
|
||||
return val;
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package ca.momothereal.mojangson;
|
||||
|
||||
public enum MojangsonToken
|
||||
{
|
||||
|
||||
COMPOUND_START(0, "Compound_Start", '{'),
|
||||
COMPOUND_END(1, "Compound_End", '}'),
|
||||
ELEMENT_SEPERATOR(2, "Element_Seperator", ','),
|
||||
ARRAY_START(3, "Array_Start", '['),
|
||||
ARRAY_END(4, "Array_End", ']'),
|
||||
ELEMENT_PAIR_SEPERATOR(5, "Pair_Seperator", ':'),
|
||||
|
||||
STRING_QUOTES(6, "String_Quotes", '\"'),
|
||||
DOUBLE_SUFFIX(8, "Double_Suffix", 'd'),
|
||||
BYTE_SUFFIX(9, "Byte_Suffix", 'b'),
|
||||
FLOAT_SUFFIX(10, "Float_Suffix", 'f'),
|
||||
SHORT_SUFFIX(11, "Short_Suffix", 's'),
|
||||
LONG_SUFFIX(12, "Long_Suffix", 'l'),
|
||||
|
||||
WHITE_SPACE(13, "WhiteSpace", ' ');
|
||||
|
||||
private int id;
|
||||
private String name;
|
||||
private char symbol;
|
||||
|
||||
MojangsonToken(int id, String name, char symbol)
|
||||
{
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public char getSymbol()
|
||||
{
|
||||
return symbol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.valueOf(symbol);
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package ca.momothereal.mojangson.ex;
|
||||
|
||||
public class MojangsonParseException extends Exception
|
||||
{
|
||||
|
||||
private ParseExceptionReason reason;
|
||||
|
||||
public MojangsonParseException(String message, ParseExceptionReason reason)
|
||||
{
|
||||
super(message);
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public ParseExceptionReason getReason()
|
||||
{
|
||||
return reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage()
|
||||
{
|
||||
return reason.getMessage() + ": " + super.getMessage();
|
||||
}
|
||||
|
||||
public enum ParseExceptionReason
|
||||
{
|
||||
INVALID_FORMAT_NUM("Given value is not numerical"),
|
||||
UNEXPECTED_SYMBOL("Unexpected symbol in Mojangson string");
|
||||
|
||||
private String message;
|
||||
|
||||
ParseExceptionReason(String message)
|
||||
{
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage()
|
||||
{
|
||||
return message;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
package ca.momothereal.mojangson.value;
|
||||
|
||||
import ca.momothereal.mojangson.MojangsonFinder;
|
||||
import ca.momothereal.mojangson.ex.MojangsonParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import static ca.momothereal.mojangson.MojangsonToken.*;
|
||||
|
||||
public class MojangsonCompound extends HashMap<String, List<MojangsonValue>> implements MojangsonValue<Map<String, MojangsonValue>>
|
||||
{
|
||||
|
||||
private final int C_COMPOUND_START = 0; // Parsing context
|
||||
private final int C_COMPOUND_PAIR_KEY = 1; // Parsing context
|
||||
private final int C_COMPOUND_PAIR_VALUE = 2; // Parsing context
|
||||
|
||||
public MojangsonCompound()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public MojangsonCompound(Map map)
|
||||
{
|
||||
super(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(StringBuilder builder)
|
||||
{
|
||||
builder.append(COMPOUND_START);
|
||||
boolean start = true;
|
||||
|
||||
for (String key : keySet())
|
||||
{
|
||||
if (start)
|
||||
{
|
||||
start = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.append(ELEMENT_SEPERATOR);
|
||||
}
|
||||
|
||||
builder.append(key).append(ELEMENT_PAIR_SEPERATOR);
|
||||
List<MojangsonValue> value = get(key);
|
||||
for (MojangsonValue val : value)
|
||||
{
|
||||
val.write(builder);
|
||||
}
|
||||
}
|
||||
builder.append(COMPOUND_END);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(String string) throws MojangsonParseException
|
||||
{
|
||||
int context = C_COMPOUND_START;
|
||||
String tmp_key = "", tmp_val = "";
|
||||
int scope = 0;
|
||||
boolean inString = false;
|
||||
|
||||
for (int index = 0; index < string.length(); index++)
|
||||
{
|
||||
Character character = string.charAt(index);
|
||||
|
||||
if (character == STRING_QUOTES.getSymbol())
|
||||
{
|
||||
inString = !inString;
|
||||
}
|
||||
if (character == WHITE_SPACE.getSymbol())
|
||||
{
|
||||
if (!inString)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((character == COMPOUND_START.getSymbol() || character == ARRAY_START.getSymbol()) && !inString)
|
||||
{
|
||||
scope++;
|
||||
}
|
||||
if ((character == COMPOUND_END.getSymbol() || character == ARRAY_END.getSymbol()) && !inString)
|
||||
{
|
||||
scope--;
|
||||
}
|
||||
if (context == C_COMPOUND_START)
|
||||
{
|
||||
if (character != COMPOUND_START.getSymbol())
|
||||
{
|
||||
parseException(index, character);
|
||||
return;
|
||||
}
|
||||
context++;
|
||||
continue;
|
||||
}
|
||||
if (context == C_COMPOUND_PAIR_KEY)
|
||||
{
|
||||
if (character == ELEMENT_PAIR_SEPERATOR.getSymbol() && scope <= 1)
|
||||
{
|
||||
context++;
|
||||
continue;
|
||||
}
|
||||
tmp_key += character;
|
||||
continue;
|
||||
}
|
||||
if (context == C_COMPOUND_PAIR_VALUE)
|
||||
{
|
||||
if ((character == ELEMENT_SEPERATOR.getSymbol() || character == COMPOUND_END.getSymbol()) && scope <= 1 && !inString)
|
||||
{
|
||||
context = C_COMPOUND_PAIR_KEY;
|
||||
computeIfAbsent(tmp_key, k -> new ArrayList<>()).add(MojangsonFinder.readFromValue(tmp_val));
|
||||
tmp_key = tmp_val = "";
|
||||
continue;
|
||||
}
|
||||
tmp_val += character;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, MojangsonValue> getValue()
|
||||
{
|
||||
HashMap<String, MojangsonValue> hack = new HashMap<>();
|
||||
for (String string : keySet())
|
||||
{
|
||||
for (MojangsonValue value : get(string))
|
||||
{
|
||||
hack.put(string, value);
|
||||
}
|
||||
}
|
||||
return hack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getValueClass()
|
||||
{
|
||||
return Map.class;
|
||||
}
|
||||
|
||||
private void parseException(int index, char symbol) throws MojangsonParseException
|
||||
{
|
||||
throw new MojangsonParseException("Index: " + index + ", symbol: \'" + symbol + "\'", MojangsonParseException.ParseExceptionReason.UNEXPECTED_SYMBOL);
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package ca.momothereal.mojangson.value;
|
||||
|
||||
import ca.momothereal.mojangson.MojangsonToken;
|
||||
import ca.momothereal.mojangson.ex.MojangsonParseException;
|
||||
|
||||
public class MojangsonString implements MojangsonValue<String>
|
||||
{
|
||||
private String value;
|
||||
|
||||
public MojangsonString()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public MojangsonString(String value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(StringBuilder builder)
|
||||
{
|
||||
builder.append(MojangsonToken.STRING_QUOTES).append(value).append(MojangsonToken.STRING_QUOTES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getValueClass()
|
||||
{
|
||||
return String.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(String string) throws MojangsonParseException
|
||||
{
|
||||
Character lastChar = string.charAt(string.length() - 1);
|
||||
Character firstChar = string.charAt(0);
|
||||
|
||||
if (firstChar == MojangsonToken.STRING_QUOTES.getSymbol() && lastChar == MojangsonToken.STRING_QUOTES.getSymbol())
|
||||
{
|
||||
value = string.substring(1, string.length() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = string;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package ca.momothereal.mojangson.value;
|
||||
|
||||
import ca.momothereal.mojangson.ex.MojangsonParseException;
|
||||
|
||||
/**
|
||||
* Represents a value inside a compound or array.
|
||||
*
|
||||
* @param <T> The type of value this MojangsonValue holds
|
||||
*/
|
||||
public interface MojangsonValue<T>
|
||||
{
|
||||
|
||||
/**
|
||||
* Writes the value to a StringBuilder buffer.
|
||||
*
|
||||
* @param builder The buffer to write to
|
||||
*/
|
||||
void write(StringBuilder builder);
|
||||
|
||||
/**
|
||||
* Parses and updates the current value to the given string representation
|
||||
*
|
||||
* @param string The string representation of the value
|
||||
* @throws MojangsonParseException if the given value cannot be parsed
|
||||
*/
|
||||
void read(String string) throws MojangsonParseException;
|
||||
|
||||
/**
|
||||
* Gets the current literal value
|
||||
*
|
||||
* @return The current literal value of the MojangsonValue
|
||||
*/
|
||||
T getValue();
|
||||
|
||||
/**
|
||||
* Gets the literal value's class
|
||||
*
|
||||
* @return The literal value's class
|
||||
*/
|
||||
Class getValueClass();
|
||||
|
||||
}
|
|
@ -50,7 +50,7 @@ import me.totalfreedom.totalfreedommod.util.MethodTimer;
|
|||
import me.totalfreedom.totalfreedommod.world.CleanroomChunkGenerator;
|
||||
import me.totalfreedom.totalfreedommod.world.WorldManager;
|
||||
import me.totalfreedom.totalfreedommod.world.WorldRestrictions;
|
||||
import org.bstats.Metrics;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.sql.ResultSet;
|
|||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import me.totalfreedom.totalfreedommod.FreedomService;
|
||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
||||
|
@ -103,7 +104,7 @@ public class CoreProtectBridge extends FreedomService
|
|||
@Override
|
||||
public void run()
|
||||
{
|
||||
coreProtect.performRollback(86400, Arrays.asList(name), null, null, null, null, 0, null);
|
||||
coreProtect.performRollback(86400, Collections.singletonList(name), null, null, null, null, 0, null);
|
||||
}
|
||||
}.runTaskAsynchronously(plugin);
|
||||
}
|
||||
|
@ -123,7 +124,7 @@ public class CoreProtectBridge extends FreedomService
|
|||
@Override
|
||||
public void run()
|
||||
{
|
||||
coreProtect.performRestore(86400, Arrays.asList(name), null, null, null, null, 0, null);
|
||||
coreProtect.performRestore(86400, Collections.singletonList(name), null, null, null, null, 0, null);
|
||||
}
|
||||
}.runTaskAsynchronously(plugin);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import java.util.Map;
|
|||
import me.totalfreedom.totalfreedommod.FreedomService;
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.CoreProtectAPI;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
|
@ -24,7 +23,7 @@ import org.bukkit.block.data.BlockData;
|
|||
|
||||
public class FAWEBridge extends FreedomService
|
||||
{
|
||||
private CoreProtectAPI api;
|
||||
private final CoreProtectAPI api = plugin.cpb.getCoreProtectAPI();;
|
||||
private World world = null;
|
||||
private final Map<Map.Entry<String, EditSession>, Map<BlockVector3, String>> blocksBroken = new HashMap<>();
|
||||
private final Map<Map.Entry<String, EditSession>, Map.Entry<Pattern, List<BlockVector3>>> blocksPlaced = new HashMap<>();
|
||||
|
@ -32,68 +31,62 @@ public class FAWEBridge extends FreedomService
|
|||
@Override
|
||||
public void onStart()
|
||||
{
|
||||
api = ((CoreProtect)Bukkit.getPluginManager().getPlugin("CoreProtect")).getAPI();
|
||||
|
||||
/*
|
||||
* Iterates over blocks placed by GenerationCommands (in the EditSession) and adds them to the CoreProtect logs.
|
||||
*/
|
||||
server.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable()
|
||||
server.getScheduler().scheduleSyncRepeatingTask(plugin, () ->
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
if (!(blocksBroken.isEmpty() && blocksPlaced.isEmpty()))
|
||||
{
|
||||
if (!(blocksBroken.isEmpty() && blocksPlaced.isEmpty()))
|
||||
// Send all broken blocks from the last ticks to the CoreProtect API.
|
||||
Map.Entry<String, EditSession> playerAndSessionEntry = null;
|
||||
for (Map.Entry<Map.Entry<String, EditSession>, Map<BlockVector3, String>> entry : blocksBroken.entrySet())
|
||||
{
|
||||
// Send all broken blocks from the last ticks to the CoreProtect API.
|
||||
Map.Entry<String, EditSession> playerAndSessionEntry = null;
|
||||
for (Map.Entry<Map.Entry<String, EditSession>, Map<BlockVector3, String>> entry : blocksBroken.entrySet())
|
||||
{
|
||||
playerAndSessionEntry = entry.getKey();
|
||||
Map<BlockVector3, String> dataAndVectorEntry = entry.getValue();
|
||||
List<BlockVector3> blockVector3List = new ArrayList<>();
|
||||
blockVector3List.addAll(dataAndVectorEntry.keySet()); // Deep clone the block vector to avoid a change later in the code.
|
||||
playerAndSessionEntry = entry.getKey();
|
||||
Map<BlockVector3, String> dataAndVectorEntry = entry.getValue();
|
||||
List<BlockVector3> blockVector3List = new ArrayList<>();
|
||||
blockVector3List.addAll(dataAndVectorEntry.keySet()); // Deep clone the block vector to avoid a change later in the code.
|
||||
|
||||
for (BlockVector3 blockVector3 : blockVector3List)
|
||||
for (BlockVector3 blockVector3 : blockVector3List)
|
||||
{
|
||||
if (blockVector3 != null)
|
||||
{
|
||||
if (blockVector3 != null)
|
||||
{
|
||||
EditSession editSession = playerAndSessionEntry.getValue();
|
||||
World world = server.getWorld(editSession.getWorld().getName());
|
||||
Location location = new Location(world, blockVector3.getX(), blockVector3.getY(), blockVector3.getZ());
|
||||
BlockData blockData = server.createBlockData(dataAndVectorEntry.get(blockVector3));
|
||||
api.logRemoval(playerAndSessionEntry.getKey(), location, blockData.getMaterial(), blockData);
|
||||
}
|
||||
EditSession editSession = playerAndSessionEntry.getValue();
|
||||
World world = server.getWorld(editSession.getWorld().getName());
|
||||
Location location = new Location(world, blockVector3.getX(), blockVector3.getY(), blockVector3.getZ());
|
||||
BlockData blockData = server.createBlockData(dataAndVectorEntry.get(blockVector3));
|
||||
api.logRemoval(playerAndSessionEntry.getKey(), location, blockData.getMaterial(), blockData);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear after broken blocks have been updated.
|
||||
blocksBroken.values().clear();
|
||||
blocksBroken.putIfAbsent(playerAndSessionEntry, new HashMap<>());
|
||||
|
||||
// Send all blocks placed to the CoreProtect API (except from the air as it's only a broken block).
|
||||
for (Map.Entry<Map.Entry<String, EditSession>, Map.Entry<Pattern, List<BlockVector3>>> entry : blocksPlaced.entrySet())
|
||||
{
|
||||
playerAndSessionEntry = entry.getKey();
|
||||
Map.Entry<Pattern, List<BlockVector3>> patternAndListEntry = entry.getValue();
|
||||
Pattern pattern = patternAndListEntry.getKey();
|
||||
List<BlockVector3> blockVector3List = new ArrayList<>();
|
||||
blockVector3List.addAll(patternAndListEntry.getValue()); // Deep clone the block vector to avoid a change later in the code.
|
||||
|
||||
for (BlockVector3 blockVector3 : blockVector3List)
|
||||
{
|
||||
if (blockVector3 != null && !pattern.apply(blockVector3).getBlockType().getMaterial().isAir())
|
||||
{
|
||||
World world = server.getWorld(playerAndSessionEntry.getValue().getWorld().getName());
|
||||
Location location = new Location(world, blockVector3.getX(), blockVector3.getY(), blockVector3.getZ());
|
||||
BaseBlock block = pattern.apply(blockVector3);
|
||||
Material material = Material.getMaterial(block.getBlockType().getId().replaceFirst("minecraft:", "").toUpperCase());
|
||||
api.logPlacement(playerAndSessionEntry.getKey(), location, material, material.createBlockData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blocksPlaced.values().forEach(collection -> collection.getValue().clear());
|
||||
}
|
||||
|
||||
// Clear after broken blocks have been updated.
|
||||
blocksBroken.values().clear();
|
||||
blocksBroken.putIfAbsent(playerAndSessionEntry, new HashMap<>());
|
||||
|
||||
// Send all blocks placed to the CoreProtect API (except from the air as it's only a broken block).
|
||||
for (Map.Entry<Map.Entry<String, EditSession>, Map.Entry<Pattern, List<BlockVector3>>> entry : blocksPlaced.entrySet())
|
||||
{
|
||||
playerAndSessionEntry = entry.getKey();
|
||||
Map.Entry<Pattern, List<BlockVector3>> patternAndListEntry = entry.getValue();
|
||||
Pattern pattern = patternAndListEntry.getKey();
|
||||
List<BlockVector3> blockVector3List = new ArrayList<>();
|
||||
blockVector3List.addAll(patternAndListEntry.getValue()); // Deep clone the block vector to avoid a change later in the code.
|
||||
|
||||
for (BlockVector3 blockVector3 : blockVector3List)
|
||||
{
|
||||
if (blockVector3 != null && !pattern.apply(blockVector3).getBlockType().getMaterial().isAir())
|
||||
{
|
||||
World world = server.getWorld(playerAndSessionEntry.getValue().getWorld().getName());
|
||||
Location location = new Location(world, blockVector3.getX(), blockVector3.getY(), blockVector3.getZ());
|
||||
BaseBlock block = pattern.apply(blockVector3);
|
||||
Material material = Material.getMaterial(block.getBlockType().getId().replaceFirst("minecraft:", "").toUpperCase());
|
||||
api.logPlacement(playerAndSessionEntry.getKey(), location, material, material.createBlockData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blocksPlaced.values().forEach(collection -> collection.getValue().clear());
|
||||
}
|
||||
}, 0L, 40L);
|
||||
}
|
||||
|
@ -101,10 +94,8 @@ public class FAWEBridge extends FreedomService
|
|||
@Override
|
||||
public void onStop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void logBlockEdit(String playerName, EditSession editSession, Pattern pattern, BlockVector3 blockVector3)
|
||||
{
|
||||
// Cache the world used for the next iterations to come.
|
||||
|
|
|
@ -60,7 +60,7 @@ public class WorldEditBridge extends FreedomService
|
|||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
com.sk89q.worldedit.entity.Player fuckyou = (com.sk89q.worldedit.entity.Player)bukkitPlayer;
|
||||
com.sk89q.worldedit.entity.Player fuckyou = bukkitPlayer;
|
||||
session.undo(session.getBlockBag(fuckyou), fuckyou);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import org.bukkit.entity.Player;
|
|||
@CommandParameters(description = "Shows the amount of coins you have or another player has", usage = "/<command> [playername]")
|
||||
public class Command_coins extends FreedomCommand
|
||||
{
|
||||
|
||||
@Override
|
||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package me.totalfreedom.totalfreedommod.command;
|
||||
|
||||
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
||||
import me.totalfreedom.totalfreedommod.rank.Rank;
|
||||
import me.totalfreedom.totalfreedommod.shop.ShopItem;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME)
|
||||
@CommandParameters(description = "Change your login message", usage = "/<command> [message]")
|
||||
public class Command_loginmessage extends FreedomCommand
|
||||
{
|
||||
|
||||
@Override
|
||||
public boolean run(final CommandSender sender, final Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
||||
{
|
||||
if (!plugin.pl.getData(playerSender).hasItem(ShopItem.LOGIN_MESSAGES) && !isStaff(playerSender))
|
||||
{
|
||||
msg("You did not purchase the ability to use login messages! Purchase the ability from the shop.", ChatColor.RED);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 0)
|
||||
{
|
||||
playerSender.openInventory(plugin.sh.generateLoginMessageGUI(playerSender));
|
||||
return true;
|
||||
}
|
||||
|
||||
checkRank(Rank.ADMIN);
|
||||
|
||||
String message = StringUtils.join(args, " ");
|
||||
if (!message.contains("%rank%") && !message.contains("%coloredrank%"))
|
||||
{
|
||||
msg("Your login message must contain your rank. Use either %rank% or %coloredrank% to specify where you want the rank", ChatColor.RED);
|
||||
return true;
|
||||
}
|
||||
int length = message.replace("%name%", "").replace("%rank%", "").replace("%coloredrank%", "").replace("%art%", "").length();
|
||||
if (length > 100)
|
||||
{
|
||||
msg("Your login message cannot be more than 100 characters (excluding your rank and your name)", ChatColor.RED);
|
||||
return true;
|
||||
}
|
||||
PlayerData data = getData(playerSender);
|
||||
data.setLoginMessage(message);
|
||||
plugin.pl.save(data);
|
||||
msg("Your login message is now the following:\n" + plugin.rm.craftLoginMessage(playerSender, message), ChatColor.GREEN);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -88,7 +88,7 @@ public class Command_manageshop extends FreedomCommand
|
|||
msg(PLAYER_NOT_FOUND);
|
||||
return true;
|
||||
}
|
||||
playerData.setCoins(playerData.getCoins() + amount);
|
||||
playerData.setCoins(playerData.getCoins() - amount);
|
||||
if (playerData.getCoins() < 0)
|
||||
{
|
||||
playerData.setCoins(0);
|
||||
|
|
|
@ -17,7 +17,7 @@ import org.bukkit.entity.Player;
|
|||
|
||||
@CommandPermissions(level = Rank.ADMIN, source = SourceType.ONLY_IN_GAME)
|
||||
@CommandParameters(description = "Manage your staff entry.", usage = "/<command> [-o <staff member>] <clearips | clearip <ip> | setlogin <message> | clearlogin | setscformat <format> | clearscformat> | oldtags | logstick | syncroles>")
|
||||
public class Command_mystaff extends FreedomCommand
|
||||
public class Command_myadmin extends FreedomCommand
|
||||
{
|
||||
|
||||
@Override
|
||||
|
@ -139,46 +139,6 @@ public class Command_mystaff extends FreedomCommand
|
|||
return true;
|
||||
}
|
||||
|
||||
case "setlogin":
|
||||
{
|
||||
checkRank(Rank.ADMIN);
|
||||
if (args.length < 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
String message = StringUtils.join(args, " ", 1, args.length);
|
||||
if (!message.contains("%rank%") && !message.contains("%coloredrank%"))
|
||||
{
|
||||
msg("Your login message must contain your rank. Use either %rank% or %coloredrank% to specify where you want the rank", ChatColor.RED);
|
||||
return true;
|
||||
}
|
||||
int length = message.replace("%name%", "").replace("%rank%", "").replace("%coloredrank%", "").length();
|
||||
if (length > 100)
|
||||
{
|
||||
msg("Your login message cannot be more than 100 characters (excluding your rank and your name)", ChatColor.RED);
|
||||
return true;
|
||||
}
|
||||
FUtil.staffAction(sender.getName(), "Setting personal login message" + (init == null ? "" : " for " + targetPlayer.getName()), false);
|
||||
target.setLoginMessage(message);
|
||||
String previewMessage = plugin.rm.craftLoginMessage(targetPlayer, message);
|
||||
msg((init == null ? "Your" : targetPlayer.getName() + "'s") + " login message is now: ");
|
||||
msg("> " + previewMessage);
|
||||
plugin.sl.save(target);
|
||||
plugin.sl.updateTables();
|
||||
return true;
|
||||
}
|
||||
|
||||
case "clearlogin":
|
||||
{
|
||||
checkRank(Rank.ADMIN);
|
||||
FUtil.staffAction(sender.getName(), "Clearing personal login message" + (init == null ? "" : " for " + targetPlayer.getName()), false);
|
||||
target.setLoginMessage(null);
|
||||
plugin.sl.save(target);
|
||||
plugin.sl.updateTables();
|
||||
return true;
|
||||
}
|
||||
|
||||
case "setscformat":
|
||||
{
|
||||
String format = StringUtils.join(args, " ", 1, args.length);
|
||||
|
@ -229,10 +189,6 @@ public class Command_mystaff extends FreedomCommand
|
|||
return true;
|
||||
}
|
||||
|
||||
case "genbackupcodes":
|
||||
msg("Moved to /pv genbackupcodes", ChatColor.RED);
|
||||
return true;
|
||||
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
|
@ -248,8 +204,8 @@ public class Command_mystaff extends FreedomCommand
|
|||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<String> singleArguments = Arrays.asList("clearips", "setlogin", "setscformat");
|
||||
List<String> doubleArguments = Arrays.asList("clearip", "clearlogin", "clearscformat", "oldtags", "syncroles");
|
||||
List<String> singleArguments = Arrays.asList("clearips", "setscformat");
|
||||
List<String> doubleArguments = Arrays.asList("clearip", "clearscformat", "syncroles");
|
||||
if (args.length == 1)
|
||||
{
|
||||
List<String> options = new ArrayList<>();
|
|
@ -3,7 +3,6 @@ package me.totalfreedom.totalfreedommod.command;
|
|||
import io.papermc.lib.PaperLib;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TimerTask;
|
||||
import me.totalfreedom.totalfreedommod.player.FPlayer;
|
||||
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
||||
import me.totalfreedom.totalfreedommod.rank.Rank;
|
||||
|
@ -12,6 +11,7 @@ import org.bukkit.ChatColor;
|
|||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME)
|
||||
@CommandParameters(description = "Ride on the top of the specified player.", usage = "/<command> <playername | mode <normal | off | ask>>")
|
||||
|
@ -39,7 +39,7 @@ public class Command_ride extends FreedomCommand
|
|||
{
|
||||
if (!RIDE_REQUESTS.containsKey(playerSender))
|
||||
{
|
||||
msg("You don't have a request currently.");
|
||||
msg("You don't have any pending requests.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,7 @@ public class Command_ride extends FreedomCommand
|
|||
PaperLib.teleportAsync(requester, playerSender.getLocation());
|
||||
}
|
||||
|
||||
RIDE_REQUESTS.remove(playerSender);
|
||||
playerSender.addPassenger(requester);
|
||||
return true;
|
||||
}
|
||||
|
@ -67,7 +68,7 @@ public class Command_ride extends FreedomCommand
|
|||
{
|
||||
if (!RIDE_REQUESTS.containsKey(playerSender))
|
||||
{
|
||||
msg("You don't have a request currently.");
|
||||
msg("You don't have any pending requests.");
|
||||
return true;
|
||||
}
|
||||
Player requester = RIDE_REQUESTS.get(playerSender);
|
||||
|
@ -125,22 +126,23 @@ public class Command_ride extends FreedomCommand
|
|||
player.sendMessage(ChatColor.AQUA + sender.getName() + " has requested to ride you.");
|
||||
player.sendMessage(ChatColor.AQUA + "Type " + ChatColor.GREEN + "/ride accept" + ChatColor.AQUA + " to allow the player to ride you.");
|
||||
player.sendMessage(ChatColor.AQUA + "Type " + ChatColor.RED + "/ride deny" + ChatColor.AQUA + " to deny the player permission.");
|
||||
player.sendMessage(ChatColor.AQUA + "Request will expire after 30 seconds.");
|
||||
player.sendMessage(ChatColor.AQUA + "Request will expire in 30 seconds.");
|
||||
RIDE_REQUESTS.put(player, playerSender);
|
||||
timer.schedule(new TimerTask()
|
||||
|
||||
new BukkitRunnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (!RIDE_REQUESTS.containsKey(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RIDE_REQUESTS.remove(player);
|
||||
msg("Request expired.", ChatColor.RED);
|
||||
playerSender.sendMessage(ChatColor.RED + "It has been 30 seconds and " + player.getName() + " has not accepted your request.");
|
||||
player.sendMessage(ChatColor.RED + "Request expired.");
|
||||
}
|
||||
}, 30000);
|
||||
}.runTaskLater(plugin, 20 * 30);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,11 +99,6 @@ public enum ConfigEntry
|
|||
PTERO_ADMIN_KEY(String.class, "ptero.admin_key"),
|
||||
PTERO_SERVER_KEY(String.class, "ptero.server_key"),
|
||||
//
|
||||
DONATION_PROBOARDS_URL(String.class, "donation.proboards_url"),
|
||||
DONATION_GROUP_ID(String.class, "donation.donator_group_id"),
|
||||
DONATION_SESSION_ID(String.class, "donation.session_id"),
|
||||
DONATION_CSRF_TOKEN(String.class, "donation.csrf_token"),
|
||||
//
|
||||
SHOP_ENABLED(Boolean.class, "shop.enabled"),
|
||||
SHOP_TITLE(String.class, "shop.title"),
|
||||
SHOP_PREFIX(String.class, "shop.prefix"),
|
||||
|
@ -113,12 +108,14 @@ public enum ConfigEntry
|
|||
SHOP_REACTIONS_TIME(Double.class, "shop.reactions.time"),
|
||||
SHOP_REACTIONS_COINS_PER_WIN(Integer.class, "shop.reactions.coins_per_win"),
|
||||
SHOP_REACTIONS_STRING_LENGTH(Integer.class, "shop.reactions.string_length"),
|
||||
SHOP_LOGIN_MESSAGES(List.class, "shop.login_messages"),
|
||||
SHOP_PRICES_GRAPPLING_HOOK(Integer.class, "shop.prices.grappling_hook"),
|
||||
SHOP_PRICES_LIGHTNING_ROD(Integer.class, "shop.prices.lightning_rod"),
|
||||
SHOP_PRICES_FIRE_BALL(Integer.class, "shop.prices.fire_ball"),
|
||||
SHOP_PRICES_RIDEABLE_PEARL(Integer.class, "shop.prices.rideable_pearl"),
|
||||
SHOP_PRICES_STACKING_POTATO(Integer.class, "shop.prices.stacking_potato"),
|
||||
SHOP_PRICES_CLOWN_FISH(Integer.class, "shop.prices.clown_fish"),
|
||||
SHOP_PRICES_LOGIN_MESSAGES(Integer.class, "shop.prices.login_messages"),
|
||||
//
|
||||
STAFFLIST_CLEAN_THESHOLD_HOURS(Integer.class, "stafflist.clean_threshold_hours"),
|
||||
STAFFLIST_CONSOLE_IS_ADMIN(Boolean.class, "stafflist.console_is_admin"),
|
||||
|
|
|
@ -7,8 +7,12 @@ import me.totalfreedom.totalfreedommod.rank.Title;
|
|||
import me.totalfreedom.totalfreedommod.util.FLog;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -20,21 +24,43 @@ public class DiscordToMinecraftListener extends ListenerAdapter
|
|||
String chat_channel_id = ConfigEntry.DISCORD_CHAT_CHANNEL_ID.getString();
|
||||
if (event.getMember() != null && !chat_channel_id.isEmpty() && event.getChannel().getId().equals(chat_channel_id))
|
||||
{
|
||||
if (!event.getAuthor().getId().equals(Discord.bot.getSelfUser().getId()) && !event.getMessage().getContentDisplay().isEmpty())
|
||||
if (!event.getAuthor().getId().equals(Discord.bot.getSelfUser().getId()))
|
||||
{
|
||||
Member member = event.getMember();
|
||||
String tag = getDisplay(member);
|
||||
String message = ChatColor.DARK_GRAY + "[" + ChatColor.DARK_AQUA + "Discord" + ChatColor.DARK_GRAY + "]";
|
||||
Message msg = event.getMessage();
|
||||
if (tag != null)
|
||||
{
|
||||
message += " " + tag;
|
||||
}
|
||||
message += " " + ChatColor.RED + ChatColor.stripColor(member.getEffectiveName()) + ChatColor.DARK_GRAY + ": " + ChatColor.RESET + ChatColor.stripColor(event.getMessage().getContentDisplay());
|
||||
message += " " + ChatColor.RED + ChatColor.stripColor(member.getEffectiveName()) + ChatColor.DARK_GRAY + ":" + ChatColor.RESET;
|
||||
ComponentBuilder builder = new ComponentBuilder(message);
|
||||
if (!msg.getContentDisplay().isEmpty())
|
||||
{
|
||||
builder.append(" ").append(ChatColor.stripColor(msg.getContentDisplay()));
|
||||
message += " " + ChatColor.stripColor(msg.getContentDisplay()); // for logging
|
||||
}
|
||||
if (!msg.getAttachments().isEmpty())
|
||||
{
|
||||
for (Message.Attachment attachment : msg.getAttachments())
|
||||
{
|
||||
if (attachment.getUrl() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
builder.append(" ");
|
||||
TextComponent text = new TextComponent(ChatColor.YELLOW + "[Media]");
|
||||
text.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, attachment.getUrl()));
|
||||
builder.append(text);
|
||||
message += " [Media]"; // for logging
|
||||
}
|
||||
}
|
||||
for (Player player : Bukkit.getOnlinePlayers())
|
||||
{
|
||||
if (TotalFreedomMod.getPlugin().pl.getData(player).doesDisplayDiscord())
|
||||
{
|
||||
player.sendMessage(message);
|
||||
player.spigot().sendMessage(builder.create());
|
||||
}
|
||||
}
|
||||
FLog.info(message);
|
||||
|
|
|
@ -256,12 +256,6 @@ public class ItemFun extends FreedomService
|
|||
break;
|
||||
}
|
||||
|
||||
if (onCooldown(player, ShopItem.CLOWN_FISH))
|
||||
{
|
||||
player.sendMessage(ChatColor.RED + "You're currently on a cool-down for 30 seconds.");
|
||||
break;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
boolean didHit = false;
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ public class Module_list extends HTTPDModule
|
|||
operators.add(player.getName());
|
||||
}
|
||||
|
||||
if (!hasSpecialTitle(player) && plugin.sl.isStaff(player))
|
||||
if (!hasSpecialTitle(player) && plugin.sl.isStaff(player) && !plugin.sl.isVanished(player.getName()))
|
||||
{
|
||||
StaffMember staffMember = plugin.sl.getAdmin(player);
|
||||
switch (staffMember.getRank())
|
||||
|
@ -142,7 +142,7 @@ public class Module_list extends HTTPDModule
|
|||
|
||||
public boolean hasSpecialTitle(Player player)
|
||||
{
|
||||
if (FUtil.DEVELOPERS.contains(player.getName()) || ConfigEntry.SERVER_EXECUTIVES.getList().contains(player.getName()) || ConfigEntry.SERVER_OWNERS.getList().contains(player.getName()))
|
||||
if (FUtil.DEVELOPERS.contains(player.getUniqueId().toString()) || ConfigEntry.SERVER_EXECUTIVES.getList().contains(player.getName()) || ConfigEntry.SERVER_OWNERS.getList().contains(player.getName()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ public class Module_players extends HTTPDModule
|
|||
masterbuilders.addAll(plugin.pl.getMasterBuilderNames());
|
||||
|
||||
// Developers
|
||||
developers.addAll(FUtil.DEVELOPERS);
|
||||
developers.addAll(FUtil.DEVELOPER_NAMES);
|
||||
|
||||
// Executives
|
||||
executives.addAll(ConfigEntry.SERVER_EXECUTIVES.getList());
|
||||
|
|
|
@ -33,8 +33,6 @@ public class PlayerData
|
|||
private String discordID = null;
|
||||
private final List<String> backupCodes = Lists.newArrayList();
|
||||
@Setter
|
||||
private boolean donator = false;
|
||||
@Setter
|
||||
private Boolean masterBuilder = false;
|
||||
@Setter
|
||||
private Boolean verification = false;
|
||||
|
@ -53,6 +51,9 @@ public class PlayerData
|
|||
@Getter
|
||||
@Setter
|
||||
private String redditUsername;
|
||||
@Getter
|
||||
@Setter
|
||||
private String loginMessage;
|
||||
|
||||
public PlayerData(ResultSet resultSet)
|
||||
{
|
||||
|
@ -67,7 +68,6 @@ public class PlayerData
|
|||
discordID = resultSet.getString("discord_id");
|
||||
backupCodes.clear();
|
||||
backupCodes.addAll(FUtil.stringToList(resultSet.getString("backup_codes")));
|
||||
donator = resultSet.getBoolean("donator");
|
||||
masterBuilder = resultSet.getBoolean("master_builder");
|
||||
verification = resultSet.getBoolean("verification");
|
||||
rideMode = resultSet.getString("ride_mode");
|
||||
|
@ -77,6 +77,7 @@ public class PlayerData
|
|||
totalVotes = resultSet.getInt("total_votes");
|
||||
displayDiscord = resultSet.getBoolean("display_discord");
|
||||
redditUsername = resultSet.getString("reddit_username");
|
||||
loginMessage = resultSet.getString("login_message");
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
|
@ -104,7 +105,6 @@ public class PlayerData
|
|||
output.append("Player: ").append(name).append("\n")
|
||||
.append("- IPs: ").append(StringUtils.join(ips, ", ")).append("\n")
|
||||
.append("- Discord ID: ").append(discordID).append("\n")
|
||||
.append("- Donator: ").append(donator).append("\n")
|
||||
.append("- Master Builder: ").append(masterBuilder).append("\n")
|
||||
.append("- Has Verification: ").append(verification).append("\n")
|
||||
.append("- Coins: ").append(coins).append("\n")
|
||||
|
@ -113,7 +113,8 @@ public class PlayerData
|
|||
.append("- Tag: ").append(FUtil.colorize(tag)).append(ChatColor.GRAY).append("\n")
|
||||
.append("- Ride Mode: ").append(rideMode).append("\n")
|
||||
.append("- Backup Codes: ").append(backupCodes.size()).append("/10").append("\n")
|
||||
.append("- Reddit Username: ").append(redditUsername);
|
||||
.append("- Reddit Username: ").append(redditUsername)
|
||||
.append("- Login Message: ").append(loginMessage);
|
||||
|
||||
return output.toString();
|
||||
}
|
||||
|
@ -128,6 +129,11 @@ public class PlayerData
|
|||
return Collections.unmodifiableList(ips);
|
||||
}
|
||||
|
||||
public boolean hasLoginMessage()
|
||||
{
|
||||
return loginMessage != null && !loginMessage.isEmpty();
|
||||
}
|
||||
|
||||
public boolean addIp(String ip)
|
||||
{
|
||||
return !ips.contains(ip) && ips.add(ip);
|
||||
|
@ -221,11 +227,6 @@ public class PlayerData
|
|||
return verification;
|
||||
}
|
||||
|
||||
public boolean isDonator()
|
||||
{
|
||||
return donator;
|
||||
}
|
||||
|
||||
public boolean isMasterBuilder()
|
||||
{
|
||||
return masterBuilder;
|
||||
|
@ -241,7 +242,6 @@ public class PlayerData
|
|||
put("tag", tag);
|
||||
put("discord_id", discordID);
|
||||
put("backup_codes", FUtil.listToString(backupCodes));
|
||||
put("donator", donator);
|
||||
put("master_builder", masterBuilder);
|
||||
put("verification", verification);
|
||||
put("ride_mode", rideMode);
|
||||
|
@ -250,6 +250,7 @@ public class PlayerData
|
|||
put("total_votes", totalVotes);
|
||||
put("display_discord", displayDiscord);
|
||||
put("reddit_username", redditUsername);
|
||||
put("login_message", loginMessage);
|
||||
}};
|
||||
return map;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import net.md_5.bungee.api.ChatColor;
|
|||
public interface Displayable
|
||||
{
|
||||
|
||||
public String getArticle();
|
||||
|
||||
public String getName();
|
||||
|
||||
public String getTag();
|
||||
|
@ -21,7 +23,8 @@ public interface Displayable
|
|||
|
||||
public String getColoredLoginMessage();
|
||||
|
||||
|
||||
public boolean hasTeam();
|
||||
|
||||
public boolean hasDefaultLoginMessage();
|
||||
|
||||
}
|
||||
|
|
|
@ -5,20 +5,21 @@ import net.md_5.bungee.api.ChatColor;
|
|||
|
||||
public enum Rank implements Displayable
|
||||
{
|
||||
IMPOSTOR("an", "Impostor", Type.PLAYER, "Imp", ChatColor.YELLOW, null, false),
|
||||
NON_OP("a", "Non-Op", Type.PLAYER, "", ChatColor.WHITE, null, false),
|
||||
OP("an", "Operator", Type.PLAYER, "OP", ChatColor.GREEN, null, false),
|
||||
ADMIN("an", "Admin", Type.STAFF, "Admin", ChatColor.DARK_GREEN, org.bukkit.ChatColor.DARK_GREEN, true),
|
||||
SENIOR_ADMIN("a", "Senior Admin", Type.STAFF, "SrA", ChatColor.GOLD, org.bukkit.ChatColor.GOLD, true),
|
||||
ADMIN_CONSOLE("the", "Console", Type.STAFF_CONSOLE, "Console", ChatColor.DARK_PURPLE, null, false),
|
||||
SENIOR_CONSOLE("the", "Console", Type.STAFF_CONSOLE, "Console", ChatColor.DARK_PURPLE, null, false);
|
||||
IMPOSTOR("an", "Impostor", Type.PLAYER, "Imp", ChatColor.YELLOW, null, false, false),
|
||||
NON_OP("a", "Non-Op", Type.PLAYER, "", ChatColor.WHITE, null, false, false),
|
||||
OP("an", "Operator", Type.PLAYER, "OP", ChatColor.GREEN, null, false, false),
|
||||
ADMIN("an", "Admin", Type.STAFF, "Admin", ChatColor.DARK_GREEN, org.bukkit.ChatColor.DARK_GREEN, true, true),
|
||||
SENIOR_ADMIN("a", "Senior Admin", Type.STAFF, "SrA", ChatColor.GOLD, org.bukkit.ChatColor.GOLD, true, true),
|
||||
ADMIN_CONSOLE("the", "Console", Type.STAFF_CONSOLE, "Console", ChatColor.DARK_PURPLE, null, false, false),
|
||||
SENIOR_CONSOLE("the", "Console", Type.STAFF_CONSOLE, "Console", ChatColor.DARK_PURPLE, null, false, false);
|
||||
@Getter
|
||||
private final Type type;
|
||||
@Getter
|
||||
private final String name;
|
||||
@Getter
|
||||
private final String abbr;
|
||||
private final String determiner;
|
||||
@Getter
|
||||
private final String article;
|
||||
@Getter
|
||||
private final String tag;
|
||||
@Getter
|
||||
|
@ -29,18 +30,21 @@ public enum Rank implements Displayable
|
|||
private final org.bukkit.ChatColor teamColor;
|
||||
@Getter
|
||||
private final boolean hasTeam;
|
||||
@Getter
|
||||
private final boolean hasDefaultLoginMessage;
|
||||
|
||||
Rank(String determiner, String name, Type type, String abbr, ChatColor color, org.bukkit.ChatColor teamColor, Boolean hasTeam)
|
||||
Rank(String article, String name, Type type, String abbr, ChatColor color, org.bukkit.ChatColor teamColor, Boolean hasTeam, Boolean hasDefaultLoginMessage)
|
||||
{
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.abbr = abbr;
|
||||
this.determiner = determiner;
|
||||
this.article = article;
|
||||
this.tag = abbr.isEmpty() ? "" : "[" + abbr + "]";
|
||||
this.coloredTag = abbr.isEmpty() ? "" : ChatColor.DARK_GRAY + "[" + color + abbr + ChatColor.DARK_GRAY + "]" + color;
|
||||
this.color = color;
|
||||
this.teamColor = teamColor;
|
||||
this.hasTeam = hasTeam;
|
||||
this.hasDefaultLoginMessage = hasDefaultLoginMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -52,7 +56,7 @@ public enum Rank implements Displayable
|
|||
@Override
|
||||
public String getColoredLoginMessage()
|
||||
{
|
||||
return determiner + " " + color + name;
|
||||
return article + " " + color + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -61,6 +65,12 @@ public enum Rank implements Displayable
|
|||
return hasTeam;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDefaultLoginMessage()
|
||||
{
|
||||
return hasDefaultLoginMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAbbr()
|
||||
{
|
||||
|
|
|
@ -168,7 +168,7 @@ public class RankManager extends FreedomService
|
|||
FPlayer fPlayer = plugin.pl.getPlayer(player);
|
||||
PlayerData data = plugin.pl.getData(player);
|
||||
Displayable display = getDisplay(player);
|
||||
if (plugin.sl.isStaff(player) || data.isMasterBuilder() || data.isDonator() || FUtil.isDeveloper(player))
|
||||
if (plugin.sl.isStaff(player) || data.isMasterBuilder() || FUtil.isDeveloper(player))
|
||||
{
|
||||
String displayName = display.getColor() + player.getName();
|
||||
player.setPlayerListName(displayName);
|
||||
|
@ -237,7 +237,7 @@ public class RankManager extends FreedomService
|
|||
}
|
||||
|
||||
// Broadcast login message
|
||||
if (isStaff || FUtil.isDeveloper(player) || plugin.pl.getData(player).isMasterBuilder() || plugin.pl.getData(player).isDonator())
|
||||
if (isStaff || FUtil.isDeveloper(player) || plugin.pl.getData(player).isMasterBuilder() || plugin.pl.getData(player).hasLoginMessage())
|
||||
{
|
||||
if (!plugin.sl.isVanished(player.getName()))
|
||||
{
|
||||
|
@ -260,23 +260,32 @@ public class RankManager extends FreedomService
|
|||
public String craftLoginMessage(Player player, String message)
|
||||
{
|
||||
Displayable display = plugin.rm.getDisplay(player);
|
||||
String loginMessage = ChatColor.AQUA + player.getName() + " is " + display.getColoredLoginMessage();
|
||||
if (plugin.sl.isStaff(player))
|
||||
PlayerData playerData = plugin.pl.getData(player);
|
||||
if (message == null)
|
||||
{
|
||||
StaffMember staffMember = plugin.sl.getAdmin(player);
|
||||
if (staffMember.hasLoginMessage())
|
||||
if (playerData.hasLoginMessage())
|
||||
{
|
||||
if (message == null)
|
||||
message = playerData.getLoginMessage();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (display.hasDefaultLoginMessage())
|
||||
{
|
||||
message = staffMember.getLoginMessage();
|
||||
message = "%name% is %art% %coloredrank%";
|
||||
}
|
||||
loginMessage = FUtil.colorize(ChatColor.AQUA + (message.contains("%name%") ? "" : player.getName() + " is ")
|
||||
+ FUtil.colorize(message).replace("%name%", player.getName())
|
||||
.replace("%rank%", display.getName())
|
||||
.replace("%coloredrank%", display.getColoredName()));
|
||||
}
|
||||
}
|
||||
return loginMessage;
|
||||
if (message != null)
|
||||
{
|
||||
String loginMessage = FUtil.colorize(ChatColor.AQUA + (message.contains("%name%") ? "" : player.getName() + " is ")
|
||||
+ FUtil.colorize(message).replace("%name%", player.getName())
|
||||
.replace("%rank%", display.getName())
|
||||
.replace("%coloredrank%", display.getColoredName())
|
||||
.replace("%art%", display.getArticle()));
|
||||
return loginMessage;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updatePlayerTeam(Player player)
|
||||
|
@ -304,4 +313,4 @@ public class RankManager extends FreedomService
|
|||
team.addPlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,14 @@ import net.md_5.bungee.api.ChatColor;
|
|||
public enum Title implements Displayable
|
||||
{
|
||||
|
||||
MASTER_BUILDER("a", "Master Builder", ChatColor.DARK_AQUA, org.bukkit.ChatColor.DARK_AQUA, "MB", true),
|
||||
VERIFIED_STAFF("a", "Verified Staff", ChatColor.LIGHT_PURPLE, org.bukkit.ChatColor.LIGHT_PURPLE, "VS", false),
|
||||
EXECUTIVE("an", "Executive", ChatColor.RED, org.bukkit.ChatColor.RED, "Exec", true),
|
||||
DEVELOPER("a", "Developer", ChatColor.DARK_PURPLE, org.bukkit.ChatColor.DARK_PURPLE, "Dev", true),
|
||||
OWNER("the", "Owner", ChatColor.of("#ff0000"), org.bukkit.ChatColor.DARK_RED, "Owner", true);
|
||||
MASTER_BUILDER("a", "Master Builder", ChatColor.DARK_AQUA, org.bukkit.ChatColor.DARK_AQUA, "MB", true, true),
|
||||
VERIFIED_STAFF("a", "Verified Staff Member", ChatColor.LIGHT_PURPLE, org.bukkit.ChatColor.LIGHT_PURPLE, "VS", false, true),
|
||||
EXECUTIVE("an", "Executive", ChatColor.RED, org.bukkit.ChatColor.RED, "Exec", true, true),
|
||||
DEVELOPER("a", "Developer", ChatColor.DARK_PURPLE, org.bukkit.ChatColor.DARK_PURPLE, "Dev", true, true),
|
||||
OWNER("the", "Owner", ChatColor.of("#ff0000"), org.bukkit.ChatColor.DARK_RED, "Owner", true, true);
|
||||
|
||||
private final String determiner;
|
||||
@Getter
|
||||
private final String article;
|
||||
@Getter
|
||||
private final String name;
|
||||
@Getter
|
||||
|
@ -27,10 +28,11 @@ public enum Title implements Displayable
|
|||
private final org.bukkit.ChatColor teamColor;
|
||||
@Getter
|
||||
private final boolean hasTeam;
|
||||
private final boolean hasDefaultLoginMessage;
|
||||
|
||||
Title(String determiner, String name, ChatColor color, org.bukkit.ChatColor teamColor, String tag, Boolean hasTeam)
|
||||
Title(String article, String name, ChatColor color, org.bukkit.ChatColor teamColor, String tag, Boolean hasTeam, Boolean hasDefaultLoginMessage)
|
||||
{
|
||||
this.determiner = determiner;
|
||||
this.article = article;
|
||||
this.name = name;
|
||||
this.coloredTag = ChatColor.DARK_GRAY + "[" + color + tag + ChatColor.DARK_GRAY + "]" + color;
|
||||
this.abbr = tag;
|
||||
|
@ -38,6 +40,7 @@ public enum Title implements Displayable
|
|||
this.color = color;
|
||||
this.teamColor = teamColor;
|
||||
this.hasTeam = hasTeam;
|
||||
this.hasDefaultLoginMessage = hasDefaultLoginMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -52,9 +55,15 @@ public enum Title implements Displayable
|
|||
return hasTeam;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDefaultLoginMessage()
|
||||
{
|
||||
return hasDefaultLoginMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColoredLoginMessage()
|
||||
{
|
||||
return determiner + " " + color + name;
|
||||
return article + " " + color + name;
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@ public class Shop extends FreedomService
|
|||
public final String prefix = ChatColor.DARK_GRAY + "[" + ChatColor.YELLOW + "Reaction" + ChatColor.DARK_GRAY + "] ";
|
||||
public BukkitTask countdownTask;
|
||||
private BossBar countdownBar = null;
|
||||
private final String LOGIN_MESSAGE_GUI_TITLE = ChatColor.DARK_GREEN + ChatColor.BOLD.toString() + "Login Messages";
|
||||
|
||||
@Override
|
||||
public void onStart()
|
||||
|
@ -174,6 +175,27 @@ public class Shop extends FreedomService
|
|||
return gui;
|
||||
}
|
||||
|
||||
public Inventory generateLoginMessageGUI(Player player)
|
||||
{
|
||||
Inventory gui = server.createInventory(null, 36, LOGIN_MESSAGE_GUI_TITLE);
|
||||
int slot = 0;
|
||||
for (String loginMessage : ConfigEntry.SHOP_LOGIN_MESSAGES.getStringList())
|
||||
{
|
||||
ItemStack icon = new ItemStack(Material.NAME_TAG);
|
||||
ItemMeta meta = icon.getItemMeta();
|
||||
meta.setDisplayName(FUtil.colorize(plugin.rm.craftLoginMessage(player, loginMessage)));
|
||||
icon.setItemMeta(meta);
|
||||
gui.setItem(slot, icon);
|
||||
slot++;
|
||||
}
|
||||
ItemStack clear = new ItemStack(Material.BARRIER);
|
||||
ItemMeta meta = clear.getItemMeta();
|
||||
meta.setDisplayName(ChatColor.RED + "Clear login message");
|
||||
clear.setItemMeta(meta);
|
||||
gui.setItem(35, clear);
|
||||
return gui;
|
||||
}
|
||||
|
||||
public boolean isRealItem(PlayerData data, ShopItem shopItem, PlayerInventory inventory, ItemStack realItem)
|
||||
{
|
||||
if (isRealItem(data, shopItem, inventory.getItemInMainHand(), realItem) || isRealItem(data, shopItem, inventory.getItemInOffHand(), realItem))
|
||||
|
@ -306,7 +328,7 @@ public class Shop extends FreedomService
|
|||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onInventoryClick(InventoryClickEvent event)
|
||||
public void onShopGUIClick(InventoryClickEvent event)
|
||||
{
|
||||
if (!(event.getWhoClicked() instanceof Player))
|
||||
{
|
||||
|
@ -350,6 +372,44 @@ public class Shop extends FreedomService
|
|||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onLoginMessageGUIClick(InventoryClickEvent event)
|
||||
{
|
||||
if (!(event.getWhoClicked() instanceof Player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Inventory inventory = event.getInventory();
|
||||
if (inventory.getSize() != 36 || !event.getView().getTitle().equals(LOGIN_MESSAGE_GUI_TITLE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
|
||||
int slot = event.getSlot();
|
||||
|
||||
Player player = (Player)event.getWhoClicked();
|
||||
PlayerData data = plugin.pl.getData(player);
|
||||
|
||||
if (slot == 35)
|
||||
{
|
||||
data.setLoginMessage(null);
|
||||
plugin.pl.save(data);
|
||||
player.sendMessage(ChatColor.GREEN + "Removed your login message");
|
||||
}
|
||||
else
|
||||
{
|
||||
String message = ConfigEntry.SHOP_LOGIN_MESSAGES.getStringList().get(slot);
|
||||
data.setLoginMessage(message);
|
||||
plugin.pl.save(data);
|
||||
player.sendMessage(ChatColor.GREEN + "Your login message is now the following:\n" + plugin.rm.craftLoginMessage(player, message));
|
||||
}
|
||||
|
||||
player.closeInventory();
|
||||
|
||||
}
|
||||
|
||||
public ShopItem getShopItem(int slot)
|
||||
{
|
||||
for (ShopItem shopItem : ShopItem.values())
|
||||
|
|
|
@ -12,17 +12,18 @@ public enum ShopItem
|
|||
FIRE_BALL("Fire Ball", Material.FIRE_CHARGE, 14, ConfigEntry.SHOP_PRICES_FIRE_BALL, ChatColor.RED, "fireBall", "/fireball"),
|
||||
RIDEABLE_PEARL("Rideable Ender Pearl", Material.ENDER_PEARL, 16, ConfigEntry.SHOP_PRICES_RIDEABLE_PEARL, ChatColor.DARK_PURPLE, "rideablePearl", "/rideablepearl"),
|
||||
STACKING_POTATO("Stacking Potato", Material.POTATO, 20, ConfigEntry.SHOP_PRICES_STACKING_POTATO, ChatColor.YELLOW, "stackingPotato", "/stackingpotato"),
|
||||
CLOWN_FISH("Clown Fish", Material.TROPICAL_FISH, 24, ConfigEntry.SHOP_PRICES_CLOWN_FISH, ChatColor.GOLD, "clownFish", "/clownfish");
|
||||
CLOWN_FISH("Clown Fish", Material.TROPICAL_FISH, 22, ConfigEntry.SHOP_PRICES_CLOWN_FISH, ChatColor.GOLD, "clownFish", "/clownfish"),
|
||||
LOGIN_MESSAGES("Login Messages", Material.NAME_TAG, 24, ConfigEntry.SHOP_PRICES_LOGIN_MESSAGES, ChatColor.DARK_GREEN, "loginMessages", "/loginmessage");
|
||||
|
||||
/*
|
||||
Shop GUI Layout:
|
||||
|
||||
Dimensions: 9x4 = 36
|
||||
Key: g = Grappling Hook, l = Lightning Rod, f = Fire Ball, r = Rideable Ender Pearl, s = Stacking Potato, c = Clown Fish, $ = Coins}
|
||||
Key: g = Grappling Hook, l = Lightning Rod, f = Fire Ball, r = Rideable Ender Pearl, s = Stacking Potato, c = Clown Fish, x = Login Messages $ = Coins}
|
||||
|
||||
---------
|
||||
-g-l-f-r-
|
||||
--s---c--
|
||||
--s-c-x--
|
||||
--------$
|
||||
*/
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ public class SQLite extends FreedomService
|
|||
{
|
||||
try
|
||||
{
|
||||
connection.createStatement().execute("CREATE TABLE `staff` (`username` VARCHAR NOT NULL, `ips` VARCHAR NOT NULL, `rank` VARCHAR NOT NULL, `active` BOOLEAN NOT NULL, `last_login` LONG NOT NULL, `login_message` VARCHAR, `command_spy` BOOLEAN NOT NULL, `potion_spy` BOOLEAN NOT NULL, `ac_format` VARCHAR, `ptero_id` VARCHAR);");
|
||||
connection.createStatement().execute("CREATE TABLE `staff` (`username` VARCHAR NOT NULL, `ips` VARCHAR NOT NULL, `rank` VARCHAR NOT NULL, `active` BOOLEAN NOT NULL, `last_login` LONG NOT NULL, `command_spy` BOOLEAN NOT NULL, `potion_spy` BOOLEAN NOT NULL, `ac_format` VARCHAR, `ptero_id` VARCHAR);");
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
|
@ -93,7 +93,7 @@ public class SQLite extends FreedomService
|
|||
{
|
||||
try
|
||||
{
|
||||
connection.createStatement().execute("CREATE TABLE `players` (`username` VARCHAR NOT NULL, `ips` VARCHAR NOT NULL, `notes` VARCHAR, `tag` VARCHAR, `discord_id` VARCHAR, `backup_codes` VARCHAR, `donator` BOOLEAN NOT NULL, `master_builder` BOOLEAN NOT NULL,`verification` BOOLEAN NOT NULL, `ride_mode` VARCHAR NOT NULL, `coins` INT NOT NULL, `items` VARCHAR, `total_votes` INT NOT NULL, `display_discord` BOOLEAN NOT NULL, `reddit_username` VARCHAR NOT NULL);");
|
||||
connection.createStatement().execute("CREATE TABLE `players` (`username` VARCHAR NOT NULL, `ips` VARCHAR NOT NULL, `notes` VARCHAR, `tag` VARCHAR, `discord_id` VARCHAR, `backup_codes` VARCHAR, `donator` BOOLEAN NOT NULL, `master_builder` BOOLEAN NOT NULL,`verification` BOOLEAN NOT NULL, `ride_mode` VARCHAR NOT NULL, `coins` INT NOT NULL, `items` VARCHAR, `total_votes` INT NOT NULL, `display_discord` BOOLEAN NOT NULL, `reddit_username` VARCHAR, `login_message` VARCHAR);");
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
|
@ -141,7 +141,8 @@ public class SQLite extends FreedomService
|
|||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
FLog.severe("Failed to update staff member value: " + e.getMessage());
|
||||
FLog.severe("Failed to update staff member value:");
|
||||
FLog.severe(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,7 +253,6 @@ public class SQLite extends FreedomService
|
|||
statement.setString(3, staffMember.getRank().toString());
|
||||
statement.setBoolean(4, staffMember.isActive());
|
||||
statement.setLong(5, staffMember.getLastLogin().getTime());
|
||||
statement.setString(6, staffMember.getLoginMessage());
|
||||
statement.setBoolean(7, staffMember.getCommandSpy());
|
||||
statement.setBoolean(8, staffMember.getPotionSpy());
|
||||
statement.setString(9, staffMember.getAcFormat());
|
||||
|
@ -261,7 +261,8 @@ public class SQLite extends FreedomService
|
|||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
FLog.severe("Failed to add staff member: " + e);
|
||||
FLog.severe("Failed to add staff member:");
|
||||
FLog.severe(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,27 +270,28 @@ public class SQLite extends FreedomService
|
|||
{
|
||||
try
|
||||
{
|
||||
PreparedStatement statement = connection.prepareStatement("INSERT INTO players VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
PreparedStatement statement = connection.prepareStatement("INSERT INTO players VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
statement.setString(1, player.getName());
|
||||
statement.setString(2, FUtil.listToString(player.getIps()));
|
||||
statement.setString(3, FUtil.listToString(player.getNotes()));
|
||||
statement.setString(4, player.getTag());
|
||||
statement.setString(5, player.getDiscordID());
|
||||
statement.setString(6, FUtil.listToString(player.getBackupCodes()));
|
||||
statement.setBoolean(7, player.isDonator());
|
||||
statement.setBoolean(8, player.isMasterBuilder());
|
||||
statement.setBoolean(9, player.hasVerification());
|
||||
statement.setString(10, player.getRideMode());
|
||||
statement.setInt(11, player.getCoins());
|
||||
statement.setBoolean(7, player.isMasterBuilder());
|
||||
statement.setBoolean(8, player.hasVerification());
|
||||
statement.setString(9, player.getRideMode());
|
||||
statement.setInt(10, player.getCoins());
|
||||
statement.setString(12, FUtil.listToString(player.getItems()));
|
||||
statement.setInt(13, player.getTotalVotes());
|
||||
statement.setBoolean(14, player.doesDisplayDiscord());
|
||||
statement.setString(15, player.getRedditUsername());
|
||||
statement.setString(16, player.getLoginMessage());
|
||||
statement.executeUpdate();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
FLog.severe("Failed to add player: " + e);
|
||||
FLog.severe("Failed to add player:");
|
||||
FLog.severe(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,7 +307,8 @@ public class SQLite extends FreedomService
|
|||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
FLog.severe("Failed to get staff member by name: " + e);
|
||||
FLog.severe("Failed to get staff member by name:");
|
||||
FLog.severe(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -323,7 +326,8 @@ public class SQLite extends FreedomService
|
|||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
FLog.severe("Failed to get player by name: " + e);
|
||||
FLog.severe("Failed to get player by name:");
|
||||
FLog.severe(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -337,7 +341,8 @@ public class SQLite extends FreedomService
|
|||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
FLog.severe("Failed to get Master Builders: " + e);
|
||||
FLog.severe("Failed to get Master Builders:");
|
||||
FLog.severe(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -355,7 +360,8 @@ public class SQLite extends FreedomService
|
|||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
FLog.severe("Failed to get player by ip: " + e.getMessage());
|
||||
FLog.severe("Failed to get player by ip:");
|
||||
FLog.severe(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -369,7 +375,8 @@ public class SQLite extends FreedomService
|
|||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
FLog.severe("Failed to remove staff member: " + e.getMessage());
|
||||
FLog.severe("Failed to remove staff member:");
|
||||
FLog.severe(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,9 +35,6 @@ public class StaffMember
|
|||
private Date lastLogin = new Date();
|
||||
@Getter
|
||||
@Setter
|
||||
private String loginMessage = null;
|
||||
@Getter
|
||||
@Setter
|
||||
private Boolean commandSpy = false;
|
||||
@Getter
|
||||
@Setter
|
||||
|
@ -65,7 +62,6 @@ public class StaffMember
|
|||
this.ips.clear();
|
||||
this.ips.addAll(FUtil.stringToList(resultSet.getString("ips")));
|
||||
this.lastLogin = new Date(resultSet.getLong("last_login"));
|
||||
this.loginMessage = resultSet.getString("login_message");
|
||||
this.commandSpy = resultSet.getBoolean("command_spy");
|
||||
this.potionSpy = resultSet.getBoolean("potion_spy");
|
||||
this.acFormat = resultSet.getString("ac_format");
|
||||
|
@ -85,7 +81,6 @@ public class StaffMember
|
|||
output.append("Staff: ").append(name).append("\n")
|
||||
.append("- IPs: ").append(StringUtils.join(ips, ", ")).append("\n")
|
||||
.append("- Last Login: ").append(FUtil.dateToString(lastLogin)).append("\n")
|
||||
.append("- Custom Login Message: ").append(loginMessage).append("\n")
|
||||
.append("- Rank: ").append(rank.getName()).append("\n")
|
||||
.append("- Is Active: ").append(active).append("\n")
|
||||
.append("- Potion Spy: ").append(potionSpy).append("\n")
|
||||
|
@ -104,7 +99,6 @@ public class StaffMember
|
|||
put("rank", rank.toString());
|
||||
put("ips", FUtil.listToString(ips));
|
||||
put("last_login", lastLogin.getTime());
|
||||
put("login_message", loginMessage);
|
||||
put("command_spy", commandSpy);
|
||||
put("potion_spy", potionSpy);
|
||||
put("ac_format", acFormat);
|
||||
|
@ -113,11 +107,6 @@ public class StaffMember
|
|||
return map;
|
||||
}
|
||||
|
||||
public boolean hasLoginMessage()
|
||||
{
|
||||
return loginMessage != null && !loginMessage.isEmpty();
|
||||
}
|
||||
|
||||
// Util IP methods
|
||||
public void addIp(String ip)
|
||||
{
|
||||
|
|
|
@ -56,7 +56,7 @@ public class FUtil
|
|||
public static final String SAVED_FLAGS_FILENAME = "savedflags.dat";
|
||||
/* See https://github.com/TotalFreedom/License - None of the listed names may be removed.
|
||||
Leaving this list here for anyone running TFM on a cracked server:
|
||||
public static final List<String> DEVELOPERS = Arrays.asList("Madgeek1450", "Prozza", "WickedGamingUK", "Wild1145", "aggelosQQ", "scripthead", "supernt", "Telesphoreo", "CoolJWB");
|
||||
public static final List<String> DEVELOPERS = Arrays.asList("Madgeek1450", "Prozza", "WickedGamingUK", "Wild1145", "aggelosQQ", "scripthead", "Telesphoreo", "CoolJWB");
|
||||
*/
|
||||
public static final List<String> DEVELOPERS = Arrays.asList(
|
||||
"1156a81a-23fb-435e-9aff-fe9c2ea7e82d", // Madgeek1450
|
||||
|
@ -65,10 +65,10 @@ public class FUtil
|
|||
"604cbb51-842d-4b43-8b0a-d1d7c6cd2869", // Wild1145
|
||||
"e67d77c4-fff9-4cea-94cc-9f1f1ab7806b", // aggelosQQ
|
||||
"0061326b-8b3d-44c8-830a-5f2d59f5dc1b", // scripthead
|
||||
"53b1512e-3481-4702-9f4f-63cb9c8be6a1", // supernt
|
||||
"78408086-1991-4c33-a571-d8fa325465b2", // Telesphoreo
|
||||
"67ce0e28-3d6b-469c-ab71-304eec81b614" // CoolJWB
|
||||
);
|
||||
public static final List<String> DEVELOPER_NAMES = Arrays.asList("Madgeek1450", "Prozza", "WickedGamingUK", "Wild1145", "aggelosQQ", "scripthead", "Telesphoreo", "CoolJWB");
|
||||
public static String DATE_STORAGE_FORMAT = "EEE, d MMM yyyy HH:mm:ss Z";
|
||||
public static final Map<String, ChatColor> CHAT_COLOR_NAMES = new HashMap<>();
|
||||
public static final List<ChatColor> CHAT_COLOR_POOL = Arrays.asList(
|
||||
|
|
|
@ -1,847 +0,0 @@
|
|||
package org.bstats;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
|
||||
/**
|
||||
* bStats collects some data for plugin authors.
|
||||
* <p>
|
||||
* Check out https://bStats.org/ to learn more about bStats!
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public class Metrics
|
||||
{
|
||||
static
|
||||
{
|
||||
// You can use the property to disable the check in your test environment
|
||||
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false"))
|
||||
{
|
||||
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
|
||||
final String defaultPackage = new String(
|
||||
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
|
||||
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||
// We want to make sure nobody just copy & pastes the example and use the wrong package names
|
||||
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage))
|
||||
{
|
||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The version of this bStats class
|
||||
public static final int B_STATS_VERSION = 1;
|
||||
|
||||
// The url to which the data is sent
|
||||
private static final String URL = "https://bStats.org/submitData/bukkit";
|
||||
|
||||
// Is bStats enabled on this server?
|
||||
private boolean enabled;
|
||||
|
||||
// Should failed requests be logged?
|
||||
private static boolean logFailedRequests;
|
||||
|
||||
// Should the sent data be logged?
|
||||
private static boolean logSentData;
|
||||
|
||||
// Should the response text be logged?
|
||||
private static boolean logResponseStatusText;
|
||||
|
||||
// The uuid of the server
|
||||
private static String serverUUID;
|
||||
|
||||
// The plugin
|
||||
private final Plugin plugin;
|
||||
|
||||
// The plugin id
|
||||
private final int pluginId;
|
||||
|
||||
// A list with all custom charts
|
||||
private final List<CustomChart> charts = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param plugin The plugin which stats should be submitted.
|
||||
* @param pluginId The id of the plugin.
|
||||
* It can be found at <a href="https://bstats.org/what-is-my-plugin-id">What is my plugin id?</a>
|
||||
*/
|
||||
public Metrics(Plugin plugin, int pluginId)
|
||||
{
|
||||
if (plugin == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Plugin cannot be null!");
|
||||
}
|
||||
this.plugin = plugin;
|
||||
this.pluginId = pluginId;
|
||||
|
||||
// Get the config file
|
||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||
File configFile = new File(bStatsFolder, "config.yml");
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||
|
||||
// Check if the config file exists
|
||||
if (!config.isSet("serverUuid"))
|
||||
{
|
||||
|
||||
// Add default values
|
||||
config.addDefault("enabled", true);
|
||||
// Every server gets it's unique random id.
|
||||
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
||||
// Should failed request be logged?
|
||||
config.addDefault("logFailedRequests", false);
|
||||
// Should the sent data be logged?
|
||||
config.addDefault("logSentData", false);
|
||||
// Should the response text be logged?
|
||||
config.addDefault("logResponseStatusText", false);
|
||||
|
||||
// Inform the server owners about bStats
|
||||
config.options().header(
|
||||
"bStats collects some data for plugin authors like how many servers are using their plugins.\n" +
|
||||
"To honor their work, you should not disable it.\n" +
|
||||
"This has nearly no effect on the server performance!\n" +
|
||||
"Check out https://bStats.org/ to learn more :)"
|
||||
).copyDefaults(true);
|
||||
try
|
||||
{
|
||||
config.save(configFile);
|
||||
}
|
||||
catch (IOException ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// Load the data
|
||||
enabled = config.getBoolean("enabled", true);
|
||||
serverUUID = config.getString("serverUuid");
|
||||
logFailedRequests = config.getBoolean("logFailedRequests", false);
|
||||
logSentData = config.getBoolean("logSentData", false);
|
||||
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
boolean found = false;
|
||||
// Search for all other bStats Metrics classes to see if we are the first one
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
found = true; // We aren't the first
|
||||
break;
|
||||
}
|
||||
catch (NoSuchFieldException ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
// Register our service
|
||||
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
|
||||
if (!found)
|
||||
{
|
||||
// We are the first!
|
||||
startSubmitting();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if bStats is enabled.
|
||||
*
|
||||
* @return Whether bStats is enabled or not.
|
||||
*/
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom chart.
|
||||
*
|
||||
* @param chart The chart to add.
|
||||
*/
|
||||
public void addCustomChart(CustomChart chart)
|
||||
{
|
||||
if (chart == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Chart cannot be null!");
|
||||
}
|
||||
charts.add(chart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Scheduler which submits our data every 30 minutes.
|
||||
*/
|
||||
private void startSubmitting()
|
||||
{
|
||||
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
|
||||
timer.scheduleAtFixedRate(new TimerTask()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (!plugin.isEnabled())
|
||||
{ // Plugin was disabled
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
|
||||
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
|
||||
Bukkit.getScheduler().runTask(plugin, () -> submitData());
|
||||
}
|
||||
}, 1000 * 60 * 5, 1000 * 60 * 30);
|
||||
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
|
||||
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
|
||||
// WARNING: Just don't do it!
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the plugin specific data.
|
||||
* This method is called using Reflection.
|
||||
*
|
||||
* @return The plugin specific data.
|
||||
*/
|
||||
public JsonObject getPluginData()
|
||||
{
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
String pluginName = plugin.getDescription().getName();
|
||||
String pluginVersion = plugin.getDescription().getVersion();
|
||||
|
||||
data.addProperty("pluginName", pluginName); // Append the name of the plugin
|
||||
data.addProperty("id", pluginId); // Append the id of the plugin
|
||||
data.addProperty("pluginVersion", pluginVersion); // Append the version of the plugin
|
||||
JsonArray customCharts = new JsonArray();
|
||||
for (CustomChart customChart : charts)
|
||||
{
|
||||
// Add the data of the custom charts
|
||||
JsonObject chart = customChart.getRequestJsonObject();
|
||||
if (chart == null)
|
||||
{ // If the chart is null, we skip it
|
||||
continue;
|
||||
}
|
||||
customCharts.add(chart);
|
||||
}
|
||||
data.add("customCharts", customCharts);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server specific data.
|
||||
*
|
||||
* @return The server specific data.
|
||||
*/
|
||||
private JsonObject getServerData()
|
||||
{
|
||||
// Minecraft specific data
|
||||
int playerAmount;
|
||||
try
|
||||
{
|
||||
// Around MC 1.8 the return type was changed to a collection from an array,
|
||||
// This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
|
||||
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
|
||||
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
|
||||
? ((Collection<?>)onlinePlayersMethod.invoke(Bukkit.getServer())).size()
|
||||
: ((Player[])onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
|
||||
}
|
||||
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
|
||||
String bukkitVersion = Bukkit.getVersion();
|
||||
String bukkitName = Bukkit.getName();
|
||||
|
||||
// OS/Java specific data
|
||||
String javaVersion = System.getProperty("java.version");
|
||||
String osName = System.getProperty("os.name");
|
||||
String osArch = System.getProperty("os.arch");
|
||||
String osVersion = System.getProperty("os.version");
|
||||
int coreCount = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
data.addProperty("serverUUID", serverUUID);
|
||||
|
||||
data.addProperty("playerAmount", playerAmount);
|
||||
data.addProperty("onlineMode", onlineMode);
|
||||
data.addProperty("bukkitVersion", bukkitVersion);
|
||||
data.addProperty("bukkitName", bukkitName);
|
||||
|
||||
data.addProperty("javaVersion", javaVersion);
|
||||
data.addProperty("osName", osName);
|
||||
data.addProperty("osArch", osArch);
|
||||
data.addProperty("osVersion", osVersion);
|
||||
data.addProperty("coreCount", coreCount);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the data and sends it afterwards.
|
||||
*/
|
||||
private void submitData()
|
||||
{
|
||||
final JsonObject data = getServerData();
|
||||
|
||||
JsonArray pluginData = new JsonArray();
|
||||
// Search for all other bStats Metrics classes to get their plugin data
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
|
||||
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service))
|
||||
{
|
||||
try
|
||||
{
|
||||
Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider());
|
||||
if (plugin instanceof JsonObject)
|
||||
{
|
||||
pluginData.add((JsonObject)plugin);
|
||||
}
|
||||
else
|
||||
{ // old bstats version compatibility
|
||||
try
|
||||
{
|
||||
Class<?> jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject");
|
||||
if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple))
|
||||
{
|
||||
Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString");
|
||||
jsonStringGetter.setAccessible(true);
|
||||
String jsonString = (String)jsonStringGetter.invoke(plugin);
|
||||
JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject();
|
||||
pluginData.add(object);
|
||||
}
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
// minecraft version 1.14+
|
||||
if (logFailedRequests)
|
||||
{
|
||||
this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NoSuchFieldException ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
data.add("plugins", pluginData);
|
||||
|
||||
// Create a new thread for the connection to the bStats server
|
||||
new Thread(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
// Send the data
|
||||
sendData(plugin, data);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Something went wrong! :(
|
||||
if (logFailedRequests)
|
||||
{
|
||||
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the data to the bStats server.
|
||||
*
|
||||
* @param plugin Any plugin. It's just used to get a logger instance.
|
||||
* @param data The data to send.
|
||||
* @throws Exception If the request failed.
|
||||
*/
|
||||
private static void sendData(Plugin plugin, JsonObject data) throws Exception
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Data cannot be null!");
|
||||
}
|
||||
if (Bukkit.isPrimaryThread())
|
||||
{
|
||||
throw new IllegalAccessException("This method must not be called from the main thread!");
|
||||
}
|
||||
if (logSentData)
|
||||
{
|
||||
plugin.getLogger().info("Sending data to bStats: " + data);
|
||||
}
|
||||
HttpsURLConnection connection = (HttpsURLConnection)new URL(URL).openConnection();
|
||||
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
|
||||
// Add headers
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
||||
|
||||
// Send data
|
||||
connection.setDoOutput(true);
|
||||
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream()))
|
||||
{
|
||||
outputStream.write(compressedData);
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream())))
|
||||
{
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null)
|
||||
{
|
||||
builder.append(line);
|
||||
}
|
||||
}
|
||||
|
||||
if (logResponseStatusText)
|
||||
{
|
||||
plugin.getLogger().info("Sent data to bStats and received response: " + builder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given String.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped String.
|
||||
* @throws IOException If the compression failed.
|
||||
*/
|
||||
private static byte[] compress(final String str) throws IOException
|
||||
{
|
||||
if (str == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream))
|
||||
{
|
||||
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom chart.
|
||||
*/
|
||||
public static abstract class CustomChart
|
||||
{
|
||||
|
||||
// The id of the chart
|
||||
final String chartId;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
*/
|
||||
CustomChart(String chartId)
|
||||
{
|
||||
if (chartId == null || chartId.isEmpty())
|
||||
{
|
||||
throw new IllegalArgumentException("ChartId cannot be null or empty!");
|
||||
}
|
||||
this.chartId = chartId;
|
||||
}
|
||||
|
||||
private JsonObject getRequestJsonObject()
|
||||
{
|
||||
JsonObject chart = new JsonObject();
|
||||
chart.addProperty("chartId", chartId);
|
||||
try
|
||||
{
|
||||
JsonObject data = getChartData();
|
||||
if (data == null)
|
||||
{
|
||||
// If the data is null we don't send the chart.
|
||||
return null;
|
||||
}
|
||||
chart.add("data", data);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
if (logFailedRequests)
|
||||
{
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return chart;
|
||||
}
|
||||
|
||||
protected abstract JsonObject getChartData() throws Exception;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom simple pie.
|
||||
*/
|
||||
public static class SimplePie extends CustomChart
|
||||
{
|
||||
|
||||
private final Callable<String> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimplePie(String chartId, Callable<String> callable)
|
||||
{
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception
|
||||
{
|
||||
JsonObject data = new JsonObject();
|
||||
String value = callable.call();
|
||||
if (value == null || value.isEmpty())
|
||||
{
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.addProperty("value", value);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom advanced pie.
|
||||
*/
|
||||
public static class AdvancedPie extends CustomChart
|
||||
{
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable)
|
||||
{
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception
|
||||
{
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty())
|
||||
{
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet())
|
||||
{
|
||||
if (entry.getValue() == 0)
|
||||
{
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.addProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped)
|
||||
{
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.add("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom drilldown pie.
|
||||
*/
|
||||
public static class DrilldownPie extends CustomChart
|
||||
{
|
||||
|
||||
private final Callable<Map<String, Map<String, Integer>>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable)
|
||||
{
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getChartData() throws Exception
|
||||
{
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
Map<String, Map<String, Integer>> map = callable.call();
|
||||
if (map == null || map.isEmpty())
|
||||
{
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean reallyAllSkipped = true;
|
||||
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet())
|
||||
{
|
||||
JsonObject value = new JsonObject();
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet())
|
||||
{
|
||||
value.addProperty(valueEntry.getKey(), valueEntry.getValue());
|
||||
allSkipped = false;
|
||||
}
|
||||
if (!allSkipped)
|
||||
{
|
||||
reallyAllSkipped = false;
|
||||
values.add(entryValues.getKey(), value);
|
||||
}
|
||||
}
|
||||
if (reallyAllSkipped)
|
||||
{
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.add("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom single line chart.
|
||||
*/
|
||||
public static class SingleLineChart extends CustomChart
|
||||
{
|
||||
|
||||
private final Callable<Integer> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SingleLineChart(String chartId, Callable<Integer> callable)
|
||||
{
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception
|
||||
{
|
||||
JsonObject data = new JsonObject();
|
||||
int value = callable.call();
|
||||
if (value == 0)
|
||||
{
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.addProperty("value", value);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom multi line chart.
|
||||
*/
|
||||
public static class MultiLineChart extends CustomChart
|
||||
{
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable)
|
||||
{
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception
|
||||
{
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty())
|
||||
{
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet())
|
||||
{
|
||||
if (entry.getValue() == 0)
|
||||
{
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.addProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped)
|
||||
{
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.add("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom simple bar chart.
|
||||
*/
|
||||
public static class SimpleBarChart extends CustomChart
|
||||
{
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable)
|
||||
{
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception
|
||||
{
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty())
|
||||
{
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet())
|
||||
{
|
||||
JsonArray categoryValues = new JsonArray();
|
||||
categoryValues.add(new JsonPrimitive(entry.getValue()));
|
||||
values.add(entry.getKey(), categoryValues);
|
||||
}
|
||||
data.add("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom advanced bar chart.
|
||||
*/
|
||||
public static class AdvancedBarChart extends CustomChart
|
||||
{
|
||||
|
||||
private final Callable<Map<String, int[]>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable)
|
||||
{
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception
|
||||
{
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
Map<String, int[]> map = callable.call();
|
||||
if (map == null || map.isEmpty())
|
||||
{
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, int[]> entry : map.entrySet())
|
||||
{
|
||||
if (entry.getValue().length == 0)
|
||||
{
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
JsonArray categoryValues = new JsonArray();
|
||||
for (int categoryValue : entry.getValue())
|
||||
{
|
||||
categoryValues.add(new JsonPrimitive(categoryValue));
|
||||
}
|
||||
values.add(entry.getKey(), categoryValues);
|
||||
}
|
||||
if (allSkipped)
|
||||
{
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.add("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -146,6 +146,25 @@ shop:
|
|||
# How long is the random string (in characters)?
|
||||
string_length: 10
|
||||
|
||||
# Login messages. Use %name% for usernames, and %rank% for ranks/titles
|
||||
login_messages:
|
||||
- '%name% is a terrible %coloredrank%'
|
||||
- 'that %name% dude is a shitty %coloredrank%'
|
||||
- 'Hi, my name is %name% and I''m %art% %coloredrank%&b that wasted coins on this login message.'
|
||||
- '&aDo not fear, %coloredrank% &b%name% &ais here!'
|
||||
- '%name% is %art% %coloredrank%&b, say hi to them before they gets banned for doing something stupid'
|
||||
- 'Oh. It''s &l%name%&r&b the %coloredrank%&b again. Great.'
|
||||
- 'Make way for %name% the %coloredrank%&b!'
|
||||
- 'It''s a bird! It''s a plane! No, it''s %art% %rank%! It''s %name%'
|
||||
- '%rank% %name%'
|
||||
- '%coloredrank%&b %name%'
|
||||
- 'A wild %name%, %art% %coloredrank%&b, appeared!'
|
||||
- 'All in all, the %rank% %name% is just another brick in the wall'
|
||||
- '&a%name% &bis a a geeky &6%rank%'
|
||||
- '%name% is the %rank% who just exists'
|
||||
- '%name% based cringe poggers based based %rank%'
|
||||
- '%name% thinks that &dWindows Server 2019 &bis the best server OS'
|
||||
|
||||
# Item prices
|
||||
prices:
|
||||
grappling_hook: 100
|
||||
|
@ -154,6 +173,7 @@ shop:
|
|||
rideable_pearl: 700
|
||||
stacking_potato: 300
|
||||
clown_fish: 1500
|
||||
login_messages: 5000
|
||||
|
||||
# Staff list
|
||||
stafflist:
|
||||
|
@ -190,12 +210,6 @@ social_links:
|
|||
Website: 'https://totalfreedom.me/'
|
||||
Discord: 'https://discordapp.com/invite/XXjmAmV/'
|
||||
|
||||
donation:
|
||||
proboards_url: ''
|
||||
donator_group_id: ''
|
||||
session_id: ''
|
||||
csrf_token: ''
|
||||
|
||||
# Blocking certain events
|
||||
allow:
|
||||
fire_place: false
|
||||
|
|
|
@ -60,15 +60,12 @@ master_builders:
|
|||
- "voxelsniper.goto"
|
||||
- "voxelsniper.brush.*"
|
||||
|
||||
# Trial Mod permission nodes
|
||||
trial_mods:
|
||||
# Admin permission nodes
|
||||
admins:
|
||||
- "coreprotect.*"
|
||||
- "worldedit.*"
|
||||
- "worldguard.*"
|
||||
- "bending.*"
|
||||
|
||||
# Moderator permission nodes
|
||||
mods: []
|
||||
|
||||
# Admin permission nodes
|
||||
admins: []
|
||||
# Senior Admin permission nodes
|
||||
senior_admins: []
|
||||
|
|
Loading…
Reference in New Issue