Merge branch 'master' of ssh://184.154.0.242:7999/min/Mineplex

Conflicts:
	Plugins/Mineplex.Core/src/mineplex/core/portal/Portal.java
	Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java
	Plugins/Mineplex.ServerData/src/mineplex/serverdata/ServerCommandManager.java
This commit is contained in:
MrTwiggy 2014-11-10 18:55:57 -05:00
commit e3c50bfb39
681 changed files with 30249 additions and 6825 deletions

3
.gitignore vendored
View File

@ -26,3 +26,6 @@ Servers
Debug Debug
*.gitignore *.gitignore
/Maps/GRASER UHC /Maps/GRASER UHC
/MutualNDA (1)-signed.pdf
/MutualNDA - signed-signed.pdf
/MutualNDA - signed.pdf

View File

@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="bukkit">
<CLASSES>
<root url="jar://$PROJECT_DIR$/Libraries/bukkit.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/Libraries/bukkit.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="commons-dbcp2">
<CLASSES>
<root url="jar://$PROJECT_DIR$/Libraries/commons-dbcp2-2.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="commons-logging">
<CLASSES>
<root url="jar://$PROJECT_DIR$/Libraries/commons-logging-1.1.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -20,6 +20,8 @@
<RunnerSettings RunnerId="Run" /> <RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Debug" /> <ConfigurationWrapper RunnerId="Debug" />
<ConfigurationWrapper RunnerId="Run" /> <ConfigurationWrapper RunnerId="Run" />
<method /> <method>
<option name="Make" enabled="false" />
</method>
</configuration> </configuration>
</component> </component>

View File

@ -12,12 +12,16 @@
<option name="PASS_PARENT_ENVS" value="true" /> <option name="PASS_PARENT_ENVS" value="true" />
<module name="Classpath.Dummy" /> <module name="Classpath.Dummy" />
<envs /> <envs />
<RunnerSettings RunnerId="Cover" />
<RunnerSettings RunnerId="Debug"> <RunnerSettings RunnerId="Debug">
<option name="DEBUG_PORT" value="" /> <option name="DEBUG_PORT" value="" />
<option name="TRANSPORT" value="0" /> <option name="TRANSPORT" value="0" />
<option name="LOCAL" value="true" /> <option name="LOCAL" value="true" />
</RunnerSettings> </RunnerSettings>
<RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Cover" />
<ConfigurationWrapper RunnerId="Debug" /> <ConfigurationWrapper RunnerId="Debug" />
<ConfigurationWrapper RunnerId="Run" />
<method> <method>
<option name="BuildArtifacts" enabled="true"> <option name="BuildArtifacts" enabled="true">
<artifact name="Mineplex.Hub:test" /> <artifact name="Mineplex.Hub:test" />

View File

@ -8,6 +8,9 @@
<fileset dir="../Mineplex.Core.Common/bin"> <fileset dir="../Mineplex.Core.Common/bin">
<include name="**/*.class"/> <include name="**/*.class"/>
</fileset> </fileset>
<fileset dir="../Mineplex.Database/bin">
<include name="**/*.class"/>
</fileset>
<fileset dir="../Mineplex.EnjinTranslator/bin"> <fileset dir="../Mineplex.EnjinTranslator/bin">
<include name="**/*.class"/> <include name="**/*.class"/>
@ -16,9 +19,17 @@
<include name="*.yml"/> <include name="*.yml"/>
</fileset> </fileset>
<zipfileset src="../Libraries/jooq-3.4.2.jar" />
<zipfileset src="../Libraries/httpclient-4.2.jar" /> <zipfileset src="../Libraries/httpclient-4.2.jar" />
<zipfileset src="../Libraries/httpcore-4.2.jar" /> <zipfileset src="../Libraries/httpcore-4.2.jar" />
<zipfileset src="../Libraries/httpclient-cache-4.2.jar" />
<zipfileset src="../Libraries/httpmime-4.2.jar" />
<zipfileset src="../Libraries/gson-2.2.1.jar" />
<zipfileset src="../Libraries/commons-logging-1.1.1.jar" /> <zipfileset src="../Libraries/commons-logging-1.1.1.jar" />
<zipfileset src="../Libraries/commons-codec-1.6.jar" />
<zipfileset src="../Libraries/commons-dbcp2-2.0.1.jar" />
<zipfileset src="../Libraries/jedis-2.4.2.jar" />
<zipfileset src="../Libraries/commons-pool2-2.2.jar" />
</jar> </jar>
<copy file="../bin/EnjinTranslator.jar" todir="../../Testing/EnjinTranslator/plugins"/> <copy file="../bin/EnjinTranslator.jar" todir="../../Testing/EnjinTranslator/plugins"/>
</target> </target>

View File

@ -35,8 +35,10 @@
<zipfileset src="../Libraries/gson-2.2.1.jar" /> <zipfileset src="../Libraries/gson-2.2.1.jar" />
<zipfileset src="../Libraries/commons-logging-1.1.1.jar" /> <zipfileset src="../Libraries/commons-logging-1.1.1.jar" />
<zipfileset src="../Libraries/commons-codec-1.6.jar" /> <zipfileset src="../Libraries/commons-codec-1.6.jar" />
<zipfileset src="../Libraries/commons-dbcp2-2.0.1.jar" />
<zipfileset src="../Libraries/jedis-2.4.2.jar" /> <zipfileset src="../Libraries/jedis-2.4.2.jar" />
<zipfileset src="../Libraries/commons-pool2-2.2.jar" /> <zipfileset src="../Libraries/commons-pool2-2.2.jar" />
<zipfileset src="../Libraries/commons-dbcp2-2.0.1.jar" />
</jar> </jar>
<copy file="../bin/Arcade.jar" todir="../../Testing/Arcade/plugins"/> <copy file="../bin/Arcade.jar" todir="../../Testing/Arcade/plugins"/>
</target> </target>
@ -74,10 +76,12 @@
<zipfileset src="../Libraries/gson-2.2.1.jar" /> <zipfileset src="../Libraries/gson-2.2.1.jar" />
<zipfileset src="../Libraries/commons-logging-1.1.1.jar" /> <zipfileset src="../Libraries/commons-logging-1.1.1.jar" />
<zipfileset src="../Libraries/commons-io-2.4.jar" /> <zipfileset src="../Libraries/commons-io-2.4.jar" />
<zipfileset src="../Libraries/commons-dbcp2-2.0.1.jar" />
<zipfileset src="../Libraries/commons-codec-1.6.jar" /> <zipfileset src="../Libraries/commons-codec-1.6.jar" />
<zipfileset src="../Libraries/jooq-3.4.2.jar" /> <zipfileset src="../Libraries/jooq-3.4.2.jar" />
<zipfileset src="../Libraries/jedis-2.4.2.jar" /> <zipfileset src="../Libraries/jedis-2.4.2.jar" />
<zipfileset src="../Libraries/commons-pool2-2.2.jar" /> <zipfileset src="../Libraries/commons-pool2-2.2.jar" />
<zipfileset src="../Libraries/commons-dbcp2-2.0.1.jar" />
</jar> </jar>
<copy file="../bin/Hub.jar" todir="../../Testing/Hub/plugins"/> <copy file="../bin/Hub.jar" todir="../../Testing/Hub/plugins"/>
</target> </target>
@ -95,20 +99,25 @@
<fileset dir="../Mineplex.StaffServer"> <fileset dir="../Mineplex.StaffServer">
<include name="*.yml"/> <include name="*.yml"/>
</fileset> </fileset>
<fileset dir="../Mineplex.Database/bin">
<include name="**/*.class"/>
</fileset>
<fileset dir="../Mineplex.ServerData/bin"> <fileset dir="../Mineplex.ServerData/bin">
<include name="**/*.class"/> <include name="**/*.class"/>
</fileset> </fileset>
<zipfileset src="../Libraries/jooq-3.4.2.jar" />
<zipfileset src="../Libraries/httpclient-4.2.jar" /> <zipfileset src="../Libraries/httpclient-4.2.jar" />
<zipfileset src="../Libraries/httpcore-4.2.jar" /> <zipfileset src="../Libraries/httpcore-4.2.jar" />
<zipfileset src="../Libraries/httpclient-cache-4.2.jar" /> <zipfileset src="../Libraries/httpclient-cache-4.2.jar" />
<zipfileset src="../Libraries/httpmime-4.2.jar" /> <zipfileset src="../Libraries/httpmime-4.2.jar" />
<zipfileset src="../Libraries/gson-2.2.1.jar" /> <zipfileset src="../Libraries/gson-2.2.1.jar" />
<zipfileset src="../Libraries/commons-logging-1.1.1.jar" /> <zipfileset src="../Libraries/commons-logging-1.1.1.jar" />
<zipfileset src="../Libraries/commons-io-2.4.jar" />
<zipfileset src="../Libraries/commons-codec-1.6.jar" /> <zipfileset src="../Libraries/commons-codec-1.6.jar" />
<zipfileset src="../Libraries/commons-dbcp2-2.0.1.jar" />
<zipfileset src="../Libraries/jedis-2.4.2.jar" /> <zipfileset src="../Libraries/jedis-2.4.2.jar" />
<zipfileset src="../Libraries/commons-pool2-2.2.jar" /> <zipfileset src="../Libraries/commons-pool2-2.2.jar" />
<zipfileset src="../Libraries/commons-dbcp2-2.0.1.jar" />
</jar> </jar>
<copy file="../bin/StaffServer.jar" todir="../../Testing/StaffServer/plugins"/> <copy file="../bin/StaffServer.jar" todir="../../Testing/StaffServer/plugins"/>
</target> </target>
@ -204,6 +213,30 @@
</jar> </jar>
<copy file="../bin/DDoSProtectionSwitcher.jar" todir="../../Testing/DDoSProtectionSwitcher/"/> <copy file="../bin/DDoSProtectionSwitcher.jar" todir="../../Testing/DDoSProtectionSwitcher/"/>
</target> </target>
<target name ="BungeeRotator" description="BungeeRotator">
<jar jarfile="../bin/BungeeRotator.jar">
<fileset dir="../Mineplex.BungeeRotator/bin">
<include name="**/*.class"/>
</fileset>
<zipfileset src="../Libraries/mysql.zip" />
<manifest>
<attribute name="Main-Class"
value="mineplex.bungee.BungeeRotator"/>
</manifest>
<zipfileset src="../Libraries/httpclient-4.2.jar" />
<zipfileset src="../Libraries/httpcore-4.2.jar" />
<zipfileset src="../Libraries/httpclient-cache-4.2.jar" />
<zipfileset src="../Libraries/httpmime-4.2.jar" />
<zipfileset src="../Libraries/gson-2.2.1.jar" />
<zipfileset src="../Libraries/javax.mail.jar" />
<zipfileset src="../Libraries/commons-logging-1.1.1.jar" />
<zipfileset src="../Libraries/commons-codec-1.6.jar" />
</jar>
<copy file="../bin/BungeeRotator.jar" todir="../../Testing/BungeeRotator/"/>
</target>
<target name ="ServerMonitor" description="ServerMonitor"> <target name ="ServerMonitor" description="ServerMonitor">
<jar jarfile="../bin/ServerMonitor.jar"> <jar jarfile="../bin/ServerMonitor.jar">
<fileset dir="../Mineplex.Core.Common/bin"> <fileset dir="../Mineplex.Core.Common/bin">

View File

@ -8,6 +8,9 @@
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="craftbukkit" level="project" /> <orderEntry type="library" name="craftbukkit" level="project" />
<orderEntry type="library" name="commons-dbcp2" level="project" />
<orderEntry type="library" name="commons-pool2" level="project" />
<orderEntry type="library" name="commons-logging" level="project" />
</component> </component>
</module> </module>

View File

@ -0,0 +1,73 @@
package net.minecraft.server.v1_7_R4;
import java.io.IOException;
public class PacketPlayOutChat
extends Packet
{
private IChatBaseComponent a;
private boolean b;
private byte _chatType = 0;
public PacketPlayOutChat()
{
this.b = true;
}
public PacketPlayOutChat(IChatBaseComponent ichatbasecomponent)
{
this(ichatbasecomponent, true);
}
public PacketPlayOutChat(IChatBaseComponent ichatbasecomponent, boolean flag)
{
this.b = true;
this.a = ichatbasecomponent;
this.b = flag;
}
public PacketPlayOutChat(String text)
{
this(ChatSerializer.a(text));
}
public void a(PacketDataSerializer packetdataserializer)
throws IOException
{
this.a = ChatSerializer.a(packetdataserializer.c(32767));
}
public void b(PacketDataSerializer packetdataserializer)
throws IOException
{
packetdataserializer.a(ChatSerializer.a(this.a));
if (packetdataserializer.version >= 16) {
packetdataserializer.writeByte(_chatType);
}
}
public void setChatType(byte chatType)
{
_chatType = chatType;
}
public void a(PacketPlayOutListener packetplayoutlistener)
{
packetplayoutlistener.a(this);
}
public String b()
{
return String.format("message='%s'", new Object[] { this.a });
}
public boolean d()
{
return this.b;
}
public void handle(PacketListener packetlistener)
{
a((PacketPlayOutListener)packetlistener);
}
}

View File

@ -0,0 +1,121 @@
package net.minecraft.server.v1_7_R4;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class PacketPlayOutScoreboardTeam
extends Packet
{
private String a = "";
private String b = "";
private String c = "";
private String d = "";
private String _nameTagVisibility;
private Collection e = new ArrayList();
private int f;
private int g;
public PacketPlayOutScoreboardTeam() {}
public PacketPlayOutScoreboardTeam(ScoreboardTeam scoreboardteam, int i)
{
this.a = scoreboardteam.getName();
this.f = i;
if ((i == 0) || (i == 2))
{
this.b = scoreboardteam.getDisplayName();
this.c = scoreboardteam.getPrefix();
this.d = scoreboardteam.getSuffix();
this.g = scoreboardteam.packOptionData();
this._nameTagVisibility = scoreboardteam.getNametagVisibility();
}
if (i == 0) {
this.e.addAll(scoreboardteam.getPlayerNameSet());
}
}
public PacketPlayOutScoreboardTeam(ScoreboardTeam scoreboardteam, Collection collection, int i)
{
if ((i != 3) && (i != 4)) {
throw new IllegalArgumentException("Method must be join or leave for player constructor");
}
if ((collection != null) && (!collection.isEmpty()))
{
this.f = i;
this.a = scoreboardteam.getName();
this.e.addAll(collection);
this._nameTagVisibility = _nameTagVisibility;
}
else
{
throw new IllegalArgumentException("Players cannot be null/empty");
}
}
public void a(PacketDataSerializer packetdataserializer)
throws IOException
{
this.a = packetdataserializer.c(16);
this.f = packetdataserializer.readByte();
if ((this.f == 0) || (this.f == 2))
{
this.b = packetdataserializer.c(32);
this.c = packetdataserializer.c(16);
this.d = packetdataserializer.c(16);
this.g = packetdataserializer.readByte();
}
if ((this.f == 0) || (this.f == 3) || (this.f == 4))
{
short short1 = packetdataserializer.readShort();
for (int i = 0; i < short1; i++) {
this.e.add(packetdataserializer.c(40));
}
}
}
public void b(PacketDataSerializer packetdataserializer)
throws IOException
{
packetdataserializer.a(this.a);
packetdataserializer.writeByte(this.f);
if ((this.f == 0) || (this.f == 2))
{
packetdataserializer.a(this.b);
packetdataserializer.a(this.c);
packetdataserializer.a(this.d);
packetdataserializer.writeByte(this.g);
if (packetdataserializer.version >= 16)
{
packetdataserializer.a(_nameTagVisibility);
packetdataserializer.writeByte(EnumChatFormat.WHITE.ordinal());
}
}
if ((this.f == 0) || (this.f == 3) || (this.f == 4))
{
if (packetdataserializer.version < 16) {
packetdataserializer.writeShort(this.e.size());
} else {
packetdataserializer.b(this.e.size());
}
Iterator iterator = this.e.iterator();
while (iterator.hasNext())
{
String s = (String)iterator.next();
packetdataserializer.a(s);
}
}
}
public void a(PacketPlayOutListener packetplayoutlistener)
{
packetplayoutlistener.a(this);
}
public void handle(PacketListener packetlistener)
{
a((PacketPlayOutListener)packetlistener);
}
}

View File

@ -0,0 +1,135 @@
package net.minecraft.server.v1_7_R4;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class ScoreboardTeam
extends ScoreboardTeamBase
{
private final Scoreboard a;
private final String b;
private final Set c = new HashSet();
private String d;
private String e = "";
private String f = "";
private String _nametagVisibility = "always";
private boolean g = true;
private boolean h = true;
public ScoreboardTeam(Scoreboard paramScoreboard, String paramString)
{
this.a = paramScoreboard;
this.b = paramString;
this.d = paramString;
}
public String getName()
{
return this.b;
}
public String getDisplayName()
{
return this.d;
}
public void setDisplayName(String paramString)
{
if (paramString == null) {
throw new IllegalArgumentException("Name cannot be null");
}
this.d = paramString;
this.a.handleTeamChanged(this);
}
public Collection getPlayerNameSet()
{
return this.c;
}
public String getPrefix()
{
return this.e;
}
public void setPrefix(String paramString)
{
if (paramString == null) {
throw new IllegalArgumentException("Prefix cannot be null");
}
this.e = paramString;
this.a.handleTeamChanged(this);
}
public String getSuffix()
{
return this.f;
}
public void setSuffix(String paramString)
{
if (paramString == null) {
throw new IllegalArgumentException("Suffix cannot be null");
}
this.f = paramString;
this.a.handleTeamChanged(this);
}
public String getFormattedName(String paramString)
{
return getPrefix() + paramString + getSuffix();
}
public static String getPlayerDisplayName(ScoreboardTeamBase paramScoreboardTeamBase, String paramString)
{
if (paramScoreboardTeamBase == null) {
return paramString;
}
return paramScoreboardTeamBase.getFormattedName(paramString);
}
public boolean allowFriendlyFire()
{
return this.g;
}
public void setAllowFriendlyFire(boolean paramBoolean)
{
this.g = paramBoolean;
this.a.handleTeamChanged(this);
}
public boolean canSeeFriendlyInvisibles()
{
return this.h;
}
public void setCanSeeFriendlyInvisibles(boolean paramBoolean)
{
this.h = paramBoolean;
this.a.handleTeamChanged(this);
}
public String getNametagVisibility()
{
return _nametagVisibility;
}
public void setNametagVisibility(String visibility)
{
_nametagVisibility = visibility;
}
public int packOptionData()
{
int i = 0;
if (allowFriendlyFire()) {
i |= 0x1;
}
if (canSeeFriendlyInvisibles()) {
i |= 0x2;
}
return i;
}
}

View File

@ -0,0 +1,225 @@
package org.bukkit.craftbukkit.v1_7_R4.scoreboard;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.scoreboard.Team;
import org.bukkit.scoreboard.TeamNameTagVisibility;
import net.minecraft.server.v1_7_R4.ScoreboardTeam;
import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang.Validate;
final class CraftTeam
extends CraftScoreboardComponent
implements Team
{
private final ScoreboardTeam team;
CraftTeam(CraftScoreboard scoreboard, ScoreboardTeam team)
{
super(scoreboard);
this.team = team;
scoreboard.teams.put(team.getName(), this);
}
public String getName()
throws IllegalStateException
{
CraftScoreboard scoreboard = checkState();
return this.team.getName();
}
public String getDisplayName()
throws IllegalStateException
{
CraftScoreboard scoreboard = checkState();
return this.team.getDisplayName();
}
public void setDisplayName(String displayName)
throws IllegalStateException
{
Validate.notNull(displayName, "Display name cannot be null");
Validate.isTrue(displayName.length() <= 32, "Display name '" + displayName + "' is longer than the limit of 32 characters");
CraftScoreboard scoreboard = checkState();
this.team.setDisplayName(displayName);
}
public String getPrefix()
throws IllegalStateException
{
CraftScoreboard scoreboard = checkState();
return this.team.getPrefix();
}
public void setPrefix(String prefix)
throws IllegalStateException, IllegalArgumentException
{
Validate.notNull(prefix, "Prefix cannot be null");
Validate.isTrue(prefix.length() <= 32, "Prefix '" + prefix + "' is longer than the limit of 32 characters");
CraftScoreboard scoreboard = checkState();
this.team.setPrefix(prefix);
}
public String getSuffix()
throws IllegalStateException
{
CraftScoreboard scoreboard = checkState();
return this.team.getSuffix();
}
public void setSuffix(String suffix)
throws IllegalStateException, IllegalArgumentException
{
Validate.notNull(suffix, "Suffix cannot be null");
Validate.isTrue(suffix.length() <= 32, "Suffix '" + suffix + "' is longer than the limit of 32 characters");
CraftScoreboard scoreboard = checkState();
this.team.setSuffix(suffix);
}
public boolean allowFriendlyFire()
throws IllegalStateException
{
CraftScoreboard scoreboard = checkState();
return this.team.allowFriendlyFire();
}
// Mineplex
@Override
public void setNameTagVisibility(TeamNameTagVisibility visibility) throws IllegalStateException
{
this.team.setNametagVisibility(visibility.toString());
}
public void setAllowFriendlyFire(boolean enabled)
throws IllegalStateException
{
CraftScoreboard scoreboard = checkState();
this.team.setAllowFriendlyFire(enabled);
}
public boolean canSeeFriendlyInvisibles()
throws IllegalStateException
{
CraftScoreboard scoreboard = checkState();
return this.team.canSeeFriendlyInvisibles();
}
public void setCanSeeFriendlyInvisibles(boolean enabled)
throws IllegalStateException
{
CraftScoreboard scoreboard = checkState();
this.team.setCanSeeFriendlyInvisibles(enabled);
}
public Set<OfflinePlayer> getPlayers()
throws IllegalStateException
{
CraftScoreboard scoreboard = checkState();
ImmutableSet.Builder<OfflinePlayer> players = ImmutableSet.builder();
for (Object o : this.team.getPlayerNameSet()) {
players.add(Bukkit.getOfflinePlayer(o.toString()));
}
return players.build();
}
public Set<String> getEntries()
throws IllegalStateException
{
CraftScoreboard scoreboard = checkState();
ImmutableSet.Builder<String> entries = ImmutableSet.builder();
for (Object o : this.team.getPlayerNameSet()) {
entries.add(o.toString());
}
return entries.build();
}
public int getSize()
throws IllegalStateException
{
CraftScoreboard scoreboard = checkState();
return this.team.getPlayerNameSet().size();
}
public void addPlayer(OfflinePlayer player)
throws IllegalStateException, IllegalArgumentException
{
Validate.notNull(player, "OfflinePlayer cannot be null");
addEntry(player.getName());
}
public void addEntry(String entry)
throws IllegalStateException, IllegalArgumentException
{
Validate.notNull(entry, "Entry cannot be null");
CraftScoreboard scoreboard = checkState();
scoreboard.board.addPlayerToTeam(entry, this.team.getName());
}
public boolean removePlayer(OfflinePlayer player)
throws IllegalStateException, IllegalArgumentException
{
Validate.notNull(player, "OfflinePlayer cannot be null");
return removeEntry(player.getName());
}
public boolean removeEntry(String entry)
throws IllegalStateException, IllegalArgumentException
{
Validate.notNull(entry, "Entry cannot be null");
CraftScoreboard scoreboard = checkState();
if (!this.team.getPlayerNameSet().contains(entry)) {
return false;
}
scoreboard.board.removePlayerFromTeam(entry, this.team);
return true;
}
public boolean hasPlayer(OfflinePlayer player)
throws IllegalArgumentException, IllegalStateException
{
Validate.notNull(player, "OfflinePlayer cannot be null");
return hasEntry(player.getName());
}
public boolean hasEntry(String entry)
throws IllegalArgumentException, IllegalStateException
{
Validate.notNull("Entry cannot be null");
CraftScoreboard scoreboard = checkState();
return this.team.getPlayerNameSet().contains(entry);
}
public void unregister()
throws IllegalStateException
{
CraftScoreboard scoreboard = checkState();
scoreboard.board.removeTeam(this.team);
scoreboard.teams.remove(this.team.getName());
setUnregistered();
}
}

View File

@ -0,0 +1,77 @@
package org.bukkit.scoreboard;
import java.util.Set;
import org.bukkit.OfflinePlayer;
public abstract interface Team
{
public abstract String getName()
throws IllegalStateException;
public abstract String getDisplayName()
throws IllegalStateException;
public abstract void setDisplayName(String paramString)
throws IllegalStateException, IllegalArgumentException;
public abstract String getPrefix()
throws IllegalStateException;
public abstract void setPrefix(String paramString)
throws IllegalStateException, IllegalArgumentException;
public abstract String getSuffix()
throws IllegalStateException;
public abstract void setSuffix(String paramString)
throws IllegalStateException, IllegalArgumentException;
public abstract boolean allowFriendlyFire()
throws IllegalStateException;
// Mineplex
public abstract void setNameTagVisibility(TeamNameTagVisibility visibility)
throws IllegalStateException;
public abstract void setAllowFriendlyFire(boolean paramBoolean)
throws IllegalStateException;
public abstract boolean canSeeFriendlyInvisibles()
throws IllegalStateException;
public abstract void setCanSeeFriendlyInvisibles(boolean paramBoolean)
throws IllegalStateException;
public abstract Set<OfflinePlayer> getPlayers()
throws IllegalStateException;
public abstract Set<String> getEntries()
throws IllegalStateException;
public abstract int getSize()
throws IllegalStateException;
public abstract Scoreboard getScoreboard();
public abstract void addPlayer(OfflinePlayer paramOfflinePlayer)
throws IllegalStateException, IllegalArgumentException;
public abstract void addEntry(String paramString)
throws IllegalStateException, IllegalArgumentException;
public abstract boolean removePlayer(OfflinePlayer paramOfflinePlayer)
throws IllegalStateException, IllegalArgumentException;
public abstract boolean removeEntry(String paramString)
throws IllegalStateException, IllegalArgumentException;
public abstract void unregister()
throws IllegalStateException;
public abstract boolean hasPlayer(OfflinePlayer paramOfflinePlayer)
throws IllegalArgumentException, IllegalStateException;
public abstract boolean hasEntry(String paramString)
throws IllegalArgumentException, IllegalStateException;
}

View File

@ -0,0 +1,22 @@
package org.bukkit.scoreboard;
/**
* Created by shaun on 14-10-05.
*/
public enum TeamNameTagVisibility
{
NEVER("never"), HIDE_FOR_OTHER_TEAMS("hideForOtherTeams"), HIDE_FOR_OWN_TEAM("hideForOwnTeam"), ALWAYS("always");
private String _keyword;
TeamNameTagVisibility(String keyword)
{
_keyword = keyword;
}
@Override
public String toString()
{
return _keyword;
}
}

Binary file not shown.

Binary file not shown.

View File

@ -4,6 +4,7 @@ import mineplex.bungee.lobbyBalancer.LobbyBalancer;
import mineplex.bungee.motd.MotdManager; import mineplex.bungee.motd.MotdManager;
import mineplex.bungee.playerCount.PlayerCount; import mineplex.bungee.playerCount.PlayerCount;
import mineplex.bungee.playerStats.PlayerStats; import mineplex.bungee.playerStats.PlayerStats;
import mineplex.bungee.playerTracker.PlayerTracker;
import mineplex.bungee.status.InternetStatus; import mineplex.bungee.status.InternetStatus;
import net.md_5.bungee.api.plugin.Plugin; import net.md_5.bungee.api.plugin.Plugin;
@ -18,5 +19,6 @@ public class Mineplexer extends Plugin
new FileUpdater(this); new FileUpdater(this);
new PlayerStats(this); new PlayerStats(this);
new InternetStatus(this); new InternetStatus(this);
new PlayerTracker(this);
} }
} }

View File

@ -25,9 +25,7 @@ public class LobbyBalancer implements Listener, Runnable
private List<MinecraftServer> _sortedLobbies = new ArrayList<MinecraftServer>(); private List<MinecraftServer> _sortedLobbies = new ArrayList<MinecraftServer>();
private static Object _serverLock = new Object(); private static Object _serverLock = new Object();
private int _bestServerIndex = 0; private int _lobbyIndex = 0;
private int _playersSentToBestServer = 0;
private int _maxPlayersToSendToBestServer = 1;
public LobbyBalancer(Plugin plugin) public LobbyBalancer(Plugin plugin)
{ {
@ -39,7 +37,7 @@ public class LobbyBalancer implements Listener, Runnable
loadLobbyServers(); loadLobbyServers();
_plugin.getProxy().getPluginManager().registerListener(_plugin, this); _plugin.getProxy().getPluginManager().registerListener(_plugin, this);
_plugin.getProxy().getScheduler().schedule(_plugin, this, 200L, 200L, TimeUnit.MILLISECONDS); _plugin.getProxy().getScheduler().schedule(_plugin, this, 150L, 150L, TimeUnit.MILLISECONDS);
} }
@EventHandler @EventHandler
@ -48,44 +46,15 @@ public class LobbyBalancer implements Listener, Runnable
if (!event.getTarget().getName().equalsIgnoreCase("Lobby")) if (!event.getTarget().getName().equalsIgnoreCase("Lobby"))
return; return;
int bungeeBufferNumber = 20;
synchronized (_serverLock) synchronized (_serverLock)
{ {
if (_playersSentToBestServer >= _maxPlayersToSendToBestServer) if (_lobbyIndex >= _sortedLobbies.size() || _sortedLobbies.get(_lobbyIndex).getPlayerCount() >= _sortedLobbies.get(_lobbyIndex).getMaxPlayerCount())
{ _lobbyIndex = 0;
_playersSentToBestServer = 0;
while (_bestServerIndex < _sortedLobbies.size()) event.setTarget(_plugin.getProxy().getServerInfo(_sortedLobbies.get(_lobbyIndex).getName()));
{ _sortedLobbies.get(_lobbyIndex).incrementPlayerCount(1);
_maxPlayersToSendToBestServer = (_sortedLobbies.get(_bestServerIndex).getMaxPlayerCount() - _sortedLobbies.get(_bestServerIndex).getPlayerCount()) / bungeeBufferNumber; System.out.println("Sending " + event.getPlayer().getName() + " to " + _sortedLobbies.get(_lobbyIndex).getName() + "(" + _sortedLobbies.get(_lobbyIndex).getPublicAddress() + ")");
_lobbyIndex++;
if (_maxPlayersToSendToBestServer > 0)
break;
_bestServerIndex++;
}
if (_maxPlayersToSendToBestServer == 0)
{
_bestServerIndex = 0;
_maxPlayersToSendToBestServer = 1;
// Since we had to enter our dangerzone, decrease buffer so we try to hit another server
bungeeBufferNumber -= 2;
if (bungeeBufferNumber <= 0)
bungeeBufferNumber = 0;
}
}
if (_bestServerIndex < _sortedLobbies.size())
{
event.setTarget(_plugin.getProxy().getServerInfo(_sortedLobbies.get(_bestServerIndex).getName()));
System.out.println("Sending " + event.getPlayer().getName() + " to " + _sortedLobbies.get(_bestServerIndex).getName() + "(" + _sortedLobbies.get(_bestServerIndex).getPublicAddress() + ")");
}
_playersSentToBestServer++;
} }
} }
@ -122,16 +91,12 @@ public class LobbyBalancer implements Listener, Runnable
Collections.sort(_sortedLobbies, new LobbySorter()); Collections.sort(_sortedLobbies, new LobbySorter());
_playersSentToBestServer = 0;
_bestServerIndex = 0;
if (_sortedLobbies.size() > 0)
_maxPlayersToSendToBestServer = (_sortedLobbies.get(_bestServerIndex).getMaxPlayerCount() - _sortedLobbies.get(_bestServerIndex).getPlayerCount());
long timeSpentInLock = System.currentTimeMillis() - startTime; long timeSpentInLock = System.currentTimeMillis() - startTime;
if (timeSpentInLock > 50) if (timeSpentInLock > 50)
System.out.println("[==] TIMING [==] Locked loading servers for " + timeSpentInLock + "ms"); System.out.println("[==] TIMING [==] Locked loading servers for " + timeSpentInLock + "ms");
_lobbyIndex = 0;
} }
} }
} }

View File

@ -45,6 +45,6 @@ public class PlayerCount implements Listener, Runnable
{ {
net.md_5.bungee.api.ServerPing serverPing = event.getResponse(); net.md_5.bungee.api.ServerPing serverPing = event.getResponse();
event.setResponse(new net.md_5.bungee.api.ServerPing(serverPing.getVersion(), new Players(_totalMaxPlayers, _totalPlayers, null), serverPing.getDescription(), serverPing.getFaviconObject())); event.setResponse(new net.md_5.bungee.api.ServerPing(serverPing.getVersion(), new Players(_totalPlayers + 1, _totalPlayers, null), serverPing.getDescription(), serverPing.getFaviconObject()));
} }
} }

View File

@ -0,0 +1,49 @@
package mineplex.bungee.playerTracker;
import java.io.File;
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
import net.md_5.bungee.api.event.ServerSwitchEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.event.EventHandler;
public class PlayerTracker implements Listener
{
private Plugin _plugin;
private PlayerTrackerRepository _repository = null;
public PlayerTracker(Plugin plugin)
{
_plugin = plugin;
_plugin.getProxy().getPluginManager().registerListener(_plugin, this);
_repository = new PlayerTrackerRepository();
_repository.initialize(!new File("eu.dat").exists());
}
@EventHandler
public void playerConnect(final ServerSwitchEvent event)
{
_plugin.getProxy().getScheduler().runAsync(_plugin, new Runnable()
{
public void run()
{
_repository.updatePlayerServer(event.getPlayer().getName(), event.getPlayer().getServer().getInfo().getName());
}
});
}
@EventHandler
public void playerDisconnect(final PlayerDisconnectEvent event)
{
_plugin.getProxy().getScheduler().runAsync(_plugin, new Runnable()
{
public void run()
{
_repository.deleteServerTransfers(event.getPlayer().getName());
}
});
}
}

View File

@ -1,4 +1,4 @@
package mineplex.core.playerTracker; package mineplex.bungee.playerTracker;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
@ -14,19 +14,17 @@ public class PlayerTrackerRepository
private String _userName = "root"; private String _userName = "root";
private String _password = "tAbechAk3wR7tuTh"; private String _password = "tAbechAk3wR7tuTh";
private String _serverName = "";
private boolean _us = true; private boolean _us = true;
private static String CREATE_PLAYERMAP_TABLE = "CREATE TABLE IF NOT EXISTS playerMap (id INT NOT NULL AUTO_INCREMENT, playerName VARCHAR(256), serverName VARCHAR(256), us BOOLEAN NOT NULL DEFAULT 1, PRIMARY KEY (id), UNIQUE INDEX playerIndex (playerName));"; private static String CREATE_PLAYERMAP_TABLE = "CREATE TABLE IF NOT EXISTS playerMap (id INT NOT NULL AUTO_INCREMENT, playerName VARCHAR(256), serverName VARCHAR(256), us BOOLEAN NOT NULL DEFAULT 1, PRIMARY KEY (id), UNIQUE INDEX playerIndex (playerName));";
private static String RETRIEVE_PLAYERMAP = "SELECT playerName, serverName FROM playerMap WHERE playerName = ? AND us = ?;"; private static String RETRIEVE_PLAYERMAP = "SELECT playerName, serverName FROM playerMap WHERE playerName = ? AND us = ?;";
private static String INSERT_PLAYERMAP = "INSERT INTO playerMap (playerName, serverName, us) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE serverName = VALUES(serverName), us = VALUES(us);"; private static String INSERT_PLAYERMAP = "INSERT INTO playerMap (playerName, serverName, us) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE serverName = VALUES(serverName), us = VALUES(us);";
private static String DELETE_PLAYERMAP = "DELETE FROM playerMap WHERE playerName = ? AND serverName = ? AND us = ?;"; private static String DELETE_PLAYERMAP = "DELETE FROM playerMap WHERE playerName = ? AND us = ?;";
private Connection _connection = null; private Connection _connection = null;
public void initialize(String serverName, boolean us) public void initialize(boolean us)
{ {
_serverName = serverName;
_us = us; _us = us;
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
@ -137,8 +135,7 @@ public class PlayerTrackerRepository
preparedStatement = _connection.prepareStatement(DELETE_PLAYERMAP); preparedStatement = _connection.prepareStatement(DELETE_PLAYERMAP);
preparedStatement.setString(1, playerName); preparedStatement.setString(1, playerName);
preparedStatement.setString(2, _serverName); preparedStatement.setBoolean(2, _us);
preparedStatement.setBoolean(3, _us);
preparedStatement.executeUpdate(); preparedStatement.executeUpdate();
} }
@ -163,7 +160,7 @@ public class PlayerTrackerRepository
} }
} }
public void updatePlayerServer(String playerName) public void updatePlayerServer(String playerName, String serverName)
{ {
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
@ -178,7 +175,7 @@ public class PlayerTrackerRepository
preparedStatement = _connection.prepareStatement(INSERT_PLAYERMAP); preparedStatement = _connection.prepareStatement(INSERT_PLAYERMAP);
preparedStatement.setString(1, playerName); preparedStatement.setString(1, playerName);
preparedStatement.setString(2, _serverName); preparedStatement.setString(2, serverName);
preparedStatement.setBoolean(3, _us); preparedStatement.setBoolean(3, _us);
preparedStatement.executeUpdate(); preparedStatement.executeUpdate();

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre7"/>
<classpathentry kind="var" path="REPO_DIR/Plugins/Libraries/httpclient-4.2.jar"/>
<classpathentry kind="var" path="REPO_DIR/Plugins/Libraries/httpcore-4.2.jar"/>
<classpathentry kind="var" path="REPO_DIR/Plugins/Libraries/commons-codec-1.6.jar"/>
<classpathentry kind="var" path="REPO_DIR/Plugins/Libraries/gson-2.2.1.jar"/>
<classpathentry kind="var" path="REPO_DIR/Plugins/Libraries/javax.mail.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/Mineplex.Core"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_AFTER_CLEAN_TARGETS" value="BungeeRotator,"/>
<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_AUTO_TARGETS" value="BungeeRotator,"/>
<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_MANUAL_TARGETS" value="BungeeRotator,"/>
<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/>
<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${project}"/>
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value=""/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${BUILD_FILES}/common.xml"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,"/>
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/Mineplex.BungeeRotator}"/>
</launchConfiguration>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Mineplex.BungeeRotator</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
<triggers>auto,full,incremental,</triggers>
<arguments>
<dictionary>
<key>LaunchConfigHandle</key>
<value>&lt;project&gt;/.externalToolBuilders/BungeeRotator.launch</value>
</dictionary>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7

View File

@ -0,0 +1,142 @@
package mineplex.bungee;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
public class BungeeRepository
{
// Yip Yip actual IP because if null route happens we can't resolve the HOSTNAME DERP FACE DEFEK7!!! -defek7
private String _connectionString = "jdbc:mysql://10.35.74.133:3306/BungeeServers?autoReconnect=true&failOverReadOnly=false&maxReconnects=10";
private String _userName = "root";
private String _password = "tAbechAk3wR7tuTh";
private static String CREATE_ONLINE_TABLE = "CREATE TABLE IF NOT EXISTS bungeeOnlineStatus (id INT NOT NULL AUTO_INCREMENT, address VARCHAR(40), online BOOLEAN NOT NULL DEFAULT 0, updated LONG, us BOOLEAN NOT NULL DEFAULT 1, lastOnline LONG, PRIMARY KEY (id), UNIQUE INDEX addressIndex(address));";
private static String CREATE_PLAYER_TABLE = "CREATE TABLE IF NOT EXISTS BungeeServers (id INT NOT NULL AUTO_INCREMENT, address VARCHAR(256), updated LONG, players INT, maxPlayers INT, ram INT, maxRam INT, PRIMARY KEY (id));";
private static String RETRIEVE_SERVERS_PLAYERCOUNTS = "SELECT bos.address, players, maxPlayers, BungeeServers.updated, bos.lastOnline, BungeeServers.US, now() FROM BungeeServers INNER JOIN bungeeOnlineStatus AS bos ON bos.address = BungeeServers.address WHERE TIME_TO_SEC(TIMEDIFF(now(), BungeeServers.updated)) < 15;";
public void initialize()
{
Connection connection = null;
PreparedStatement preparedStatement = null;
try
{
connection = DriverManager.getConnection(_connectionString, _userName, _password);
// Create table
preparedStatement = connection.prepareStatement(CREATE_ONLINE_TABLE);
preparedStatement.execute();
preparedStatement.close();
preparedStatement = connection.prepareStatement(CREATE_PLAYER_TABLE);
preparedStatement.execute();
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
if (connection != null)
{
try
{
connection.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
public List<BungeeServer> getBungeeServers()
{
List<BungeeServer> bungeeServers = new ArrayList<BungeeServer>();
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try
{
connection = DriverManager.getConnection(_connectionString, _userName, _password);
preparedStatement = connection.prepareStatement(RETRIEVE_SERVERS_PLAYERCOUNTS);
resultSet = preparedStatement.executeQuery();
while (resultSet.next())
{
long current = dateFormat.parse(resultSet.getString(7)).getTime();
long updated = dateFormat.parse(resultSet.getString(4)).getTime();
long lastOnline = dateFormat.parse(resultSet.getString(5)).getTime();
if (current - updated <= 15000 && current - lastOnline <= 660000)
{
BungeeServer server = new BungeeServer();
server.Address = resultSet.getString(1).split(":")[0];
server.Players = resultSet.getInt(2);
server.MaxPlayers = resultSet.getInt(3);
server.US = resultSet.getBoolean(6);
bungeeServers.add(server);
}
}
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
if (connection != null)
{
try
{
connection.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
return bungeeServers;
}
}

View File

@ -0,0 +1,183 @@
package mineplex.bungee;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import mineplex.bungee.api.ApiDeleteCall;
import mineplex.bungee.api.ApiGetCall;
import mineplex.bungee.api.ApiPostCall;
import mineplex.bungee.api.token.ARecord;
import mineplex.bungee.api.token.DnsRecord;
import mineplex.bungee.api.token.DomainRecords;
public class BungeeRotator
{
private static BungeeRepository _repository = null;
private static HashSet<ProcessRunner> _processes = new HashSet<ProcessRunner>();
public static void main(String args[])
{
try
{
Class.forName("com.mysql.jdbc.Driver");
}
catch (ClassNotFoundException e1)
{
e1.printStackTrace();
}
_repository = new BungeeRepository();
BungeeSorter bungeeSorter = new BungeeSorter();
int maxRecordCount = 10;
while (true)
{
List<BungeeServer> bungeeServers = _repository.getBungeeServers();
HashSet<String> usServers = new HashSet<String>();
HashSet<String> euServers = new HashSet<String>();
Collections.sort(bungeeServers, bungeeSorter);
for (BungeeServer server : bungeeServers)
{
if (usServers.size() < maxRecordCount && server.US)
{
if (usServers.size() >= 2 && server.Players > 900)
continue;
System.out.println("SELECTED " + server.Address + " " + (server.US ? "us" : "eu") + " " + server.Players + "/" + server.MaxPlayers);
usServers.add(server.Address);
}
else if (euServers.size() < maxRecordCount && !server.US)
{
if (euServers.size() >= 2 && server.Players > 900)
continue;
System.out.println("SELECTED " + server.Address + " " + (server.US ? "us" : "eu") + " " + server.Players + "/" + server.MaxPlayers);
euServers.add(server.Address);
}
}
DomainRecords records = new ApiGetCall("https://api.dnsmadeeasy.com/V2.0/dns/managed/", 962728,
"/records", "").Execute(DomainRecords.class);
List<DnsRecord> recordsToDelete = new ArrayList<DnsRecord>();
List<DnsRecord> recordsToAdd = new ArrayList<DnsRecord>();
for (DnsRecord record : records.data)
{
if (record.type.equalsIgnoreCase("A"))
{
if (record.name.equalsIgnoreCase("us"))
{
if (usServers.contains(record.value))
usServers.remove(record.value);
else
recordsToDelete.add(record);
}
else if (record.name.equalsIgnoreCase("eu"))
{
if (euServers.contains(record.value))
euServers.remove(record.value);
else
recordsToDelete.add(record);
}
}
}
for (String address : usServers)
{
recordsToAdd.add(new ARecord("us", address, 300));
System.out.println("Addding server address in DNS : " + "us " + address);
}
for (String address : euServers)
{
recordsToAdd.add(new ARecord("eu", address, 300));
System.out.println("Addding server address in DNS : " + "eu " + address);
}
if (recordsToAdd.size() > 0)
{
new ApiPostCall("https://api.dnsmadeeasy.com/V2.0/dns/managed/", 962728, "/records/", "createMulti").Execute(recordsToAdd);
System.out.println("Created " + recordsToAdd.size() + " records.");
}
if (recordsToDelete.size() > 0)
{
StringBuilder idBuilder = new StringBuilder();
for (DnsRecord record : recordsToDelete)
{
if (idBuilder.length() != 0)
idBuilder.append("&");
idBuilder.append("ids=" + record.id);
}
new ApiDeleteCall("https://api.dnsmadeeasy.com/V2.0/dns/managed/", 962728, "/records?" + idBuilder.toString()).Execute();
System.out.println("Deleted " + recordsToDelete.size() + " records.");
}
int processWaits = 0;
while (_processes.size() > 0)
{
for (Iterator<ProcessRunner> iterator = _processes.iterator(); iterator.hasNext();)
{
ProcessRunner pr = iterator.next();
try
{
pr.join(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
if (pr.isDone())
iterator.remove();
}
if (_processes.size() > 0)
{
try
{
Thread.sleep(6000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
if (processWaits >= 60)
{
System.out.println("Killing stale processes.");
for (Iterator<ProcessRunner> iterator = _processes.iterator(); iterator.hasNext();)
{
iterator.next().abort();
iterator.remove();
}
}
processWaits++;
}
processWaits = 0;
try
{
Thread.sleep(30000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}

View File

@ -0,0 +1,9 @@
package mineplex.bungee;
public class BungeeServer
{
public String Address;
public int Players;
public int MaxPlayers;
public boolean US;
}

View File

@ -0,0 +1,17 @@
package mineplex.bungee;
import java.util.Comparator;
public class BungeeSorter implements Comparator<BungeeServer>
{
public int compare(BungeeServer a, BungeeServer b)
{
if (a.Players < b.Players)
return -1;
if (b.Players < a.Players)
return 1;
return 0;
}
}

View File

@ -0,0 +1,6 @@
package mineplex.bungee;
public interface GenericRunnable<T>
{
void run(T t);
}

View File

@ -0,0 +1,81 @@
package mineplex.bungee;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ProcessRunner extends Thread
{
private ProcessBuilder _processBuilder;
private Process _process;
private GenericRunnable<Boolean> _runnable;
boolean _done = false;
Boolean _error = false;
ProcessRunner(String[] args)
{
super("ProcessRunner " + args);
_processBuilder = new ProcessBuilder(args);
}
public void run()
{
try
{
_process = _processBuilder.start();
_process.waitFor();
BufferedReader reader=new BufferedReader(new InputStreamReader(_process.getInputStream()));
String line = reader.readLine();
while(line != null)
{
if (line.equals("255"))
_error = true;
line=reader.readLine();
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
finally
{
_done = true;
if (_runnable != null)
_runnable.run(_error);
}
}
public void start(GenericRunnable<Boolean> runnable)
{
super.start();
_runnable = runnable;
}
public int exitValue() throws IllegalStateException
{
if (_process != null)
{
return _process.exitValue();
}
throw new IllegalStateException("Process not started yet");
}
public boolean isDone()
{
return _done;
}
public void abort()
{
if (!isDone())
{
_process.destroy();
}
}
}

View File

@ -0,0 +1,18 @@
package mineplex.bungee.api;
import org.apache.http.client.methods.HttpDelete;
public class ApiDeleteCall extends DnsMadeEasyApiCallBase
{
public ApiDeleteCall(String apiUrl, int domainId, String category)
{
super(apiUrl, domainId, category);
}
public void Execute()
{
HttpDelete request = new HttpDelete(ApiUrl + DomainId + Category);
execute(request);
}
}

View File

@ -0,0 +1,33 @@
package mineplex.bungee.api;
import java.lang.reflect.Type;
import org.apache.http.client.methods.HttpGet;
import com.google.gson.Gson;
public class ApiGetCall extends DnsMadeEasyApiCallBase
{
private String _action;
public ApiGetCall(String apiUrl, int domainId, String category, String action)
{
super(apiUrl, domainId, category);
_action = action;
}
public void Execute()
{
HttpGet request = new HttpGet(ApiUrl + DomainId + Category + _action);
execute(request);
}
public <T> T Execute(Type returnType)
{
HttpGet request = new HttpGet(ApiUrl + DomainId + Category + _action);
String response = execute(request);
return new Gson().fromJson(response, returnType);
}
}

View File

@ -0,0 +1,77 @@
package mineplex.bungee.api;
import java.lang.reflect.Type;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import com.google.gson.Gson;
public class ApiPostCall extends DnsMadeEasyApiCallBase
{
private String _action;
public ApiPostCall(String apiUrl, int domainId, String category, String action)
{
super(apiUrl, domainId, category);
_action = action;
}
public void Execute(Object argument)
{
Gson gson = new Gson();
HttpPost request = new HttpPost(ApiUrl + DomainId + Category + _action);
try
{
StringEntity params = new StringEntity(gson.toJson(argument));
params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
request.setEntity(params);
}
catch (Exception exception)
{
System.out.println("Error executing ApiPostCall(Object): \n" + exception.getMessage());
for (StackTraceElement trace : exception.getStackTrace())
{
System.out.println(trace);
}
}
execute(request);
}
public <T> T Execute(Class<T> returnClass)
{
return Execute(returnClass, (Object)null);
}
public <T> T Execute(Type returnType, Object argument)
{
Gson gson = new Gson();
HttpPost request = new HttpPost(ApiUrl + DomainId + Category + _action);
System.out.println(request.getURI().toString());
try
{
StringEntity params = new StringEntity(gson.toJson(argument));
params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
request.setEntity(params);
}
catch (Exception exception)
{
System.out.println("Error executing ApiPostCall(Type, Object): \n" + exception.getMessage());
for (StackTraceElement trace : exception.getStackTrace())
{
System.out.println(trace);
}
}
String response = execute(request);
System.out.println(response);
return new Gson().fromJson(response, returnType);
}
}

View File

@ -0,0 +1,79 @@
package mineplex.bungee.api;
import java.lang.reflect.Type;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import com.google.gson.Gson;
public class ApiPutCall extends DnsMadeEasyApiCallBase
{
private String _action;
public ApiPutCall(String apiUrl, int domainId, String category, String action)
{
super(apiUrl, domainId, category);
_action = action;
}
public void Execute(Object argument)
{
Gson gson = new Gson();
HttpPut request = new HttpPut(ApiUrl + DomainId + Category + _action);
System.out.println(request.getURI().toString());
try
{
StringEntity params = new StringEntity(gson.toJson(argument));
params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
request.setEntity(params);
}
catch (Exception exception)
{
System.out.println("Error executing ApiPutCall(Object): \n" + exception.getMessage());
for (StackTraceElement trace : exception.getStackTrace())
{
System.out.println(trace);
}
}
System.out.println(execute(request));
}
public <T> T Execute(Class<T> returnClass)
{
return Execute(returnClass, (Object)null);
}
public <T> T Execute(Type returnType, Object argument)
{
Gson gson = new Gson();
HttpPut request = new HttpPut(ApiUrl + DomainId + Category + _action);
System.out.println(request.getURI().toString());
try
{
StringEntity params = new StringEntity(gson.toJson(argument));
params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
request.setEntity(params);
}
catch (Exception exception)
{
System.out.println("Error executing ApiPutCall(Type, Object): \n" + exception.getMessage());
for (StackTraceElement trace : exception.getStackTrace())
{
System.out.println(trace);
}
}
String response = execute(request);
System.out.println(response);
return new Gson().fromJson(response, returnType);
}
}

View File

@ -0,0 +1,140 @@
package mineplex.bungee.api;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
public abstract class DnsMadeEasyApiCallBase
{
protected String ApiUrl = "http://api.dnsmadeeasy.com/V2.0/dns/managed/";
protected int DomainId = 962728;
protected String Category = "/records/";
public DnsMadeEasyApiCallBase(String apiUrl, int domainId, String category)
{
ApiUrl = apiUrl;
DomainId = domainId;
Category = category;
}
protected String execute(HttpRequestBase request)
{
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("https", 80, PlainSocketFactory.getSocketFactory()));
PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager(schemeRegistry);
connectionManager.setMaxTotal(200);
connectionManager.setDefaultMaxPerRoute(20);
HttpClient httpClient = new DefaultHttpClient(connectionManager);
InputStream in = null;
String response = "";
try
{
String timeStamp = getServerTime();
SecretKeySpec keySpec = new SecretKeySpec("8c9af8cc-d306-4df3-8de8-944deafa8239".getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(keySpec);
byte[] hashBytes = mac.doFinal((timeStamp + "").getBytes());
Hex.encodeHexString(hashBytes);
request.addHeader("x-dnsme-apiKey", "610e21ee-4250-4b55-b637-a1fcc3847850");
request.addHeader("x-dnsme-requestDate", timeStamp + "");
request.addHeader("x-dnsme-hmac", Hex.encodeHexString(hashBytes));
request.addHeader("Content-Type", "application/json");
HttpResponse httpResponse = httpClient.execute(request);
if (httpResponse != null)
{
in = httpResponse.getEntity().getContent();
response = convertStreamToString(in);
}
}
catch (Exception ex)
{
System.out.println("DnsMadeEasyApiCall Error:\n" + ex.getMessage());
for (StackTraceElement trace : ex.getStackTrace())
{
System.out.println(trace);
}
}
finally
{
httpClient.getConnectionManager().shutdown();
if (in != null)
{
try
{
in.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
return response;
}
protected String getServerTime()
{
Calendar calendar = Calendar.getInstance();
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
return dateFormat.format(calendar.getTime());
}
protected String convertStreamToString(InputStream is)
{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try
{
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
is.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
return sb.toString();
}
}

View File

@ -0,0 +1,14 @@
package mineplex.bungee.api.token;
public class ARecord extends DnsRecord
{
public ARecord(String recordName, String ip, int recordTtl)
{
name = recordName;
value = ip;
ttl = recordTtl;
type = "A";
gtdLocation = "DEFAULT";
}
}

View File

@ -0,0 +1,14 @@
package mineplex.bungee.api.token;
public class CNameRecord extends DnsRecord
{
public CNameRecord(String recordName, String ip, int recordTtl)
{
name = recordName;
value = ip;
ttl = recordTtl;
type = "CNAME";
gtdLocation = "DEFAULT";
}
}

View File

@ -0,0 +1,11 @@
package mineplex.bungee.api.token;
public class DnsRecord
{
public int id;
public String name;
public String type;
public String value;
public String gtdLocation;
public int ttl;
}

View File

@ -0,0 +1,11 @@
package mineplex.bungee.api.token;
import java.util.List;
public class DomainRecords
{
public List<DnsRecord> data;
public int page;
public int totalPage;
public int totalRecords;
}

View File

@ -35,6 +35,14 @@ public class ChildJsonMessage extends JsonMessage
return this; return this;
} }
@Override
public ChildJsonMessage bold()
{
super.bold();
return this;
}
@Override @Override
public ChildJsonMessage click(String action, String value) public ChildJsonMessage click(String action, String value)
{ {

View File

@ -1,7 +1,11 @@
package mineplex.core.common.jsonchat; package mineplex.core.common.jsonchat;
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import net.minecraft.server.v1_7_R4.ChatSerializer;
import net.minecraft.server.v1_7_R4.PacketPlayOutChat;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilServer;
public class JsonMessage public class JsonMessage
@ -25,6 +29,13 @@ public class JsonMessage
return this; return this;
} }
public JsonMessage bold()
{
Builder.append(", bold:true");
return this;
}
public ChildJsonMessage extra(String text) public ChildJsonMessage extra(String text)
{ {
Builder.append(", \"extra\":["); Builder.append(", \"extra\":[");
@ -56,4 +67,53 @@ public class JsonMessage
{ {
UtilServer.getServer().dispatchCommand(UtilServer.getServer().getConsoleSender(), "tellraw " + player.getName() + " " + toString()); UtilServer.getServer().dispatchCommand(UtilServer.getServer().getConsoleSender(), "tellraw " + player.getName() + " " + toString());
} }
/**
* Send a message to players using the new 1.8 message types
*
* @param messageType Message type to send
* @param players Players to send to
*/
public void send(MessageType messageType, Player... players)
{
send(messageType, false, players);
}
/**
* Send a message to players using the new 1.8 message types
*
* @param messageType Message type to send
* @param defaultToChat Only applies to MessageType.ABOVE_HOTBAR. If true, it will send this to chat for 1.7 clients
* @param players Players to send to
*/
public void send(MessageType messageType, boolean defaultToChat, Player... players)
{
PacketPlayOutChat chatPacket = new PacketPlayOutChat(ChatSerializer.a(toString()));
chatPacket.setChatType(messageType.getId());
for (Player player : players)
{
if (defaultToChat || messageType != MessageType.ABOVE_HOTBAR || UtilPlayer.is1_8(player))
((CraftPlayer) player).getHandle().playerConnection.sendPacket(chatPacket);
}
}
public static enum MessageType
{
CHAT_BOX((byte) 0), // Inside Chat Box
SYSTEM_MESSAGE((byte) 1), // Inside Chat Box - This is used for the client to identify difference between chat message and server messages
ABOVE_HOTBAR((byte) 2); // Shows above hotbar
private byte _id;
MessageType(byte id)
{
_id = id;
}
public byte getId()
{
return _id;
}
}
} }

View File

@ -7,6 +7,7 @@ public class C
public static String Scramble = "§k"; public static String Scramble = "§k";
public static String Bold = "§l"; public static String Bold = "§l";
public static String Strike = "§m"; public static String Strike = "§m";
public static String BoldStrike = "§l§m";
public static String Line = "§n"; public static String Line = "§n";
public static String Italics = "§o"; public static String Italics = "§o";

View File

@ -151,6 +151,11 @@ public class MapUtil
} }
} }
public static void ChunkBlockSet(World world, int x, int y, int z, int id, byte data, boolean notifyPlayers)
{
world.getBlockAt(x, y, z).setTypeIdAndData(id, data, notifyPlayers);
}
private static boolean changeChunkBlock(int x, int y, int z, net.minecraft.server.v1_7_R4.Chunk chunk, Block block, private static boolean changeChunkBlock(int x, int y, int z, net.minecraft.server.v1_7_R4.Chunk chunk, Block block,
byte data) byte data)
{ {

View File

@ -1,5 +1,6 @@
package mineplex.core.common.util; package mineplex.core.common.util;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
@ -21,6 +22,11 @@ public class UtilAlg
return sortedSet; return sortedSet;
} }
public static Location getMidpoint(Location a, Location b)
{
return a.add(b.subtract(a).multiply(0.5));
}
public static Vector getTrajectory(Entity from, Entity to) public static Vector getTrajectory(Entity from, Entity to)
{ {
return getTrajectory(from.getLocation().toVector(), to.getLocation().toVector()); return getTrajectory(from.getLocation().toVector(), to.getLocation().toVector());
@ -113,6 +119,16 @@ public class UtilAlg
return new Vector(vec.getX(), vec.getY(), vec.getZ()); return new Vector(vec.getX(), vec.getY(), vec.getZ());
} }
public static <T> T Random(Set<T> set)
{
List<T> list = new ArrayList<T>();
list.addAll(set);
return Random(list);
}
public static <T> T Random(List<T> list) public static <T> T Random(List<T> list)
{ {
if (list.isEmpty()) if (list.isEmpty())
@ -168,4 +184,6 @@ public class UtilAlg
{ {
return cross(vec, getRight(vec)); return cross(vec, getRight(vec));
} }
} }

View File

@ -302,6 +302,21 @@ public class UtilBlock
return blockList; return blockList;
} }
public static ArrayList<Block> getInSquare(Block block, double dR)
{
ArrayList<Block> blockList = new ArrayList<Block>();
int iR = (int)dR + 1;
for (int x=-iR ; x <= iR ; x++)
for (int z=-iR ; z <= iR ; z++)
for (int y=-iR ; y <= iR ; y++)
{
blockList.add(block.getRelative(x, y, z));
}
return blockList;
}
public static boolean isBlock(ItemStack item) public static boolean isBlock(ItemStack item)
{ {
if (item == null) if (item == null)
@ -320,9 +335,12 @@ public class UtilBlock
Block block = world.getHighestBlockAt(x, z); Block block = world.getHighestBlockAt(x, z);
//Shuffle Down //Shuffle Down
while (airFoliage(block) || while (block.getY() > 0 &&
(
airFoliage(block) ||
block.getType() == Material.LEAVES || block.getType() == Material.LEAVES ||
(ignore != null && ignore.contains(block.getType()))) (ignore != null && ignore.contains(block.getType()))
))
{ {
block = block.getRelative(BlockFace.DOWN); block = block.getRelative(BlockFace.DOWN);
} }

View File

@ -10,7 +10,7 @@ import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
public class UtilText public class UtilBlockText
{ {
public enum TextAlign public enum TextAlign
{ {
@ -139,21 +139,21 @@ public class UtilText
if (align == TextAlign.CENTER) if (align == TextAlign.CENTER)
for (int i=-64 ; i<=64 ; i++) for (int i=-64 ; i<=64 ; i++)
{ {
MapUtil.ChunkBlockChange(world, bX + i * face.getModX(), bY + i * face.getModY(), bZ + i * face.getModZ(), 0, (byte)0, true); MapUtil.ChunkBlockSet(world, bX + i * face.getModX(), bY + i * face.getModY(), bZ + i * face.getModZ(), 0, (byte)0, true);
} }
if (align == TextAlign.LEFT) if (align == TextAlign.LEFT)
for (int i=0 ; i<=128 ; i++) for (int i=0 ; i<=128 ; i++)
{ {
MapUtil.ChunkBlockChange(world, bX + i * face.getModX(), bY + i * face.getModY(), bZ + i * face.getModZ(), 0, (byte)0, true); MapUtil.ChunkBlockSet(world, bX + i * face.getModX(), bY + i * face.getModY(), bZ + i * face.getModZ(), 0, (byte)0, true);
} }
if (align == TextAlign.RIGHT) if (align == TextAlign.RIGHT)
for (int i=-128 ; i<=0 ; i++) for (int i=-128 ; i<=0 ; i++)
{ {
MapUtil.ChunkBlockChange(world, bX + i * face.getModX(), bY + i * face.getModY(), bZ + i * face.getModZ(), 0, (byte)0, true); MapUtil.ChunkBlockSet(world, bX + i * face.getModX(), bY + i * face.getModY(), bZ + i * face.getModZ(), 0, (byte)0, true);
} }
@ -181,7 +181,7 @@ public class UtilText
if (letter[x][y] == 1) if (letter[x][y] == 1)
{ {
changes.add(world.getBlockAt(bX, bY, bZ)); changes.add(world.getBlockAt(bX, bY, bZ));
MapUtil.ChunkBlockChange(world, bX, bY, bZ, id, data, true); MapUtil.ChunkBlockSet(world, bX, bY, bZ, id, data, true);
} }
//Forward //Forward

View File

@ -1,169 +0,0 @@
package mineplex.core.common.util;
import java.lang.reflect.Field;
import java.util.HashMap;
import mineplex.core.common.DummyEntity;
import net.minecraft.server.v1_7_R4.DataWatcher;
import net.minecraft.server.v1_7_R4.EntityPlayer;
import net.minecraft.server.v1_7_R4.MathHelper;
import net.minecraft.server.v1_7_R4.Packet;
import net.minecraft.server.v1_7_R4.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_7_R4.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntityLiving;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_7_R4.CraftWorld;
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
public class UtilDisplay
{
public static final int ENTITY_ID = 777777;
public static final EntityType ENTITY_TYPE = EntityType.WITHER;
public static final boolean HALF_HEALTH = true;
private static HashMap<String, Boolean> hasHealthBar = new HashMap<String, Boolean>();
public static void sendPacket(Player player, Packet packet){
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
entityPlayer.playerConnection.sendPacket(packet);
}
//Accessing packets
public static PacketPlayOutSpawnEntityLiving getMobPacket(String text, double healthPercent, Location loc)
{
PacketPlayOutSpawnEntityLiving mobPacket = new PacketPlayOutSpawnEntityLiving();
mobPacket.a = (int) ENTITY_ID; //Entity ID
mobPacket.b = (byte) ENTITY_TYPE.getTypeId(); //Mob type (ID: 64)
mobPacket.c = (int) Math.floor(loc.getBlockX() * 32.0D); //X position
mobPacket.d = (int) MathHelper.floor(loc.getBlockY() * 32.0D); //Y position
mobPacket.e = (int) Math.floor(loc.getBlockZ() * 32.0D); //Z position
mobPacket.f = (byte) 0; //Pitch
mobPacket.g = (byte) 0; //Head Pitch
mobPacket.h = (byte) 0; //Yaw
mobPacket.i = (short) 0; //X velocity
mobPacket.j = (short) 0; //Y velocity
mobPacket.k = (short) 0; //Z velocity
//Dragon or Wither
double health;
if (ENTITY_TYPE == EntityType.WITHER)
{
if (HALF_HEALTH)
health = healthPercent * 149 + 151;
else
health = healthPercent * 299.9 + 0.1;
}
else
{
if (HALF_HEALTH)
health = healthPercent * 99 + 101;
else
health = healthPercent * 199.9 + 0.1;
}
DataWatcher watcher = getWatcher(text, health, loc.getWorld());
mobPacket.l = watcher;
return mobPacket;
}
public static PacketPlayOutEntityDestroy getDestroyEntityPacket()
{
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ENTITY_ID);
return packet;
}
public static PacketPlayOutEntityMetadata getMetadataPacket(DataWatcher watcher)
{
PacketPlayOutEntityMetadata metaPacket = new PacketPlayOutEntityMetadata();
metaPacket.a = (int) ENTITY_ID;
try
{
Field b = PacketPlayOutEntityMetadata.class.getDeclaredField("b");
b.setAccessible(true);
b.set(metaPacket, watcher.c());
}
catch(Exception e)
{
e.printStackTrace();
}
return metaPacket;
}
public static DataWatcher getWatcher(String text, double health, World world)
{
DataWatcher watcher = new DataWatcher(new DummyEntity(((CraftWorld)world).getHandle()));
watcher.a(0, (Byte) (byte) 0); //Flags, 0x20 = invisible
watcher.a(6, (Float) (float) health);
watcher.a(2, (String) text); //Entity name
watcher.a(10, (String) text); //Entity name
watcher.a(3, (Byte) (byte) 0); //Show name, 1 = show, 0 = don't show
watcher.a(11, (Byte) (byte) 0); //Show name, 1 = show, 0 = don't show
watcher.a(16, (Integer) (int) health); //Wither health, 300 = full health
watcher.a(20, (Integer) (int) 0); //Wither invuln,
int i1 = watcher.getInt(0);
watcher.watch(0, Byte.valueOf((byte)(i1 | 1 << 5)));
watcher.watch(20, 0);
return watcher;
}
//Display
public static void displayTextBar(JavaPlugin plugin, final Player player, double healthPercent, String text)
{
PacketPlayOutEntityDestroy destroyEntityPacket = getDestroyEntityPacket();
sendPacket(player, destroyEntityPacket);
Location loc = player.getEyeLocation().add(player.getLocation().getDirection().multiply(24));
/*
//Downward
if (player.getLocation().getPitch() > 0)
{
loc = player.getLocation().subtract(0, 10, 0);
}
//Upward
else
{
loc.add(player.getLocation().getDirection().multiply(12));
loc.add(UtilAlg.getDown(player.getLocation().getDirection()).multiply(12));
}
*/
PacketPlayOutSpawnEntityLiving mobPacket = getMobPacket(text, healthPercent, loc);
sendPacket(player, mobPacket);
hasHealthBar.put(player.getName(), true);
Bukkit.getServer().getScheduler().runTaskLater(plugin, new Runnable()
{
public void run()
{
PacketPlayOutEntityDestroy destroyEntityPacket = getDestroyEntityPacket();
sendPacket(player, destroyEntityPacket);
hasHealthBar.put(player.getName(), false);
}
}, 20);
}
}

View File

@ -515,6 +515,7 @@ public class UtilEnt
Material beneath = player.getLocation().add(x, -1.5, z).getBlock().getType(); Material beneath = player.getLocation().add(x, -1.5, z).getBlock().getType();
if (player.getLocation().getY() % 0.5 == 0 && if (player.getLocation().getY() % 0.5 == 0 &&
(beneath == Material.FENCE || (beneath == Material.FENCE ||
beneath == Material.FENCE_GATE ||
beneath == Material.NETHER_FENCE || beneath == Material.NETHER_FENCE ||
beneath == Material.COBBLE_WALL)) beneath == Material.COBBLE_WALL))
return true; return true;
@ -535,11 +536,11 @@ public class UtilEnt
EntityCreature ec = ((CraftCreature)ent).getHandle(); EntityCreature ec = ((CraftCreature)ent).getHandle();
Navigation nav = ec.getNavigation(); Navigation nav = ec.getNavigation();
if (UtilMath.offset(ent.getLocation(), target) > 24) if (UtilMath.offset(ent.getLocation(), target) > 16)
{ {
Location newTarget = ent.getLocation(); Location newTarget = ent.getLocation();
newTarget.add(UtilAlg.getTrajectory(ent.getLocation(), target).multiply(24)); newTarget.add(UtilAlg.getTrajectory(ent.getLocation(), target).multiply(16));
nav.a(newTarget.getX(), newTarget.getY(), newTarget.getZ(), speed); nav.a(newTarget.getX(), newTarget.getY(), newTarget.getZ(), speed);
} }

View File

@ -1,6 +1,8 @@
package mineplex.core.common.util; package mineplex.core.common.util;
import org.bukkit.Color;
import org.bukkit.FireworkEffect; import org.bukkit.FireworkEffect;
import org.bukkit.FireworkEffect.Type;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; import org.bukkit.craftbukkit.v1_7_R4.CraftWorld;
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity;
@ -57,4 +59,9 @@ public class UtilFirework
firework.remove(); firework.remove();
} }
public static void playFirework(Location loc, Type type, Color color, boolean flicker, boolean trail)
{
playFirework(loc, FireworkEffect.builder().flicker(false).withColor(color).with(type).trail(false).build());
}
} }

View File

@ -0,0 +1,192 @@
package mineplex.core.common.util;
import net.minecraft.server.v1_7_R4.ChatSerializer;
import net.minecraft.server.v1_7_R4.IChatBaseComponent;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.spigotmc.ProtocolInjector;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class UtilTabTitle
{
private static final int PROTOCOL_VERSION = 47;
public static void broadcastHeader(String header)
{
broadcastHeaderAndFooter(header, null);
}
public static void broadcastFooter(String footer)
{
broadcastHeaderAndFooter(null, footer);
}
public static void broadcastHeaderAndFooter(String header, String footer)
{
for (Player player : Bukkit.getOnlinePlayers())
doHeaderAndFooter(player, header, footer);
}
public static void setHeaderAndFooter(Player player, String header, String footer)
{
doHeaderAndFooter(player, header, footer);
}
public static void setHeader(Player p, String header)
{
doHeaderAndFooter(p, header, null);
}
public static void setFooter(Player p, String footer)
{
doHeaderAndFooter(p, null, footer);
}
public static void doHeaderAndFooter(Player p, String rawHeader, String rawFooter)
{
CraftPlayer player = (CraftPlayer) p;
if (player.getHandle().playerConnection.networkManager.getVersion() != PROTOCOL_VERSION) return;
IChatBaseComponent header = ChatSerializer.a(TextConverter.convert(rawHeader));
IChatBaseComponent footer = ChatSerializer.a(TextConverter.convert(rawFooter));
if (header == null || footer == null)
{
TabTitleCache titleCache = TabTitleCache.getTabTitle(p.getUniqueId());
if (titleCache != null)
{
if (header == null)
{
String headerString = titleCache.getHeader();
if (headerString != null)
{
rawHeader = headerString;
header = ChatSerializer.a(TextConverter.convert(headerString));
}
}
if (footer == null)
{
String footerString = titleCache.getFooter();
if (footerString != null)
{
rawHeader = footerString;
header = ChatSerializer.a(TextConverter.convert(footerString));
}
}
}
}
TabTitleCache.addTabTitle(p.getUniqueId(), new TabTitleCache(rawHeader, rawFooter));
ProtocolInjector.PacketTabHeader packet = new ProtocolInjector.PacketTabHeader(header, footer);
player.getHandle().playerConnection.sendPacket(packet);
}
private static class TextConverter
{
public static String convert(String text)
{
if (text == null || text.length() == 0)
{
return "\"\"";
}
char c;
int i;
int len = text.length();
StringBuilder sb = new StringBuilder(len + 4);
String t;
sb.append('"');
for (i = 0; i < len; i += 1)
{
c = text.charAt(i);
switch (c)
{
case '\\':
case '"':
sb.append('\\');
sb.append(c);
break;
case '/':
sb.append('\\');
sb.append(c);
break;
case '\b':
sb.append("\\b");
break;
case '\t':
sb.append("\\t");
break;
case '\n':
sb.append("\\n");
break;
case '\f':
sb.append("\\f");
break;
case '\r':
sb.append("\\r");
break;
default:
if (c < ' ')
{
t = "000" + Integer.toHexString(c);
sb.append("\\u").append(t.substring(t.length() - 4));
}
else
{
sb.append(c);
}
}
}
sb.append('"');
return sb.toString();
}
public static String setPlayerName(Player player, String text)
{
return text.replaceAll("(?i)\\{PLAYER\\}", player.getName());
}
}
private static class TabTitleCache
{
final private static Map<UUID, TabTitleCache> playerTabTitles = new HashMap<>();
private String header;
private String footer;
public TabTitleCache(String header, String footer)
{
this.header = header;
this.footer = footer;
}
public static TabTitleCache getTabTitle(UUID uuid)
{
return playerTabTitles.get(uuid);
}
public static void addTabTitle(UUID uuid, TabTitleCache titleCache)
{
playerTabTitles.put(uuid, titleCache);
}
public static void removeTabTitle(UUID uuid)
{
playerTabTitles.remove(uuid);
}
public String getHeader()
{
return header;
}
public String getFooter()
{
return footer;
}
}
}

View File

@ -0,0 +1,71 @@
package mineplex.core.common.util;
import mineplex.core.common.jsonchat.JsonMessage;
import mineplex.core.common.jsonchat.JsonMessage.MessageType;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
public class UtilTextBottom
{
public static void display(String text, Player... players)
{
JsonMessage msg = new JsonMessage(text);
//1.8
msg.send(MessageType.ABOVE_HOTBAR, players);
//1.7 Players
for (Player player : players)
{
if (!UtilPlayer.is1_8(player))
{
UtilTextTop.display(text, player);
}
}
}
public static void displayProgress(double amount, Player... players)
{
displayProgress(null, amount, null, players);
}
public static void displayProgress(String prefix, double amount, Player... players)
{
displayProgress(prefix, amount, null, players);
}
public static void displayProgress(String prefix, double amount, String suffix, Player... players)
{
//Generate Bar
int bars = 12;
String progressBar = C.cGreen + "";
boolean colorChange = false;
for (int i=0 ; i<bars ; i++)
{
if (!colorChange && (float)i/(float)bars >= amount)
{
progressBar += C.cRed;
colorChange = true;
}
progressBar += "";
}
//Send to Player
for (Player player : players)
{
//1.7
if (!UtilPlayer.is1_8(player))
{
UtilTextTop.displayProgress((prefix == null ? "" : prefix) + (suffix == null ? "" : ChatColor.RESET + C.Bold + " - " + ChatColor.RESET + suffix),
amount, player);
}
//1.8
else
{
display((prefix == null ? "" : prefix + ChatColor.RESET + " ") + progressBar + (suffix == null ? "" : ChatColor.RESET + " " + suffix), players);
}
}
}
}

View File

@ -11,7 +11,7 @@ import org.spigotmc.ProtocolInjector.PacketTitle.Action;
/** /**
* Created by Shaun on 9/5/2014. * Created by Shaun on 9/5/2014.
*/ */
public class UtilTitle public class UtilTextMiddle
{ {
public static void display(String text, String subtitle, Player... players) public static void display(String text, String subtitle, Player... players)
{ {

View File

@ -0,0 +1,158 @@
package mineplex.core.common.util;
import mineplex.core.common.DummyEntity;
import net.minecraft.server.v1_7_R4.DataWatcher;
import net.minecraft.server.v1_7_R4.MathHelper;
import net.minecraft.server.v1_7_R4.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntityLiving;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_7_R4.CraftWorld;
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
public class UtilTextTop
{
//Base Commands
public static void display(String text, Player... players)
{
displayProgress(text, 1, players);
}
public static void displayProgress(String text, double progress, Player... players)
{
for (Player player : players)
displayTextBar(player, progress, text);
}
//Logic
public static final int EntityDragonId = 777777;
public static final int EntityWitherId = 777778;
//Display
public static void displayTextBar(final Player player, double healthPercent, String text)
{
deleteOld(player);
healthPercent = Math.min(1, healthPercent);
boolean halfHealth = UtilPlayer.is1_8(player);
//Display Dragon
{
Location loc = player.getLocation().subtract(0, 200, 0);
((CraftPlayer)player).getHandle().playerConnection.sendPacket(getDragonPacket(text, healthPercent, halfHealth, loc));
}
//Display Wither (as well as Dragon)
if (UtilPlayer.is1_8(player))
{
Location loc = player.getEyeLocation().add(player.getLocation().getDirection().multiply(24));
((CraftPlayer)player).getHandle().playerConnection.sendPacket(getWitherPacket(text, healthPercent, halfHealth, loc));
}
//Remove
Bukkit.getServer().getScheduler().runTaskLater(Bukkit.getPluginManager().getPlugins()[0], new Runnable()
{
public void run()
{
deleteOld(player);
}
}, 20);
}
private static void deleteOld(Player player)
{
//Delete Dragon (All Clients)
PacketPlayOutEntityDestroy destroyDragonPacket = new PacketPlayOutEntityDestroy(EntityDragonId);
((CraftPlayer)player).getHandle().playerConnection.sendPacket(destroyDragonPacket);
//Delete Wither (1.8+ Only)
if (UtilPlayer.is1_8(player))
{
PacketPlayOutEntityDestroy destroyWitherPacket = new PacketPlayOutEntityDestroy(EntityWitherId);
((CraftPlayer)player).getHandle().playerConnection.sendPacket(destroyWitherPacket);
}
}
public static PacketPlayOutSpawnEntityLiving getDragonPacket(String text, double healthPercent, boolean halfHealth, Location loc)
{
PacketPlayOutSpawnEntityLiving mobPacket = new PacketPlayOutSpawnEntityLiving();
mobPacket.a = (int) EntityDragonId; //Entity ID
mobPacket.b = (byte) EntityType.ENDER_DRAGON.getTypeId(); //Mob type
mobPacket.c = (int) Math.floor(loc.getBlockX() * 32.0D); //X position
mobPacket.d = (int) MathHelper.floor(loc.getBlockY() * 32.0D); //Y position
mobPacket.e = (int) Math.floor(loc.getBlockZ() * 32.0D); //Z position
mobPacket.f = (byte) 0; //Pitch
mobPacket.g = (byte) 0; //Head Pitch
mobPacket.h = (byte) 0; //Yaw
mobPacket.i = (short) 0; //X velocity
mobPacket.j = (short) 0; //Y velocity
mobPacket.k = (short) 0; //Z velocity
//Health
double health = healthPercent * 199.9 + 0.1;
if (halfHealth)
health = healthPercent * 99 + 101;
//Watcher
DataWatcher watcher = getWatcher(text, health, loc.getWorld());
mobPacket.l = watcher;
return mobPacket;
}
public static PacketPlayOutSpawnEntityLiving getWitherPacket(String text, double healthPercent, boolean halfHealth, Location loc)
{
PacketPlayOutSpawnEntityLiving mobPacket = new PacketPlayOutSpawnEntityLiving();
mobPacket.a = (int) EntityWitherId; //Entity ID
mobPacket.b = (byte) EntityType.WITHER.getTypeId(); //Mob type
mobPacket.c = (int) Math.floor(loc.getBlockX() * 32.0D); //X position
mobPacket.d = (int) MathHelper.floor(loc.getBlockY() * 32.0D); //Y position
mobPacket.e = (int) Math.floor(loc.getBlockZ() * 32.0D); //Z position
mobPacket.f = (byte) 0; //Pitch
mobPacket.g = (byte) 0; //Head Pitch
mobPacket.h = (byte) 0; //Yaw
mobPacket.i = (short) 0; //X velocity
mobPacket.j = (short) 0; //Y velocity
mobPacket.k = (short) 0; //Z velocity
//Health
double health = healthPercent * 299.9 + 0.1;
if (halfHealth)
health = healthPercent * 149 + 151;
//Watcher
DataWatcher watcher = getWatcher(text, health, loc.getWorld());
mobPacket.l = watcher;
return mobPacket;
}
public static DataWatcher getWatcher(String text, double health, World world)
{
DataWatcher watcher = new DataWatcher(new DummyEntity(((CraftWorld)world).getHandle()));
watcher.a(0, (Byte) (byte) 0); //Flags, 0x20 = invisible
watcher.a(6, (Float) (float) health);
watcher.a(2, (String) text); //Entity name
watcher.a(10, (String) text); //Entity name
watcher.a(3, (Byte) (byte) 0); //Show name, 1 = show, 0 = don't show
watcher.a(11, (Byte) (byte) 0); //Show name, 1 = show, 0 = don't show
watcher.a(16, (Integer) (int) health); //Health
watcher.a(20, (Integer) (int) 0); //Inv
int i1 = watcher.getInt(0);
watcher.watch(0, Byte.valueOf((byte)(i1 | 1 << 5)));
watcher.watch(20, 0);
return watcher;
}
}

View File

@ -5,8 +5,8 @@ import java.util.Calendar;
public class UtilTime public class UtilTime
{ {
public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss"; public static final String DATE_FORMAT_NOW = "MM-dd-yyyy HH:mm:ss";
public static final String DATE_FORMAT_DAY = "yyyy-MM-dd"; public static final String DATE_FORMAT_DAY = "MM-dd-yyyy";
public static String now() public static String now()
{ {

View File

@ -10,6 +10,7 @@
<classpathentry combineaccessrules="false" kind="src" path="/Mineplex.ServerData"/> <classpathentry combineaccessrules="false" kind="src" path="/Mineplex.ServerData"/>
<classpathentry kind="var" path="REPO_DIR/Plugins/Libraries/jedis-2.4.2.jar"/> <classpathentry kind="var" path="REPO_DIR/Plugins/Libraries/jedis-2.4.2.jar"/>
<classpathentry kind="var" path="REPO_DIR/Plugins/Libraries/commons-pool2-2.2.jar"/> <classpathentry kind="var" path="REPO_DIR/Plugins/Libraries/commons-pool2-2.2.jar"/>
<classpathentry kind="var" path="REPO_DIR/Plugins/Libraries/commons-dbcp2-2.0.1.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/Mineplex.Database"/> <classpathentry combineaccessrules="false" kind="src" path="/Mineplex.Database"/>
<classpathentry kind="var" path="REPO_DIR/Plugins/Libraries/jooq-3.4.2.jar"/> <classpathentry kind="var" path="REPO_DIR/Plugins/Libraries/jooq-3.4.2.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>

View File

@ -17,6 +17,7 @@
<orderEntry type="library" name="craftbukkit" level="project" /> <orderEntry type="library" name="craftbukkit" level="project" />
<orderEntry type="module" module-name="Mineplex.Database" /> <orderEntry type="module" module-name="Mineplex.Database" />
<orderEntry type="library" name="jooq" level="project" /> <orderEntry type="library" name="jooq" level="project" />
<orderEntry type="library" name="commons-dbcp2" level="project" />
</component> </component>
</module> </module>

View File

@ -1,16 +1,20 @@
package mineplex.core; package mineplex.core;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.List; import java.util.List;
import mineplex.core.common.DummyEntity; import mineplex.core.common.DummyEntity;
import mineplex.core.common.util.NautHashMap; import mineplex.core.common.util.NautHashMap;
import mineplex.core.event.CustomTagEvent;
import mineplex.core.packethandler.IPacketHandler; import mineplex.core.packethandler.IPacketHandler;
import mineplex.core.common.util.UtilEnt; import mineplex.core.common.util.UtilEnt;
import mineplex.core.packethandler.PacketHandler; import mineplex.core.packethandler.PacketHandler;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.core.packethandler.PacketVerifier; import mineplex.core.packethandler.PacketVerifier;
import mineplex.core.packethandler.PacketInfo; import mineplex.core.packethandler.PacketInfo;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import net.minecraft.server.v1_7_R4.DataWatcher; import net.minecraft.server.v1_7_R4.DataWatcher;
import net.minecraft.server.v1_7_R4.EnumEntitySize; import net.minecraft.server.v1_7_R4.EnumEntitySize;
import net.minecraft.server.v1_7_R4.MathHelper; import net.minecraft.server.v1_7_R4.MathHelper;
@ -31,6 +35,9 @@ import org.bukkit.plugin.java.JavaPlugin;
public class CustomTagFix extends MiniPlugin implements IPacketHandler public class CustomTagFix extends MiniPlugin implements IPacketHandler
{ {
private NautHashMap<Player, NautHashMap<Integer, Integer>> _entityMap = new NautHashMap<Player, NautHashMap<Integer, Integer>>(); private NautHashMap<Player, NautHashMap<Integer, Integer>> _entityMap = new NautHashMap<Player, NautHashMap<Integer, Integer>>();
private NautHashMap<Player, NautHashMap<Integer, String>> _entityNameMap = new NautHashMap<Player, NautHashMap<Integer, String>>();
private NautHashMap<Player, NautHashMap<Integer, Integer>> _entityVehicleMap = new NautHashMap<Player, NautHashMap<Integer, Integer>>();
private NautHashMap<Player, Long> _loggedIn = new NautHashMap<Player, Long>();
private Field _destroyId; private Field _destroyId;
@ -56,6 +63,30 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler
public void playerQuit(PlayerQuitEvent event) public void playerQuit(PlayerQuitEvent event)
{ {
_entityMap.remove(event.getPlayer()); _entityMap.remove(event.getPlayer());
_entityNameMap.remove(event.getPlayer());
_entityVehicleMap.remove(event.getPlayer());
_loggedIn.remove(event.getPlayer());
}
@EventHandler
public void cleanMap(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
return;
for (Iterator<Player> iterator = _loggedIn.keySet().iterator(); iterator.hasNext();)
{
Player player = iterator.next();
if (System.currentTimeMillis() - _loggedIn.get(player) > 5000 && !player.isOnline())
{
iterator.remove();
_entityMap.remove(player);
_entityNameMap.remove(player);
_entityVehicleMap.remove(player);
System.out.println("Found broken player in CustomTagFix.... '" + player.getName() + "'");
}
}
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -68,10 +99,15 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler
Player owner = packetInfo.getPlayer(); Player owner = packetInfo.getPlayer();
PacketVerifier verifier = packetInfo.getVerifier(); PacketVerifier verifier = packetInfo.getVerifier();
if (UtilPlayer.is1_8(owner)) if (owner.isOnline() && UtilPlayer.is1_8(owner))
{ {
if (owner.isOnline() && !_entityMap.containsKey(owner)) if (owner.isOnline() && !_entityMap.containsKey(owner))
{
_entityMap.put(owner, new NautHashMap<Integer, Integer>()); _entityMap.put(owner, new NautHashMap<Integer, Integer>());
_entityNameMap.put(owner, new NautHashMap<Integer, String>());
_entityVehicleMap.put(owner, new NautHashMap<Integer, Integer>());
_loggedIn.put(owner, System.currentTimeMillis());
}
if (packet instanceof PacketPlayOutSpawnEntityLiving) if (packet instanceof PacketPlayOutSpawnEntityLiving)
{ {
@ -85,12 +121,15 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler
for (WatchableObject watchable : (List<WatchableObject>)spawnPacket.l.c()) for (WatchableObject watchable : (List<WatchableObject>)spawnPacket.l.c())
{ {
if ((watchable.a() == 11 || watchable.a() == 3) && watchable.b() instanceof Byte) if ((watchable.a() == 11 || watchable.a() == 3) && watchable.b() instanceof Byte && ((Byte)watchable.b()) == 1)
{ {
final String entityName = spawnPacket.l.getString(10); final String entityName = spawnPacket.l.getString(10);
if (entityName.isEmpty()) if (entityName.isEmpty())
{
_entityNameMap.get(owner).remove(spawnPacket.a);
return; return;
}
if (_entityMap.get(owner).containsKey(spawnPacket.a)) if (_entityMap.get(owner).containsKey(spawnPacket.a))
{ {
@ -100,6 +139,7 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler
int newId = UtilEnt.getNewEntityId(); int newId = UtilEnt.getNewEntityId();
sendProtocolPackets(owner, spawnPacket.a, newId, entityName, verifier); sendProtocolPackets(owner, spawnPacket.a, newId, entityName, verifier);
_entityMap.get(owner).put(spawnPacket.a, newId); _entityMap.get(owner).put(spawnPacket.a, newId);
_entityNameMap.get(owner).put(spawnPacket.a, entityName);
break; break;
} }
@ -112,19 +152,30 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler
if (!_entityMap.get(owner).containsKey(metaPacket.a) && metaPacket.a != 777777) if (!_entityMap.get(owner).containsKey(metaPacket.a) && metaPacket.a != 777777)
{ {
String entityName = ""; String entityName = "";
boolean nameShowing = false;
for (WatchableObject watchable : (List<WatchableObject>)metaPacket.b) for (WatchableObject watchable : (List<WatchableObject>)metaPacket.b)
{ {
if ((watchable.a() == 11 || watchable.a() == 3) && watchable.b() instanceof Byte && ((Byte)watchable.b()) == 1)
{
nameShowing = true;
}
if ((watchable.a() == 10 || watchable.a() == 2) && watchable.b() instanceof String) if ((watchable.a() == 10 || watchable.a() == 2) && watchable.b() instanceof String)
{ {
entityName = (String)watchable.b(); entityName = (String)watchable.b();
} }
} }
if (!entityName.isEmpty()) if (nameShowing && !entityName.isEmpty())
{ {
int newId = UtilEnt.getNewEntityId(); int newId = UtilEnt.getNewEntityId();
sendProtocolPackets(owner, metaPacket.a, newId, entityName, verifier); sendProtocolPackets(owner, metaPacket.a, newId, entityName, verifier);
_entityMap.get(owner).put(metaPacket.a, newId); _entityMap.get(owner).put(metaPacket.a, newId);
_entityNameMap.get(owner).put(metaPacket.a, entityName);
}
else if (!entityName.isEmpty())
{
_entityNameMap.get(owner).remove(metaPacket.a);
} }
} }
} }
@ -138,6 +189,8 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler
{ {
verifier.bypassProcess(new PacketPlayOutEntityDestroy(_entityMap.get(owner).get(id))); verifier.bypassProcess(new PacketPlayOutEntityDestroy(_entityMap.get(owner).get(id)));
_entityMap.get(owner).remove(id); _entityMap.get(owner).remove(id);
_entityVehicleMap.get(owner).remove(id);
_entityNameMap.get(owner).remove(id);
} }
} }
} }
@ -146,19 +199,53 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler
exception.printStackTrace(); exception.printStackTrace();
} }
} }
/*
else if (packet instanceof PacketPlayOutAttachEntity) else if (packet instanceof PacketPlayOutAttachEntity)
{ {
PacketPlayOutAttachEntity attachPacket = (PacketPlayOutAttachEntity)packet; PacketPlayOutAttachEntity attachPacket = (PacketPlayOutAttachEntity)packet;
if (attachPacket.c == owner.getEntityId()) /* TODO dynamic attach handling?
if (attachPacket.c == -1)
{ {
if (_entityVehicleMap.get(owner).containsKey(attachPacket.b) && _entityNameMap.get(owner).containsKey(_entityVehicleMap.get(owner).get(attachPacket.b)))
{
int newId = UtilEnt.getNewEntityId();
sendProtocolPackets(owner, _entityVehicleMap.get(owner).get(attachPacket.b), newId, _entityNameMap.get(owner).get(_entityVehicleMap.get(owner).get(attachPacket.b)), verifier);
_entityMap.get(owner).put(attachPacket.b, newId);
_entityVehicleMap.get(owner).remove(attachPacket.b);
packetInfo.setCancelled(true); packetInfo.setCancelled(true);
//verifier.bypassProcess(new PacketPlayOutEntityDestroy(attachPacket.b)); }
}
else
{
_entityVehicleMap.get(owner).put(attachPacket.b, attachPacket.c);
}
if (_entityMap.get(owner).containsKey(attachPacket.c))
{
verifier.bypassProcess(new PacketPlayOutEntityDestroy(_entityMap.get(owner).get(attachPacket.c)));
_entityMap.get(owner).remove(attachPacket.c);
}
else
*/
/* /*
System.out.println("Adding patch item."); //System.out.println(owner.getName() + " id=" + owner.getEntityId() + " recieving AttachPacket b=" + attachPacket.b + " c=" + attachPacket.c);
if (attachPacket.c == -1 && _entityMap.get(owner).containsKey(attachPacket.b))
{
verifier.bypassProcess(new PacketPlayOutEntityDestroy(_entityMap.get(owner).get(attachPacket.b)));
_entityMap.get(owner).remove(attachPacket.b);
}
else if (attachPacket.c == owner.getEntityId())
{
if (_entityMap.get(owner).containsKey(attachPacket.b))
{
verifier.bypassProcess(new PacketPlayOutEntityDestroy(_entityMap.get(owner).get(attachPacket.b)));
}
PacketPlayOutSpawnEntityLiving armorPacket = new PacketPlayOutSpawnEntityLiving(); PacketPlayOutSpawnEntityLiving armorPacket = new PacketPlayOutSpawnEntityLiving();
armorPacket.a = _fakeIdCounter++; armorPacket.a = UtilEnt.getNewEntityId();
armorPacket.b = (byte) EntityType.SLIME.getTypeId(); armorPacket.b = (byte) 30;
armorPacket.c = (int)EnumEntitySize.SIZE_2.a(100); armorPacket.c = (int)EnumEntitySize.SIZE_2.a(100);
armorPacket.d = (int)MathHelper.floor(64 * 32.0D); armorPacket.d = (int)MathHelper.floor(64 * 32.0D);
armorPacket.e = (int)EnumEntitySize.SIZE_2.a(100); armorPacket.e = (int)EnumEntitySize.SIZE_2.a(100);
@ -230,23 +317,33 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler
armorPacket.l = watcher; armorPacket.l = watcher;
verifier.bypassProcess(packet); // Spawn armor packet
verifier.bypassProcess(armorPacket);
attachPacket.c = armorPacket.a;
PacketPlayOutAttachEntity attachPacket2 = new PacketPlayOutAttachEntity(); PacketPlayOutAttachEntity attachPacket2 = new PacketPlayOutAttachEntity();
attachPacket2.c = owner.getEntityId(); attachPacket2.c = owner.getEntityId();
attachPacket2.b = attachPacket.a; attachPacket2.b = armorPacket.a;
attachPacket2.a = 0; attachPacket2.a = 0;
verifier.bypassProcess(packet);
// Send armor attach to player.
verifier.bypassProcess(attachPacket2);
// Change original packet to attach to armor stand
attachPacket.c = armorPacket.a;
_entityMap.get(owner).put(attachPacket.b, armorPacket.a);
}
}
*/ */
} }
} }
}
}
private void sendProtocolPackets(final Player owner, final int entityId, final int newEntityId, final String entityName, final PacketVerifier packetList) private void sendProtocolPackets(final Player owner, final int entityId, final int newEntityId, String entityName, final PacketVerifier packetList)
{ {
CustomTagEvent event = new CustomTagEvent(owner, entityId, entityName);
_plugin.getServer().getPluginManager().callEvent(event);
final String finalEntityName = event.getCustomName();
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(GetPlugin(), new Runnable() Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(GetPlugin(), new Runnable()
{ {
public void run() public void run()
@ -323,7 +420,7 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler
watcher.watch(10, Byte.valueOf(b1)); watcher.watch(10, Byte.valueOf(b1));
watcher.watch(2, entityName); watcher.watch(2, finalEntityName);
watcher.watch(3, Byte.valueOf((byte)1)); watcher.watch(3, Byte.valueOf((byte)1));
packet.l = watcher; packet.l = watcher;
@ -336,7 +433,24 @@ public class CustomTagFix extends MiniPlugin implements IPacketHandler
vehiclePacket.c = entityId; vehiclePacket.c = entityId;
packetList.bypassProcess(vehiclePacket); packetList.bypassProcess(vehiclePacket);
/* TODO dynamic attach handling?
if (_entityVehicleMap.get(owner).containsValue(entityId))
{
vehiclePacket = new PacketPlayOutAttachEntity();
vehiclePacket.a = 0;
for (Entry<Integer, Integer> entry : _entityVehicleMap.get(owner).entrySet())
{
if (entry.getValue() == entityId)
vehiclePacket.b = entry.getKey();
}
vehiclePacket.c = packet.a;
}
*/
} }
}); });
} }
} }

View File

@ -5,6 +5,10 @@ import java.util.HashSet;
import mineplex.core.account.CoreClientManager; import mineplex.core.account.CoreClientManager;
import mineplex.core.account.event.RetrieveClientInformationEvent; import mineplex.core.account.event.RetrieveClientInformationEvent;
import mineplex.core.common.Rank; import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.NautHashMap;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.inventory.InventoryManager; import mineplex.core.inventory.InventoryManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -19,7 +23,7 @@ public class RankBenefitsGiver9000 extends MiniPlugin
private InventoryManager _inventoryManager; private InventoryManager _inventoryManager;
private RankBenefitsGiver9000Repository _repository; private RankBenefitsGiver9000Repository _repository;
private HashSet<String> _playersNeedingBenefit = new HashSet<String>(); private NautHashMap<String, String> _playersNeedingBenefit = new NautHashMap<String, String>();
public RankBenefitsGiver9000(JavaPlugin plugin, CoreClientManager clientManager, InventoryManager inventoryManager) public RankBenefitsGiver9000(JavaPlugin plugin, CoreClientManager clientManager, InventoryManager inventoryManager)
{ {
@ -34,25 +38,61 @@ public class RankBenefitsGiver9000 extends MiniPlugin
public void loadPlayer(RetrieveClientInformationEvent event) public void loadPlayer(RetrieveClientInformationEvent event)
{ {
boolean treasureUpdate = false; boolean treasureUpdate = false;
boolean horrorUpdate = false;
for (String benefit : _repository.retrievePlayerBenefits(event.getUniqueId().toString())) for (String benefit : _repository.retrievePlayerBenefits(event.getUniqueId().toString()))
{ {
if (benefit.equalsIgnoreCase("TreasureUpdate")) if (benefit.equalsIgnoreCase("TreasureUpdate"))
treasureUpdate = true; treasureUpdate = true;
if (benefit.equalsIgnoreCase("HalloweenHorror"))
horrorUpdate = true;
}
if (!horrorUpdate)
{
_playersNeedingBenefit.put(event.getPlayerName(), "Horror");
} }
if (!treasureUpdate) if (!treasureUpdate)
{ {
_playersNeedingBenefit.add(event.getPlayerName()); _playersNeedingBenefit.put(event.getPlayerName(), "Treasure");
} }
} }
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
public void giveBenefit(final PlayerJoinEvent event) public void giveBenefit(final PlayerJoinEvent event)
{ {
if (!_playersNeedingBenefit.contains(event.getPlayer().getName())) if (!_playersNeedingBenefit.containsKey(event.getPlayer().getName()))
return; return;
if (_playersNeedingBenefit.get(event.getPlayer().getName()).contains("Horror"))
{
_inventoryManager.addItemToInventory(event.getPlayer(), "Treasure", "Treasure Key", 2);
Bukkit.getServer().getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable()
{
public void run()
{
_repository.addBenefit(event.getPlayer().getUniqueId().toString(), "HalloweenHorror");
}
});
Bukkit.getServer().getScheduler().runTaskLater(GetPlugin(), new Runnable()
{
public void run()
{
UtilPlayer.message(event.getPlayer(), C.cPurple + C.Strike + "=============================================");
UtilPlayer.message(event.getPlayer(), "");
UtilPlayer.message(event.getPlayer(), C.cGold + C.Strike + "HAPPY HALLOWEEN");
UtilPlayer.message(event.getPlayer(), "You received 2 Treasure Keys!");
UtilPlayer.message(event.getPlayer(), "");
UtilPlayer.message(event.getPlayer(), C.cPurple + C.Strike + "=============================================");
}
}, 5L);
}
else if (_playersNeedingBenefit.get(event.getPlayer().getName()).contains("Treasure"))
{
if (_clientManager.Get(event.getPlayer()).GetRank() == Rank.ALL) if (_clientManager.Get(event.getPlayer()).GetRank() == Rank.ALL)
{ {
_inventoryManager.addItemToInventory(event.getPlayer(), "Utility", "Treasure Chest", 1); _inventoryManager.addItemToInventory(event.getPlayer(), "Utility", "Treasure Chest", 1);
@ -76,6 +116,7 @@ public class RankBenefitsGiver9000 extends MiniPlugin
_repository.addBenefit(event.getPlayer().getUniqueId().toString(), "TreasureUpdate"); _repository.addBenefit(event.getPlayer().getUniqueId().toString(), "TreasureUpdate");
} }
}); });
}
_playersNeedingBenefit.remove(event.getPlayer().getName()); _playersNeedingBenefit.remove(event.getPlayer().getName());
} }

View File

@ -5,15 +5,17 @@ import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import mineplex.core.database.DBPool;
import mineplex.core.database.RepositoryBase; import mineplex.core.database.RepositoryBase;
import mineplex.core.database.ResultSetCallable; import mineplex.core.database.ResultSetCallable;
import mineplex.core.database.column.ColumnVarChar; import mineplex.core.database.column.ColumnVarChar;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
public class RankBenefitsGiver9000Repository extends RepositoryBase public class RankBenefitsGiver9000Repository extends RepositoryBase
{ {
private static String CREATE_BENEFIT_TABLE = "CREATE TABLE IF NOT EXISTS rankBenefits (id INT NOT NULL AUTO_INCREMENT, uuid VARCHAR(100), benefit VARCHAR(100), PRIMARY KEY (id), INDEX rankUuid (uuid));"; // private static String CREATE_BENEFIT_TABLE = "CREATE TABLE IF NOT EXISTS rankBenefits (id INT NOT NULL AUTO_INCREMENT, uuid VARCHAR(100), benefit VARCHAR(100), PRIMARY KEY (id), INDEX rankUuid (uuid));";
private static String INSERT_BENEFIT = "INSERT INTO rankBenefits (uuid, benefit) VALUES (?, ?);"; private static String INSERT_BENEFIT = "INSERT INTO rankBenefits (uuid, benefit) VALUES (?, ?);";
private static String RETRIEVE_BENEFITS = "SELECT benefit FROM rankBenefits WHERE uuid = ?;"; private static String RETRIEVE_BENEFITS = "SELECT benefit FROM rankBenefits WHERE uuid = ?;";
@ -26,7 +28,7 @@ public class RankBenefitsGiver9000Repository extends RepositoryBase
@Override @Override
protected void initialize() protected void initialize()
{ {
executeUpdate(CREATE_BENEFIT_TABLE); // executeUpdate(CREATE_BENEFIT_TABLE);
} }
@Override @Override

View File

@ -0,0 +1,79 @@
package mineplex.core;
import java.util.Iterator;
import java.util.Map.Entry;
import mineplex.core.common.util.NautHashMap;
import mineplex.core.packethandler.IPacketHandler;
import mineplex.core.packethandler.PacketHandler;
import mineplex.core.packethandler.PacketInfo;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
public class Replay extends MiniPlugin implements IPacketHandler
{
private NautHashMap<PacketInfo, Long> _packetList = new NautHashMap<PacketInfo, Long>();
private long _startTime = 0;
private long _replayTime = 0;
private boolean _replay = false;
private long _speed = 20;
public Replay(JavaPlugin plugin, PacketHandler packetHandler)
{
super("Replay", plugin);
}
@EventHandler
public void interact(PlayerInteractEvent event)
{
if (event.getItem().getType() == Material.WEB)
{
event.getPlayer().setItemInHand(new ItemStack(Material.STICK, 1));
_replay = true;
_replayTime = System.currentTimeMillis();
}
}
@EventHandler
public void replay(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK || !_replay)
return;
for (Iterator<Entry<PacketInfo, Long>> entryIterator = _packetList.entrySet().iterator(); entryIterator.hasNext();)
{
Entry<PacketInfo, Long> entry = entryIterator.next();
if ((System.currentTimeMillis() + _speed) - _replayTime > entry.getValue())
{
entry.getKey().getVerifier().bypassProcess(entry.getKey().getPacket());
entryIterator.remove();
}
}
}
@SuppressWarnings("unchecked")
public void handle(PacketInfo packetInfo)
{
if (_replay)
{
packetInfo.setCancelled(true);
return;
}
if (_startTime == 0)
_startTime = System.currentTimeMillis();
_packetList.put(packetInfo, System.currentTimeMillis() - _startTime);
// write out packets?
if (packetInfo.isCancelled())
return;
}
}

View File

@ -1,5 +1,7 @@
package mineplex.core.account; package mineplex.core.account;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -13,7 +15,6 @@ import mineplex.core.account.event.ClientUnloadEvent;
import mineplex.core.account.event.ClientWebResponseEvent; import mineplex.core.account.event.ClientWebResponseEvent;
import mineplex.core.account.event.RetrieveClientInformationEvent; import mineplex.core.account.event.RetrieveClientInformationEvent;
import mineplex.core.account.repository.AccountRepository; import mineplex.core.account.repository.AccountRepository;
import mineplex.core.account.repository.MysqlAccountRepository;
import mineplex.core.account.repository.token.ClientToken; import mineplex.core.account.repository.token.ClientToken;
import mineplex.core.common.Rank; import mineplex.core.common.Rank;
import mineplex.core.common.util.Callback; import mineplex.core.common.util.Callback;
@ -42,19 +43,19 @@ public class CoreClientManager extends MiniPlugin
{ {
private JavaPlugin _plugin; private JavaPlugin _plugin;
private AccountRepository _repository; private AccountRepository _repository;
private MysqlAccountRepository _mysqlRepository;
private NautHashMap<String, CoreClient> _clientList; private NautHashMap<String, CoreClient> _clientList;
private HashSet<String> _duplicateLoginGlitchPreventionList; private HashSet<String> _duplicateLoginGlitchPreventionList;
private Object _clientLock = new Object(); private Object _clientLock = new Object();
private static int _connectingClients = 0;
public CoreClientManager(JavaPlugin plugin, String webServer) public CoreClientManager(JavaPlugin plugin, String webServer)
{ {
super("Client Manager", plugin); super("Client Manager", plugin);
_plugin = plugin; _plugin = plugin;
_repository = new AccountRepository(webServer); _repository = new AccountRepository(plugin, webServer);
_mysqlRepository = new MysqlAccountRepository(plugin);
_clientList = new NautHashMap<String, CoreClient>(); _clientList = new NautHashMap<String, CoreClient>();
_duplicateLoginGlitchPreventionList = new HashSet<String>(); _duplicateLoginGlitchPreventionList = new HashSet<String>();
} }
@ -123,6 +124,20 @@ public class CoreClientManager extends MiniPlugin
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
public void AsyncLogin(AsyncPlayerPreLoginEvent event) public void AsyncLogin(AsyncPlayerPreLoginEvent event)
{ {
while (_connectingClients >= 5)
{
try
{
Thread.sleep(25);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
_connectingClients++;
try try
{ {
LoadClient(Add(event.getName()), event.getUniqueId(), event.getAddress().getHostAddress()); LoadClient(Add(event.getName()), event.getUniqueId(), event.getAddress().getHostAddress());
@ -135,6 +150,10 @@ public class CoreClientManager extends MiniPlugin
System.out.println(exception.getMessage()); System.out.println(exception.getMessage());
} }
finally
{
_connectingClients--;
}
if (Bukkit.hasWhitelist() && !Get(event.getName()).GetRank().Has(Rank.MODERATOR)) if (Bukkit.hasWhitelist() && !Get(event.getName()).GetRank().Has(Rank.MODERATOR))
{ {
@ -175,7 +194,7 @@ public class CoreClientManager extends MiniPlugin
{ {
public void run() public void run()
{ {
_mysqlRepository.login(uuid.toString(), client.GetPlayerName()); _repository.login(uuid.toString(), client.GetPlayerName());
Bukkit.getServer().getPluginManager().callEvent(clientInformationEvent); Bukkit.getServer().getPluginManager().callEvent(clientInformationEvent);
clientInformationEvent.decreaseProcessingCount(); clientInformationEvent.decreaseProcessingCount();
@ -183,7 +202,7 @@ public class CoreClientManager extends MiniPlugin
}); });
// JSON sql response // JSON sql response
Bukkit.getServer().getPluginManager().callEvent(new ClientWebResponseEvent(response)); Bukkit.getServer().getPluginManager().callEvent(new ClientWebResponseEvent(response, uuid));
// Load client in miniplugins // Load client in miniplugins
Bukkit.getServer().getPluginManager().callEvent(new AsyncClientLoadEvent(token, client)); Bukkit.getServer().getPluginManager().callEvent(new AsyncClientLoadEvent(token, client));
@ -225,7 +244,7 @@ public class CoreClientManager extends MiniPlugin
{ {
public void run() public void run()
{ {
_mysqlRepository.login(uuid.toString(), client.GetPlayerName()); _repository.login(uuid.toString(), client.GetPlayerName());
Bukkit.getServer().getPluginManager().callEvent(clientInformationEvent); Bukkit.getServer().getPluginManager().callEvent(clientInformationEvent);
} }
@ -237,8 +256,10 @@ public class CoreClientManager extends MiniPlugin
client.SetAccountId(token.AccountId); client.SetAccountId(token.AccountId);
client.SetRank(Rank.valueOf(token.Rank)); client.SetRank(Rank.valueOf(token.Rank));
_repository.updateMysqlRank(uuid.toString(), token.Rank, token.RankPerm, new Timestamp(Date.parse(token.RankExpire)).toString());
// JSON sql response // JSON sql response
Bukkit.getServer().getPluginManager().callEvent(new ClientWebResponseEvent(response)); Bukkit.getServer().getPluginManager().callEvent(new ClientWebResponseEvent(response, uuid));
// Load client in miniplugins // Load client in miniplugins
Bukkit.getServer().getPluginManager().callEvent(new AsyncClientLoadEvent(token, client)); Bukkit.getServer().getPluginManager().callEvent(new AsyncClientLoadEvent(token, client));
@ -322,7 +343,7 @@ public class CoreClientManager extends MiniPlugin
public void SaveRank(final String name, Rank rank, boolean perm) public void SaveRank(final String name, Rank rank, boolean perm)
{ {
_repository.SaveRank(new Callback<Rank>() _repository.saveRank(new Callback<Rank>()
{ {
public void run(Rank newRank) public void run(Rank newRank)
{ {

View File

@ -86,7 +86,7 @@ public class UpdateRank extends CommandBase<CoreClientManager>
return; return;
} }
Plugin.getRepository().SaveRank(new Callback<Rank>() Plugin.getRepository().saveRank(new Callback<Rank>()
{ {
public void run(Rank rank) public void run(Rank rank)
{ {

View File

@ -1,5 +1,7 @@
package mineplex.core.account.event; package mineplex.core.account.event;
import java.util.UUID;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
@ -8,10 +10,12 @@ public class ClientWebResponseEvent extends Event
private static final HandlerList handlers = new HandlerList(); private static final HandlerList handlers = new HandlerList();
private String _response; private String _response;
private UUID _uuid;
public ClientWebResponseEvent(String response) public ClientWebResponseEvent(String response, UUID uuid)
{ {
_response = response; _response = response;
_uuid = uuid;
} }
public String GetResponse() public String GetResponse()
@ -28,4 +32,9 @@ public class ClientWebResponseEvent extends Event
{ {
return handlers; return handlers;
} }
public UUID getUniqueId()
{
return _uuid;
}
} }

View File

@ -1,26 +1,58 @@
package mineplex.core.account.repository; package mineplex.core.account.repository;
import java.sql.Timestamp;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import org.bukkit.craftbukkit.libs.com.google.gson.reflect.TypeToken; import org.bukkit.craftbukkit.libs.com.google.gson.reflect.TypeToken;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.account.repository.token.LoginToken; import mineplex.core.account.repository.token.LoginToken;
import mineplex.core.account.repository.token.RankUpdateToken; import mineplex.core.account.repository.token.RankUpdateToken;
import mineplex.core.common.Rank; import mineplex.core.common.Rank;
import mineplex.core.common.util.Callback; import mineplex.core.common.util.Callback;
import mineplex.core.server.remotecall.AsyncJsonWebCall; import mineplex.core.common.util.UUIDFetcher;
import mineplex.core.database.DatabaseRunnable;
import mineplex.core.database.RepositoryBase;
import mineplex.core.database.column.ColumnBoolean;
import mineplex.core.database.column.ColumnTimestamp;
import mineplex.core.database.column.ColumnVarChar;
import mineplex.core.server.remotecall.JsonWebCall; import mineplex.core.server.remotecall.JsonWebCall;
public class AccountRepository public class AccountRepository extends RepositoryBase
{ {
private static String CREATE_ACCOUNT_TABLE = "CREATE TABLE IF NOT EXISTS accounts (id INT NOT NULL AUTO_INCREMENT, uuid VARCHAR(100), name VARCHAR(40), gems INT, rank VARCHAR(40), rankPerm BOOL, rankExpire LONG, lastLogin LONG, totalPlayTime LONG, PRIMARY KEY (id), UNIQUE INDEX uuidIndex (uuid), UNIQUE INDEX nameIndex (name), INDEX rankIndex (rank));";
private static String ACCOUNT_LOGIN_NEW = "INSERT INTO accounts (uuid, name, lastLogin) values(?, ?, now()) ON DUPLICATE KEY UPDATE name=VALUES(name), lastLogin=VALUES(lastLogin);";
private static String ACCOUNT_LOGIN_UPDATE = "UPDATE accounts SET uuid=?, name=?, lastLogin=now() WHERE uuid = ?;";
private static String UPDATE_ACCOUNT_RANK = "UPDATE accounts SET rank=?, rankPerm=false, rankExpire=now() + INTERVAL 1 MONTH WHERE uuid = ?;";
private static String UPDATE_ACCOUNT_RANK_DONOR = "UPDATE accounts SET rank=?, donorRank=?, rankPerm=false, rankExpire=now() + INTERVAL 1 MONTH WHERE uuid = ?;";
private static String UPDATE_ACCOUNT_RANK_PERM = "UPDATE accounts SET rank=?, rankPerm=true WHERE uuid = ?;";
private static String UPDATE_ACCOUNT_RANK_DONOR_PERM = "UPDATE accounts SET rank=?, donorRank=?, rankPerm=true WHERE uuid = ?;";
private static String UPDATE_ACCOUNT_NULL_RANK = "UPDATE accounts SET rank=?, donorRank=?, rankPerm=?, rankExpire=? WHERE uuid = ? AND rank IS NULL;";
private String _webAddress; private String _webAddress;
public AccountRepository(String webAddress) public AccountRepository(JavaPlugin plugin, String webAddress)
{ {
super(plugin, "jdbc:mysql://db.mineplex.com:3306/Account?autoReconnect=true&failOverReadOnly=false&maxReconnects=10", "root", "tAbechAk3wR7tuTh");
_webAddress = webAddress; _webAddress = webAddress;
} }
@Override
protected void initialize()
{
executeUpdate(CREATE_ACCOUNT_TABLE);
}
public void login(String uuid, String name)
{
int affectedRows = executeUpdate(ACCOUNT_LOGIN_UPDATE, new ColumnVarChar("uuid", 100, uuid), new ColumnVarChar("name", 40, name), new ColumnVarChar("uuid", 100, uuid));
if (affectedRows == 0)
executeUpdate(ACCOUNT_LOGIN_NEW, new ColumnVarChar("uuid", 100, uuid), new ColumnVarChar("name", 40, name));
}
public String GetClient(String name, UUID uuid, String ipAddress) public String GetClient(String name, UUID uuid, String ipAddress)
{ {
LoginToken token = new LoginToken(); LoginToken token = new LoginToken();
@ -36,14 +68,44 @@ public class AccountRepository
return new JsonWebCall(_webAddress + "PlayerAccount/GetAccountByUUID").ExecuteReturnStream(uuid.toString()); return new JsonWebCall(_webAddress + "PlayerAccount/GetAccountByUUID").ExecuteReturnStream(uuid.toString());
} }
public void SaveRank(Callback<Rank> callback, String name, Rank rank, boolean perm) public void saveRank(final Callback<Rank> callback, final String name, final Rank rank, final boolean perm)
{ {
RankUpdateToken token = new RankUpdateToken(); final RankUpdateToken token = new RankUpdateToken();
token.Name = name; token.Name = name;
token.Rank = rank.toString(); token.Rank = rank.toString();
token.Perm = perm; token.Perm = perm;
new AsyncJsonWebCall(_webAddress + "PlayerAccount/RankUpdate").Execute(Rank.class, callback, token); final Callback<Rank> extraCallback = new Callback<Rank>()
{
public void run(Rank response)
{
if (rank == Rank.ULTRA || rank == Rank.HERO)
{
if (perm)
executeUpdate(UPDATE_ACCOUNT_RANK_DONOR_PERM, new ColumnVarChar("rank", 100, rank.toString()), new ColumnVarChar("donorRank", 100, rank.toString()), new ColumnVarChar("uuid", 100, UUIDFetcher.getUUIDOf(name).toString()));
else
executeUpdate(UPDATE_ACCOUNT_RANK_DONOR, new ColumnVarChar("rank", 100, rank.toString()), new ColumnVarChar("donorRank", 100, rank.toString()), new ColumnVarChar("uuid", 100, UUIDFetcher.getUUIDOf(name).toString()));
}
else
{
if (perm)
executeUpdate(UPDATE_ACCOUNT_RANK_PERM, new ColumnVarChar("rank", 100, rank.toString()), new ColumnVarChar("uuid", 100, UUIDFetcher.getUUIDOf(name).toString()));
else
executeUpdate(UPDATE_ACCOUNT_RANK, new ColumnVarChar("rank", 100, rank.toString()), new ColumnVarChar("uuid", 100, UUIDFetcher.getUUIDOf(name).toString()));
}
callback.run(response);
}
};
handleDatabaseCall(new DatabaseRunnable(new Runnable()
{
public void run()
{
new JsonWebCall(_webAddress + "PlayerAccount/RankUpdate").Execute(Rank.class, extraCallback, token);
}
}), "Error saving player " + token.Name + "'s rank in AccountRepository : ");
} }
public void MatchPlayerName(final Callback<List<String>> callback, final String userName) public void MatchPlayerName(final Callback<List<String>> callback, final String userName)
@ -59,4 +121,20 @@ public class AccountRepository
asyncThread.start(); asyncThread.start();
} }
@Override
protected void update()
{
}
public void updateMysqlRank(final String uuid, final String rank, final boolean perm, final String rankExpire)
{
handleDatabaseCall(new DatabaseRunnable(new Runnable()
{
public void run()
{
executeUpdate(UPDATE_ACCOUNT_NULL_RANK, new ColumnVarChar("rank", 100, rank), new ColumnVarChar("donorRank", 100, rank), new ColumnBoolean("rankPerm", perm), new ColumnTimestamp("rankExpire", Timestamp.valueOf(rankExpire)), new ColumnVarChar("uuid", 100, uuid));
}
}), "Error updating player's mysql rank AccountRepository : ");
}
} }

View File

@ -1,38 +0,0 @@
package mineplex.core.account.repository;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.database.RepositoryBase;
import mineplex.core.database.column.ColumnVarChar;
public class MysqlAccountRepository extends RepositoryBase
{
private static String CREATE_ACCOUNT_TABLE = "CREATE TABLE IF NOT EXISTS accounts (id INT NOT NULL AUTO_INCREMENT, uuid VARCHAR(100), name VARCHAR(40), gems INT, rank VARCHAR(40), rankPerm BOOL, rankExpire LONG, lastLogin LONG, totalPlayTime LONG, PRIMARY KEY (id), UNIQUE INDEX uuidIndex (uuid), UNIQUE INDEX nameIndex (name), INDEX rankIndex (rank));";
private static String ACCOUNT_LOGIN_NEW = "INSERT INTO accounts (uuid, name, lastLogin) values(?, ?, now()) ON DUPLICATE KEY UPDATE name=VALUES(name), lastLogin=VALUES(lastLogin);";
private static String ACCOUNT_LOGIN_UPDATE = "UPDATE accounts SET uuid=?, name=?, lastLogin=now() WHERE uuid = ?;";
public MysqlAccountRepository(JavaPlugin plugin)
{
super(plugin, "jdbc:mysql://db.mineplex.com:3306/Account?autoReconnect=true&failOverReadOnly=false&maxReconnects=10", "root", "tAbechAk3wR7tuTh");
}
@Override
protected void initialize()
{
executeUpdate(CREATE_ACCOUNT_TABLE);
}
@Override
protected void update() { }
public void login(String uuid, String name)
{
int affectedRows = executeUpdate(ACCOUNT_LOGIN_UPDATE, new ColumnVarChar("uuid", 100, uuid), new ColumnVarChar("name", 40, name), new ColumnVarChar("uuid", 100, uuid));
if (affectedRows == 0)
{
executeUpdate(ACCOUNT_LOGIN_NEW, new ColumnVarChar("uuid", 100, uuid), new ColumnVarChar("name", 40, name));
System.out.println("Executed LOGIN_NEW");
}
}
}

View File

@ -5,6 +5,8 @@ public class ClientToken
public int AccountId; public int AccountId;
public String Name; public String Name;
public String Rank; public String Rank;
public boolean RankPerm;
public String RankExpire;
public int EconomyBalance; public int EconomyBalance;
public AccountToken AccountToken; public AccountToken AccountToken;

View File

@ -1,475 +1,576 @@
package mineplex.core.achievement; package mineplex.core.achievement;
import mineplex.core.common.util.C;
public enum Achievement public enum Achievement
{ {
GLOBAL_MINEPLEX_LEVEL("Mineplex Level", 20000,
new String[]{"Global.ExpEarned"},
new String[]{"Level up by doing well in games!"},
getExperienceLevels(),
AchievementCategory.GLOBAL),
GLOBAL_GEM_HUNTER("Gem Hunter", 10000, GLOBAL_GEM_HUNTER("Gem Hunter", 10000,
new String[] {"Global.GemsEarned"}, new String[]{"Global.GemsEarned"},
new String[] {"+1 for every Gem earned in any game."}, new String[]{"+1 for every Gem earned in any game."},
new int[] {10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 55000, 60000, 65000}, new int[]{10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 55000, 60000, 65000},
AchievementCategory.GLOBAL), AchievementCategory.GLOBAL),
//Bridges //Bridges
BRIDGES_WINS("Bridge Champion", 600, BRIDGES_WINS("Bridge Champion", 600,
new String[] {"The Bridges.Wins"}, new String[]{"The Bridges.Wins"},
new String[] {"Win 50 games of The Bridges"}, new String[]{"Win 30 games of The Bridges"},
new int[] {50}, new int[]{30},
AchievementCategory.BRIDGES), AchievementCategory.BRIDGES),
BRIDGES_FOOD("Food for the Masses", 600, BRIDGES_FOOD("Food for the Masses", 600,
new String[] {"The Bridges.FoodForTheMasses"}, new String[]{"The Bridges.FoodForTheMasses"},
new String[] {"Get 20 kills with Apples"}, new String[]{"Get 20 kills with Apples"},
new int[] {20}, new int[]{20},
AchievementCategory.BRIDGES), AchievementCategory.BRIDGES),
BRIDGES_SNIPER("Sniper", 600, BRIDGES_SNIPER("Sniper", 600,
new String[] {"The Bridges.Sniper"}, new String[]{"The Bridges.Sniper"},
new String[] {"Kill an enemy with Archery before Bridges fall"}, new String[]{"Kill an enemy with Archery before Bridges fall"},
new int[] {1}, new int[]{1},
AchievementCategory.BRIDGES), AchievementCategory.BRIDGES),
BRIDGES_FORTUNE_BOMBER("Fortune Bomber", 600, BRIDGES_FORTUNE_BOMBER("Fortune Bomber", 600,
new String[] {"The Bridges.FortuneBomber"}, new String[]{"The Bridges.FortuneBomber"},
new String[] {"Mine 30 Diamond Ore using TNT"}, new String[]{"Mine 30 Diamond Ore using TNT"},
new int[] {30}, new int[]{30},
AchievementCategory.BRIDGES), AchievementCategory.BRIDGES),
BRIDGES_RAMPAGE("Rampage", 1200, BRIDGES_RAMPAGE("Rampage", 1200,
new String[] {"The Bridges.Rampage"}, new String[]{"The Bridges.Rampage"},
new String[] {"Get 4 kills in a row, with no more than", "10 seconds between each kill"}, new String[]{"Get 4 kills in a row, with no more than", "10 seconds between each kill"},
new int[] {1}, new int[]{1},
AchievementCategory.BRIDGES), AchievementCategory.BRIDGES),
BRIDGES_DEATH_BOMBER("Death Bomber", 1000, BRIDGES_DEATH_BOMBER("Death Bomber", 1000,
new String[] {"The Bridges.DeathBomber"}, new String[]{"The Bridges.DeathBomber"},
new String[] {"Get 5 Kills in a single game with TNT"}, new String[]{"Get 5 kills in a single game with TNT"},
new int[] {1}, new int[]{1},
AchievementCategory.BRIDGES), AchievementCategory.BRIDGES),
//Survival Games //Survival Games
SURVIVAL_GAMES_WINS("Katniss Everdeen", 600, SURVIVAL_GAMES_WINS("Katniss Everdeen", 600,
new String[] {"Survival Games.Wins"}, new String[]{"Survival Games.Wins"},
new String[] {"Win 50 games of Survival Games"}, new String[]{"Win 30 games of Survival Games"},
new int[] {50}, new int[]{30},
AchievementCategory.SURVIVAL_GAMES), AchievementCategory.SURVIVAL_GAMES),
SURVIVAL_GAMES_LIGHT_WEIGHT("Light Weight", 1000, SURVIVAL_GAMES_LIGHT_WEIGHT("Light Weight", 1000,
new String[] {"Survival Games.NoArmor"}, new String[]{"Survival Games.NoArmor"},
new String[] {"Win a game without wearing any armor"}, new String[]{"Win a game without wearing any armor"},
new int[] {1}, new int[]{1},
AchievementCategory.SURVIVAL_GAMES), AchievementCategory.SURVIVAL_GAMES),
SURVIVAL_GAMES_BLOODLUST("Bloodlust", 1200, SURVIVAL_GAMES_BLOODLUST("Bloodlust", 1200,
new String[] {"Survival Games.Bloodlust"}, new String[]{"Survival Games.Bloodlust"},
new String[] {"Kill 3 other players in the first minute"}, new String[]{"Kill 3 other players in the first minute"},
new int[] {1}, new int[]{1},
AchievementCategory.SURVIVAL_GAMES), AchievementCategory.SURVIVAL_GAMES),
SURVIVAL_GAMES_LOOT("Loot Hoarder", 600, SURVIVAL_GAMES_LOOT("Loot Hoarder", 600,
new String[] {"Survival Games.SupplyDropsOpened"}, new String[]{"Survival Games.SupplyDropsOpened"},
new String[] {"Be the first to open 50 Supply Drops"}, new String[]{"Be the first to open 50 Supply Drops"},
new int[] {50}, new int[]{50},
AchievementCategory.SURVIVAL_GAMES), AchievementCategory.SURVIVAL_GAMES),
SURVIVAL_GAMES_SKELETONS("Skeletal Army", 1000, SURVIVAL_GAMES_SKELETONS("Skeletal Army", 1000,
new String[] {"Survival Games.Skeletons"}, new String[]{"Survival Games.Skeletons"},
new String[] {"Have 5 Necromanced Skeletons alive"}, new String[]{"Have 5 Necromanced Skeletons alive"},
new int[] {1}, new int[]{1},
AchievementCategory.SURVIVAL_GAMES), AchievementCategory.SURVIVAL_GAMES),
//Survival Games //Survival Games
UHC_WINS("Ultimate Winner", 600, UHC_WINS("Ultimate Winner", 600,
new String[] {"Ultra Hardcore.Wins"}, new String[]{"Ultra Hardcore.Wins"},
new String[] {"Win 20 games of Ultra Hardcore"}, new String[]{"Win 10 games of Ultra Hardcore"},
new int[] {20}, new int[]{10},
AchievementCategory.UHC), AchievementCategory.UHC),
//Smash Mobs //Smash Mobs
SMASH_MOBS_WINS("SO SUPER!", 600, SMASH_MOBS_WINS("SO SUPER!", 600,
new String[] {"Super Smash Mobs.Wins"}, new String[]{"Super Smash Mobs.Wins"},
new String[] {"Win 100 games of Super Smash Mobs"}, new String[]{"Win 100 games of Super Smash Mobs"},
new int[] {100}, new int[]{100},
AchievementCategory.SMASH_MOBS), AchievementCategory.SMASH_MOBS),
SMASH_MOBS_MLG_PRO("MLG Pro", 1200, SMASH_MOBS_MLG_PRO("MLG Pro", 1200,
new String[] {"Super Smash Mobs.MLGPro"}, new String[]{"Super Smash Mobs.MLGPro"},
new String[] {"Win a game without dying"}, new String[]{"Win a game without dying"},
new int[] {1}, new int[]{1},
AchievementCategory.SMASH_MOBS), AchievementCategory.SMASH_MOBS),
SMASH_MOBS_FREE_KITS("Free Kits Forever", 800, SMASH_MOBS_FREE_KITS("Free Kits Forever", 800,
new String[] {"Super Smash Mobs.FreeKitsForever"}, new String[]{"Super Smash Mobs.FreeKitsForever"},
new String[] {"Win 100 games using only Free Kits"}, new String[]{"Win 100 games using only Free Kits"},
new int[] {100}, new int[]{100},
AchievementCategory.SMASH_MOBS), AchievementCategory.SMASH_MOBS),
SMASH_MOBS_1V3("1v3", 2000, SMASH_MOBS_1V3("1v3", 2000,
new String[] {"Super Smash Mobs.1v3"}, new String[]{"Super Smash Mobs.1v3"},
new String[] {"Get 10 kills in a game with 4 players"}, new String[]{"Get 10 kills in a game with 4 players"},
new int[] {1}, new int[]{1},
AchievementCategory.SMASH_MOBS), AchievementCategory.SMASH_MOBS),
SMASH_MOBS_TRIPLE_KILL("Triple Kill", 1200, SMASH_MOBS_TRIPLE_KILL("Triple Kill", 1200,
new String[] {"Super Smash Mobs.TripleKill"}, new String[]{"Super Smash Mobs.TripleKill"},
new String[] {"Get 3 kills in a row, with no more than", "10 seconds between each kill"}, new String[]{"Get 3 kills in a row, with no more than", "10 seconds between each kill"},
new int[] {1}, new int[]{1},
AchievementCategory.SMASH_MOBS), AchievementCategory.SMASH_MOBS),
SMASH_MOBS_RECOVERY_MASTER("Recovery Master", 800, SMASH_MOBS_RECOVERY_MASTER("Recovery Master", 800,
new String[] {"Super Smash Mobs.RecoveryMaster"}, new String[]{"Super Smash Mobs.RecoveryMaster"},
new String[] {"Take 200 damage in a single life"}, new String[]{"Take 200 damage in a single life"},
new int[] {1}, new int[]{1},
AchievementCategory.SMASH_MOBS), AchievementCategory.SMASH_MOBS),
//Block Hunt //Block Hunt
BLOCK_HUNT_WINS("The Blockiest Block", 600, BLOCK_HUNT_WINS("The Blockiest Block", 600,
new String[] {"Block Hunt.Wins"}, new String[]{"Block Hunt.Wins"},
new String[] {"Win 50 games of Block Hunt"}, new String[]{"Win 50 games of Block Hunt"},
new int[] {50}, new int[]{50},
AchievementCategory.BLOCK_HUNT), AchievementCategory.BLOCK_HUNT),
BLOCK_HUNT_HUNTER_KILLER("Hunter Killer", 1200, BLOCK_HUNT_HUNTER_KILLER("Hunter Killer", 1200,
new String[] {"Block Hunt.HunterKiller"}, new String[]{"Block Hunt.HunterKiller"},
new String[] {"Kill 10 Hunters in a single game"}, new String[]{"Kill 10 Hunters in a single game"},
new int[] {1}, new int[]{1},
AchievementCategory.BLOCK_HUNT), AchievementCategory.BLOCK_HUNT),
BLOCK_HUNT_MEOW("Meow Meow Meow Meow", 800, BLOCK_HUNT_MEOW("Meow Meow Meow Meow", 800,
new String[] {"Block Hunt.Meow"}, new String[]{"Block Hunt.Meow"},
new String[] {"Meow 50 times in a single game"}, new String[]{"Meow 50 times in a single game"},
new int[] {1}, new int[]{1},
AchievementCategory.BLOCK_HUNT), AchievementCategory.BLOCK_HUNT),
BLOCK_HUNT_HUNTER_OF_THE_YEAR("Hunter of the Year", 1200, BLOCK_HUNT_HUNTER_OF_THE_YEAR("Hunter of the Year", 1200,
new String[] {"Block Hunt.HunterOfTheYear"}, new String[]{"Block Hunt.HunterOfTheYear"},
new String[] {"Kill 7 Hiders in a single game"}, new String[]{"Kill 7 Hiders in a single game"},
new int[] {1}, new int[]{1},
AchievementCategory.BLOCK_HUNT), AchievementCategory.BLOCK_HUNT),
BLOCK_HUNT_BAD_HIDER("Bad Hider", 1000, BLOCK_HUNT_BAD_HIDER("Bad Hider", 1000,
new String[] {"Block Hunt.BadHider"}, new String[]{"Block Hunt.BadHider"},
new String[] {"Win as Hider without disguising"}, new String[]{"Win as Hider without disguising"},
new int[] {1}, new int[]{1},
AchievementCategory.BLOCK_HUNT), AchievementCategory.BLOCK_HUNT),
//Draw My Thing //Draw My Thing
DRAW_MY_THING_WINS("Art Hipster", 600, DRAW_MY_THING_WINS("Art Hipster", 600,
new String[] {"Draw My Thing.Wins"}, new String[]{"Draw My Thing.Wins"},
new String[] {"Win 50 games of Draw My Thing"}, new String[]{"Win 50 games of Draw My Thing"},
new int[] {50}, new int[]{50},
AchievementCategory.DRAW_MY_THING), AchievementCategory.DRAW_MY_THING),
DRAW_MY_THING_MR_SQUIGGLE("Mr. Squiggle", 800, DRAW_MY_THING_MR_SQUIGGLE("Mr. Squiggle", 800,
new String[] {"Draw My Thing.MrSquiggle"}, new String[]{"Draw My Thing.MrSquiggle"},
new String[] {"Both your drawings are guessed", "within the first 15 seconds."}, new String[]{"Both your drawings are guessed", "within the first 15 seconds."},
new int[] {1}, new int[]{1},
AchievementCategory.DRAW_MY_THING), AchievementCategory.DRAW_MY_THING),
DRAW_MY_THING_KEEN_EYE("Keen Eye", 1200, DRAW_MY_THING_KEEN_EYE("Keen Eye", 1200,
new String[] {"Draw My Thing.KeenEye"}, new String[]{"Draw My Thing.KeenEye"},
new String[] {"Guess every single drawing in a game"}, new String[]{"Guess every single drawing in a game"},
new int[] {1}, new int[]{1},
AchievementCategory.DRAW_MY_THING), AchievementCategory.DRAW_MY_THING),
DRAW_MY_THING_PURE_LUCK("Pure Luck", 800, DRAW_MY_THING_PURE_LUCK("Pure Luck", 800,
new String[] {"Draw My Thing.PureLuck"}, new String[]{"Draw My Thing.PureLuck"},
new String[] {"Guess a word in the first 5 seconds"}, new String[]{"Guess a word in the first 8 seconds"},
new int[] {1}, new int[]{1},
AchievementCategory.DRAW_MY_THING), AchievementCategory.DRAW_MY_THING),
//Castle Siege //Castle Siege
CASTLE_SIEGE_WINS("FOR THE KING!", 600, CASTLE_SIEGE_WINS("FOR THE KING!", 600,
new String[] {"Castle Siege.ForTheKing"}, new String[]{"Castle Siege.ForTheKing"},
new String[] {"Win as Defenders 50 times"}, new String[]{"Win as Defenders 50 times"},
new int[] {50}, new int[]{50},
AchievementCategory.CASTLE_SIEGE), AchievementCategory.CASTLE_SIEGE),
CASTLE_SIEGE_KINGSLAYER("Kingslayer", 800, CASTLE_SIEGE_KINGSLAYER("Kingslayer", 800,
new String[] {"Castle Siege.KingSlayer"}, new String[]{"Castle Siege.KingSlayer"},
new String[] {"Get the killing blow on the King"}, new String[]{"Get the killing blow on the King"},
new int[] {1}, new int[]{1},
AchievementCategory.CASTLE_SIEGE), AchievementCategory.CASTLE_SIEGE),
CASTLE_SIEGE_BLOOD_THIRSTY("Blood Thirsty", 1200, CASTLE_SIEGE_BLOOD_THIRSTY("Blood Thirsty", 1200,
new String[] {"Castle Siege.BloodThirsty"}, new String[]{"Castle Siege.BloodThirsty"},
new String[] {"Kill 50 Undead in a single game"}, new String[]{"Kill 50 Undead in a single game"},
new int[] {1}, new int[]{1},
AchievementCategory.CASTLE_SIEGE), AchievementCategory.CASTLE_SIEGE),
CASTLE_SIEGE_ASSASSIN("Assassin", 1000, CASTLE_SIEGE_ASSASSIN("Assassin", 1000,
new String[] {"Castle Siege.Assassin"}, new String[]{"Castle Siege.Assassin"},
new String[] {"Do 50% or more of the damage to the king"}, new String[]{"Do 50% or more of the damage to the king"},
new int[] {1}, new int[]{1},
AchievementCategory.CASTLE_SIEGE), AchievementCategory.CASTLE_SIEGE),
//Champions //Champions
CHAMPIONS_WINS("Champion", 600, CHAMPIONS_WINS("Champion", 600,
new String[] {"Champions Domination.Wins", "Champions TDM.Wins"}, new String[]{"Champions Domination.Wins", "Champions TDM.Wins"},
new String[] {"Win 80 games of Dominate or TDM"}, new String[]{"Win 80 games of Dominate or TDM"},
new int[] {80}, new int[]{80},
AchievementCategory.CHAMPIONS), AchievementCategory.CHAMPIONS),
CHAMPIONS_FLAWLESS_VICTORY("Flawless Victory", 800, CHAMPIONS_FLAWLESS_VICTORY("Flawless Victory", 800,
new String[] {"Champions TDM.FlawlessVictory"}, new String[]{"Champions TDM.FlawlessVictory"},
new String[] {"Win TDM without losing a player"}, new String[]{"Win TDM without losing a player"},
new int[] {1}, new int[]{1},
AchievementCategory.CHAMPIONS), AchievementCategory.CHAMPIONS),
CHAMPIONS_ACE("Ace", 2000, CHAMPIONS_ACE("Ace", 2000,
new String[] {"Champions TDM.Ace"}, new String[]{"Champions TDM.Ace"},
new String[] {"Kill all enemies in a game of TDM"}, new String[]{"Kill all enemies in a game of TDM"},
new int[] {1}, new int[]{1},
AchievementCategory.CHAMPIONS), AchievementCategory.CHAMPIONS),
CHAMPIONS_ASSASSINATION("Assassination", 1000, CHAMPIONS_ASSASSINATION("Assassination", 1000,
new String[] {"Champions Domination.Assassination", "Champions TDM.Assassination"}, new String[]{"Champions Domination.Assassination", "Champions TDM.Assassination"},
new String[] {"Kill 40 players with Backstab without", "taking any damage from them"}, new String[]{"Kill 40 players with Backstab without", "taking any damage from them"},
new int[] {40}, new int[]{40},
AchievementCategory.CHAMPIONS), AchievementCategory.CHAMPIONS),
CHAMPIONS_MASS_ELECTROCUTION("Mass Electrocution", 1200, CHAMPIONS_MASS_ELECTROCUTION("Mass Electrocution", 1200,
new String[] {"Champions Domination.MassElectrocution", "Champions TDM.MassElectrocution"}, new String[]{"Champions Domination.MassElectrocution", "Champions TDM.MassElectrocution"},
new String[] {"Hit 4 enemies with a Lightning Orb"}, new String[]{"Hit 4 enemies with a Lightning Orb"},
new int[] {1}, new int[]{1},
AchievementCategory.CHAMPIONS), AchievementCategory.CHAMPIONS),
CHAMPIONS_THE_LONGEST_SHOT("The Longest Shot", 1200, CHAMPIONS_THE_LONGEST_SHOT("The Longest Shot", 1200,
new String[] {"Champions Domination.TheLongestShot", "Champions TDM.TheLongestShot"}, new String[]{"Champions Domination.TheLongestShot", "Champions TDM.TheLongestShot"},
new String[] {"Kill someone using Longshot who", "is over 64 Blocks away from you"}, new String[]{"Kill someone using Longshot who", "is over 64 Blocks away from you"},
new int[] {1}, new int[]{1},
AchievementCategory.CHAMPIONS), AchievementCategory.CHAMPIONS),
CHAMPIONS_EARTHQUAKE("Earthquake", 1200, CHAMPIONS_EARTHQUAKE("Earthquake", 1200,
new String[] {"Champions Domination.Earthquake", "Champions TDM.Earthquake"}, new String[]{"Champions Domination.Earthquake", "Champions TDM.Earthquake"},
new String[] {"Launch 5 enemies using Seismic Slam"}, new String[]{"Launch 5 enemies using Seismic Slam"},
new int[] {1}, new int[]{1},
AchievementCategory.CHAMPIONS), AchievementCategory.CHAMPIONS),
//Paintball //Paintball
SUPER_PAINTBALL_WINS("Paintball King", 600, SUPER_PAINTBALL_WINS("Paintball King", 600,
new String[] {"Super Paintball.Wins"}, new String[]{"Super Paintball.Wins"},
new String[] {"Win 50 games of Paintball"}, new String[]{"Win 50 games of Paintball"},
new int[] {50}, new int[]{50},
AchievementCategory.SUPER_PAINTBALL), AchievementCategory.SUPER_PAINTBALL),
SUPER_PAINTBALL_KILLING_SPREE("Killing Spree", 1200, SUPER_PAINTBALL_KILLING_SPREE("Killing Spree", 1200,
new String[] {"Super Paintball.KillingSpree"}, new String[]{"Super Paintball.KillingSpree"},
new String[] {"Get 4 kills in a row, with no more than", "5 seconds between each kill"}, new String[]{"Get 4 kills in a row, with no more than", "5 seconds between each kill"},
new int[] {1}, new int[]{1},
AchievementCategory.SUPER_PAINTBALL), AchievementCategory.SUPER_PAINTBALL),
SUPER_PAINTBALL_FLAWLESS_VICTORY("Flawless Victory", 1000, SUPER_PAINTBALL_FLAWLESS_VICTORY("Flawless Victory", 1000,
new String[] {"Super Paintball.Wins"}, new String[]{"Super Paintball.Wins"},
new String[] {"Win a team with your entire team alive"}, new String[]{"Win a team with your entire team alive"},
new int[] {1}, new int[]{1},
AchievementCategory.SUPER_PAINTBALL), AchievementCategory.SUPER_PAINTBALL),
SUPER_PAINTBALL_MEDIC("Medic!", 800, SUPER_PAINTBALL_MEDIC("Medic!", 800,
new String[] {"Super Paintball.Medic"}, new String[]{"Super Paintball.Medic"},
new String[] {"Revive 200 team members"}, new String[]{"Revive 200 team members"},
new int[] {200}, new int[]{200},
AchievementCategory.SUPER_PAINTBALL), AchievementCategory.SUPER_PAINTBALL),
SUPER_PAINTBALL_SPEEDRUNNER("Speedrunner", 1000, SUPER_PAINTBALL_SPEEDRUNNER("Speedrunner", 1000,
new String[] {"Super Paintball.Speedrunner"}, new String[]{"Super Paintball.Speedrunner"},
new String[] {"Win a game in 20 seconds"}, new String[]{"Win a game in 20 seconds"},
new int[] {1}, new int[]{1},
AchievementCategory.SUPER_PAINTBALL), AchievementCategory.SUPER_PAINTBALL),
SUPER_PAINTBALL_LAST_STAND("Last Stand", 1200, SUPER_PAINTBALL_LAST_STAND("Last Stand", 1200,
new String[] {"Super Paintball.LastStand"}, new String[]{"Super Paintball.LastStand"},
new String[] {"Be the last alive on your team", "and kill 3 enemy players"}, new String[]{"Be the last alive on your team", "and kill 3 enemy players"},
new int[] {1}, new int[]{1},
AchievementCategory.SUPER_PAINTBALL), AchievementCategory.SUPER_PAINTBALL),
//Sheep Quest //Sheep Quest
SHEEP_QUEST_WINS("Hungry Hungry Hippo", 600, SHEEP_QUEST_WINS("Hungry Hungry Hippo", 600,
new String[] {"Sheep Quest.Wins"}, new String[]{"Sheep Quest.Wins"},
new String[] {"Win 50 games of Sheep Quest"}, new String[]{"Win 50 games of Sheep Quest"},
new int[] {50}, new int[]{50},
AchievementCategory.SHEEP_QUEST), AchievementCategory.SHEEP_QUEST),
SHEEP_QUEST_THIEF("Thief", 800, SHEEP_QUEST_THIEF("Thief", 800,
new String[] {"Sheep Quest.Thief"}, new String[]{"Sheep Quest.Thief"},
new String[] {"Steal 300 Sheep from enemy pens"}, new String[]{"Steal 300 Sheep from enemy pens"},
new int[] {300}, new int[]{300},
AchievementCategory.SHEEP_QUEST), AchievementCategory.SHEEP_QUEST),
SHEEP_QUEST_ANIMAL_RESCUE("Animal Rescue", 800, SHEEP_QUEST_ANIMAL_RESCUE("Animal Rescue", 800,
new String[] {"Sheep Quest.AnimalRescue"}, new String[]{"Sheep Quest.AnimalRescue"},
new String[] {"Make 300 enemies drop their Sheep"}, new String[]{"Make 300 enemies drop their Sheep"},
new int[] {300}, new int[]{300},
AchievementCategory.SHEEP_QUEST), AchievementCategory.SHEEP_QUEST),
SHEEP_QUEST_SELFISH("Selfish", 1200, SHEEP_QUEST_SELFISH("Selfish", 1200,
new String[] {"Sheep Quest.Selfish"}, new String[]{"Sheep Quest.Selfish"},
new String[] {"Win with more than 12 Sheep"}, new String[]{"Win with more than 12 Sheep"},
new int[] {1}, new int[]{1},
AchievementCategory.SHEEP_QUEST), AchievementCategory.SHEEP_QUEST),
//Snake //Snake
SNAKE_WINS("Nokia 3310", 600, SNAKE_WINS("Nokia 3310", 600,
new String[] {"Snake.Wins"}, new String[]{"Snake.Wins"},
new String[] {"Win 50 games of Snake"}, new String[]{"Win 50 games of Snake"},
new int[] {50}, new int[]{50},
AchievementCategory.SNAKE), AchievementCategory.SNAKE),
SNAKE_CANNIBAL("Cannibal", 1600, SNAKE_CANNIBAL("Cannibal", 1600,
new String[] {"Snake.Cannibal"}, new String[]{"Snake.Cannibal"},
new String[] {"Kill 8 players in a single game"}, new String[]{"Kill 8 players in a single game"},
new int[] {1}, new int[]{1},
AchievementCategory.SNAKE), AchievementCategory.SNAKE),
SNAKE_CHOO_CHOO("Choo Choo", 1000, SNAKE_CHOO_CHOO("Choo Choo", 1000,
new String[] {"Snake.ChooChoo"}, new String[]{"Snake.ChooChoo"},
new String[] {"Grow to be 60 Sheep or longer"}, new String[]{"Grow to be 60 Sheep or longer"},
new int[] {1}, new int[]{1},
AchievementCategory.SNAKE), AchievementCategory.SNAKE),
SNAKE_SLIMY_SHEEP("Slimy Sheep", 800, SNAKE_SLIMY_SHEEP("Slimy Sheep", 800,
new String[] {"Snake.SlimySheep"}, new String[]{"Snake.SlimySheep"},
new String[] {"Eat 20 slimes in a single game"}, new String[]{"Eat 20 slimes in a single game"},
new int[] {1}, new int[]{1},
AchievementCategory.SNAKE), AchievementCategory.SNAKE),
//Dragons //Dragons
DRAGONS_WINS("Dragon Tamer", 600, DRAGONS_WINS("Dragon Tamer", 600,
new String[] {"Dragons.Wins"}, new String[]{"Dragons.Wins"},
new String[] {"Win 50 games of Dragons"}, new String[]{"Win 50 games of Dragons"},
new int[] {50}, new int[]{50},
AchievementCategory.DRAGONS), AchievementCategory.DRAGONS),
DRAGONS_SPARKLEZ("Sparklez", 400, DRAGONS_SPARKLEZ("Sparklez", 400,
new String[] {"Dragons.Sparklez"}, new String[]{"Dragons.Sparklez"},
new String[] {"Throw 100 Sparklers"}, new String[]{"Throw 100 Sparklers"},
new int[] {100}, new int[]{100},
AchievementCategory.DRAGONS), AchievementCategory.DRAGONS),
//Turf Wars //Turf Wars
TURF_WARS_WINS("Turf Master 3000", 600, TURF_WARS_WINS("Turf Master 3000", 600,
new String[] {"Turf Wars.Wins"}, new String[]{"Turf Wars.Wins"},
new String[] {"Win 50 games of Turf Wars"}, new String[]{"Win 50 games of Turf Wars"},
new int[] {50}, new int[]{50},
AchievementCategory.TURF_WARS), AchievementCategory.TURF_WARS),
TURF_WARS_SHREDDINATOR("The Shreddinator", 800, TURF_WARS_SHREDDINATOR("The Shreddinator", 800,
new String[] {"Turf Wars.TheShreddinator"}, new String[]{"Turf Wars.TheShreddinator"},
new String[] {"Destroy 2000 blocks as Shredder"}, new String[]{"Destroy 2000 blocks as Shredder"},
new int[] {2000}, new int[]{2000},
AchievementCategory.TURF_WARS), AchievementCategory.TURF_WARS),
TURF_WARS_BEHIND_ENEMY_LINES("Behind Enemy Lines", 1000, TURF_WARS_BEHIND_ENEMY_LINES("Behind Enemy Lines", 1000,
new String[] {"Turf Wars.BehindEnemyLines"}, new String[]{"Turf Wars.BehindEnemyLines"},
new String[] {"Stay on enemy turf for 15 seconds"}, new String[]{"Stay on enemy turf for 15 seconds"},
new int[] {1}, new int[]{1},
AchievementCategory.TURF_WARS), AchievementCategory.TURF_WARS),
TURF_WARS_COMEBACK("The Comeback", 2000, TURF_WARS_COMEBACK("The Comeback", 2000,
new String[] {"Turf Wars.TheComeback"}, new String[]{"Turf Wars.TheComeback"},
new String[] {"Win a game after having 5 or less turf"}, new String[]{"Win a game after having 5 or less turf"},
new int[] {1}, new int[]{1},
AchievementCategory.TURF_WARS), AchievementCategory.TURF_WARS),
//Death Tag //Death Tag
DEATH_TAG_WINS("Death Proof", 600, DEATH_TAG_WINS("Death Proof", 600,
new String[] {"Death Tag.Wins"}, new String[]{"Death Tag.Wins"},
new String[] {"Win 50 games of Death Tag"}, new String[]{"Win 50 games of Death Tag"},
new int[] {50}, new int[]{50},
AchievementCategory.DEATH_TAG), AchievementCategory.DEATH_TAG),
DEATH_TAG_COME_AT_ME_BRO("Come At Me Bro!", 1200, DEATH_TAG_COME_AT_ME_BRO("Come At Me Bro!", 1200,
new String[] {"Death Tag.ComeAtMeBro"}, new String[]{"Death Tag.ComeAtMeBro"},
new String[] {"Kill 2 Undead Chasers in a single game"}, new String[]{"Kill 2 Undead Chasers in a single game"},
new int[] {1}, new int[]{1},
AchievementCategory.DEATH_TAG), AchievementCategory.DEATH_TAG),
//Runner //Runner
RUNNER_WINS("Hot Feet", 600, RUNNER_WINS("Hot Feet", 600,
new String[] {"Runner.Wins"}, new String[]{"Runner.Wins"},
new String[] {"Win 50 games of Runner"}, new String[]{"Win 50 games of Runner"},
new int[] {50}, new int[]{50},
AchievementCategory.RUNNER),
RUNNER_MARATHON_RUNNER("Marathon Runner", 1000,
new String[]{"Runner.MarathonRunner"},
new String[]{"Run over 20,000 blocks"},
new int[]{20000},
AchievementCategory.RUNNER), AchievementCategory.RUNNER),
//Dragon Escape //Dragon Escape
DRAGON_ESCAPE_WINS("Douglas Defeater", 600, DRAGON_ESCAPE_WINS("Douglas Defeater", 600,
new String[] {"Dragon Escape.Wins"}, new String[]{"Dragon Escape.Wins"},
new String[] {"Win 50 games of Dragon Escape"}, new String[]{"Win 50 games of Dragon Escape"},
new int[] {50}, new int[]{50},
AchievementCategory.DRAGON_ESCAPE), AchievementCategory.DRAGON_ESCAPE),
DRAGON_ESCAPE_PARALYMPICS("Paralympics", 1200, DRAGON_ESCAPE_PARALYMPICS("Paralympics", 1200,
new String[] {"Dragon Escape.Wins"}, new String[]{"Dragon Escape.Wins"},
new String[] {"Win a game without using Leap"}, new String[]{"Win a game without using Leap"},
new int[] {1}, new int[]{1},
AchievementCategory.DRAGON_ESCAPE), AchievementCategory.DRAGON_ESCAPE),
DRAGON_ESCAPE_SKYLANDS("Skylands Master", 1000, DRAGON_ESCAPE_SKYLANDS("Skylands Master", 1000,
new String[] {"Dragon Escape.Win.Skylands"}, new String[]{"Dragon Escape.Win.Skylands"},
new String[] {"Win by finishing Skylands 5 times"}, new String[]{"Win by finishing Skylands 5 times"},
new int[] {5}, new int[]{5},
AchievementCategory.DRAGON_ESCAPE), AchievementCategory.DRAGON_ESCAPE),
DRAGON_ESCAPE_THROUGH_HELL("To Hell and Back", 1000, DRAGON_ESCAPE_THROUGH_HELL("To Hell and Back", 1000,
new String[] {"Dragon Escape.Win.Through Hell"}, new String[]{"Dragon Escape.Win.Through Hell"},
new String[] {"Win by finishing Through Hell 5 times"}, new String[]{"Win by finishing Through Hell 5 times"},
new int[] {5}, new int[]{5},
AchievementCategory.DRAGON_ESCAPE), AchievementCategory.DRAGON_ESCAPE),
DRAGON_ESCAPE_PIRATE_BAY("Plundered", 1000, DRAGON_ESCAPE_PIRATE_BAY("Plundered", 1000,
new String[] {"Dragon Escape.Win.Pirate Bay"}, new String[]{"Dragon Escape.Win.Pirate Bay"},
new String[] {"Win by finishing Pirate Bay 5 times"}, new String[]{"Win by finishing Pirate Bay 5 times"},
new int[] {5}, new int[]{5},
AchievementCategory.DRAGON_ESCAPE), AchievementCategory.DRAGON_ESCAPE),
//OITQ //OITQ
OITQ_WINS("One of a Kind", 600, OITQ_WINS("One of a Kind", 600,
new String[] {"One in the Quiver.Wins"}, new String[]{"One in the Quiver.Wins"},
new String[] {"Win 50 games of One in the Quiver"}, new String[]{"Win 50 games of One in the Quiver"},
new int[] {50}, new int[]{50},
AchievementCategory.ONE_IN_THE_QUIVER), AchievementCategory.ONE_IN_THE_QUIVER),
OITQ_PERFECTIONIST("The Perfect Game", 3000, OITQ_PERFECTIONIST("The Perfect Game", 3000,
new String[] {"One in the Quiver.Perfectionist"}, new String[]{"One in the Quiver.Perfectionist"},
new String[] {"Win without dying"}, new String[]{"Win without dying"},
new int[] {1}, new int[]{1},
AchievementCategory.ONE_IN_THE_QUIVER), AchievementCategory.ONE_IN_THE_QUIVER),
OITQ_SHARPSHOOTER("SharpShooter", 1200, OITQ_SHARPSHOOTER("SharpShooter", 1200,
new String[] {"One in the Quiver.Sharpshooter"}, new String[]{"One in the Quiver.Sharpshooter"},
new String[] {"Hit with 8 Arrows in a row"}, new String[]{"Hit with 8 Arrows in a row"},
new int[] {1}, new int[]{1},
AchievementCategory.ONE_IN_THE_QUIVER),
OITQ_WHATS_A_BOW("What's A Bow?", 1200,
new String[]{"One in the Quiver.WhatsABow"},
new String[]{"Win a game without using a bow"},
new int[]{1},
AchievementCategory.ONE_IN_THE_QUIVER), AchievementCategory.ONE_IN_THE_QUIVER),
//Super Spleef //Super Spleef
SPLEEF_WINS("Spleef King (or Queen)", 600, SPLEEF_WINS("Spleef King (or Queen)", 600,
new String[] {"Super Spleef.Wins"}, new String[]{"Super Spleef.Wins"},
new String[] {"Win 50 games of Super Spleef"}, new String[]{"Win 50 games of Super Spleef"},
new int[] {50}, new int[]{50},
AchievementCategory.SPLEEF),
SPLEEF_DEMOLITIONIST("Demolitionist", 1000,
new String[]{"Super Spleef.SpleefBlocks"},
new String[]{"Destroy 20,000 blocks."},
new int[]{20000},
AchievementCategory.SPLEEF), AchievementCategory.SPLEEF),
//Bacon Brawl //Bacon Brawl
BACON_BRAWL_WINS("King of Bacon", 600, BACON_BRAWL_WINS("King of Bacon", 600,
new String[] {"Bacon Brawl.Wins"}, new String[]{"Bacon Brawl.Wins"},
new String[] {"Win 50 games of Bacon Brawl"}, new String[]{"Win 50 games of Bacon Brawl"},
new int[] {50}, new int[]{50},
AchievementCategory.BACON_BRAWL), AchievementCategory.BACON_BRAWL),
//Sneaky Assassins //Sneaky Assassins
SNEAKY_ASSASSINS_WINS("So So Sneaky", 600, SNEAKY_ASSASSINS_WINS("So So Sneaky", 600,
new String[] {"Sneaky Assassins.Wins"}, new String[]{"Sneaky Assassins.Wins"},
new String[] {"Win 50 games of Sneaky Assassins"}, new String[]{"Win 50 games of Sneaky Assassins"},
new int[] {50}, new int[]{50},
AchievementCategory.SNEAKY_ASSASSINS),
SNEAK_ASSASSINS_MASTER_ASSASSIN("Master Assassin", 600,
new String[]{"Sneaky Assassins.MasterAssassin"},
new String[]{"Get Master Assassin 10 times"},
new int[]{10},
AchievementCategory.SNEAKY_ASSASSINS),
SNEAK_ASSASSINS_THE_MASTERS_MASTER("The Master's Master", 700,
new String[]{"Sneaky Assassins.TheMastersMaster"},
new String[]{"Kill a Master Assassin without", "having a single power-up."},
new int[]{1},
AchievementCategory.SNEAKY_ASSASSINS),
SNEAK_ASSASSINS_INCOMPETENCE("Incompetence", 600,
new String[]{"Sneaky Assassins.Incompetence"},
new String[]{"Kill 200 NPCs."},
new int[]{200},
AchievementCategory.SNEAKY_ASSASSINS),
SNEAK_ASSASSINS_I_SEE_YOU("I See You", 800,
new String[]{"Sneaky Assassins.ISeeYou"},
new String[]{"Reveal 50 players."},
new int[]{50},
AchievementCategory.SNEAKY_ASSASSINS), AchievementCategory.SNEAKY_ASSASSINS),
//Micro Battle //Micro Battle
MICRO_BATTLE_WINS("Micro Champion", 600, MICRO_BATTLE_WINS("Micro Champion", 600,
new String[] {"Micro Battle.Wins"}, new String[]{"Micro Battle.Wins"},
new String[] {"Win 100 games of Micro Battle"}, new String[]{"Win 100 games of Micro Battle"},
new int[] {100}, new int[]{100},
AchievementCategory.MICRO_BATTLE), AchievementCategory.MICRO_BATTLE),
MICRO_BATTLE_ANNIHILATION("Annihilation", 1200,
new String[]{"Micro Battle.Annihilation"},
new String[]{"Kill 12 players in one game"},
new int[]{1},
AchievementCategory.MICRO_BATTLE),
//MineStrike
MINE_STRIKE_WINS("Striker", 800,
new String[]{"MineStrike.Wins"},
new String[]{"Win 50 games of MineStrike"},
new int[]{50},
AchievementCategory.MINE_STRIKE),
MINE_STRIKE_BOOM_HEADSHOT("BOOM! HEADSHOT!", 800,
new String[]{"MineStrike.BoomHeadshot"},
new String[]{"Kill 500 people with headshots"},
new int[]{500},
AchievementCategory.MINE_STRIKE),
MINE_STRIKE_ACE("Ace", 2000,
new String[]{"MineStrike.Ace"},
new String[]{"Get the kill on all enemies in a single round"},
new int[]{1},
AchievementCategory.MINE_STRIKE),
MINE_STRIKE_KABOOM("Kaboom!", 1000,
new String[]{"MineStrike.Kaboom"},
new String[]{"Kill two people with a single", "High Explosive Grenade"},
new int[]{1},
AchievementCategory.MINE_STRIKE),
MINE_STRIKE_ASSASSINATION("Assassination", 800,
new String[]{"MineStrike.Assassination"},
new String[]{"Get 20 backstab kills with the knife"},
new int[]{20},
AchievementCategory.MINE_STRIKE),
MINE_STRIKE_CLUTCH_OR_KICK("Clutch or Kick", 1000,
new String[]{"MineStrike.ClutchOrKick"},
new String[]{"Be the last one alive, and kill", "3 or more enemies to achieve victory"},
new int[]{1},
AchievementCategory.MINE_STRIKE),
MINE_STRIKE_KILLING_SPREE("Killing Spree", 1000,
new String[]{"MineStrike.KillingSpree"},
new String[]{"Kill 4 enemies in a row with no more", "than 5 seconds between each kill"},
new int[]{1},
AchievementCategory.MINE_STRIKE),
MINE_STRIKE_BLINDFOLDED("Blindfolded", 800,
new String[]{"MineStrike.Blindfolded"},
new String[]{"Kill 2 enemies while blinded from", "a single flashbang"},
new int[]{1},
AchievementCategory.MINE_STRIKE),
; ;
private String _name; private String _name;
@ -489,6 +590,62 @@ public enum Achievement
_category = category; _category = category;
} }
private static int[] getExperienceLevels()
{
int[] levels = new int[100];
int expReq = 0;
for (int i=0 ; i<20 ; i++)
{
expReq += 2000;
levels[i] = expReq;
}
for (int i=20 ; i<40 ; i++)
{
expReq += 3000;
levels[i] = expReq;
}
for (int i=40 ; i<60 ; i++)
{
expReq += 4000;
levels[i] = expReq;
}
for (int i=60 ; i<80 ; i++)
{
expReq += 5000;
levels[i] = expReq;
}
for (int i=80 ; i<levels.length ; i++)
{
expReq += 6000;
levels[i] = expReq;
}
return levels;
}
public static String getExperienceString(int level)
{
if (level < 20)
return C.cGray + level;
if (level < 40)
return C.cBlue + level;
if (level < 60)
return C.cDGreen + level;
if (level < 80)
return C.cGold + level;
return C.cRed + level;
}
public String getName() public String getName()
{ {
return _name; return _name;
@ -531,7 +688,7 @@ public enum Achievement
public AchievementData getLevelData(int exp) public AchievementData getLevelData(int exp)
{ {
for (int i=0 ; i<_levels.length ; i++) for (int i = 0; i < _levels.length; i++)
{ {
int req = _levels[i]; int req = _levels[i];

View File

@ -1,8 +1,16 @@
package mineplex.core.achievement; package mineplex.core.achievement;
import org.bukkit.ChatColor; import java.util.List;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.entity.Player;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilTime;
import mineplex.core.stats.PlayerStats;
import mineplex.core.stats.StatsManager;
/** /**
* Created by Shaun on 8/21/2014. * Created by Shaun on 8/21/2014.
@ -11,118 +19,125 @@ import org.bukkit.inventory.ItemStack;
public enum AchievementCategory public enum AchievementCategory
{ {
GLOBAL("Global", null, GLOBAL("Global", null,
new String[] { "GemsEarned" }, new String[] { "GemsEarned", null, "GamesPlayed", "TimeInGame" },
new String[] { "Gems Earned" }, new String[] { "Gems Earned", null, "Games Played", "Time In Game" },
Material.EMERALD, 0, GameCategory.GLOBAL), Material.EMERALD, 0, GameCategory.GLOBAL, null),
//Survival //Survival
BRIDGES("The Bridges", null, BRIDGES("The Bridges", null,
new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] { "Wins", "Losses", "Kills", "Deaths", "Gems Earned" }, new String[] { "Wins", "Losses", "Kills", "Deaths", "Gems Earned" },
Material.IRON_PICKAXE, 0, GameCategory.SURVIVAL), Material.IRON_PICKAXE, 0, GameCategory.SURVIVAL, "Destructor Kit"),
SURVIVAL_GAMES("Survival Games", null, SURVIVAL_GAMES("Survival Games", null,
new String[] { "Wins", "Losses", "Kills", "Deaths", "GemsEarned" }, new String[] { "Wins", "Losses", "Kills", "Deaths", "GemsEarned" },
new String[] { "Wins", "Losses", "Kills", "Deaths", "Gems Earned" }, new String[] { "Wins", "Losses", "Kills", "Deaths", "Gems Earned" },
Material.IRON_SWORD, 0, GameCategory.SURVIVAL), Material.IRON_SWORD, 0, GameCategory.SURVIVAL, "Horseman Kit"),
UHC("Ultra Hardcore", null, MINE_STRIKE("MineStrike", null,
new String[] { "Wins", "Losses", "Kills", "Deaths", "GemsEarned" }, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] { "Wins", "Losses", "Kills", "Deaths", "Gems Earned" }, new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"},
Material.GOLD_INGOT, 0, GameCategory.SURVIVAL), Material.TNT, 0, GameCategory.CLASSICS, null),
//Classics //Classics
SMASH_MOBS("Super Smash Mobs", null, SMASH_MOBS("Super Smash Mobs", null,
new String[] { "Wins", "Losses", "Kills", "Deaths", "GemsEarned" }, new String[] { "Wins", "Losses", "Kills", "Deaths", "GemsEarned" },
new String[] { "Wins", "Losses", "Kills", "Deaths", "Gems Earned" }, new String[] { "Wins", "Losses", "Kills", "Deaths", "Gems Earned" },
Material.SKULL_ITEM, 4, GameCategory.CLASSICS), Material.SKULL_ITEM, 4, GameCategory.CLASSICS, "Sheep Kit"),
BLOCK_HUNT("Block Hunt", null, BLOCK_HUNT("Block Hunt", null,
new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"},
Material.GRASS, 0, GameCategory.CLASSICS), Material.GRASS, 0, GameCategory.CLASSICS, null),
DRAW_MY_THING("Draw My Thing", null, DRAW_MY_THING("Draw My Thing", null,
new String[] {"Wins", "Losses", "GemsEarned"}, new String[] {"Wins", "Losses", "GemsEarned"},
new String[] {"Wins", "Losses", "GemsEarned"}, new String[] {"Wins", "Losses", "GemsEarned"},
Material.BOOK_AND_QUILL, 0, GameCategory.CLASSICS), Material.BOOK_AND_QUILL, 0, GameCategory.CLASSICS, null),
CASTLE_SIEGE("Castle Siege", null, CASTLE_SIEGE("Castle Siege", null,
new String[] {"Wins", "Losses", "Kills as Defenders", "Deaths as Defenders", "Kills as Undead", "Deaths as Undead", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills as Defenders", "Deaths as Defenders", "Kills as Undead", "Deaths as Undead", "GemsEarned"},
new String[] {"Wins", "Losses", "Kills as Defenders", "Deaths as Defenders", "Kills as Undead", "Deaths as Undead", "Gems Earned"}, new String[] {"Wins", "Losses", "Kills as Defenders", "Deaths as Defenders", "Kills as Undead", "Deaths as Undead", "Gems Earned"},
Material.DIAMOND_CHESTPLATE, 0, GameCategory.CLASSICS), Material.DIAMOND_CHESTPLATE, 0, GameCategory.CLASSICS, null),
//Champions //Champions
CHAMPIONS("Champions", new String[] {"Champions Domination", "Champions TDM"}, CHAMPIONS("Champions", new String[] {"Champions Domination", "Champions TDM"},
new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"},
Material.BEACON, 0, GameCategory.CHAMPIONS), Material.BEACON, 0, GameCategory.CHAMPIONS, null),
UHC("Ultra Hardcore", null,
new String[] { "Wins", "Losses", "Kills", "Deaths", "GemsEarned" },
new String[] { "Wins", "Losses", "Kills", "Deaths", "Gems Earned" },
Material.GOLD_INGOT, 0, GameCategory.SURVIVAL, null),
//Arcade //Arcade
DRAGONS("Dragons", null, DRAGONS("Dragons", null,
new String[] {"Wins", "Losses", "GemsEarned"}, new String[] {"Wins", "Losses", "GemsEarned"},
new String[] {"Wins", "Losses", "Gems Earned"}, new String[] {"Wins", "Losses", "Gems Earned"},
Material.ENDER_STONE, 0, GameCategory.ARCADE), Material.ENDER_STONE, 0, GameCategory.ARCADE, null),
DRAGON_ESCAPE("Dragon Escape", null, DRAGON_ESCAPE("Dragon Escape", null,
new String[] {"Wins", "Losses", "GemsEarned"}, new String[] {"Wins", "Losses", "GemsEarned"},
new String[] {"Wins", "Losses", "Gems Earned"}, new String[] {"Wins", "Losses", "Gems Earned"},
Material.DRAGON_EGG, 0, GameCategory.ARCADE), Material.DRAGON_EGG, 0, GameCategory.ARCADE, null),
SHEEP_QUEST("Sheep Quest", null, SHEEP_QUEST("Sheep Quest", null,
new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"},
Material.WOOL, 0, GameCategory.ARCADE), Material.WOOL, 0, GameCategory.ARCADE, null),
SNEAKY_ASSASSINS("Sneaky Assassins", null, SNEAKY_ASSASSINS("Sneaky Assassins", null,
new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"},
Material.INK_SACK, 0, GameCategory.ARCADE), Material.INK_SACK, 0, GameCategory.ARCADE, null),
ONE_IN_THE_QUIVER("One in the Quiver", null, ONE_IN_THE_QUIVER("One in the Quiver", null,
new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"},
Material.BOW, 0, GameCategory.ARCADE), Material.BOW, 0, GameCategory.ARCADE, null),
SUPER_PAINTBALL("Super Paintball", null, SUPER_PAINTBALL("Super Paintball", null,
new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"},
Material.ENDER_PEARL, 0, GameCategory.ARCADE), Material.ENDER_PEARL, 0, GameCategory.ARCADE, null),
TURF_WARS("Turf Wars", null, TURF_WARS("Turf Wars", null,
new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"},
Material.HARD_CLAY, 14, GameCategory.ARCADE), Material.HARD_CLAY, 14, GameCategory.ARCADE, null),
RUNNER("Runner", null, RUNNER("Runner", null,
new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"},
Material.LEATHER_BOOTS, 0, GameCategory.ARCADE), Material.LEATHER_BOOTS, 0, GameCategory.ARCADE, null),
SPLEEF("Super Spleef", null, SPLEEF("Super Spleef", null,
new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"},
Material.IRON_SPADE, 0, GameCategory.ARCADE), Material.IRON_SPADE, 0, GameCategory.ARCADE, null),
DEATH_TAG("Death Tag", null, DEATH_TAG("Death Tag", null,
new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"},
Material.SKULL_ITEM, 0, GameCategory.ARCADE), Material.SKULL_ITEM, 0, GameCategory.ARCADE, null),
SNAKE("Snake", null, SNAKE("Snake", null,
new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"},
Material.WOOL, 4, GameCategory.ARCADE), Material.WOOL, 4, GameCategory.ARCADE, null),
BACON_BRAWL("Bacon Brawl", null, BACON_BRAWL("Bacon Brawl", null,
new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"},
Material.PORK, 0, GameCategory.ARCADE), Material.PORK, 0, GameCategory.ARCADE, null),
MICRO_BATTLE("Micro Battle", null, MICRO_BATTLE("Micro Battle", null,
new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "GemsEarned"},
new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"}, new String[] {"Wins", "Losses", "Kills", "Deaths", "Gems Earned"},
Material.LAVA, 0, GameCategory.ARCADE); Material.LAVA, 0, GameCategory.ARCADE, null),
;
private String _name; private String _name;
@ -132,8 +147,9 @@ public enum AchievementCategory
private Material _icon; private Material _icon;
private GameCategory _gameCategory; private GameCategory _gameCategory;
private byte _iconData; private byte _iconData;
private String _kitReward;
AchievementCategory(String name, String[] statsToPull, String[] statsToDisplay, String[] friendlyStatNames, Material icon, int iconData, GameCategory gameCategory) AchievementCategory(String name, String[] statsToPull, String[] statsToDisplay, String[] friendlyStatNames, Material icon, int iconData, GameCategory gameCategory, String kitReward)
{ {
_name = name; _name = name;
@ -147,6 +163,7 @@ public enum AchievementCategory
_icon = icon; _icon = icon;
_iconData = (byte)iconData; _iconData = (byte)iconData;
_gameCategory = gameCategory; _gameCategory = gameCategory;
_kitReward = kitReward;
} }
public String getFriendlyName() public String getFriendlyName()
@ -154,6 +171,11 @@ public enum AchievementCategory
return _name; return _name;
} }
public String getReward()
{
return _kitReward;
}
public Material getIcon() public Material getIcon()
{ {
return _icon; return _icon;
@ -184,6 +206,40 @@ public enum AchievementCategory
return _friendlyStatNames; return _friendlyStatNames;
} }
public void addStats(CoreClientManager clientManager, StatsManager statsManager, List<String> lore, Player player, Player target)
{
addStats(clientManager, statsManager, lore, Integer.MAX_VALUE, player, target);
}
public void addStats(CoreClientManager clientManager, StatsManager statsManager, List<String> lore, int max, Player player, Player target)
{
PlayerStats stats = statsManager.Get(target);
for (int i = 0; i < _statsToDisplay.length && i < max; i++)
{
// If the stat is null then just display a blank line instead
if (_statsToDisplay[i] == null || _friendlyStatNames[i] == null)
{
lore.add(" ");
continue;
}
// Skip showing Losses, Kills, Deaths for other players
if (!clientManager.Get(player).GetRank().Has(Rank.MODERATOR) && !player.equals(target) && (_statsToDisplay[i].contains("Losses") || _statsToDisplay[i].contains("Kills") || _statsToDisplay[i].contains("Deaths") || _statsToDisplay[i].equals("Time In Game") || _statsToDisplay.equals("Games Played")))
continue;
int statNumber = 0;
for (String statToPull : _statsToPull)
statNumber += stats.getStat(statToPull + "." + _statsToDisplay[i]);
String statString = C.cWhite + statNumber;
// Need to display special for time
if (_statsToDisplay[i].equalsIgnoreCase("TimeInGame"))
statString = C.cWhite + UtilTime.convertString(statNumber * 1000L, 0, UtilTime.TimeUnit.FIT);
lore.add(C.cYellow + _friendlyStatNames[i] + ": " + statString);
}
}
public static enum GameCategory public static enum GameCategory
{ {
GLOBAL, SURVIVAL, CLASSICS, CHAMPIONS, ARCADE; GLOBAL, SURVIVAL, CLASSICS, CHAMPIONS, ARCADE;

View File

@ -12,6 +12,7 @@ import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager; import mineplex.core.account.CoreClientManager;
import mineplex.core.achievement.command.StatsCommand; import mineplex.core.achievement.command.StatsCommand;
import mineplex.core.achievement.ui.AchievementShop; import mineplex.core.achievement.ui.AchievementShop;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
import mineplex.core.common.util.NautHashMap; import mineplex.core.common.util.NautHashMap;
import mineplex.core.common.util.UtilGear; import mineplex.core.common.util.UtilGear;
@ -176,4 +177,33 @@ public class AchievementManager extends MiniPlugin
openShop(event.getPlayer()); openShop(event.getPlayer());
} }
} }
public boolean hasCategory(Player player, Achievement[] required)
{
if (required == null || required.length == 0)
return false;
for (Achievement cur : required)
{
if (get(player, cur).getLevel() < cur.getMaxLevel())
return false;
}
return true;
}
public String getMineplexLevel(Player sender, Rank rank)
{
int level = get(sender, Achievement.GLOBAL_MINEPLEX_LEVEL).getLevel();
if (rank.Has(Rank.OWNER))
level = Math.max(level, 50 + get(sender, Achievement.GLOBAL_GEM_HUNTER).getLevel());
else if (rank.Has(Rank.ADMIN))
level = Math.max(level, 30 + get(sender, Achievement.GLOBAL_GEM_HUNTER).getLevel());
else if (rank.Has(Rank.MODERATOR))
level = Math.max(level, 5);
return Achievement.getExperienceString(level) + " " + ChatColor.RESET;
}
} }

View File

@ -19,7 +19,6 @@ import mineplex.core.common.util.C;
import mineplex.core.donation.DonationManager; import mineplex.core.donation.DonationManager;
import mineplex.core.shop.item.ShopItem; import mineplex.core.shop.item.ShopItem;
import mineplex.core.shop.page.ShopPageBase; import mineplex.core.shop.page.ShopPageBase;
import mineplex.core.stats.PlayerStats;
import mineplex.core.stats.StatsManager; import mineplex.core.stats.StatsManager;
/** /**
@ -55,7 +54,7 @@ public class AchievementMainPage extends ShopPageBase<AchievementManager, Achiev
ArrayList<String> lore = new ArrayList<String>(); ArrayList<String> lore = new ArrayList<String>();
lore.add(" "); lore.add(" ");
addStats(category, lore, 2); category.addStats(ClientManager, _statsManager, lore, category == AchievementCategory.GLOBAL ? 5 : 2, Player, _target);
lore.add(" "); lore.add(" ");
addAchievements(category, lore, 9); addAchievements(category, lore, 9);
lore.add(" "); lore.add(" ");
@ -81,33 +80,12 @@ public class AchievementMainPage extends ShopPageBase<AchievementManager, Achiev
addArcadeButton(); addArcadeButton();
} }
protected void addStats(AchievementCategory category, List<String> lore, int max)
{
String[] statsToDisplay = category.getStatsToDisplay();
String[] friendlyStatNames = category.getFriendlyStatNames();
PlayerStats stats = _statsManager.Get(_target);
for (int i = 0; i < statsToDisplay.length && i < max; i++)
{
// Skip showing Losses, Kills, Deaths for other players
if ((!Player.equals(_target)) && (statsToDisplay[i].equalsIgnoreCase("Losses") || statsToDisplay[i].contains("Kills") || statsToDisplay[i].contains("Deaths")))
continue;
String statName = statsToDisplay[i];
int statNumber = 0;
for (String statToPull : category.getStatsToPull())
statNumber += stats.getStat(statToPull + "." + statName);
lore.add(C.cYellow + friendlyStatNames[i] + ": " + C.cWhite + statNumber);
}
}
protected void addArcadeButton() protected void addArcadeButton()
{ {
ArcadeButton button = new ArcadeButton(Shop, Plugin, _statsManager, DonationManager, ClientManager, _target); ArcadeButton button = new ArcadeButton(Shop, Plugin, _statsManager, DonationManager, ClientManager, _target);
ShopItem shopItem = new ShopItem(Material.TNT, (byte) 0, C.Bold + "Arcade Games", new String[] {" ", ChatColor.RESET + "Click for more!"}, 1, false, false); ShopItem shopItem = new ShopItem(Material.BOW, (byte) 0, C.Bold + "Arcade Games", new String[] {" ", ChatColor.RESET + "Click for more!"}, 1, false, false);
AddButton(42, shopItem, button); AddButton(44, shopItem, button);
} }
protected void addAchievements(AchievementCategory category, List<String> lore, int max) protected void addAchievements(AchievementCategory category, List<String> lore, int max)

View File

@ -118,7 +118,12 @@ public class AchievementPage extends ShopPageBase<AchievementManager, Achievemen
String itemName = ChatColor.RESET + _category.getFriendlyName() + " Master Achievement"; String itemName = ChatColor.RESET + _category.getFriendlyName() + " Master Achievement";
masterAchievementLore.add(" "); masterAchievementLore.add(" ");
if (Player.equals(_target)) if (Player.equals(_target))
masterAchievementLore.add(ChatColor.RESET + "Kit Reward Coming Soon!"); {
if (_category.getReward() != null)
masterAchievementLore.add(C.cYellow + C.Bold + "Reward: " + ChatColor.RESET + _category.getReward());
else
masterAchievementLore.add(C.cYellow + C.Bold + "Reward: " + ChatColor.RESET + "Coming Soon...");
}
AddItem(40, new ShopItem(hasAllAchievements ? Material.EMERALD_BLOCK : Material.REDSTONE_BLOCK, (byte)0, itemName, masterAchievementLore.toArray(new String[0]), 1, false, true)); AddItem(40, new ShopItem(hasAllAchievements ? Material.EMERALD_BLOCK : Material.REDSTONE_BLOCK, (byte)0, itemName, masterAchievementLore.toArray(new String[0]), 1, false, true));
} }
@ -155,23 +160,8 @@ public class AchievementPage extends ShopPageBase<AchievementManager, Achievemen
Material material = Material.BOOK; Material material = Material.BOOK;
String itemName = C.Bold + _category.getFriendlyName() + " Stats"; String itemName = C.Bold + _category.getFriendlyName() + " Stats";
List<String> lore = new ArrayList<String>(); List<String> lore = new ArrayList<String>();
lore.add(""); lore.add(" ");
_category.addStats(ClientManager, _statsManager, lore, Player, _target);
PlayerStats stats = _statsManager.Get(_target);
String[] statsToDisplay = _category.getStatsToDisplay();
String[] friendlyStatNames = _category.getFriendlyStatNames();
for (int i = 0; i < statsToDisplay.length; i++)
{
// Skip showing Losses, Kills, Deaths for other players
if ((!Player.equals(_target)) && (statsToDisplay[i].equalsIgnoreCase("Losses") || statsToDisplay[i].contains("Kills") || statsToDisplay[i].contains("Deaths")))
continue;
int statNumber = 0;
for (String statToPull : _category.getStatsToPull())
statNumber += stats.getStat(statToPull + "." + statsToDisplay[i]);
lore.add(C.cYellow + friendlyStatNames[i] + ": " + C.cWhite + statNumber);
}
ItemStack item = new ItemStack(material); ItemStack item = new ItemStack(material);
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();

View File

@ -16,7 +16,6 @@ import mineplex.core.common.util.C;
import mineplex.core.donation.DonationManager; import mineplex.core.donation.DonationManager;
import mineplex.core.shop.item.ShopItem; import mineplex.core.shop.item.ShopItem;
import mineplex.core.shop.item.SingleButton; import mineplex.core.shop.item.SingleButton;
import mineplex.core.shop.page.ShopPageBase;
import mineplex.core.stats.StatsManager; import mineplex.core.stats.StatsManager;
/** /**
@ -43,7 +42,7 @@ public class ArcadeMainPage extends AchievementMainPage
ArrayList<String> lore = new ArrayList<String>(); ArrayList<String> lore = new ArrayList<String>();
lore.add(" "); lore.add(" ");
addStats(category, lore, 2); category.addStats(ClientManager, _statsManager, lore, 2, Player, _target);
lore.add(" "); lore.add(" ");
addAchievements(category, lore, 9); addAchievements(category, lore, 9);
lore.add(" "); lore.add(" ");

View File

@ -6,33 +6,40 @@ import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import mineplex.core.MiniPlugin;
import mineplex.core.antihack.types.*;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilGear;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.portal.Portal;
import mineplex.core.punish.Punish;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerToggleFlightEvent;
import org.bukkit.event.player.PlayerVelocityEvent; import org.bukkit.event.player.PlayerVelocityEvent;
import org.bukkit.event.server.ServerListPingEvent; import org.bukkit.event.server.ServerListPingEvent;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.antihack.types.Fly;
import mineplex.core.antihack.types.Idle;
import mineplex.core.antihack.types.Reach;
import mineplex.core.antihack.types.Speed;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.portal.Portal;
import mineplex.core.preferences.PreferencesManager;
import mineplex.core.punish.Punish;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
public class AntiHack extends MiniPlugin public class AntiHack extends MiniPlugin
{ {
private static Object _antiHackLock = new Object(); private static Object _antiHackLock = new Object();
@ -40,14 +47,15 @@ public class AntiHack extends MiniPlugin
public static AntiHack Instance; public static AntiHack Instance;
private boolean _enabled = true; private boolean _enabled = true;
private boolean _strict = false;
private boolean _kick = true;
public Punish Punish; public Punish Punish;
public Portal Portal; public Portal Portal;
private PreferencesManager _preferences;
private CoreClientManager _clientManager;
//Record Offenses //Record Offenses
private HashMap<Player, HashMap<String, ArrayList<Long>>> _suspicion = new HashMap<Player, HashMap<String, ArrayList<Long>>>();
//Some suspicions will not become offenses, for example, using double jump will remove suspicion 2 seconds prior
private HashMap<Player, HashMap<String, ArrayList<Long>>> _offense = new HashMap<Player, HashMap<String, ArrayList<Long>>>(); private HashMap<Player, HashMap<String, ArrayList<Long>>> _offense = new HashMap<Player, HashMap<String, ArrayList<Long>>>();
//Ignore Player //Ignore Player
@ -58,39 +66,47 @@ public class AntiHack extends MiniPlugin
private HashMap<Player, Long> _lastMoveEvent = new HashMap<Player, Long>(); private HashMap<Player, Long> _lastMoveEvent = new HashMap<Player, Long>();
//Hack Requirements //Hack Requirements
public int FloatHackTicks = 6; public int FloatHackTicks = 10;
public int HoverHackTicks = 3; public int HoverHackTicks = 4;
public int RiseHackTicks = 6; public int RiseHackTicks = 6;
public int SpeedHackTicks = 6; public int SpeedHackTicks = 6;
public int IdleTime = 20000; public int IdleTime = 20000;
public int KeepOffensesFor = 30000;
//Other Times //Other Times
public int FlightTriggerCancel = 2000; public int FlightTriggerCancel = 2000;
public ArrayList<Detector> _detectors; public ArrayList<Detector> _movementDetectors;
public ArrayList<Detector> _combatDetectors;
private AntiHackRepository _repository; private AntiHackRepository _repository;
protected AntiHack(JavaPlugin plugin, Punish punish, Portal portal) protected AntiHack(JavaPlugin plugin, Punish punish, Portal portal, PreferencesManager preferences, CoreClientManager clientManager)
{ {
super("AntiHack", plugin); super("AntiHack", plugin);
Punish = punish; Punish = punish;
Portal = portal; Portal = portal;
_preferences = preferences;
_clientManager = clientManager;
_repository = new AntiHackRepository(plugin.getConfig().getString("serverstatus.name")); _repository = new AntiHackRepository(plugin.getConfig().getString("serverstatus.name"));
_repository.initialize(); _repository.initialize();
_detectors = new ArrayList<Detector>(); _movementDetectors = new ArrayList<Detector>();
_combatDetectors = new ArrayList<Detector>();
_detectors.add(new Fly(this)); _movementDetectors.add(new Fly(this));
_detectors.add(new Idle(this)); _movementDetectors.add(new Idle(this));
_detectors.add(new Speed(this)); _movementDetectors.add(new Speed(this));
_combatDetectors.add(new Reach(this));
} }
public static void Initialize(JavaPlugin plugin, Punish punish, Portal portal) public static void Initialize(JavaPlugin plugin, Punish punish, Portal portal, PreferencesManager preferences, CoreClientManager clientManager)
{ {
Instance = new AntiHack(plugin, punish, portal); Instance = new AntiHack(plugin, punish, portal, preferences, clientManager);
} }
@EventHandler @EventHandler
@ -113,7 +129,7 @@ public class AntiHack extends MiniPlugin
synchronized (_antiHackLock) synchronized (_antiHackLock)
{ {
_ignore.put(event.getPlayer(), System.currentTimeMillis() + 2000); setIgnore(event.getPlayer(), 2000);
} }
} }
@ -129,35 +145,6 @@ public class AntiHack extends MiniPlugin
} }
} }
@EventHandler
public void playerToggleFly(PlayerToggleFlightEvent event)
{
if (!_enabled)
return;
Player player = event.getPlayer();
synchronized (_antiHackLock)
{
if (!_suspicion.containsKey(player))
return;
//Remove all infractions within last 2 seconds.
for (ArrayList<Long> offenseList : _suspicion.get(player).values())
{
Iterator<Long> offenseIterator = offenseList.iterator();
while (offenseIterator.hasNext())
{
long time = offenseIterator.next();
if (!UtilTime.elapsed(time, FlightTriggerCancel))
offenseIterator.remove();
}
}
}
}
@EventHandler @EventHandler
public void playerQuit(PlayerQuitEvent event) public void playerQuit(PlayerQuitEvent event)
{ {
@ -189,7 +176,7 @@ public class AntiHack extends MiniPlugin
if (timeBetweenPackets > 500) if (timeBetweenPackets > 500)
{ {
setIgnore(player, 5000); setIgnore(player, Math.min(4000, timeBetweenPackets));
} }
} }
} }
@ -198,7 +185,7 @@ public class AntiHack extends MiniPlugin
public void setIgnore(Player player, long time) public void setIgnore(Player player, long time)
{ {
//Wipe Detection //Wipe Detection
for (Detector detector : _detectors) for (Detector detector : _movementDetectors)
detector.Reset(player); detector.Reset(player);
synchronized (_antiHackLock) synchronized (_antiHackLock)
@ -214,11 +201,28 @@ public class AntiHack extends MiniPlugin
public boolean isValid(Player player, boolean groundValid) public boolean isValid(Player player, boolean groundValid)
{ {
//Near Other Player
for (Player other : UtilServer.getPlayers())
{
if (player.equals(other))
continue;
if (other.getGameMode() != GameMode.SURVIVAL)
continue;
if (other.getVehicle() != null)
continue;
if (UtilMath.offset(player, other) < 2)
return true;
}
if (player.isFlying() || player.isInsideVehicle() || player.getGameMode() != GameMode.SURVIVAL) if (player.isFlying() || player.isInsideVehicle() || player.getGameMode() != GameMode.SURVIVAL)
{ {
return true; return true;
} }
//On Ground
if (groundValid) if (groundValid)
{ {
if (UtilEnt.onBlock(player) || player.getLocation().getBlock().getType() != Material.AIR) if (UtilEnt.onBlock(player) || player.getLocation().getBlock().getType() != Material.AIR)
@ -227,7 +231,12 @@ public class AntiHack extends MiniPlugin
} }
} }
return (_ignore.containsKey(player) && System.currentTimeMillis() < _ignore.get(player)); if ((_ignore.containsKey(player) && System.currentTimeMillis() < _ignore.get(player)))
{
return true;
}
return false;
} }
public void addSuspicion(Player player, String type) public void addSuspicion(Player player, String type)
@ -235,62 +244,45 @@ public class AntiHack extends MiniPlugin
if (!_enabled) if (!_enabled)
return; return;
System.out.println(C.cRed + C.Bold + player.getName() + " suspected for " + type + ".");
synchronized (_antiHackLock) synchronized (_antiHackLock)
{ {
//Add Offense //Add Offense
if (!_suspicion.containsKey(player))
_suspicion.put(player, new HashMap<String, ArrayList<Long>>());
if (!_suspicion.get(player).containsKey(type))
_suspicion.get(player).put(type, new ArrayList<Long>());
_suspicion.get(player).get(type).add(System.currentTimeMillis());
}
for (Player admin : UtilServer.getPlayers())
if (admin.isOp() && UtilGear.isMat(admin.getItemInHand(), Material.PAPER))
UtilPlayer.message(admin, C.cRed + C.Bold + player.getName() + " suspected for " + type + ".");
// Print (Debug)
System.out.println("[Offense] " + player.getName() + " received suspicion for " + type + ".");
}
@EventHandler
public void processOffenses(UpdateEvent event)
{
if (!_enabled)
return;
if (event.getType() != UpdateType.SEC)
return;
synchronized (_antiHackLock)
{
for (Player player : _suspicion.keySet())
{
if (!_offense.containsKey(player)) if (!_offense.containsKey(player))
_offense.put(player, new HashMap<String, ArrayList<Long>>()); _offense.put(player, new HashMap<String, ArrayList<Long>>());
for (String type : _suspicion.get(player).keySet())
{
if (!_offense.get(player).containsKey(type)) if (!_offense.get(player).containsKey(type))
_offense.get(player).put(type, new ArrayList<Long>()); _offense.get(player).put(type, new ArrayList<Long>());
Iterator<Long> offenseIterator = _suspicion.get(player).get(type).iterator(); _offense.get(player).get(type).add(System.currentTimeMillis());
//Cull & Count
int total = 0;
for (String curType : _offense.get(player).keySet())
{
//Remove Old Offenses
Iterator<Long> offenseIterator = _offense.get(player).get(curType).iterator();
while (offenseIterator.hasNext()) while (offenseIterator.hasNext())
{ {
long time = offenseIterator.next(); if (UtilTime.elapsed(offenseIterator.next(), KeepOffensesFor))
//Suspicion turns into Offense
if (UtilTime.elapsed(time, FlightTriggerCancel))
{
offenseIterator.remove(); offenseIterator.remove();
_offense.get(player).get(type).add(time);
}
} }
//Count
total += _offense.get(player).get(curType).size();
} }
//Inform
for (Player admin : UtilServer.getPlayers())
if (_clientManager.Get(admin).GetRank().Has(Rank.MODERATOR) && _preferences.Get(admin).ShowMacReports)
{
UtilPlayer.message(admin, "#" + total + ": " + C.cRed + C.Bold + player.getName() + " suspected for " + type + ".");
} }
// Print (Debug)
System.out.println("[Offense] #" + total + ": "+ player.getName() + " received suspicion for " + type + ".");
} }
} }
@ -300,7 +292,7 @@ public class AntiHack extends MiniPlugin
if (!_enabled) if (!_enabled)
return; return;
if (event.getType() != UpdateType.SLOW) if (event.getType() != UpdateType.SEC)
return; return;
synchronized (_antiHackLock) synchronized (_antiHackLock)
@ -313,12 +305,12 @@ public class AntiHack extends MiniPlugin
for (String type : _offense.get(player).keySet()) for (String type : _offense.get(player).keySet())
{ {
//Remove Old Offenses //Remove Old Offenses
Iterator<Long> offenseIterator = _suspicion.get(player).get(type).iterator(); Iterator<Long> offenseIterator = _offense.get(player).get(type).iterator();
while (offenseIterator.hasNext()) while (offenseIterator.hasNext())
{ {
long time = offenseIterator.next(); long time = offenseIterator.next();
if (UtilTime.elapsed(time, 300000)) if (UtilTime.elapsed(time, KeepOffensesFor))
offenseIterator.remove(); offenseIterator.remove();
} }
@ -332,10 +324,10 @@ public class AntiHack extends MiniPlugin
if (out.length() > 0) if (out.length() > 0)
out = out.substring(0, out.length() - 2); out = out.substring(0, out.length() - 2);
String severity = ""; String severity;
if (total > 24) severity = "Extreme"; if (total > (_strict ? 6 : 18)) severity = "Extreme";
else if (total > 16) severity = "High"; else if (total > (_strict ? 4 : 12)) severity = "High";
else if (total > 8) severity = "Medium"; else if (total > (_strict ? 2 : 6)) severity = "Medium";
else severity = "Low"; else severity = "Low";
//Send Report //Send Report
@ -347,6 +339,28 @@ public class AntiHack extends MiniPlugin
public void sendReport(Player player, String report, String severity) public void sendReport(Player player, String report, String severity)
{ {
if (severity.equals("Extreme")) if (severity.equals("Extreme"))
{
ResetAll(player);
//Staff
boolean handled = false;
for (Player staff : UtilServer.getPlayers())
{
if (_clientManager.Get(staff).GetRank().Has(Rank.MODERATOR))
{
UtilPlayer.message(staff, C.cAqua + C.Scramble + "A" + ChatColor.RESET + C.cRed + C.Bold + " MAC > " + ChatColor.RESET + C.cYellow + report);
UtilPlayer.message(staff, C.cAqua + C.Scramble + "A" + ChatColor.RESET + C.cRed + C.Bold + " MAC > " + ChatColor.RESET + C.cGold + player.getName() + C.cYellow + " has extreme violation. Please investigate.");
handled = true;
}
}
//Auto-Kick
if (!handled)
{
player.playSound(player.getLocation(), Sound.ENDERDRAGON_GROWL, 2f, 0.5f);
if (_kick)
{ {
player.kickPlayer( player.kickPlayer(
C.cGold + "Mineplex Anti-Cheat" + "\n" + C.cGold + "Mineplex Anti-Cheat" + "\n" +
@ -354,9 +368,25 @@ public class AntiHack extends MiniPlugin
C.cWhite + "Cheating may result in a " + C.cRed + "Permanent Ban" + C.cWhite + "." + "\n" + C.cWhite + "Cheating may result in a " + C.cRed + "Permanent Ban" + C.cWhite + "." + "\n" +
C.cWhite + "If you were not cheating, you will not be banned." C.cWhite + "If you were not cheating, you will not be banned."
); );
}
else
{
UtilPlayer.message(player, C.cGold + C.Strike + "---------------------------------------------");
UtilPlayer.message(player, "");
UtilPlayer.message(player, C.cGold + "Mineplex Anti-Cheat");
UtilPlayer.message(player, "");
UtilPlayer.message(player, "You were kicked from the game for suspicious movement.");
UtilPlayer.message(player, "Cheating may result in a " + C.cRed + "Permanent Ban" + C.cWhite + ".");
UtilPlayer.message(player, "If you were not cheating, you will not be banned.");
UtilPlayer.message(player, "");
UtilPlayer.message(player, C.cGold + C.Strike + "---------------------------------------------");
Portal.SendPlayerToServer(player, "Lobby");
}
UtilServer.broadcast(F.main("MAC", player.getName() + " was kicked for suspicious movement.")); UtilServer.broadcast(F.main("MAC", player.getName() + " was kicked for suspicious movement."));
}
//Record
ServerListPingEvent event = new ServerListPingEvent(null, Bukkit.getServer().getMotd(), Bukkit.getServer().getOnlinePlayers().size(), Bukkit.getServer().getMaxPlayers()); ServerListPingEvent event = new ServerListPingEvent(null, Bukkit.getServer().getMotd(), Bukkit.getServer().getOnlinePlayers().size(), Bukkit.getServer().getMaxPlayers());
GetPluginManager().callEvent(event); GetPluginManager().callEvent(event);
@ -379,6 +409,12 @@ public class AntiHack extends MiniPlugin
} }
} }
private void Reset()
{
for (Player player : UtilServer.getPlayers())
ResetAll(player);
}
private void ResetAll(Player player) private void ResetAll(Player player)
{ {
synchronized (_antiHackLock) synchronized (_antiHackLock)
@ -389,9 +425,11 @@ public class AntiHack extends MiniPlugin
_offense.remove(player); _offense.remove(player);
_suspicion.remove(player);
for (Detector detector : _detectors) for (Detector detector : _movementDetectors)
detector.Reset(player);
for (Detector detector : _combatDetectors)
detector.Reset(player); detector.Reset(player);
} }
} }
@ -405,6 +443,8 @@ public class AntiHack extends MiniPlugin
if (event.getType() != UpdateType.SLOW) if (event.getType() != UpdateType.SLOW)
return; return;
synchronized (_antiHackLock)
{
for (Iterator<Entry<Player, Long>> playerIterator = _ignore.entrySet().iterator(); playerIterator.hasNext();) for (Iterator<Entry<Player, Long>> playerIterator = _ignore.entrySet().iterator(); playerIterator.hasNext();)
{ {
Player player = playerIterator.next().getKey(); Player player = playerIterator.next().getKey();
@ -417,17 +457,15 @@ public class AntiHack extends MiniPlugin
_lastMoveEvent.remove(player); _lastMoveEvent.remove(player);
_offense.remove(player); _offense.remove(player);
_suspicion.remove(player);
for (Detector detector : _detectors) for (Detector detector : _movementDetectors)
detector.Reset(player);
for (Detector detector : _combatDetectors)
detector.Reset(player); detector.Reset(player);
} }
} }
} }
public HashMap<Player, HashMap<String, ArrayList<Long>>> getOffenses()
{
return _offense;
} }
public void SetEnabled(boolean b) public void SetEnabled(boolean b)
@ -440,4 +478,25 @@ public class AntiHack extends MiniPlugin
{ {
return _enabled; return _enabled;
} }
public void setStrict(boolean strict)
{
_strict = strict;
Reset();
System.out.println("MAC Strict: " + strict);
}
public boolean isStrict()
{
return _strict;
}
public void setKick(boolean kick)
{
_kick = kick;
System.out.println("MAC Kick: " + kick);
}
} }

View File

@ -5,6 +5,7 @@ import java.sql.DriverManager;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import mineplex.core.database.DBPool;
import mineplex.core.logger.Logger; import mineplex.core.logger.Logger;
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer;
@ -12,15 +13,8 @@ import org.bukkit.entity.Player;
public class AntiHackRepository public class AntiHackRepository
{ {
private static Object _connectionLock = new Object();
private String _serverName; private String _serverName;
private static Connection _connection;
private String _connectionString = "jdbc:mysql://sqlstats.mineplex.com:3306/Mineplex?autoReconnect=true&failOverReadOnly=false&maxReconnects=10";
private String _userName = "root";
private String _password = "tAbechAk3wR7tuTh";
private static String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS AntiHack_Kick_Log (id INT NOT NULL AUTO_INCREMENT, updated LONG, playerName VARCHAR(256), motd VARCHAR(56), gameType VARCHAR(56), map VARCHAR(256), serverName VARCHAR(256), report VARCHAR(256), ping VARCHAR(25), PRIMARY KEY (id));"; private static String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS AntiHack_Kick_Log (id INT NOT NULL AUTO_INCREMENT, updated LONG, playerName VARCHAR(256), motd VARCHAR(56), gameType VARCHAR(56), map VARCHAR(256), serverName VARCHAR(256), report VARCHAR(256), ping VARCHAR(25), PRIMARY KEY (id));";
private static String UPDATE_PLAYER_OFFENSES = "INSERT INTO AntiHack_Kick_Log (updated, playerName, motd, gameType, map, serverName, report, ping) VALUES (now(), ?, ?, ?, ?, ?, ?, ?);"; private static String UPDATE_PLAYER_OFFENSES = "INSERT INTO AntiHack_Kick_Log (updated, playerName, motd, gameType, map, serverName, report, ping) VALUES (now(), ?, ?, ?, ?, ?, ?, ?);";
@ -33,13 +27,10 @@ public class AntiHackRepository
{ {
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
try try (Connection connection = DBPool.STATS_MINEPLEX.getConnection())
{ {
if (_connection == null || _connection.isClosed())
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
// Create table // Create table
preparedStatement = _connection.prepareStatement(CREATE_TABLE); preparedStatement = connection.prepareStatement(CREATE_TABLE);
preparedStatement.execute(); preparedStatement.execute();
} }
catch (Exception exception) catch (Exception exception)
@ -71,15 +62,9 @@ public class AntiHackRepository
{ {
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
synchronized (_connectionLock) try (Connection connection = DBPool.STATS_MINEPLEX.getConnection())
{ {
try preparedStatement = connection.prepareStatement(UPDATE_PLAYER_OFFENSES);
{
if (_connection == null || _connection.isClosed())
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
preparedStatement = _connection.prepareStatement(UPDATE_PLAYER_OFFENSES);
preparedStatement.setString(1, player.getName()); preparedStatement.setString(1, player.getName());
preparedStatement.setString(2, motd); preparedStatement.setString(2, motd);
@ -111,7 +96,6 @@ public class AntiHackRepository
} }
} }
} }
}
}).start(); }).start();
} }
} }

View File

@ -44,7 +44,7 @@ public class Fly extends MiniPlugin implements Detector
//100% Valid //100% Valid
if (Host.isValid(player, true)) if (Host.isValid(player, true))
return; Reset(player);
//Hasn't moved, just looking around //Hasn't moved, just looking around
if (UtilMath.offset(event.getFrom(), event.getTo()) <= 0) if (UtilMath.offset(event.getFrom(), event.getTo()) <= 0)
@ -52,6 +52,10 @@ public class Fly extends MiniPlugin implements Detector
updateFloat(player); updateFloat(player);
return; return;
} }
else
{
_floatTicks.remove(player);
}
updateHover(player); updateHover(player);
updateRise(player); updateRise(player);
@ -76,7 +80,7 @@ public class Fly extends MiniPlugin implements Detector
if (count > Host.FloatHackTicks) if (count > Host.FloatHackTicks)
{ {
Host.addSuspicion(player, "Fly (Float)"); Host.addSuspicion(player, "Fly (Float)");
count = 0; count -= 2;
} }
_floatTicks.put(player, new AbstractMap.SimpleEntry<Integer, Double>(count, player.getLocation().getY())); _floatTicks.put(player, new AbstractMap.SimpleEntry<Integer, Double>(count, player.getLocation().getY()));
@ -96,12 +100,14 @@ public class Fly extends MiniPlugin implements Detector
{ {
count = 0; count = 0;
} }
//player.sendMessage(count + " - " + player.getLocation().getY() + " vs " + _hoverTicks.get(player).getValue());
} }
if (count > Host.HoverHackTicks) if (count > Host.HoverHackTicks)
{ {
Host.addSuspicion(player, "Fly (Hover)"); Host.addSuspicion(player, "Fly (Hover)");
count = 0; count -= 2;
} }
_hoverTicks.put(player, new AbstractMap.SimpleEntry<Integer, Double>(count, player.getLocation().getY())); _hoverTicks.put(player, new AbstractMap.SimpleEntry<Integer, Double>(count, player.getLocation().getY()));
@ -113,7 +119,7 @@ public class Fly extends MiniPlugin implements Detector
if (_riseTicks.containsKey(player)) if (_riseTicks.containsKey(player))
{ {
if (player.getLocation().getY() > _riseTicks.get(player).getValue()) if (player.getLocation().getY() >= _riseTicks.get(player).getValue())
{ {
boolean nearBlocks = false; boolean nearBlocks = false;
for (Block block : UtilBlock.getSurrounding(player.getLocation().getBlock(), true)) for (Block block : UtilBlock.getSurrounding(player.getLocation().getBlock(), true))
@ -143,8 +149,11 @@ public class Fly extends MiniPlugin implements Detector
if (count > Host.RiseHackTicks) if (count > Host.RiseHackTicks)
{ {
//Only give Offense if actually rising - initial ticks can be trigged via Hover.
if (player.getLocation().getY() > _riseTicks.get(player).getValue())
Host.addSuspicion(player, "Fly (Rise)"); Host.addSuspicion(player, "Fly (Rise)");
count = 0;
count -= 2;
} }
_riseTicks.put(player, new AbstractMap.SimpleEntry<Integer, Double>(count, player.getLocation().getY())); _riseTicks.put(player, new AbstractMap.SimpleEntry<Integer, Double>(count, player.getLocation().getY()));

View File

@ -0,0 +1,124 @@
package mineplex.core.antihack.types;
import java.util.ArrayList;
import java.util.HashMap;
import mineplex.core.MiniPlugin;
import mineplex.core.antihack.AntiHack;
import mineplex.core.antihack.Detector;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.player.PlayerMoveEvent;
public class Reach extends MiniPlugin implements Detector
{
private AntiHack Host;
private HashMap<Player, ArrayList<Location>> _history = new HashMap<Player, ArrayList<Location>>();
public Reach (AntiHack host)
{
super("Speed Detector", host.GetPlugin());
Host = host;
}
@EventHandler(priority = EventPriority.LOWEST)
public void recordMove(UpdateEvent event)
{
if (!Host.IsEnabled())
return;
if (event.getType() != UpdateType.TICK)
return;
for (Player player : UtilServer.getPlayers())
{
if (player.getGameMode() != GameMode.SURVIVAL)
continue;
if (!_history.containsKey(player))
_history.put(player, new ArrayList<Location>());
_history.get(player).add(0, player.getLocation());
while (_history.get(player).size() > 40)
{
_history.get(player).remove(_history.get(player).size()-1);
}
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void reachDetect(EntityDamageEvent event)
{
if (event.getCause() != DamageCause.ENTITY_ATTACK)
return;
if (!(event.getEntity() instanceof Player))
return;
LivingEntity damagerEntity = UtilEvent.GetDamagerEntity(event, false);
if (!(damagerEntity instanceof Player))
return;
Player damager = (Player)damagerEntity;
Player damagee = (Player)event.getEntity();
if (!isInRange(damager.getLocation(), damagee.getLocation()))
{
ArrayList<Location> damageeHistory = _history.get(damagee);
if (damageeHistory != null)
{
for (Location historyLoc : damageeHistory)
{
if (isInRange(damager.getLocation(), historyLoc))
{
return;
}
}
}
//Host.addSuspicion(damager, "Reach");
}
}
private boolean isInRange(Location a, Location b)
{
//2d Range
double distFlat = UtilMath.offset2d(a, b); //Limit is 3.40
if (distFlat > 3.4)
{
return true;
}
//3d Range
double dist = UtilMath.offset(a, b); //Limit is 6 (highest i saw was 5.67)
if (dist > 6.0)
{
return true;
}
return false;
}
@Override
public void Reset(Player player)
{
_history.remove(player);
}
}

View File

@ -91,7 +91,7 @@ public class Speed extends MiniPlugin implements Detector
if (count > Host.SpeedHackTicks) if (count > Host.SpeedHackTicks)
{ {
Host.addSuspicion(player, "Speed (Fly/Move)"); Host.addSuspicion(player, "Speed (Fly/Move)");
count = 0; count -= 2;
} }
_speedTicks.put(player, new AbstractMap.SimpleEntry<Integer, Long>(count, System.currentTimeMillis())); _speedTicks.put(player, new AbstractMap.SimpleEntry<Integer, Long>(count, System.currentTimeMillis()));

View File

@ -94,6 +94,14 @@ public class BlockRestore extends MiniPlugin
_blocks.remove(block).restore(); _blocks.remove(block).restore();
} }
public void RestoreAll()
{
for (BlockRestoreData data : _blocks.values())
data.restore();
_blocks.clear();
}
public HashSet<Location> RestoreBlockAround(Material type, Location location, int radius) public HashSet<Location> RestoreBlockAround(Material type, Location location, int radius)
{ {
HashSet<Location> restored = new HashSet<Location>(); HashSet<Location> restored = new HashSet<Location>();
@ -120,9 +128,15 @@ public class BlockRestore extends MiniPlugin
return restored; return restored;
} }
public void Add(Block block, int toID, byte toData, long expireTime) public void Add(Block block, int toID, byte toData, long expireTime)
{ {
if (!Contains(block)) GetBlocks().put(block, new BlockRestoreData(block, toID, toData, expireTime, 0)); Add(block, toID, toData, block.getTypeId(), block.getData(), expireTime);
}
public void Add(Block block, int toID, byte toData, int fromID, byte fromData, long expireTime)
{
if (!Contains(block)) GetBlocks().put(block, new BlockRestoreData(block, toID, toData, fromID, fromData, expireTime, 0));
else GetData(block).update(toID, toData, expireTime); else GetData(block).update(toID, toData, expireTime);
} }
@ -175,7 +189,7 @@ public class BlockRestore extends MiniPlugin
//Snow //Snow
if (!Contains(block)) if (!Contains(block))
GetBlocks().put(block, new BlockRestoreData(block, 78, (byte)Math.max(0, heightAdd-1), expireTime, meltDelay)); GetBlocks().put(block, new BlockRestoreData(block, 78, (byte)Math.max(0, heightAdd-1), block.getTypeId(), block.getData(), expireTime, meltDelay));
else else
GetData(block).update(78, heightAdd, expireTime, meltDelay); GetData(block).update(78, heightAdd, expireTime, meltDelay);
} }

View File

@ -19,12 +19,12 @@ public class BlockRestoreData
protected long _meltDelay = 0; protected long _meltDelay = 0;
protected long _meltLast = 0; protected long _meltLast = 0;
public BlockRestoreData(Block block, int toID, byte toData, long expireDelay, long meltDelay) public BlockRestoreData(Block block, int toID, byte toData, int fromID, byte fromData, long expireDelay, long meltDelay)
{ {
_block = block; _block = block;
_fromID = block.getTypeId(); _fromID = fromID;
_fromData = block.getData(); _fromData = fromData;
_toID = toID; _toID = toID;
_toData = toData; _toData = toData;

View File

@ -67,27 +67,31 @@ public class Menu extends ShopPageBase<CosmeticManager, CosmeticShop>
ArrayList<String> lore = new ArrayList<String>(); ArrayList<String> lore = new ArrayList<String>();
lore.add(ChatColor.RESET + "You can find all kinds of rare");
lore.add(ChatColor.RESET + "" + treasureKeyCount + C.cGold + " Treasure Keys"); lore.add(ChatColor.RESET + "and exciting loot inside!");
lore.add(" ");
lore.add(ChatColor.RESET + C.cYellow + "Treasure Chests: " + ChatColor.RESET + treasureChestCount);
lore.add(ChatColor.RESET + C.cYellow + "Treasure Keys: " + ChatColor.RESET + treasureKeyCount);
lore.add(" "); lore.add(" ");
if (treasureChestCount > 0 && treasureKeyCount > 0) if (treasureChestCount > 0 && treasureKeyCount > 0)
{ {
lore.add(ChatColor.RESET + C.cGreen + "Left-Click to open Treasure Chest"); lore.add(ChatColor.RESET + C.cGreen + "Left-Click to open Treasure Chest");
lore.add(ChatColor.RESET + "Uses 1 Treasure Key"); lore.add(ChatColor.RESET + " Uses 1 Treasure Chest");
lore.add(ChatColor.RESET + "Uses 1 Treasure Chest"); lore.add(ChatColor.RESET + " Uses 1 Treasure Key");
} }
else if (treasureChestCount > 0) else if (treasureChestCount > 0)
{ {
lore.add(ChatColor.RESET + C.cRed + "Left-Click to open Treasure Chest"); lore.add(ChatColor.RESET + C.cRed + "Left-Click to open Treasure Chest");
lore.add(ChatColor.RESET + "This requires 1 Treasure Key"); lore.add(ChatColor.RESET + " This requires 1 Treasure Key");
lore.add(ChatColor.RESET + " You do not have any Treasure Keys");
} }
else else
{ {
lore.add(ChatColor.RESET + C.cRed + "Left-Click to open Treasure Chest"); lore.add(ChatColor.RESET + C.cRed + "Left-Click to open Treasure Chest");
lore.add(ChatColor.RESET + "This requires 1 Treasure Chest"); lore.add(ChatColor.RESET + " This requires 1 Treasure Chest");
lore.add(ChatColor.RESET + "Find Treasure Chests by playing games"); lore.add(ChatColor.RESET + " Find Treasure Chests by playing games");
} }
@ -95,19 +99,23 @@ public class Menu extends ShopPageBase<CosmeticManager, CosmeticShop>
if (canPurchaseKey) if (canPurchaseKey)
{ {
lore.add(ChatColor.RESET + C.cGreen + "Right-Click to purchase Treasure Key"); lore.add(ChatColor.RESET + C.cGreen + "Right-Click to purchase Treasure Key");
lore.add(ChatColor.RESET + "Costs 1000 Coins"); lore.add(ChatColor.RESET + " Costs 1000 Coins");
} }
else else
{ {
lore.add(ChatColor.RESET + C.cRed + "Right-Click to purchase Treasure Key"); lore.add(ChatColor.RESET + C.cRed + "Right-Click to purchase Treasure Key");
lore.add(ChatColor.RESET + "Costs 1000 Coins"); lore.add(ChatColor.RESET + " Costs 1000 Coins");
lore.add(ChatColor.RESET + " You cannot afford a Treasure Key");
} }
AddButton(4, new ShopItem(Material.CHEST, ChatColor.RESET + "" + treasureChestCount + C.cGold + " Treasure Chests", lore.toArray(new String[0]), 1, false), new TreasureButton(this, treasureChestCount > 0, treasureKeyCount > 0, canPurchaseKey)); AddButton(4, new ShopItem(Material.CHEST, ChatColor.RESET + C.cGreen + C.Bold + "Treasure Chest", lore.toArray(new String[0]), 1, false), new TreasureButton(this, treasureChestCount > 0, treasureKeyCount > 0, canPurchaseKey));
final GemBooster gemBoosterItem = new GemBooster(Shop.getBoosterEnabled(), Plugin.getInventoryManager().Get(Player).getItemCount("Gem Booster")); final GemBooster gemBoosterItem = new GemBooster(Shop.getBoosterEnabled(), Plugin.getInventoryManager().Get(Player).getItemCount("Gem Booster"));
if (DonationManager.Get(Player.getName()).GetBalance(CurrencyType.Coins) >= gemBoosterItem.GetCost(CurrencyType.Coins)
|| (Shop.getBoosterEnabled() && Plugin.getInventoryManager().Get(Player).getItemCount("Gem Booster") > 0))
{
AddButton(6, new ShopItem( AddButton(6, new ShopItem(
gemBoosterItem.GetDisplayMaterial(), gemBoosterItem.GetDisplayMaterial(),
gemBoosterItem.GetDisplayName(), gemBoosterItem.GetDisplayName(),
@ -140,14 +148,10 @@ public class Menu extends ShopPageBase<CosmeticManager, CosmeticShop>
} }
} }
); );
if (DonationManager.Get(Player.getName()).GetBalance(CurrencyType.Coins) >= gemBoosterItem.GetCost(CurrencyType.Coins))
{
} }
else else
{ {
AddItem(15, new ShopItem( AddItem(6, new ShopItem(
gemBoosterItem.GetDisplayMaterial(), gemBoosterItem.GetDisplayMaterial(),
gemBoosterItem.GetDisplayName(), gemBoosterItem.GetDisplayName(),
gemBoosterItem.GetDescription(), gemBoosterItem.GetDescription(),

View File

@ -9,6 +9,7 @@ import net.minecraft.server.v1_7_R4.Items;
import net.minecraft.server.v1_7_R4.PacketPlayOutOpenWindow; import net.minecraft.server.v1_7_R4.PacketPlayOutOpenWindow;
import net.minecraft.server.v1_7_R4.PacketPlayOutSetSlot; import net.minecraft.server.v1_7_R4.PacketPlayOutSetSlot;
import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer;
import org.bukkit.entity.Creature; import org.bukkit.entity.Creature;
@ -54,25 +55,45 @@ public class PetPage extends ShopPageBase<CosmeticManager, CosmeticShop>
{ {
List<String> itemLore = new ArrayList<String>(); List<String> itemLore = new ArrayList<String>();
itemLore.add(C.cYellow + pet.GetCost(CurrencyType.Coins) + " Coins"); //Halloween Name
if (pet.GetCost(CurrencyType.Coins) == -1)
{
itemLore.add(C.cBlack); itemLore.add(C.cBlack);
itemLore.add(ChatColor.RESET + C.cYellow + "Earned by defeating the Pumpkin King");
itemLore.add(ChatColor.RESET + C.cYellow + "in the 2014 Halloween Horror Event.");
}
//Owned
if (DonationManager.Get(Player.getName()).OwnsUnknownPackage(pet.GetPetName())) if (DonationManager.Get(Player.getName()).OwnsUnknownPackage(pet.GetPetName()))
{ {
if (Plugin.getPetManager().hasActivePet(Player.getName()) && Plugin.getPetManager().getActivePet(Player.getName()).getType() == pet.GetPetType()) if (Plugin.getPetManager().hasActivePet(Player.getName()) && Plugin.getPetManager().getActivePet(Player.getName()).getType() == pet.GetPetType())
{ {
AddButton(slot, new ShopItem(Material.MONSTER_EGG, (byte)pet.GetPetType().getTypeId(), "Deactivate " + Plugin.getPetManager().Get(Player).GetPets().get(pet.GetPetType()), new String[] {}, 1, false, false), new DeactivatePetButton(this, Plugin.getPetManager())); AddButton(slot, new ShopItem(Material.MONSTER_EGG, (byte)pet.GetPetType().getTypeId(),
"Deactivate " + pet.GetPetName() + " (" + C.cWhite + Plugin.getPetManager().Get(Player).GetPets().get(pet.GetPetType()) + C.cGreen + ")",
itemLore.toArray(new String[itemLore.size()]), 1, false, false), new DeactivatePetButton(this, Plugin.getPetManager()));
addGlow(slot); addGlow(slot);
} }
else else
{ {
AddButton(slot, new ShopItem(Material.MONSTER_EGG, (byte)pet.GetPetType().getTypeId(), "Activate " + Plugin.getPetManager().Get(Player).GetPets().get(pet.GetPetType()), new String[] {}, 1, false, false), new ActivatePetButton(pet, this)); AddButton(slot, new ShopItem(Material.MONSTER_EGG, (byte)pet.GetPetType().getTypeId(),
"Activate " + pet.GetPetName() + " (" + C.cWhite + Plugin.getPetManager().Get(Player).GetPets().get(pet.GetPetType()) + C.cGreen + ")",
itemLore.toArray(new String[itemLore.size()]), 1, false, false), new ActivatePetButton(pet, this));
} }
} }
//Not Owned
else else
{ {
if (DonationManager.Get(Player.getName()).GetBalance(CurrencyType.Coins) >= pet.GetCost(CurrencyType.Coins)) //Cost Lore
if (pet.GetCost(CurrencyType.Coins) > 0)
{
itemLore.add(C.cYellow + pet.GetCost(CurrencyType.Coins) + " Coins");
itemLore.add(C.cBlack);
}
if (pet.GetCost(CurrencyType.Coins) == -1)
setItem(slot, new ShopItem(Material.INK_SACK, (byte)8, pet.GetPetName(), itemLore.toArray(new String[itemLore.size()]), 1, true, false));
else if (DonationManager.Get(Player.getName()).GetBalance(CurrencyType.Coins) >= pet.GetCost(CurrencyType.Coins))
AddButton(slot, new ShopItem(Material.INK_SACK, (byte)8, "Purchase " + pet.GetPetName(), itemLore.toArray(new String[itemLore.size()]), 1, false, false), new PetButton(pet, this)); AddButton(slot, new ShopItem(Material.INK_SACK, (byte)8, "Purchase " + pet.GetPetName(), itemLore.toArray(new String[itemLore.size()]), 1, false, false), new PetButton(pet, this));
else else
setItem(slot, new ShopItem(Material.INK_SACK, (byte)8, "Purchase " + pet.GetPetName(), itemLore.toArray(new String[itemLore.size()]), 1, true, false)); setItem(slot, new ShopItem(Material.INK_SACK, (byte)8, "Purchase " + pet.GetPetName(), itemLore.toArray(new String[itemLore.size()]), 1, true, false));
@ -131,7 +152,7 @@ public class PetPage extends ShopPageBase<CosmeticManager, CosmeticShop>
PetTagPage petTagPage = new PetTagPage(Plugin, Shop, ClientManager, DonationManager, "Repairing", Player, pet, petPurchase); PetTagPage petTagPage = new PetTagPage(Plugin, Shop, ClientManager, DonationManager, "Repairing", Player, pet, petPurchase);
EntityPlayer entityPlayer = ((CraftPlayer)Player).getHandle(); EntityPlayer entityPlayer = ((CraftPlayer)Player).getHandle();
int containerCounter = entityPlayer.nextContainerCounter(); int containerCounter = entityPlayer.nextContainerCounter();
entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(containerCounter, 8, "Repairing", 9, true)); entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(containerCounter, 8, "Repairing", 0, true));
entityPlayer.activeContainer = new AnvilContainer(entityPlayer.inventory, petTagPage.getInventory()); entityPlayer.activeContainer = new AnvilContainer(entityPlayer.inventory, petTagPage.getInventory());
entityPlayer.activeContainer.windowId = containerCounter; entityPlayer.activeContainer.windowId = containerCounter;
entityPlayer.activeContainer.addSlotListener(entityPlayer); entityPlayer.activeContainer.addSlotListener(entityPlayer);

View File

@ -62,7 +62,10 @@ public class PetTagPage extends ShopPageBase<CosmeticManager, CosmeticShop>
public void SelectTag() public void SelectTag()
{ {
if (ChatColor.stripColor(_tagName).length() > 16) _tagName = ChatColor.stripColor(_tagName);
_tagName = _tagName.replaceAll("[^A-Za-z0-9]", "");
if (_tagName.length() > 16)
{ {
UtilPlayer.message(Player, F.main(Plugin.GetName(), ChatColor.RED + "Pet name cannot be longer than 16 characters.")); UtilPlayer.message(Player, F.main(Plugin.GetName(), ChatColor.RED + "Pet name cannot be longer than 16 characters."));
PlayDenySound(Player); PlayDenySound(Player);

View File

@ -0,0 +1,25 @@
package mineplex.core.data;
import org.bukkit.block.Block;
import org.bukkit.Material;
public class BlockData
{
public Block Block;
public Material Material;
public byte Data;
public long Time;
public BlockData(Block block)
{
Block = block;
Material = block.getType();
Data = block.getData();
Time = System.currentTimeMillis();
}
public void restore()
{
Block.setTypeIdAndData(Material.getId(), Data, true);
}
}

View File

@ -0,0 +1,38 @@
package mineplex.core.database;
import javax.sql.DataSource;
import java.sql.Connection;
import org.apache.commons.dbcp2.BasicDataSource;
public final class DBPool
{
public static final DataSource ACCOUNT = openDataSource("jdbc:mysql://db.mineplex.com/Account", "root", "tAbechAk3wR7tuTh");
public static final DataSource QUEUE = openDataSource("jdbc:mysql://db.mineplex.com/Queue", "root", "tAbechAk3wR7tuTh");
public static final DataSource MINEPLEX = openDataSource("jdbc:mysql://db.mineplex.com:3306/Mineplex", "root", "tAbechAk3wR7tuTh");
public static final DataSource STATS_MINEPLEX = openDataSource("jdbc:mysql://sqlstats.mineplex.com:3306/Mineplex", "root", "tAbechAk3wR7tuTh");
private static DataSource openDataSource(String url, String username, String password)
{
BasicDataSource source = new BasicDataSource();
source.addConnectionProperty("autoReconnect", "true");
source.setDefaultAutoCommit(true);
source.setEnableAutoCommitOnReturn(true);
source.setDefaultTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
source.setDriverClassName("com.mysql.jdbc.Driver");
source.setUrl(url);
source.setUsername(username);
source.setPassword(password);
source.setMaxTotal(10);
source.setMaxIdle(3);
source.setTimeBetweenEvictionRunsMillis(180 * 1000);
source.setSoftMinEvictableIdleTimeMillis(180 * 1000);
return source;
}
private DBPool()
{
}
}

View File

@ -1,6 +0,0 @@
package mineplex.core.database;
public class DatabaseManager
{
}

View File

@ -0,0 +1,27 @@
package mineplex.core.database;
public class DatabaseRunnable
{
private Runnable _runnable;
private int _failedAttempts = 0;
public DatabaseRunnable(Runnable runnable)
{
_runnable = runnable;
}
public void run()
{
_runnable.run();
}
public void incrementFailCount()
{
_failedAttempts++;
}
public int getFailedCounts()
{
return _failedAttempts;
}
}

View File

@ -5,24 +5,39 @@ import java.sql.DriverManager;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Iterator;
import mineplex.core.common.util.NautHashMap;
import mineplex.core.database.column.Column; import mineplex.core.database.column.Column;
import mineplex.core.logger.Logger;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
public abstract class RepositoryBase public abstract class RepositoryBase implements Listener
{ {
protected static Object _connectionLock = new Object(); protected static Object _connectionLock = new Object();
private Connection _connection = null; private Connection _connection = null;
private static Object _queueLock = new Object();
private NautHashMap<DatabaseRunnable, String> _failedQueue = new NautHashMap<DatabaseRunnable, String>();
private String _connectionString; private String _connectionString;
private String _userName; private String _userName;
private String _password; private String _password;
protected JavaPlugin Plugin;
public RepositoryBase(JavaPlugin plugin, String connectionString, String username, String password) public RepositoryBase(JavaPlugin plugin, String connectionString, String username, String password)
{ {
Plugin = plugin;
_connectionString = connectionString; _connectionString = connectionString;
_userName = username; _userName = username;
_password = password; _password = password;
@ -38,6 +53,8 @@ public abstract class RepositoryBase
} }
} }
}); });
plugin.getServer().getPluginManager().registerEvents(this, plugin);
} }
protected abstract void initialize(); protected abstract void initialize();
@ -189,4 +206,81 @@ public abstract class RepositoryBase
return affectedRows; return affectedRows;
} }
protected void handleDatabaseCall(final DatabaseRunnable databaseRunnable, final String errorMessage)
{
Thread asyncThread = new Thread(new Runnable()
{
public void run()
{
try
{
databaseRunnable.run();
}
catch (Exception exception)
{
Logger.Instance.log(errorMessage + exception.getMessage());
databaseRunnable.incrementFailCount();
synchronized (_queueLock)
{
_failedQueue.put(databaseRunnable, errorMessage);
}
}
}
});
asyncThread.start();
}
@EventHandler
public void processDatabaseQueue(UpdateEvent event)
{
if (event.getType() != UpdateType.MIN_01)
return;
processFailedQueue();
}
private void processFailedQueue()
{
synchronized (_queueLock)
{
for (Iterator<DatabaseRunnable> runnablesIterator = _failedQueue.keySet().iterator(); runnablesIterator.hasNext();)
{
final DatabaseRunnable databaseRunnable = runnablesIterator.next();
Thread asyncThread = new Thread(new Runnable()
{
public void run()
{
try
{
databaseRunnable.run();
}
catch (Exception exception)
{
Logger.Instance.log(_failedQueue.get(databaseRunnable) + exception.getMessage());
if (databaseRunnable.getFailedCounts() < 4)
{
synchronized (_queueLock)
{
_failedQueue.put(databaseRunnable, _failedQueue.get(databaseRunnable));
}
}
else
{
Logger.Instance.log("Abandoning database call : " + _failedQueue.get(databaseRunnable));
}
}
}
});
runnablesIterator.remove();
asyncThread.start();
}
}
}
} }

View File

@ -1,417 +0,0 @@
package mineplex.core.database;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import mineplex.core.common.util.NautHashMap;
import mineplex.core.database.column.Column;
public class Table
{
private static Connection _connection;
private String _connectionString = "jdbc:mysql://db.mineplex.com:3306/Mineplex?autoReconnect=true&failOverReadOnly=false&maxReconnects=10";
private String _userName = "root";
private String _password = "tAbechAk3wR7tuTh";
private String _name;
private List<Column<?>> _primaryKeys;
private NautHashMap<String, Column<?>> _columns = new NautHashMap<String, Column<?>>();
private Column<?> _index;
public Table(String name, List<Column<?>> primaryKeys, List<Column<?>> columns, Column<?> index)
{
_name = name;
_primaryKeys = primaryKeys;
for (Column<?> column : columns)
{
_columns.put(column.Name, column);
}
_index = index;
}
public void initialize()
{
if (!doesTableExist())
{
create();
}
}
/*
private void updateSchema()
{
PreparedStatement getTableColumns = null;
ResultSet resultSet = null;
try
{
if (_connection == null || _connection.isClosed())
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
getTableColumns = _connection.prepareStatement("SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '`" + _name + "`' AND table_schema = 'Mineplex';");
resultSet = getTableColumns.executeQuery();
HashSet<String> columnExists = new HashSet<String>();
while (resultSet.next())
{
columnExists.add(resultSet.getString("COLUMN_NAME"));
}
}
catch (Exception exception)
{
System.out.println("Error updating table `" + _name + "`.");
exception.printStackTrace();
}
finally
{
if (getTableColumns != null)
{
try
{
getTableColumns.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
if (resultSet != null)
{
try
{
resultSet.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
*/
private void create()
{
PreparedStatement createStatement = null;
try
{
StringBuilder columnBuilder = new StringBuilder();
for (Iterator<Column<?>> columnIterator = _columns.values().iterator(); columnIterator.hasNext();)
{
Column<?> column = columnIterator.next();
columnBuilder.append(column.getCreateString());
if (columnIterator.hasNext())
{
columnBuilder.append(", ");
}
}
StringBuilder primaryKey = new StringBuilder();
for (Column<?> column : _primaryKeys)
{
primaryKey.append(column.Name);
if (!column.equals(_primaryKeys.get(_primaryKeys.size() - 1)))
{
primaryKey.append(", ");
}
}
if (_connection == null || _connection.isClosed())
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
createStatement = _connection.prepareStatement("CREATE TABLE IF NOT EXISTS `" + _name + "` (" + columnBuilder.toString() + ", PRIMARY KEY (" + primaryKey.toString() + "), INDEX (" + _index.Name + "));");
createStatement.execute();
}
catch (Exception exception)
{
System.out.println("Error creating table `" + _name + "`.");
exception.printStackTrace();
}
finally
{
if (createStatement != null)
{
try
{
createStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
private boolean doesTableExist()
{
PreparedStatement checkIfTableExistsStatement = null;
try
{
if (_connection == null || _connection.isClosed())
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
checkIfTableExistsStatement = _connection.prepareStatement("SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = 'Mineplex' AND table_name LIKE '`" + _name + "`'");
if (checkIfTableExistsStatement.executeQuery().next())
return true;
}
catch (Exception exception)
{
System.out.println("Error updating table `" + _name + "`.");
exception.printStackTrace();
}
finally
{
if (checkIfTableExistsStatement != null)
{
try
{
checkIfTableExistsStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
return false;
}
public void insert(List<Column<?>> columns)
{
StringBuilder temporaryBuilder = new StringBuilder();
StringBuilder questionBuilder = new StringBuilder();
StringBuilder updateBuilder = new StringBuilder();
for (Column<?> column : columns)
{
temporaryBuilder.append(column.Name);
questionBuilder.append("'" + column.Value + "'");
updateBuilder.append(column.Name + " = VALUES(" + column.Name + ")");
if (!column.equals(columns.get(columns.size() - 1)))
{
temporaryBuilder.append(", ");
questionBuilder.append(", ");
updateBuilder.append(", ");
}
}
PreparedStatement preparedStatement = null;
try
{
if (_connection == null || _connection.isClosed())
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
preparedStatement = _connection.prepareStatement("INSERT INTO `" + _name + "` (" + temporaryBuilder.toString() + ") VALUES (" + questionBuilder.toString() + ") ON DUPLICATE KEY UPDATE " + updateBuilder.toString() + ";", Statement.RETURN_GENERATED_KEYS);
preparedStatement.execute();
}
catch (Exception exception)
{
System.out.println("Error updating table `" + _name + "`.");
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
public boolean update(List<Column<?>> columns, Column<?> whereColumn)
{
List<Column<?>> whereColumnList = new ArrayList<Column<?>>();
whereColumnList.add(whereColumn);
return update(columns, whereColumnList);
}
public boolean update(List<Column<?>> columns, List<Column<?>> whereColumns)
{
String updateStatement = buildUpdateStatement(columns, whereColumns);
PreparedStatement preparedStatement = null;
try
{
if (_connection == null || _connection.isClosed())
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
preparedStatement = _connection.prepareStatement(updateStatement);
if (preparedStatement.executeUpdate() != 0)
return true;
}
catch (Exception exception)
{
System.out.println("Error updating table `" + _name + "`.");
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
return false;
}
public List<Row> retrieve(List<Column<?>> columns)
{
StringBuilder temporaryBuilder = new StringBuilder();
for (Iterator<Column<?>> columnIterator = _columns.values().iterator(); columnIterator.hasNext();)
{
Column<?> column = columnIterator.next();
temporaryBuilder.append(column.Name);
if (columnIterator.hasNext())
temporaryBuilder.append(", ");
}
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
List<Row> rows = new ArrayList<Row>();
try
{
if (_connection == null || _connection.isClosed())
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
preparedStatement = _connection.prepareStatement("Select " + temporaryBuilder.toString() + " FROM `" + _name + "` " + buildWhereString(columns) + ";");
resultSet = preparedStatement.executeQuery();
while (resultSet.next())
{
Row row = new Row();
for (Column<?> column : columns)
{
column.getValue(resultSet);
row.Columns.put(column.Name, column);
}
rows.add(row);
}
}
catch (Exception exception)
{
System.out.println("Error updating table `" + _name + "`.");
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
return rows;
}
private String buildUpdateStatement(List<Column<?>> columns, List<Column<?>> whereColumns)
{
StringBuilder setBuilder = new StringBuilder();
if (columns.size() > 0)
setBuilder.append("SET ");
for (Column<?> column : columns)
{
setBuilder.append(column.Name + " = '" + column.Value + "'");
if (!column.equals(columns.get(columns.size() - 1)))
setBuilder.append(", ");
}
return "UPDATE `" + _name + "` " + setBuilder.toString() + " " + buildWhereString(whereColumns) + ";";
}
private String buildWhereString(List<Column<?>> columns)
{
StringBuilder whereBuilder = new StringBuilder();
if (columns.size() > 0)
{
whereBuilder.append("WHERE ");
}
for (Column<?> column : columns)
{
whereBuilder.append(column.Name + " = '" + column.Value + "'");
if (!column.equals(columns.get(columns.size() - 1)))
whereBuilder.append(" AND ");
}
return whereBuilder.toString();
}
public Column<?> getColumn(String columnName)
{
return _columns.get(columnName);
}
public Row createRow()
{
Row row = new Row();
for (Column<?> column : _columns.values())
{
row.Columns.put(column.Name, column);
}
return row;
}
}

View File

@ -0,0 +1,42 @@
package mineplex.core.database.column;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ColumnBoolean extends Column<Boolean>
{
public ColumnBoolean(String name)
{
super(name);
}
public ColumnBoolean(String name, boolean value)
{
super(name, value);
}
@Override
public String getCreateString()
{
return Name + " BOOLEAN";
}
@Override
public Boolean getValue(ResultSet resultSet) throws SQLException
{
return resultSet.getBoolean(Name);
}
@Override
public void setValue(PreparedStatement preparedStatement, int columnNumber) throws SQLException
{
preparedStatement.setBoolean(columnNumber, Value);
}
@Override
public ColumnBoolean clone()
{
return new ColumnBoolean(Name, Value);
}
}

View File

@ -0,0 +1,43 @@
package mineplex.core.database.column;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
public class ColumnTimestamp extends Column<Timestamp>
{
public ColumnTimestamp(String name)
{
super(name);
}
public ColumnTimestamp(String name, Timestamp value)
{
super(name, value);
}
@Override
public String getCreateString()
{
return Name + " TIMESTAMP";
}
@Override
public Timestamp getValue(ResultSet resultSet) throws SQLException
{
return resultSet.getTimestamp(Name);
}
@Override
public void setValue(PreparedStatement preparedStatement, int columnNumber) throws SQLException
{
preparedStatement.setTimestamp(columnNumber, Value);
}
@Override
public ColumnTimestamp clone()
{
return new ColumnTimestamp(Name, Value);
}
}

View File

@ -0,0 +1,80 @@
package mineplex.core.donation;
import java.util.UUID;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UUIDFetcher;
import mineplex.core.common.util.UtilPlayer;
public class CoinCommand extends CommandBase<DonationManager>
{
public CoinCommand(DonationManager plugin)
{
super(plugin, Rank.ADMIN, "coin");
}
@Override
public void Execute(final Player caller, String[] args)
{
if (args.length < 2)
{
UtilPlayer.message(caller, F.main("Coin", "Missing Args: " + F.elem("/coin <player> <amount>")));
return;
}
String targetName = args[0];
String coinsString = args[1];
Player target = UtilPlayer.searchExact(targetName);
if (target == null)
{
UUID uuid = UUIDFetcher.getUUIDOf(targetName);
if (uuid != null)
{
rewardCoins(caller, null, targetName, uuid, coinsString);
}
else
{
UtilPlayer.message(caller, F.main("Coin", "Could not find player " + F.name(targetName)));
}
}
else
{
rewardCoins(caller, target, target.getName(), target.getUniqueId(), coinsString);
}
}
private void rewardCoins(final Player caller, final Player target, final String targetName, final UUID uuid, String coinsString)
{
try
{
int coins = Integer.parseInt(coinsString);
rewardCoins(caller, target, targetName, uuid, coins);
}
catch (Exception e)
{
UtilPlayer.message(caller, F.main("Coin", "Invalid Coins Amount"));
}
}
private void rewardCoins(final Player caller, final Player target, final String targetName, final UUID uuid, final int coins)
{
Plugin.RewardCoins(new Callback<Boolean>()
{
public void run(Boolean completed)
{
UtilPlayer.message(caller, F.main("Coin", "You gave " + F.elem(coins + " Coins") + " to " + F.name(targetName) + "."));
if (target != null)
{
UtilPlayer.message(target, F.main("Coin", F.name(caller.getName()) + " gave you " + F.elem(coins + " Coins") + "."));
}
}
}, caller.getName(), targetName, uuid, coins);
}
}

View File

@ -1,5 +1,12 @@
package mineplex.core.donation; package mineplex.core.donation;
import java.util.UUID;
import org.bukkit.craftbukkit.libs.com.google.gson.Gson;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniPlugin; import mineplex.core.MiniPlugin;
import mineplex.core.account.event.ClientUnloadEvent; import mineplex.core.account.event.ClientUnloadEvent;
import mineplex.core.account.event.ClientWebResponseEvent; import mineplex.core.account.event.ClientWebResponseEvent;
@ -12,10 +19,6 @@ import mineplex.core.server.util.TransactionResponse;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import org.bukkit.craftbukkit.libs.com.google.gson.Gson;
import org.bukkit.event.EventHandler;
import org.bukkit.plugin.java.JavaPlugin;
public class DonationManager extends MiniPlugin public class DonationManager extends MiniPlugin
{ {
private DonationRepository _repository; private DonationRepository _repository;
@ -24,13 +27,14 @@ public class DonationManager extends MiniPlugin
private Object _donorLock = new Object(); private Object _donorLock = new Object();
private NautHashMap<String, NautHashMap<String, Integer>> _gemQueue = new NautHashMap<String, NautHashMap<String, Integer>>(); private NautHashMap<Player, NautHashMap<String, Integer>> _gemQueue = new NautHashMap<Player, NautHashMap<String, Integer>>();
private NautHashMap<Player, NautHashMap<String, Integer>> _coinQueue = new NautHashMap<Player, NautHashMap<String, Integer>>();
public DonationManager(JavaPlugin plugin, String webAddress) public DonationManager(JavaPlugin plugin, String webAddress)
{ {
super("Donation", plugin); super("Donation", plugin);
_repository = new DonationRepository(webAddress); _repository = new DonationRepository(plugin, webAddress);
_donors = new NautHashMap<String, Donor>(); _donors = new NautHashMap<String, Donor>();
} }
@ -39,13 +43,14 @@ public class DonationManager extends MiniPlugin
public void AddCommands() public void AddCommands()
{ {
AddCommand(new GemCommand(this)); AddCommand(new GemCommand(this));
AddCommand(new CoinCommand(this));
} }
@EventHandler @EventHandler
public void OnClientWebResponse(ClientWebResponseEvent event) public void OnClientWebResponse(ClientWebResponseEvent event)
{ {
DonorTokenWrapper token = new Gson().fromJson(event.GetResponse(), DonorTokenWrapper.class); DonorTokenWrapper token = new Gson().fromJson(event.GetResponse(), DonorTokenWrapper.class);
LoadDonor(token); LoadDonor(token, event.getUniqueId());
} }
@EventHandler @EventHandler
@ -57,11 +62,12 @@ public class DonationManager extends MiniPlugin
} }
} }
private void LoadDonor(DonorTokenWrapper token) private void LoadDonor(DonorTokenWrapper token, UUID uuid)
{ {
synchronized (_donorLock) synchronized (_donorLock)
{ {
_donors.put(token.Name, new Donor(token.DonorToken)); _donors.put(token.Name, new Donor(token.DonorToken));
_repository.updateGemsAndCoins(uuid, Get(token.Name).GetGems(), Get(token.Name).getCoins());
} }
} }
@ -73,7 +79,7 @@ public class DonationManager extends MiniPlugin
} }
} }
public void PurchaseUnknownSalesPackage(final Callback<TransactionResponse> callback, final String name, final String packageName, final boolean coinPurchase, final int cost, boolean oneTimePurchase) public void PurchaseUnknownSalesPackage(final Callback<TransactionResponse> callback, final String name, final UUID uuid, final String packageName, final boolean coinPurchase, final int cost, boolean oneTimePurchase)
{ {
Donor donor = Get(name); Donor donor = Get(name);
@ -106,10 +112,10 @@ public class DonationManager extends MiniPlugin
if (callback != null) if (callback != null)
callback.run(response); callback.run(response);
} }
}, name, packageName, coinPurchase, cost); }, name, uuid.toString(), packageName, coinPurchase, cost);
} }
public void PurchaseKnownSalesPackage(final Callback<TransactionResponse> callback, final String name, final int salesPackageId) public void PurchaseKnownSalesPackage(final Callback<TransactionResponse> callback, final String name, final UUID uuid, final int cost, final int salesPackageId)
{ {
_repository.PurchaseKnownSalesPackage(new Callback<TransactionResponse>() _repository.PurchaseKnownSalesPackage(new Callback<TransactionResponse>()
{ {
@ -128,17 +134,17 @@ public class DonationManager extends MiniPlugin
if (callback != null) if (callback != null)
callback.run(response); callback.run(response);
} }
}, name, salesPackageId); }, name, uuid.toString(), cost, salesPackageId);
} }
public void RewardGems(final Callback<Boolean> callback, final String caller, final String name, final int amount) public void RewardGems(Callback<Boolean> callback, String caller, String name, UUID uuid, int amount)
{ {
RewardGems(callback, caller, name, amount, true); RewardGems(callback, caller, name, uuid, amount, true);
} }
public void RewardGems(final Callback<Boolean> callback, final String caller, final String name, final int amount, final boolean updateTotal) public void RewardGems(final Callback<Boolean> callback, final String caller, final String name, final UUID uuid, final int amount, final boolean updateTotal)
{ {
_repository.PlayerUpdate(new Callback<Boolean>() _repository.gemReward(new Callback<Boolean>()
{ {
public void run(Boolean success) public void run(Boolean success)
{ {
@ -158,23 +164,23 @@ public class DonationManager extends MiniPlugin
callback.run(true); callback.run(true);
} }
} }
}, caller, name, amount); }, caller, name, uuid.toString(), amount);
} }
public void RewardGemsLater(final String caller, final String name, final int amount) public void RewardGemsLater(final String caller, final Player player, final int amount)
{ {
if (!_gemQueue.containsKey(name)) if (!_gemQueue.containsKey(player))
_gemQueue.put(name, new NautHashMap<String, Integer>()); _gemQueue.put(player, new NautHashMap<String, Integer>());
int totalAmount = amount; int totalAmount = amount;
if (_gemQueue.get(name).containsKey(caller)) if (_gemQueue.get(player).containsKey(caller))
totalAmount += _gemQueue.get(name).get(caller); totalAmount += _gemQueue.get(player).get(caller);
_gemQueue.get(name).put(caller, totalAmount); _gemQueue.get(player).put(caller, totalAmount);
//Do Temp Change //Do Temp Change
Donor donor = Get(name); Donor donor = Get(player.getName());
if (donor != null) if (donor != null)
donor.AddGems(amount); donor.AddGems(amount);
@ -186,39 +192,39 @@ public class DonationManager extends MiniPlugin
if (event.getType() != UpdateType.SLOWER) if (event.getType() != UpdateType.SLOWER)
return; return;
for (String name : _gemQueue.keySet()) for (Player player : _gemQueue.keySet())
{ {
String caller = null; String caller = null;
int total = 0; int total = 0;
for (String curCaller : _gemQueue.get(name).keySet()) for (String curCaller : _gemQueue.get(player).keySet())
{ {
caller = curCaller; caller = curCaller;
total += _gemQueue.get(name).get(curCaller); total += _gemQueue.get(player).get(curCaller);
} }
if (caller == null) if (caller == null)
continue; continue;
//Actually Add Gems //Actually Add Gems
RewardGems(null, caller, name, total, false); RewardGems(null, caller, player.getName(), player.getUniqueId(), total, false);
System.out.println("Queue Added [" + name + "] with Gems [" + total + "] for [" + caller + "]"); System.out.println("Queue Added [" + player + "] with Gems [" + total + "] for [" + caller + "]");
//Clean //Clean
_gemQueue.get(name).clear(); _gemQueue.get(player).clear();
} }
//Clean //Clean
_gemQueue.clear(); _gemQueue.clear();
} }
public void RewardCoins(final Callback<Boolean> callback, final String caller, final String name, final int amount) public void RewardCoins(Callback<Boolean> callback, String caller, String name, UUID uuid, int amount)
{ {
RewardCoins(callback, caller, name, amount, true); RewardCoins(callback, caller, name, uuid, amount, true);
} }
public void RewardCoins(final Callback<Boolean> callback, final String caller, final String name, final int amount, final boolean updateTotal) public void RewardCoins(final Callback<Boolean> callback, final String caller, final String name, final UUID uuid, final int amount, final boolean updateTotal)
{ {
_repository.rewardCoins(new Callback<Boolean>() _repository.rewardCoins(new Callback<Boolean>()
{ {
@ -240,6 +246,58 @@ public class DonationManager extends MiniPlugin
callback.run(true); callback.run(true);
} }
} }
}, caller, name, amount); }, caller, name, uuid.toString(), amount);
}
public void RewardCoinsLater(final String caller, final Player player, final int amount)
{
if (!_coinQueue.containsKey(player))
_coinQueue.put(player, new NautHashMap<String, Integer>());
int totalAmount = amount;
if (_coinQueue.get(player).containsKey(caller))
totalAmount += _coinQueue.get(player).get(caller);
_coinQueue.get(player).put(caller, totalAmount);
//Do Temp Change
Donor donor = Get(player.getName());
if (donor != null)
donor.addCoins(amount);
}
@EventHandler
public void UpdateCoinQueue(UpdateEvent event)
{
if (event.getType() != UpdateType.SLOWER)
return;
for (Player player : _coinQueue.keySet())
{
String caller = null;
int total = 0;
for (String curCaller : _coinQueue.get(player).keySet())
{
caller = curCaller;
total += _coinQueue.get(player).get(curCaller);
}
if (caller == null)
continue;
//Actually Add Gems
RewardCoins(null, caller, player.getName(), player.getUniqueId(), total, false);
System.out.println("Queue Added [" + player + "] with Coins [" + total + "] for [" + caller + "]");
//Clean
_coinQueue.get(player).clear();
}
//Clean
_coinQueue.clear();
} }
} }

View File

@ -1,11 +1,14 @@
package mineplex.core.donation; package mineplex.core.donation;
import java.util.UUID;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase; import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank; import mineplex.core.common.Rank;
import mineplex.core.common.util.Callback; import mineplex.core.common.util.Callback;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.UUIDFetcher;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
public class GemCommand extends CommandBase<DonationManager> public class GemCommand extends CommandBase<DonationManager>
@ -20,32 +23,58 @@ public class GemCommand extends CommandBase<DonationManager>
{ {
if (args.length < 2) if (args.length < 2)
{ {
UtilPlayer.message(caller, F.main("Gem", "Missing Args")); UtilPlayer.message(caller, F.main("gem", "Missing Args: " + F.elem("/gem <player> <amount>")));
return; return;
} }
//Try Online String targetName = args[0];
final Player target = UtilPlayer.searchOnline(caller, args[0], true); String gemsString = args[1];
Player target = UtilPlayer.searchExact(targetName);
if (target == null) if (target == null)
return; {
UUID uuid = UUIDFetcher.getUUIDOf(targetName);
if (uuid != null)
{
rewardGems(caller, null, targetName, uuid, gemsString);
}
else
{
UtilPlayer.message(caller, F.main("Gem", "Could not find player " + F.name(targetName)));
}
}
else
{
rewardGems(caller, target, target.getName(), target.getUniqueId(), gemsString);
}
}
//Give Gems to Target private void rewardGems(final Player caller, final Player target, final String targetName, final UUID uuid, String gemsString)
{
try try
{ {
final int gems = Integer.parseInt(args[1]); int gems = Integer.parseInt(gemsString);
rewardGems(caller, target, targetName, uuid, gems);
}
catch (Exception e)
{
UtilPlayer.message(caller, F.main("gem", "Invalid gems Amount"));
}
}
private void rewardGems(final Player caller, final Player target, final String targetName, final UUID uuid, final int gems)
{
Plugin.RewardGems(new Callback<Boolean>() Plugin.RewardGems(new Callback<Boolean>()
{ {
public void run(Boolean completed) public void run(Boolean completed)
{ {
UtilPlayer.message(caller, F.main("Gem", "You gave " + F.elem(gems + " Gems") + " to " + F.name(target.getName()) + ".")); UtilPlayer.message(caller, F.main("gem", "You gave " + F.elem(gems + " gems") + " to " + F.name(targetName) + "."));
UtilPlayer.message(target, F.main("Gem", F.name(caller.getName()) + " gave you " + F.elem(gems + " Gems") + "."));
} if (target != null)
}, caller.getName(), target.getName(), gems);
}
catch (Exception e)
{ {
UtilPlayer.message(caller, F.main("Gem", "Invalid Gem Amount")); UtilPlayer.message(target, F.main("gem", F.name(caller.getName()) + " gave you " + F.elem(gems + " gems") + "."));
} }
} }
}, caller.getName(), targetName, uuid, gems);
}
} }

View File

@ -1,58 +1,187 @@
package mineplex.core.donation.repository; package mineplex.core.donation.repository;
import java.util.UUID;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.common.util.Callback; import mineplex.core.common.util.Callback;
import mineplex.core.common.util.UUIDFetcher;
import mineplex.core.database.DatabaseRunnable;
import mineplex.core.database.RepositoryBase;
import mineplex.core.database.column.ColumnInt;
import mineplex.core.database.column.ColumnVarChar;
import mineplex.core.donation.repository.token.GemRewardToken; import mineplex.core.donation.repository.token.GemRewardToken;
import mineplex.core.donation.repository.token.PurchaseToken; import mineplex.core.donation.repository.token.PurchaseToken;
import mineplex.core.donation.repository.token.UnknownPurchaseToken; import mineplex.core.donation.repository.token.UnknownPurchaseToken;
import mineplex.core.server.remotecall.AsyncJsonWebCall; import mineplex.core.server.remotecall.JsonWebCall;
import mineplex.core.server.util.TransactionResponse; import mineplex.core.server.util.TransactionResponse;
public class DonationRepository public class DonationRepository extends RepositoryBase
{ {
private static String CREATE_COIN_TRANSACTION_TABLE = "CREATE TABLE IF NOT EXISTS accountCoinTransactions (id INT NOT NULL AUTO_INCREMENT, accounts_uuid VARCHAR(100), reason VARCHAR(100), coins INT, PRIMARY KEY (id), FOREIGN KEY (accounts_uuid) REFERENCES accounts(uuid), INDEX coinUuidIndex (accounts_uuid));";
private static String CREATE_GEM_TRANSACTION_TABLE = "CREATE TABLE IF NOT EXISTS accountGemTransactions (id INT NOT NULL AUTO_INCREMENT, accounts_uuid VARCHAR(100), reason VARCHAR(100), gems INT, PRIMARY KEY (id), FOREIGN KEY (accounts_uuid) REFERENCES accounts(uuid), INDEX gemUuidIndex (accounts_uuid));";
private static String INSERT_COIN_TRANSACTION = "INSERT INTO accountCoinTransactions(accounts_uuid, reason, coins) VALUES(?, ?, ?);";
private static String INSERT_GEM_TRANSACTION = "INSERT INTO accountGemTransactions(accounts_uuid, reason, gems) VALUES(?, ?, ?);";
private static String UPDATE_ACCOUNT_COINS = "UPDATE accounts SET coins = coins + ? WHERE uuid = ?;";
private static String UPDATE_ACCOUNT_GEMS = "UPDATE accounts SET gems = gems + ? WHERE uuid = ?;";
private static String UPDATE_NULL_ACCOUNT_GEMS_AND_COINS_ = "UPDATE accounts SET gems = ?, coins = ? WHERE uuid = ? AND gems IS NULL AND coins IS NULL;";
private String _webAddress; private String _webAddress;
public DonationRepository(String webAddress) public DonationRepository(JavaPlugin plugin, String webAddress)
{ {
super(plugin, "jdbc:mysql://db.mineplex.com:3306/Account?autoReconnect=true&failOverReadOnly=false&maxReconnects=10", "root", "tAbechAk3wR7tuTh");
_webAddress = webAddress; _webAddress = webAddress;
} }
public void PurchaseKnownSalesPackage(Callback<TransactionResponse> callback, String name, int salesPackageId) public void PurchaseKnownSalesPackage(final Callback<TransactionResponse> callback, String name, final String uuid, final int cost, final int salesPackageId)
{ {
PurchaseToken token = new PurchaseToken(); final PurchaseToken token = new PurchaseToken();
token.AccountName = name; token.AccountName = name;
token.UsingCredits = false; token.UsingCredits = false;
token.SalesPackageId = salesPackageId; token.SalesPackageId = salesPackageId;
new AsyncJsonWebCall(_webAddress + "PlayerAccount/PurchaseKnownSalesPackage").Execute(TransactionResponse.class, callback, token); final Callback<TransactionResponse> extraCallback = new Callback<TransactionResponse>()
{
public void run(TransactionResponse response)
{
if (response == TransactionResponse.Success)
executeUpdate(UPDATE_ACCOUNT_GEMS, new ColumnInt("gems", cost), new ColumnVarChar("uuid", 100, uuid));
callback.run(response);
}
};
handleDatabaseCall(new DatabaseRunnable(new Runnable()
{
public void run()
{
new JsonWebCall(_webAddress + "PlayerAccount/PurchaseKnownSalesPackage").Execute(TransactionResponse.class, extraCallback, token);
}
}), "Error purchasing known sales package in DonationRepository : ");
} }
public void PurchaseUnknownSalesPackage(Callback<TransactionResponse> callback, String name, String packageName, boolean coinPurchase, int cost) public void PurchaseUnknownSalesPackage(final Callback<TransactionResponse> callback, final String name, final String uuid, final String packageName, final boolean coinPurchase, final int cost)
{ {
UnknownPurchaseToken token = new UnknownPurchaseToken(); final UnknownPurchaseToken token = new UnknownPurchaseToken();
token.AccountName = name; token.AccountName = name;
token.SalesPackageName = packageName; token.SalesPackageName = packageName;
token.CoinPurchase = coinPurchase; token.CoinPurchase = coinPurchase;
token.Cost = cost; token.Cost = cost;
token.Premium = false; token.Premium = false;
new AsyncJsonWebCall(_webAddress + "PlayerAccount/PurchaseUnknownSalesPackage").Execute(TransactionResponse.class, callback, token); final Callback<TransactionResponse> extraCallback = new Callback<TransactionResponse>()
{
public void run(TransactionResponse response)
{
if (response == TransactionResponse.Success)
{
if (coinPurchase)
{
executeUpdate(UPDATE_ACCOUNT_COINS, new ColumnInt("coins", -cost), new ColumnVarChar("uuid", 100, uuid));
executeUpdate(INSERT_COIN_TRANSACTION, new ColumnVarChar("uuid", 100, uuid), new ColumnVarChar("reason", 100, "Purchased " + packageName), new ColumnInt("coins", -cost));
}
else
{
executeUpdate(UPDATE_ACCOUNT_GEMS, new ColumnInt("gems", -cost), new ColumnVarChar("uuid", 100, uuid));
executeUpdate(INSERT_GEM_TRANSACTION, new ColumnVarChar("uuid", 100, uuid), new ColumnVarChar("reason", 100, "Purchased " + packageName), new ColumnInt("gems", -cost));
}
} }
public void PlayerUpdate(Callback<Boolean> callback, String giver, String name, int greenGems) callback.run(response);
}
};
handleDatabaseCall(new DatabaseRunnable(new Runnable()
{ {
GemRewardToken token = new GemRewardToken(); public void run()
{
new JsonWebCall(_webAddress + "PlayerAccount/PurchaseUnknownSalesPackage").Execute(TransactionResponse.class, extraCallback, token);
}
}), "Error purchasing unknown sales package in DonationRepository : ");
}
public void gemReward(final Callback<Boolean> callback, final String giver, String name, final String uuid, final int greenGems)
{
final GemRewardToken token = new GemRewardToken();
token.Source = giver; token.Source = giver;
token.Name = name; token.Name = name;
token.Amount = greenGems; token.Amount = greenGems;
new AsyncJsonWebCall(_webAddress + "PlayerAccount/GemReward").Execute(Boolean.class, callback, token);
final Callback<Boolean> extraCallback = new Callback<Boolean>()
{
public void run(Boolean response)
{
if (response)
{
executeUpdate(UPDATE_ACCOUNT_GEMS, new ColumnInt("gems", greenGems), new ColumnVarChar("uuid", 100, uuid));
executeUpdate(INSERT_GEM_TRANSACTION, new ColumnVarChar("uuid", 100, uuid), new ColumnVarChar("reason", 100, "Given by " + giver), new ColumnInt("gems", greenGems));
} }
public void rewardCoins(Callback<Boolean> callback, String giver, String name, int coins) callback.run(response);
}
};
handleDatabaseCall(new DatabaseRunnable(new Runnable()
{ {
GemRewardToken token = new GemRewardToken(); public void run()
{
new JsonWebCall(_webAddress + "PlayerAccount/GemReward").Execute(Boolean.class, extraCallback, token);
}
}), "Error updating player gem amount in DonationRepository : ");
}
public void rewardCoins(final Callback<Boolean> callback, final String giver, String name, final String uuid, final int coins)
{
final GemRewardToken token = new GemRewardToken();
token.Source = giver; token.Source = giver;
token.Name = name; token.Name = name;
token.Amount = coins; token.Amount = coins;
new AsyncJsonWebCall(_webAddress + "PlayerAccount/CoinReward").Execute(Boolean.class, callback, token);
final Callback<Boolean> extraCallback = new Callback<Boolean>()
{
public void run(Boolean response)
{
if (response)
{
executeUpdate(UPDATE_ACCOUNT_COINS, new ColumnInt("coins", coins), new ColumnVarChar("uuid", 100, uuid));
executeUpdate(INSERT_COIN_TRANSACTION, new ColumnVarChar("uuid", 100, uuid), new ColumnVarChar("reason", 100, "Rewarded by " + giver), new ColumnInt("coins", coins));
}
callback.run(response);
}
};
handleDatabaseCall(new DatabaseRunnable(new Runnable()
{
public void run()
{
new JsonWebCall(_webAddress + "PlayerAccount/CoinReward").Execute(Boolean.class, extraCallback, token);
}
}), "Error updating player coin amount in DonationRepository : ");
}
@Override
protected void initialize()
{
executeUpdate(CREATE_COIN_TRANSACTION_TABLE);
executeUpdate(CREATE_GEM_TRANSACTION_TABLE);
}
@Override
protected void update()
{
}
public void updateGemsAndCoins(final UUID uuid, final int gems, final int coins)
{
handleDatabaseCall(new DatabaseRunnable(new Runnable()
{
public void run()
{
executeUpdate(UPDATE_NULL_ACCOUNT_GEMS_AND_COINS_, new ColumnInt("gems", gems), new ColumnInt("coins", coins), new ColumnVarChar("uuid", 100, uuid.toString()));
}
}), "Error updating player's null gems and coins DonationRepository : ");
} }
} }

View File

@ -0,0 +1,55 @@
package mineplex.core.event;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Created by Shaun on 10/24/2014.
*/
public class CustomTagEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private Player _player;
private int _entityId;
private String _customName;
public CustomTagEvent(Player player, int entityId, String customName)
{
_player = player;
_entityId = entityId;
_customName = customName;
}
public Player getPlayer()
{
return _player;
}
public String getCustomName()
{
return _customName;
}
public void setCustomName(String customName)
{
_customName = customName;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
public int getEntityId()
{
return _entityId;
}
}

View File

@ -38,6 +38,7 @@ public class Explosion extends MiniPlugin
private boolean _temporaryDebris = true; private boolean _temporaryDebris = true;
private boolean _enableDebris = false; private boolean _enableDebris = false;
private boolean _tntSpread = true; private boolean _tntSpread = true;
private boolean _liquidDamage = true;
private HashSet<FallingBlock> _explosionBlocks = new HashSet<FallingBlock>(); private HashSet<FallingBlock> _explosionBlocks = new HashSet<FallingBlock>();
private BlockRestore _blockRestore; private BlockRestore _blockRestore;
@ -55,6 +56,7 @@ public class Explosion extends MiniPlugin
if (event.getRadius() >= 5) if (event.getRadius() >= 5)
return; return;
if (_liquidDamage)
for (Block block : UtilBlock.getInRadius(event.getEntity().getLocation(), (double) event.getRadius()).keySet()) for (Block block : UtilBlock.getInRadius(event.getEntity().getLocation(), (double) event.getRadius()).keySet())
if (block.isLiquid()) if (block.isLiquid())
block.setTypeId(0); block.setTypeId(0);
@ -264,6 +266,11 @@ public class Explosion extends MiniPlugin
_enableDebris = value; _enableDebris = value;
} }
public void SetLiquidDamage(boolean value)
{
_liquidDamage = value;
}
public void SetTNTSpread(boolean value) public void SetTNTSpread(boolean value)
{ {
_tntSpread = value; _tntSpread = value;

View File

@ -1,47 +1,51 @@
package mineplex.core.friend; package mineplex.core.friend;
import net.minecraft.server.v1_7_R4.PacketPlayOutPlayerInfo; import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniClientPlugin; import mineplex.core.MiniClientPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.account.event.RetrieveClientInformationEvent; import mineplex.core.account.event.RetrieveClientInformationEvent;
import mineplex.core.common.Rank;
import mineplex.core.common.jsonchat.ChildJsonMessage;
import mineplex.core.common.jsonchat.JsonMessage;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.NautHashMap; import mineplex.core.common.util.NautHashMap;
import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.friend.command.AddFriend; import mineplex.core.friend.command.AddFriend;
import mineplex.core.friend.command.DeleteFriend; import mineplex.core.friend.command.DeleteFriend;
import mineplex.core.friend.data.FriendData; import mineplex.core.friend.data.FriendData;
import mineplex.core.friend.data.FriendRepository; import mineplex.core.friend.data.FriendRepository;
import mineplex.core.friend.ui.FriendTabList; import mineplex.core.friend.data.FriendStatus;
import mineplex.core.packethandler.IPacketHandler; import mineplex.core.preferences.PreferencesManager;
import mineplex.core.packethandler.PacketHandler;
import mineplex.core.packethandler.PacketInfo;
import mineplex.core.timing.TimingManager;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
public class FriendManager extends MiniClientPlugin<FriendData> implements IPacketHandler public class FriendManager extends MiniClientPlugin<FriendData>
{ {
private static FriendSorter _friendSorter = new FriendSorter();
private CoreClientManager _clientManager;
private PreferencesManager _preferenceManager;
private FriendRepository _repository; private FriendRepository _repository;
private NautHashMap<Player, FriendTabList> _playerTabMap; public FriendManager(JavaPlugin plugin, CoreClientManager clientManager, PreferencesManager preferences)
private boolean _sendingPackets = false;
public FriendManager(JavaPlugin plugin, PacketHandler packetHandler)
{ {
super("Friends", plugin); super("Friends", plugin);
packetHandler.addPacketHandler(this); _clientManager = clientManager;
_preferenceManager = preferences;
_repository = new FriendRepository(plugin); _repository = new FriendRepository(plugin);
_playerTabMap = new NautHashMap<Player, FriendTabList>();
} }
@Override @Override
@ -65,48 +69,31 @@ public class FriendManager extends MiniClientPlugin<FriendData> implements IPack
{ {
public void run() public void run()
{ {
TimingManager.start(event.getPlayerName() + " friend Account call.");
Set(event.getPlayerName(), _repository.loadClientInformation(event.getUniqueId())); Set(event.getPlayerName(), _repository.loadClientInformation(event.getUniqueId()));
TimingManager.stop(event.getPlayerName() + " friend Account call.");
event.decreaseProcessingCount(); event.decreaseProcessingCount();
} }
}); });
} }
@EventHandler
public void updateTabLists(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
return;
_sendingPackets = true;
for (Player player : Bukkit.getOnlinePlayers())
{
if (!_playerTabMap.containsKey(player) || !_playerTabMap.get(player).shouldUpdate())
continue;
_playerTabMap.get(player).refreshForPlayer(player);
}
_sendingPackets = false;
}
@EventHandler @EventHandler
public void updateFriends(UpdateEvent event) public void updateFriends(UpdateEvent event)
{ {
if (event.getType() != UpdateType.SLOW || Bukkit.getOnlinePlayers().size() == 0) if (event.getType() != UpdateType.SLOW || Bukkit.getOnlinePlayers().size() == 0)
return; return;
final Player[] onlinePlayers = UtilServer.getPlayers();
Bukkit.getServer().getScheduler().runTaskAsynchronously(_plugin, new Runnable() Bukkit.getServer().getScheduler().runTaskAsynchronously(_plugin, new Runnable()
{ {
public void run() public void run()
{ {
final NautHashMap<String, FriendData> newData = _repository.getFriendsForAll(UtilServer.getPlayers()); final NautHashMap<String, FriendData> newData = _repository.getFriendsForAll(onlinePlayers);
Bukkit.getServer().getScheduler().runTask(_plugin, new Runnable() Bukkit.getServer().getScheduler().runTask(_plugin, new Runnable()
{ {
public void run() public void run()
{ {
for (Player player : _playerTabMap.keySet()) for (Player player : Bukkit.getOnlinePlayers())
{ {
if (newData.containsKey(player.getUniqueId().toString())) if (newData.containsKey(player.getUniqueId().toString()))
{ {
@ -116,8 +103,6 @@ public class FriendManager extends MiniClientPlugin<FriendData> implements IPack
{ {
Get(player).Friends.clear(); Get(player).Friends.clear();
} }
_playerTabMap.get(player).updateFriends(Get(player).Friends);
} }
} }
}); });
@ -125,43 +110,94 @@ public class FriendManager extends MiniClientPlugin<FriendData> implements IPack
}); });
} }
@EventHandler
public void addFriendTab(PlayerJoinEvent event)
{
_playerTabMap.put(event.getPlayer(), new FriendTabList(Get(event.getPlayer().getName()).Friends));
_playerTabMap.get(event.getPlayer()).refreshForPlayer(event.getPlayer());
}
@EventHandler
public void removeFriendTab(PlayerQuitEvent event)
{
_playerTabMap.remove(event.getPlayer());
}
public void handle(PacketInfo packetInfo)
{
if (packetInfo.isCancelled())
return;
if (packetInfo.getPacket() instanceof PacketPlayOutPlayerInfo)
{
packetInfo.setCancelled(_sendingPackets);
}
}
public void addFriend(final Player caller, final String name) public void addFriend(final Player caller, final String name)
{ {
boolean update = false;
for (FriendStatus status : Get(caller).Friends)
{
if (status.Name.equalsIgnoreCase(name))
{
if (status.Status == FriendStatusType.Pending || status.Status == FriendStatusType.Blocked)
{
update = true;
break;
}
else if (status.Status == FriendStatusType.Denied)
{
caller.sendMessage(F.main(GetName(), ChatColor.GREEN + name + ChatColor.GRAY + " has denied your friend request."));
return;
}
else if (status.Status == FriendStatusType.Accepted)
{
caller.sendMessage(F.main(GetName(), "You are already friends with " + ChatColor.GREEN + name));
return;
}
else if (status.Status == FriendStatusType.Sent)
{
caller.sendMessage(F.main(GetName(), ChatColor.GREEN + name + ChatColor.GRAY + " has yet to respond to your friend request."));
return;
}
}
}
final boolean updateFinal = update;
Bukkit.getServer().getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable() Bukkit.getServer().getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable()
{ {
public void run() public void run()
{ {
_repository.addFriend(caller.getUniqueId().toString(), name); if (updateFinal)
{
_repository.updateFriend(caller.getName(), name, "Accepted");
_repository.updateFriend(name, caller.getName(), "Accepted");
Bukkit.getServer().getScheduler().runTask(_plugin, new Runnable() Bukkit.getServer().getScheduler().runTask(_plugin, new Runnable()
{ {
public void run() public void run()
{ {
caller.sendMessage(F.main(GetName(), "Added " + ChatColor.GREEN + name + " to your friends list!")); for (Iterator<FriendStatus> statusIterator = Get(caller).Friends.iterator(); statusIterator.hasNext();)
{
FriendStatus status = statusIterator.next();
if (status.Name.equalsIgnoreCase(name))
{
status.Status = FriendStatusType.Accepted;
break;
}
}
}
});
}
else
{
_repository.addFriend(caller, name);
Bukkit.getServer().getScheduler().runTask(_plugin, new Runnable()
{
public void run()
{
for (Iterator<FriendStatus> statusIterator = Get(caller).Friends.iterator(); statusIterator.hasNext();)
{
FriendStatus status = statusIterator.next();
if (status.Name.equalsIgnoreCase(name))
{
status.Status = FriendStatusType.Sent;
break;
}
}
}
});
}
Bukkit.getServer().getScheduler().runTask(_plugin, new Runnable()
{
public void run()
{
if (updateFinal)
caller.sendMessage(F.main(GetName(), "You and " + ChatColor.GREEN + name + ChatColor.GRAY + " are now friends!"));
else
caller.sendMessage(F.main(GetName(), "Added " + ChatColor.GREEN + name + ChatColor.GRAY + " to your friends list!"));
} }
}); });
} }
@ -170,20 +206,177 @@ public class FriendManager extends MiniClientPlugin<FriendData> implements IPack
public void removeFriend(final Player caller, final String name) public void removeFriend(final Player caller, final String name)
{ {
boolean delete = false;
for (Iterator<FriendStatus> statusIterator = Get(caller).Friends.iterator(); statusIterator.hasNext();)
{
FriendStatus status = statusIterator.next();
if (status.Name.equalsIgnoreCase(name))
{
if (status.Status == FriendStatusType.Sent)
{
delete = true;
statusIterator.remove();
}
break;
}
}
final boolean deleteFinal = delete;
Bukkit.getServer().getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable() Bukkit.getServer().getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable()
{ {
public void run() public void run()
{ {
_repository.removeFriend(caller.getUniqueId().toString(), name); if (deleteFinal)
{
_repository.removeFriend(caller.getName(), name);
}
else
{
_repository.updateFriend(caller.getName(), name, "Blocked");
_repository.updateFriend(name, caller.getName(), "Denied");
}
Bukkit.getServer().getScheduler().runTask(_plugin, new Runnable() Bukkit.getServer().getScheduler().runTask(_plugin, new Runnable()
{ {
public void run() public void run()
{ {
caller.sendMessage(F.main(GetName(), "Deleted " + ChatColor.GREEN + name + " from your friends list!")); for (Iterator<FriendStatus> statusIterator = Get(caller).Friends.iterator(); statusIterator.hasNext();)
{
FriendStatus status = statusIterator.next();
if (status.Name.equalsIgnoreCase(name))
{
status.Status = FriendStatusType.Blocked;
break;
}
}
caller.sendMessage(F.main(GetName(), "Deleted " + ChatColor.GREEN + name + ChatColor.GRAY + " from your friends list!"));
} }
}); });
} }
}); });
} }
public void showFriends(Player caller)
{
boolean isStaff = _clientManager.Get(caller).GetRank().Has(Rank.HELPER);
boolean gotAFriend = false;
List<FriendStatus> friendStatuses = Get(caller).Friends;
Collections.sort(friendStatuses, _friendSorter);
caller.sendMessage(C.cAqua + C.Strike + "======================[" + ChatColor.RESET + C.cWhite + C.Bold + "Friends" + ChatColor.RESET + C.cAqua + C.Strike + "]======================");
ArrayList<ChildJsonMessage> sentLines = new ArrayList<ChildJsonMessage>();
ArrayList<ChildJsonMessage> pendingLines = new ArrayList<ChildJsonMessage>();
ArrayList<ChildJsonMessage> onlineLines = new ArrayList<ChildJsonMessage>();
ArrayList<ChildJsonMessage> offlineLines = new ArrayList<ChildJsonMessage>();
for (FriendStatus friend : friendStatuses)
{
if (friend.Status == FriendStatusType.Blocked || friend.Status == FriendStatusType.Denied)
continue;
if (!_preferenceManager.Get(caller).PendingFriendRequests && friend.Status == FriendStatusType.Pending)
continue;
gotAFriend = true;
ChildJsonMessage message = new JsonMessage("").color("white").extra("").color("white");
if (friend.Status == FriendStatusType.Accepted)
{
//Online Friend
if (friend.Online)
{
if (friend.ServerName.contains("STAFF") || friend.ServerName.contains("CUST"))
{
if (isStaff && friend.ServerName.contains("STAFF"))
message.add("Teleport").color("green").bold().click("run_command", "/server " + friend.ServerName).hover("show_text", "Teleport to " + friend.Name + "'s server.");
else
message.add("No Teleport").color("yellow").bold();
}
else
message.add("Teleport").color("green").bold().click("run_command", "/server " + friend.ServerName).hover("show_text", "Teleport to " + friend.Name + "'s server.");
message.add(" - ").color("white");
message.add("Delete").color("red").bold().click("run_command", "/unfriend " + friend.Name).hover("show_text", "Remove " + friend.Name + " from your friends list.");
message.add(" - ").color("white");
message.add(friend.Name).color(friend.Online ? "green" : "gray");
message.add(" - ").color("white");
if (friend.ServerName.contains("STAFF") || friend.ServerName.contains("CUST"))
{
if (isStaff && friend.ServerName.contains("STAFF"))
message.add(friend.ServerName).color("dark_green");
else
message.add("Private Staff Server").color("dark_green");
}
else
message.add(friend.ServerName).color("dark_green");
onlineLines.add(message);
}
//Offline Friend
else
{
message.add("Delete").color("red").bold().click("run_command", "/unfriend " + friend.Name).hover("show_text", "Remove " + friend.Name + " from your friends list.");
message.add(" - ").color("white");
message.add(friend.Name).color(friend.Online ? "green" : "gray");
message.add(" - ").color("white");
message.add("Offline for ").color("gray").add(UtilTime.MakeStr(friend.LastSeenOnline)).color("gray");
offlineLines.add(message);
}
}
//Pending
else if (friend.Status == FriendStatusType.Pending)
{
message.add("Accept").color("green").bold().click("run_command", "/friend " + friend.Name).hover("show_text", "Accept " + friend.Name + "'s friend request.");
message.add(" - ").color("white");
message.add("Deny").color("red").bold().click("run_command", "/unfriend " + friend.Name).hover("show_text", "Deny " + friend.Name + "'s friend request.");
message.add(" - ").color("white");
message.add(friend.Name + " Requested Friendship").color("gray");
pendingLines.add(message);
}
//Sent
else if (friend.Status == FriendStatusType.Sent)
{
message.add("Cancel").color("red").bold().click("run_command", "/unfriend " + friend.Name).hover("show_text", "Cancel friend request to " + friend.Name);
message.add(" - ").color("white");
message.add(friend.Name + " Friendship Request").color("gray");
sentLines.add(message);
}
}
//Send In Order
for (JsonMessage msg : sentLines)
msg.sendToPlayer(caller);
for (JsonMessage msg : offlineLines)
msg.sendToPlayer(caller);
for (JsonMessage msg : pendingLines)
msg.sendToPlayer(caller);
for (JsonMessage msg : onlineLines)
msg.sendToPlayer(caller);
if (!gotAFriend)
{
caller.sendMessage(" ");
caller.sendMessage("Welcome to your Friends List!");
caller.sendMessage(" ");
caller.sendMessage("To add friends, type " + C.cGreen + "/friend <Player Name>");
caller.sendMessage(" ");
caller.sendMessage("Type " + C.cGreen + "/friend" + ChatColor.RESET + " at any time to interact with your friends!");
caller.sendMessage(" ");
}
caller.sendMessage(C.cAqua + C.Strike + "=====================================================");
}
} }

View File

@ -10,33 +10,33 @@ public class FriendSorter implements Comparator<FriendStatus>
{ {
if (a.Online && !b.Online) if (a.Online && !b.Online)
{ {
return -1; return 1;
} }
if (b.Online && !a.Online) if (b.Online && !a.Online)
{ {
return 1; return -1;
} }
// If online we sort by mutual // If online we sort by mutual
if (a.Online && b.Online) if (a.Online && b.Online)
{ {
if (a.Mutual && !b.Mutual) if (a.Status == FriendStatusType.Accepted && b.Status != FriendStatusType.Accepted)
return -1;
else if (b.Mutual && !a.Mutual)
return 1; return 1;
else if (b.Status == FriendStatusType.Accepted && a.Status != FriendStatusType.Accepted)
return -1;
if (a.Name.compareTo(b.Name) > 0) if (a.Name.compareTo(b.Name) > 0)
return -1;
else if (b.Name.compareTo(a.Name) > 0)
return 1; return 1;
else if (b.Name.compareTo(a.Name) > 0)
return -1;
} }
if (a.LastSeenOnline < b.LastSeenOnline) if (a.LastSeenOnline < b.LastSeenOnline)
return -1; return 1;
if (b.LastSeenOnline < a.LastSeenOnline) if (b.LastSeenOnline < a.LastSeenOnline)
return 1; return -1;
return 0; return 0;
} }

Some files were not shown because too many files have changed in this diff Show More